Windows server as FOG Storage Node - proof of concept blog

  • Moderator

    Part 1a

    This is more of a proof of concept than as actual desire of mine. Keeping everything in the *nix world is my motto.

    With that said. I’ve been able to setup nfs on a windows 2012 R2 server with the following powershell commands.

    Import-Module ServerManager
    Add-WindowsFeature FS-NFS-Service
    Import-Module NFS
    mkdir c:\share
    mkdir c:\share\images
    mkdir c:\share\tftpboot
    mkdir c:\share\snapins
    mkdir c:\share\snapins\ssl
    New-NfsShare –Name "images" –Path c:\share\images –Authentication sys -AllowRootAccess $True -EnableUnmappedAccess $True –Permission Readwrite
    Enable-NetFirewallRule -DisplayGroup “Server for NFS” -Verbose

    And then on the FOG Master server the following commands will setup the rest of the fog required bits.

    mount -t nfs <win_storage-node_ip>:/images /mnt
    mkdir /mnt/dev
    touch /mnt/.mntcheck
    touch /mnt/dev/.mntcheck
    umount /mnt

    Create a local FTP user for FOG to use.

    net localgroup fog_users /add
    net user fog_user "mi5ty_cl0ud" /add /EXPIRES:NEVER /PASSWORDCHG:NO /active:YES /Y
    net localgroup fog_users fog_user /add
    icacls c:\share /grant "fog_users:M"

    Setup the FTP server

    Install-WindowsFeature Web-FTP-Server,Web-FTP-Service,Web-FTP-Ext -IncludeManagementTools
    New-WebFtpSite -Name "FOGFtpSite" -Port 21 -PhysicalPath "c:\share" -IPAddress "<win_storage-node_ip>" 
    Set-ItemProperty "IIS:\Sites\FOGFtpSite" -Name -Value 0
    Set-ItemProperty "IIS:\Sites\FOGFtpSite" -Name -Value 0
    Set-ItemProperty "IIS:\Sites\FOGFtpSite" -Name -Value $true
    Set-ItemProperty "IIS:\Sites\FOGFtpSite" -Name ftpserver.userisolation.mode -Value 4
    Add-WebConfiguration "/system.ftpServer/security/authorization" -value @{accessType="Allow";roles="fog_users";permissions="Read,Write";users=""} -PSPath IIS:\ -location "FOGFtpSite"
    Restart-WebItem "IIS:\Sites\FOGFtpSite"

    The next part is the web server setup to hand out the FOS kernel and inits. Since I already installed the FTP service which relies on IIS, IIS is already installed. So all we need to do is prep for the FOS files.

    Lets first create the directory structure that mimics the path on the FOG master server.

    New-Item "IIS:\Sites\Default Web Site\fog" -type Directory
    New-Item "IIS:\Sites\Default Web Site\fog\service" -type Directory
    New-Item "IIS:\Sites\Default Web Site\fog\service\ipxe" -type Directory

    Now that we have the directory, we need to tell IIS to hand out any file that is requested. By default IIS will only pass out files with known extensions like htm, html, asp, and so on. But in our case we want IIS to hand out the inits that end in .xz and the bzImage which doesn’t have an extension. To do this we need to tell IIS to just hand out any file type request (the bzImage is what caused me some pain here, since we are saying any files requested from IIS it will hand out, which could be a security risk if the web site gets hacked)

    (Update: 15-May-2017)
    You must go manually into IIS management console and add a new mime type of “.*” (dot star without the quotes) and with a type of “application/octet-stream”

    There is a better way to configure IIS to send out files with any extension (even no extension) on a per directory basis.

    Create the following file: C:\inetpub\wwwroot\fog\service\ipxe\web.config
    Insert the following code into that web.config file

    <?xml version="1.0" encoding="UTF-8"?>
                 <mimeMap fileExtension="." mimeType="application/octet-stream" />
                 <mimeMap fileExtension=".*" mimeType="application/octet-stream" />

    (End Update: 15-May-2017)

    Now that IIS is all setup and ready you will need to copy all of the files from /var/www/html/fog/service/ipxe to the IIS server in the windows path IIS:\Sites\Default Web Site\fog\services\ipxe
    You can use the following process to copy the files form your master fog server to the windows storage node.

    In an elevated windows command prompt enter
    nfsshare fogipxe=C:\inetpub\wwwroot\fog\service\ipxe -o rw sec=sys root unmapped=yes

    On your fog server key in:

    mount -t nfs <win_storage-node_ip>:/fogipxe /mnt
    cp /var/www/html/fog/service/ipxe/* /mnt
    umount /mnt

    And then finally back on the Windows storage node
    nfsshare fogipxe /delete

    (Update: 15-May-2017)
    The files copied from the fog server seemed to come in with the wrong permissions so we need to reset the permissions on all files from the fog directory and below to the defaults by enabling inheritance on all of the files.
    the following command is wrong, its a place holder until the right syntax can be derived

    icacls C:\inetpub\wwwroot\fog /grant "fog_users:M"

    (End Update: 15-May-2017)

    After you’ve copied the files to the correct directory on IIS you should test your setup.
    First lets pull the FOG background. Open your browser and key in the url to the background. On my IIS server I’ll use this path, you will need to change the IP address to match your IIS server.
    If all goes well you should see the picture of the fog background.

    Now lets get a little daring. Lets pull memdisk (a binary file).
    If all goes well you should be prompted with a save file dialog.

    And then one last test, lets pull a file with an unknown extension.
    Again you should be prompted with a save file dialog.

    Onto the next part. For this section we need to install a tftp server to allow pxe booting from your windows storage node. Windows does have a natively built in tftp client, but no tftp server. So for this part we will use an freeware tftp server that I’ve used for years (Tftpd32).

    Go to the following URL:
    Download the tftpd64 service edition (installer)
    Launch the installer you just downloaded.
    Read and agree to EULA if you accept it continue.
    Select (all) Options: Add start menu shortcuts, Add desktop icon, Start service Tftp32_svc, start service monitoring
    Use default install location: C:\Program Files\Tftpd64_SE
    Tftpd64 Service console should launch
    Select the Settings button
    Select the GLOBAL tab
    Uncheck all options except TFTP Sever. The only selection option we need is “TFTP Server”.
    Select the TFTP tab
    For the base directory, select the browse button and then navigate to the c:\share\tftpboot folder
    Select OK
    In the tftp options section enable PXE Compatibility option. Leave all other settings at their default
    Press OK
    From a command windows with elevated rights

    netsh advfirewall firewall add rule name="TFTP Server" dir=in action=allow program="%ProgramFiles%\Tftpd64_SE\tftpd64_svc.exe"
    sc stop Tftpd32_svc
    sc start Tftpd32_svc

    The remaining steps are to copy the contents of the FOG server’s /tftpboot directory to your Windows storage node’s c:\share\tftpboot folder. For this we’ll use NFS to export the directory on the FOG server and then mount that nfs share with your windows server.

    In an elevated windows server console key in
    nfsshare fogpxe=C:\share\tftpboot -o rw sec=sys root unmapped=yes

    On the FOG server

    mount -t nfs /mnt
    cp -R /tftpboot/* /mnt
    umount /mnt

    On the Windows storage node from an elevated command prompt
    nfsshare fogpxe /delete

    If you can make it this far in the setup your storage node should be setup.

    Todo list:

    1. (done, images are now replicating because Todo #2 was required) Define the Windows storage node in the Master Storage Node (as of the next day all of my images and scripts from the Master storage node are now on the windows storage node)
    2. (done, ftp server setup) Determine if the FTP service is really required for a storage node if we will only capture to the master node [edit] duh, ftp server is required for image replication. Must work on this now[/edit]
    3. (done, tftp server setup) See if the tftp service is needed if we want to support remote pxe booting [edit] windows 2012 does not have built in tftp server, may have to use tftpd32 or similar if pxe booting is needed [/edit]
    4. (www server is setup) Determine if IIS is needed to support serving out the kernel and init images
    5. Test this entire setup to see if it actually worls.
  • Moderator

    @Tom-Elliott I’m currently spinning up a new FOG 1.4.0 server to test multicasting across subnets (and usb FOS booting it now appears). I’ll divert that setup to test FOG with a windows 2012 server setup as a storage node. I don’t have a centos template on this dev box so its going to take me some time to get up to speed. I do have a windows 2012 template so that one shouldn’t take too long.

    I would still expect it to take until this evening before I can get to testing with my day job and everything…

  • @vkenny Location Management comes from a Plugin that’s known as the “Location Plugin”.

    To install the Location Plugin first goto:

    FOG Configuration Page->FOG Settings->Plugin Settings->FOG_PLUGIN_ENABLE
    Check the box, press save. You’ll see a new menu item appear in the Main menu system. Click on this new menu item.

    You will be presented with a list of plugins.
    Click “Location” icon
    Click “Activate Plugins”
    Click “Location” icon
    Click “Install plugin”

    You will see the new Location menu item appear in your menu.

  • @george1421 Where is “Location Management” is that relating to an older version of FOG that no longer has this or am I completely missing something?

  • Moderator


    Right now this post is a jumbled up mess. I’m going to break down my POC environment and build it again. I’ll verify the settings are correct and post a concise kb one for 2008 and one for 2012. But in theory it does work.

  • @george1421 you never cease to amaze.

  • Moderator

    Part 3 (Final)

    Today I went in and registered one of my VMs on the dev fog server. I ran through the full registration and allocated this host to the “winsn” location.

    I pxe booted the vm and saw that it initially connected to the dev fog server and then the dev fog server redirected the client to pull the bzImage and init.xz from the Windows storage node (!!getting excited level 20% !!).

    The vm downloaded both bzImage and the init from the windows storage node cleanly (excitement level 50%).

    I saw the FOS kernel boot and started the initial prep work for imaging (excitement level 80%).

    Partclone did its prep work and started downloading the image (excitement level 90%). I quickly checked the windows storage node and ran netstat -an and this was the the line I was searching for


    This told me that the windows storage node was communicating with an external (dhcp) device over the NFS protocol!!

    Imaging completed and the workstation started booting windows (time for a smoke and a beer) [full disclosure I don’t smoke so I’ll just take two beers instead].

    So it IS possible to setup a FOG / MS Windows Storage node. In the end I’m still not seeing the value in it, but it IS DOABLE.

    !!Success!! and the end of this POC project…

  • Moderator

    Part 2

    For the remainder of this thread I’ll continue with the Windows 2008 R2 server as the windows storage node. If time permits I’ll circle back and attempt the same thing with 2012, but based on what I’ve done so far I have confidence that 2012 will work equally as well as 2008.

    There is one bit of error data I found running through a QC check before moving onto the next part. I created the FTP site using the powershell command: New-WebFtpSite -Name "FOGFtpSite" -Port 21 -PhysicalPath "c:\share" -IPAddress "" While testing I found that the -PhysicalPath switch did not update the ftp server setting causing the ftp server to report that the home folder could not be located. I went into the mmc console for IIS and manually set the homedrive for the ftp server. Once that was done I was able to login via FTP.

    On to the QC checks before moving on to the FOG setup of this. For these tests we’ll use a windows 7 workstation.

    First we need to test to see if the FTP server is working and we can login using the fog_user account we setup.

    Connected to
    220 Microsoft FTP Service
    User ( fog_user
    331 Password required for fog_user.
    230 User logged in.

    Just issue a dir command to see if we can see the files we created.

    ftp> dir
    200 PORT command successful.
    125 Data connection already open; Transfer starting.
    05-22-16  08:39PM       <DIR>          images
    05-22-16  07:41PM       <DIR>          snapins
    05-24-16  02:42PM       <DIR>          tftpboot
    226 Transfer complete.
    ftp: 144 bytes received in 0.00Seconds 144000.00Kbytes/sec.

    That completes the FTP test

    The next step is to test the tftp server

    C:\>tftp get default.ipxe
    Transfer successful: 427 bytes in 1 second, 427 bytes/s

    If your tests matches the above then we can move onto the FOG part of the setup.

    My dev environment was created fresh with the latest trunk version of FOG 1.2.0. The following is the complete steps I went through to setup FOG to communicate with the windows storage node.

    Fog Configuration -> Plugin System

    Plugin Managment
    Activate and install Location management plugin

    Storage Management -> Add Storage node
    Name: WinStoreNode
    IP Address:
    Web Root: /fog
    Max Clients: 10
    Is Master Node: (unchecked)
    Replication Bandwidth: 0
    Storage Group: default
    Image Path: /images
    FTP Path: /images
    Snapin Path: /snapins
    SSL Path: /snapins/ssl
    Bitrate: (blank)
    Interface: eth0
    Is Enabled: (checked)
    Is Graph enabled: (unchecked)
    Managment Username: fog_user
    Managment Password: mi5ty_cl0ud

    Location Managment -> Create New Location
    Location Name: winsn
    Storage Group: Default
    Storage Node: WinStoreNode
    Use inits and kernels from this node: (checked)
    Press the Add button

    I next copied a host image from my production server to the dev environment. Once all of the files were in place, I went back to the FOG GUI and added an Image reference that defined the image I copied over from my production server.

    And finally I restarted the FOGImageReplication service. Inspecting the /opt/fog/log directory you should see the replication service start up with a transfer log specifically for the windows storage node we just created (i.e. fogreplicator.log.transfer.WinStoreNode.log). If you see this long file, hop over to your windows storage node and inspect the directory c:\share\images to see if the image files have started to copy over from the FOG server.

  • Moderator

    Part 1b

    Here is a rough outline on how to do this same thing with Windows 2008 R2. I hope to be able to test this as soon as I get my test environment rebuilt.

    The following executed correctly on Windows 2008 R2 with Windows Managment Framework installed which installs PowerShell 3.0 I’m actually not using very many powershell commands here, basically just to add windows roles and features. Powershell on Windows 2008 is a bit lacking as compared to 2012.

    Set-ExecutionPolicy Unrestricted -Scope CurrentUser
    Import-Module ServerManager
    Add-WindowsFeature FS-FileServer
    Add-WindowsFeature FS-NFS-Services
    mkdir c:\share
    mkdir c:\share\tftpboot
    mkdir c:\share\images
    mkdir c:\share\snapins
    mkdir c:\share\snapins\ssl
    net localgroup fog_users /add
    net user fog_user "mi5ty_cl0ud" /add /EXPIRES:NEVER /PASSWORDCHG:NO /active:YES /Y
    net localgroup fog_users fog_user /add
    icacls c:\share /grant "fog_users:M"
    nfsshare images=c:\share\images -o rw sec=sys root unmapped=yes
    netsh advfirewall firewall set rule group="Server for NFS" new enable=Yes
    On FOG server
    mount -t nfs /mnt
    mkdir /mnt/dev
    touch /mnt/.mntcheck
    touch /mnt/dev/.mntcheck
    umount /mnt
    # On windows server
    Add-WindowsFeature Web-WebServer,Web-Common-Http,Web-FTP-Server,Web-FTP-Service,Web-FTP-Ext,Web-Mgmt-Console
    Import-Module WebAdministration
    New-WebFtpSite -Name "FOGFtpSite" -Port 21 -PhysicalPath "c:\share" -IPAddress "" 
    Set-ItemProperty "IIS:\Sites\FOGFtpSite" -Name -Value 0
    Set-ItemProperty "IIS:\Sites\FOGFtpSite" -Name -Value 0
    Set-ItemProperty "IIS:\Sites\FOGFtpSite" -Name -Value $true
    Set-ItemProperty "IIS:\Sites\FOGFtpSite" -Name ftpserver.userisolation.mode -Value 4
    Add-WebConfiguration "/system.ftpServer/security/authorization" -value @{accessType="Allow";roles="fog_users";permissions="Read,Write";users=""} -PSPath IIS:\ -location "FOGFtpSite"
    Restart-WebItem "IIS:\Sites\FOGFtpSite"
    New-Item "IIS:\Sites\Default Web Site\fog" -type Directory
    New-Item "IIS:\Sites\Default Web Site\fog\service" -type Directory
    New-Item "IIS:\Sites\Default Web Site\fog\service\ipxe" -type Directory
    In IIS management for the default web site must update mime types to add “.*” (dot star without the quotes) and with a type of “application/octet-stream”
    #Now that IIS is all setup and ready you will need to copy all of the files from /var/www/html/fog/service/ipxe to the IIS server in the windows path IIS:\Sites\Default Web Site\fog\services\ipxe
    #Lets do this with nfs. Create the NFS share on the Windows server
    nfsshare fogipxe=C:\inetpub\wwwroot\fog\service\ipxe -o rw sec=sys root unmapped=yes
    On FOG server
    mount -t nfs /mnt
    cp /var/www/html/fog/service/ipxe/* /mnt
    umount /mnt
    # On Windows server, remove the nfs share
    nfsshare fogipxe /delete
    (Note: you need to "replace all child objects permission with inheritable permissions from this object" on C:\inetpub\wwwroot\fog\service\ipxe or the bg download test will fail
    # need to figure out the icacls command on this one
    Install the TFTP service as outlined in the OP

  • #wiki worthy

  • @george1421 just a slight correction. It is not using 1.2.0 method of checking. That is way gone and the new method is faster and simpler. Each node is aware of the images they have available to them now where 1.2.0 just checked if it existed on the node it was to pull from. This would cause problems in 1.2.0 because the master was checked at task creation. The client would load up all the way and then if it was pointed at a node that didn’t have the image would fail quite dramatically. Now boot will only boot to a node that has the image on it.

  • Moderator

    Tom added some new code checks (30-Mar-16) that will have FOG revert back to the 1.2.0 way of checking for images if the storage node doesn’t respond properly to the http query. This opens the door again to proving if a windows storage node is possible.

  • @george1421 said:

    Determine if the FTP service is really required for a storage node if we will only capture to the master node

    If you want your images to be replicated to the node automatically, it’s absolutely required.

  • Moderator

    Well my first round of tests have failed, but also did add some light onto what I suspected. The storage node needs a web server running because the master storage node makes some calls to the storage node for image deployment. The following is a call I trapped on the IIS server.

    /fog/management/index.php node=client&sub=wakeEmUp&mac=00:50:56:94:f5:21


    /fog/status/getimages.php path=%2Fimages

    At this time I don’t think the windows server (or a synology nas) will function as a storage node out of the box. I could load apache or the php plugin for IIS and get it to work. But I’m not sure if its worth the effort.

    I can setup nfs on windows, I can setup ftp and the images will replicate to the windows server. But without php and the rest of the storage node code, I’m at a standstill.

    As it stands now, this post will not work either and should be deprecated.

  • Moderator

    (place holder)

  • Moderator

    (place holder)

  • Moderator

    (place holder)