Deployment guide

FOG Project

Overview

This image runs FOG Project 1.5.10.1903 on Ubuntu 24.04 LTS. FOG is a free, open source network cloning and imaging platform. You capture a disk image once from a reference machine, store it centrally, and then deploy that image to as many machines as you need over the network, driven by a PXE network boot rather than by anyone carrying media from desk to desk.

Around that core, FOG provides the management work that surrounds imaging: a hardware inventory of every machine that has checked in, a record of which image each one is running, machine groups, scheduled capture and deploy tasks, and snapins that install software or apply a change to a group of machines after imaging.

The appliance has two planes, and they have deliberately different security postures:

  • The management plane is the FOG web console and REST API on port 80. It is authenticated, with a console password and API tokens generated uniquely on your VM's first boot.
  • The boot plane is TFTP on 69/udp serving the iPXE bootloaders, plus NFS on 2049 serving the image store. It is anonymous by protocol necessity: a machine that is powering on cannot present credentials, and TFTP has no authentication in the protocol at all. You scope it with your Azure Network Security Group and the subnet-scoped NFS export.

This image deliberately ships no DHCP server. FOG can install and run one, but on an Azure VNet that would be actively harmful. It would compete with Azure's own platform DHCP and can break networking for every VM on the subnet.

This image is built with FOG's DHCP server disabled. The build fails if it finds any DHCP server package installed or anything listening on 67/udp. You point your existing DHCP server at this server instead, as Step 9 covers.

What you get:

  • FOG Project 1.5.10.1903, installed by the project's own installer from the pinned upstream commit c8a5665
  • Apache 2.4 with PHP 8.3 serving the web console and REST API at /fog/management
  • MariaDB, bound to 127.0.0.1 only. The database is a purely local dependency of the web application
  • tftpd-hpa on 69/udp serving the full set of iPXE bootloaders from /tftpboot (BIOS, UEFI, Secure Boot, arm64 and per-NIC variants)
  • nfs-kernel-server serving the image store at /images, scoped at first boot to your VM's own subnet rather than upstream's export-to-every-host default
  • vsftpd for FOG's own image file management
  • The seven FOG service daemons (scheduler, image replicator, multicast manager, ping hosts, snapin hash, snapin replicator, image size), all enabled
  • A per-VM console password, REST API token and user API token generated on first boot into /root/fog-project-credentials.txt, readable only by root. No shared or default login exists in the image - FOG's documented fog / password default does not work on your VM
  • The complete corresponding source at /opt/fog-source with the GPLv3 license text, which satisfies the license's source obligation on the image itself
  • An Ubuntu 24.04 LTS base, patched at build time, with unattended security upgrades enabled
  • 24/7 SecureAnyCloud support

Before you start: what PXE imaging requires

FOG images machines by PXE network boot, and that imposes real network requirements. Read this before you design your deployment, because it determines where this VM belongs.

A machine being imaged powers on, asks its local DHCP server for an address, and that DHCP server tells it where to fetch a bootloader (options 66 and 67). The machine then fetches the bootloader over TFTP, chains to FOG over HTTP, and moves image data over NFS.

  • The DHCP handoff happens on the client's local broadcast domain, so the DHCP server that answers must be one you can configure. This appliance does not provide it.
  • Everything after that handoff (TFTP, HTTP and NFS) is routed unicast. The FOG server itself therefore does not need to be on the same layer 2 segment as the clients. It needs to be routable from them.

The supported topology on Azure is therefore this VM in your VNet, with your client machines on premises or in a connected network. The clients reach the VM over VPN or ExpressRoute. Your existing on-premises DHCP server sets options 66 and 67 to point at this VM's private address.

Two FOG capabilities genuinely do not work on an Azure VNet, and no configuration changes that:

  • Multicast deployment, which images many machines simultaneously from one stream. Azure VNets do not carry multicast. Unicast deployment to each machine works normally.
  • FOG's proxyDHCP mode, which supplies boot options without running a full DHCP server. It depends on broadcast traffic, which Azure VNets also do not carry. Setting options 66 and 67 on your own DHCP server is the supported path, and is what Step 9 covers.

Plan for bandwidth as well. Disk images are tens of gigabytes, and deploying them from Azure to on-premises machines pulls that volume across your VPN or ExpressRoute link for every machine. For large on-premises fleets, a FOG storage node on the client network is the usual answer, with this VM as the management server.

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet and subnet in the target region. Standard_B2ms (2 vCPU / 8 GiB RAM) is the recommended size, because FOG runs Apache, PHP, MariaDB, NFS and TFTP together.

The OS disk holds /images. Captured images are large, so size the disk for your image library. Alternatively, attach a data disk and mount it at /images.

NSG inbound rules: allow 22/tcp from your management network, 80/tcp from the networks that need the console, and 69/udp, 2049/tcp and 21/tcp from the subnets whose machines will be imaged. Do not expose any of these to the internet. The boot plane is anonymous by design, so the NSG is what scopes it.

Step 1 - Deploy from the Azure Marketplace

In the Azure portal, search the Marketplace for FOG Project on Ubuntu 24.04 LTS by SecureAnyCloud and select Create.

Choose your subscription, resource group and region, and set the size to Standard_B2ms. Select SSH public key authentication with the username azureuser. Allow inbound 22/tcp from your management network only.

Add the remaining rules from the Prerequisites section after the VM is created.

Step 2 - Deploy from the Azure CLI

Run these commands on your own workstation, not on the VM. Accept the image terms once per subscription before the first deployment:

az vm image terms accept --publisher sac --offer fog-project-ubuntu-24-04 --plan default
az group create --name fog-rg --location eastus
az vm create \
  --resource-group fog-rg \
  --name fog-server \
  --image sac1647283583153:fog-project-ubuntu-24-04:default:latest \
  --size Standard_B2ms \
  --storage-sku StandardSSD_LRS \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Step 3 - Connect to your VM

ssh azureuser@<vm-ip>

Step 4 - Confirm the services are running

FOG is several cooperating services, so check them together. All of them must report active.

sudo systemctl is-active apache2 mariadb tftpd-hpa nfs-kernel-server vsftpd
active active active active active

The seven FOG daemons run alongside them:

sudo systemctl is-active FOGScheduler FOGImageReplicator FOGImageSize FOGMulticastManager FOGPingHosts FOGSnapinHash FOGSnapinReplicator
active active active active active active active

The web console answers on the loopback interface:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/fog/management/index.php
200

Step 5 - Confirm no DHCP server is running

This property makes FOG safe to run on a cloud network, so verify it yourself. FOG records its DHCP decision in its own settings file:

sudo grep -E '^(bldhcp|dodhcp)=' /opt/fog/.fogsettings
dodhcp='N' bldhcp='0'

No DHCP server package is installed:

for p in isc-dhcp-server kea-dhcp4-server dnsmasq; do if dpkg-query -W -f='${Status}' "$p" 2>/dev/null | grep -q '^install ok installed$'; then echo "$p: INSTALLED" else echo "$p: not installed" fi done
isc-dhcp-server: not installed kea-dhcp4-server: not installed dnsmasq: not installed

Nothing is listening on the DHCP server port:

ss -lnu | grep -c ':67 ' || echo 0
0

Step 6 - Retrieve your per-VM credentials

Every credential on this VM was generated on its own first boot. The file is readable only by root.

sudo cat /root/fog-project-credentials.txt

You will see the console login, both API tokens, the server address and the database credentials. The console password is what you use in Step 8:

sudo grep -E '^(fog_web_url|fog_admin_user|fog_server_address|fog_tftp_bootfile)=' /root/fog-project-credentials.txt

The file is 0600 root:root:

sudo ls -l /root/fog-project-credentials.txt

FOG's documented default login, fog / password, does not work on your VM. The build replaces it with the generated password before the image is captured, and first boot then sets a value unique to your machine.

Step 7 - Confirm the boot plane and image store

Fetch a PXE bootloader over TFTP exactly as a booting machine would:

cd /tmp && rm -f undionly.kpxe && tftp 127.0.0.1 -c get undionly.kpxe && ls -l undionly.kpxe
-rw-r--r-- 1 azureuser azureuser 105509 Jul 19 08:40 undionly.kpxe

The iPXE chain file tells booting machines where to find the FOG server. It is regenerated with your VM's address on first boot:

sudo tail -1 /tftpboot/default.ipxe

The image store is exported over NFS, scoped to your VM's own subnet rather than to every host:

sudo exportfs -s
/images 10.0.0.0/24(sync,no_wdelay,hide,insecure_locks,fsid=0,anonuid=1001,anongid=1001,sec=sys,ro,secure,root_squash,all_squash) /images/dev 10.0.0.0/24(async,no_wdelay,hide,fsid=1,anonuid=1001,anongid=1001,sec=sys,rw,secure,root_squash,all_squash)

If your machines are imaged from a different subnet reached over VPN or ExpressRoute, add that CIDR to /etc/exports and re-export. The following block is an example to adapt, not something to run as is:

# /etc/exports - add your imaging subnet alongside the local one /images 10.50.0.0/16(ro,sync,no_wdelay,subtree_check,insecure_locks,all_squash,anonuid=1001,anongid=1001,fsid=0) /images/dev 10.50.0.0/16(rw,async,no_wdelay,subtree_check,all_squash,anonuid=1001,anongid=1001,fsid=1)

Step 8 - Sign in to the FOG console

Browse to http://<vm-ip>/fog/management. Sign in as fog with the fog_admin_password value from Step 6.

The dashboard shows the server at a glance: storage group activity, disk usage on the storage node and imaging activity over the last 30 days.

Step 9 - Point your DHCP server at the FOG server

FOG needs your existing DHCP server to tell booting machines where to find it. Set two options on the scope serving the machines you want to image:

  • Option 66 (next-server / TFTP server name): this VM's private IP address, which is the fog_server_address value from Step 6
  • Option 67 (filename / bootfile name): undionly.kpxe for BIOS machines, or snponly.efi for UEFI machines

On an ISC DHCP server, the scope looks like this. Adapt the addresses to your network. This is an example, not something to run on this VM:

# dhcpd.conf - point PXE clients at the FOG server subnet 10.50.0.0 netmask 255.255.0.0 { range 10.50.10.100 10.50.10.200; option routers 10.50.0.1; next-server 10.0.0.4;
# your FOG server's private IP filename "undionly.kpxe"; # use "snponly.efi" for UEFI clients }

On a Windows DHCP server, set scope option 066 Boot Server Host Name to the FOG server's IP and 067 Bootfile Name to undionly.kpxe or snponly.efi.

Mixed BIOS and UEFI fleets need your DHCP server to select the bootfile by client architecture. Both ISC DHCP and Windows Server support this. FOG's documentation covers the exact syntax.

Step 10 - Register a machine

With DHCP pointing at the server, boot a client machine from the network. It fetches the bootloader, chains to FOG, and presents the FOG boot menu. Choose Perform Full Host Registration and Inventory to add it to FOG with its hardware inventory.

Registered machines appear under Host Management, where you assign an image, put them in groups and schedule tasks.

Step 11 - Define an image and capture

Under Image Management, select Create New Image and give it a name, a storage group and an image type. Single Disk - Resizable suits most single-disk Windows and Linux workstations.

To capture, assign the image to your reference machine under Host Management, schedule a Capture task, and network boot that machine. It boots into FOG's imaging environment and uploads the image to /images.

To deploy, assign the same image to the target machines, schedule a Deploy task, and boot them.

Step 12 - Use the REST API

FOG's REST API is enabled on this image with tokens generated for your VM. Both tokens are stored ready to paste straight into the request headers:

API_TOKEN=$(sudo grep '^fog_api_token=' /root/fog-project-credentials.txt | cut -d= -f2-)
USER_TOKEN=$(sudo grep '^fog_user_api_token=' /root/fog-project-credentials.txt | cut -d= -f2-)
curl -s -H "fog-api-token: ${API_TOKEN}" -H "fog-user-token: ${USER_TOKEN}" \
  http://127.0.0.1/fog/system/info
success

List the registered machines as JSON:

API_TOKEN=$(sudo grep '^fog_api_token=' /root/fog-project-credentials.txt | cut -d= -f2-)
USER_TOKEN=$(sudo grep '^fog_user_api_token=' /root/fog-project-credentials.txt | cut -d= -f2-)
curl -s -H "fog-api-token: ${API_TOKEN}" -H "fog-user-token: ${USER_TOKEN}" \
  http://127.0.0.1/fog/host | head -c 200

Requests without valid tokens are rejected:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/fog/system/info
403

FOG's hostName column is 16 characters, so machine names are truncated beyond that.

Security

  • No DHCP server. FOG's own DHCP server is not installed and is not running. The build asserts this, and every first boot asserts it again. The appliance refuses to start a DHCP server.
  • No default credentials. FOG's documented fog / password default does not authenticate on your VM. The console password, both API tokens, both database passwords and the storage account password are generated on your VM's first boot and exist nowhere else. They are written to /root/fog-project-credentials.txt at 0600 root:root.
  • The database is not reachable off the VM. MariaDB is bound to 127.0.0.1 with name resolution disabled.
  • The image store is scoped. Upstream FOG exports /images to every host with /images/dev writable. This image exports it to your VM's own subnet instead, and you widen it deliberately as shown in Step 7.
  • The boot plane is anonymous by protocol necessity. TFTP has no authentication, and a machine that is powering on cannot present credentials. Scope 69/udp, 2049/tcp and 21/tcp with your NSG to the subnets that image machines, and never expose them to the internet.
  • FOG stores console passwords as unsalted MD5. That is upstream FOG's scheme and cannot be changed without forking its authentication. Treat the console as a trusted-network service, put it behind your NSG, and do not reuse the console password anywhere else.
  • Change the console password from Users in the web console if you want a value you have chosen rather than the generated one.

Maintenance

Ubuntu security updates apply automatically through unattended upgrades. Restart the appliance after a kernel update:

sudo systemctl restart apache2 mariadb tftpd-hpa nfs-kernel-server

Back up the FOG database and your image library. The database holds the inventory, groups, tasks and settings:

sudo mysqldump fog | gzip > /tmp/fog-backup.sql.gz && ls -lh /tmp/fog-backup.sql.gz

Watch free space on /images, because it fills as your image library grows:

df -h /images | tail -1

License and source

FOG Project is licensed under the GNU General Public License, version 3 or later. The complete corresponding source for the version in this image ships on the image:

ls /opt/fog-source/LICENSE /opt/fog-source/SAC-SOURCE-NOTICE.txt

The notice file records the exact upstream commit, the source URLs for the bundled iPXE and Syslinux bootloaders, and a written offer for machine-readable source. Nothing in SecureAnyCloud's terms restricts your rights in the FOG software or any other GPL-licensed component.

Support

SecureAnyCloud provides 24/7 support for this image. Contact sales@secureanycloud.com. For questions about FOG itself, the project's own documentation is at docs.fogproject.org and its community forum is at forums.fogproject.org.

Deploy on Azure

Launch FOG Project on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure