Jump to content
  • entries
  • comments
  • views

Running pfSense as an Azure IaaS Virtual Machine



A client of mine has asked me if it would be possible to run pfSense as a Microsoft Azure IaaS Virtual Machine. pfSense® software is a free, open source customized distribution of FreeBSD, specifically tailored for use as a firewall and router that is entirely managed via web interface.

At that time, I had in mind that running FreeBSD 10 under Hyper-V and in Microsoft Azure, is something that can be done. So, I decided to build a deployment as a Proof of Concept and to write a blog post about this deployment.

This post will provide instructions and all the necessary steps to prepare, upload and run pfSense-2.2.3 in Microsoft Azure.

Please note, that FreeBSD is not currently an endorsed distribution in Microsoft Azure and therefore is not supported.


Let’s put, what we want to achieve, into context. The deployment’s design is as follows:



In order to prepare a pfSense image for Microsoft Azure, we should download the latest x64 image and install it locally, on a server with Windows Server 2012 R2, as a Hyper-V Virtual Machine:

  1. Download the latest x64 pfSense image from Latest Stable Version of pfSense (As of July 2015 the latest version is 2.2.3)
  2. Decompress the image file to extract the Installation ISO pfSense-LiveCD-2.2.3-RELEASE-amd64-20150623-1637.iso
  3. Attach the ISO file as a DVD Drive to newly created Hyper-V Virtual Machine


  1. Start the installation of pfSense


  • After successful installation of pfSense, enable SSH


  • Install Python 2.7 and required modules
[2.2.3-RELEASE][admin@pfSense.localdomain]/: pkg install python27 py27-asn1
Updating FreeBSD repository catalogue...
FreeBSD repository is up-to-date.
All repositories are up-to-date.
Checking integrity... done (0 conflicting)
The following 3 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        python27: 2.7.10
        py27-asn1: 0.1.7,1
        py27-setuptools27: 17.0

The process will require 67 MiB more space.

Proceed with this action? [y/N]: y
[1/3] Installing python27-2.7.10...
[1/3] Extracting python27-2.7.10: 100%
[2/3] Installing py27-setuptools27-17.0...
[2/3] Extracting py27-setuptools27-17.0: 100%
[3/3] Installing py27-asn1-0.1.7,1...
[3/3] Extracting py27-asn1-0.1.7,1: 100%
Message for python27-2.7.10:

Note that some standard Python modules are provided as separate ports
as they require additional dependencies. They are available as:

bsddb           databases/py-bsddb
gdbm            databases/py-gdbm
sqlite3         databases/py-sqlite3
tkinter         x11-toolkits/py-tkinter


You should symlink the new python 2.7 binary

[2.2.3-RELEASE][admin@pfSense.localdomain]/: ln -s /usr/local/bin/python2.7 /usr/bin/python
  •  Install sudo

Typically on Azure, root account is disabled and we using uprovileged user to login. An unprivileged user should utilize sudo to run commands with elevated privileges.

[2.2.3-RELEASE][admin@pfSense.localdomain]/: pkg install sudo
Updating FreeBSD repository catalogue...
FreeBSD repository is up-to-date.
All repositories are up-to-date.
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        sudo: 1.8.14

The process will require 3 MiB more space.
796 KiB to be downloaded.

Proceed with this action? [y/N]: y
Fetching sudo-1.8.14.txz: 100%  796 KiB 815.0kB/s    00:01
Checking integrity... done (0 conflicting)
[1/1] Installing sudo-1.8.14...
[1/1] Extracting sudo-1.8.14: 100%
  •  Install the Azure Linux Agent

GitHub is the repository where you can find the latest version of Azure Linux Agent


Version 2.0.10 or later is required for FreeBSD. Branch 2.0 is typically very stable and as of July 2015 the latest version is 2.0.14.

[2.2.3-RELEASE][admin@pfSense.localdomain]/: wget https://raw.githubusercontent.com/Azure/WALinuxAgent/2.0/waagent
--2015-07-23 13:25:16--  https://raw.githubusercontent.com/Azure/WALinuxAgent/2.0/waagent
Resolving raw.githubusercontent.com (raw.githubusercontent.com)...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 245087 (239K) [text/plain]
Saving to: 'waagent'

waagent                         100%[======================================================>] 239.34K   624KB/s   in 0.4s

2015-07-23 13:25:17 (624 KB/s) - 'waagent' saved [245087/245087]

[2.2.3-RELEASE][admin@pfSense.localdomain]/: mv ./waagent /usr/sbin/
[2.2.3-RELEASE][admin@pfSense.localdomain]/: chmod 755 /usr/sbin/waagent
[2.2.3-RELEASE][admin@pfSense.localdomain]/: /usr/sbin/wa
[2.2.3-RELEASE][admin@pfSense.localdomain]/: /usr/sbin/waagent -install

  • Set IP Addresses

Configure WAN (hn0) Interface as DHCP client.

Assign Static IP Address,, to LAN (hn1) Interface


  •  Shutdown The pfSense Virtual Machine

Now the pfSense Virtual Machine is ready for running in Microsoft Azure.

Upload the pfSense-2.3.3 VHD to Azure

Using the following PowerShell commands, first we upload the pfSense VHD to Microsoft Azure Storage Account and then we create a custom image:

# Variables Section
$DestFile = "https://pfsa.blob.core.windows.net/vhds/pfSense-2.2.3-amd64.vhd"
$SourceFile = "C:\Hyper-V\pfSense\Virtual Hard Disks\pfSense-2-2-3.vhd"

# VHD Upload
Add-AzureVhd -Destination $DestFile -LocalFilePath $SourceFile
# Create an Image
Add-AzureVMImage -ImageName "pfSense-2.2.3" -MediaLocation $DestFile -OS Linux

Note that we are using OS type Linux instead of FreeBSD as it is not currently supported.

Create a Multi-NIC Virtual Machine

The custom image that we created previously, can be used in order to create a pfSense Virtual Machine with two Virtual Network Interfaces (vNIC), in Microsoft Azure. More details about creating a Virtual Machine with Multiple vNICs in Microsoft Azure, you can find in a previous post here:

Create a Virtual Machine with Multiple NICs in Azure IaaS

A pfSense Virtual Machine with two vNICs will be created by running the following PowerShell commands:

$location = "West Europe"
$serviceName = "pfsvc"
$vnet = "pf-VNET"
$subscriptionName = 'My MSDN Subscription'
$storageAccount = 'pfsa'
$adminUser = "adminuser"
$pwd = "*********"
$imageName = "pfSense-2.2.3"

$MultiVM = New-AzureVMConfig -ImageName $ImageName `
	   -Name "pfSense-FW01" -InstanceSize ExtraLarge |
       Add-AzureProvisioningConfig -Linux -LinuxUser $adminUser `
	   -Password $pwd |
       Set-AzureSubnet -SubnetNames "Front-End" |
       Set-AzureStaticVNetIP -IPAddress "" |
       Add-AzureNetworkInterfaceConfig -Name "LAN NIC" `
	   -SubnetName "LAN-Subnet" -StaticVNetIPAddress

New-AzureVM -ServiceName $serviceName `
            -Location $location `
            -VNetName $vnet `
            -VMs $MultiVM

Setup User Defined Routes

With user defined routes, we have complete control over the traffic flow in our virtual network. Virtual network by default provides system routes for traffic flow between virtual machines. Now, we can customize the routing table by defining routes and that is allowing us to direct traffic through pfSense Virtual Machine that we have just created. Routes can be defined inside a routing table and applied to subnets. Every VM within a subnet automatically inherits the routes from the routing table.

The following PowerShell commands, allowing us to:

  • Create the routing tables
  • Create routes in the routing tables
  • Apply routing tables to subnets
  • Enable IP Forwarding on pfSense’s vNICs
# Variables Section
$Location="West Europe"
$ServiceName = "pfsvc"
$VM = Get-AzureVM -Name "pfSense-FW01" -ServiceName $serviceName

# Set the route table of the Frontend network:
$FrontRT = New-AzureRouteTable -Name $FrontendName `
		-Location $Location -Label "FE-RT"
Set-AzureRoute -RouteTable $FrontRT -RouteName "DMZ-Route" `
		-AddressPrefix "" -NextHopType "VirtualAppliance" `
		-NextHopIpAddress ""
Set-AzureSubnetRouteTable -VirtualNetworkName $VNetName `
		-SubnetName $FrontendName -RouteTableName $FrontendName

# Set the route table of the LAN network:
$LANRT = New-AzureRouteTable -Name $LANName `
		-Location $Location -Label "LAN-RT"
Set-AzureRoute -RouteTable $LANRT -RouteName "FE-Route" `
		-AddressPrefix -NextHopType VirtualAppliance `
Set-AzureRoute -RouteTable $LANRT -RouteName default -AddressPrefix `
		-NextHopType VirtualAppliance -NextHopIpAddress
Set-AzureSubnetRouteTable -VirtualNetworkName $VNetName -SubnetName $LANName `
		-RouteTableName $LANName

# Enable IP Forwarding on the main NIC and secondary NICs:
Set-AzureIPForwarding -ServiceName $ServiceName -VM $VM -Enable
Set-AzureIPForwarding -ServiceName $ServiceName -VM $VM `
		-NetworkInterfaceName "LAN NIC" -Enable
The pfSense Virtual Machines must be able to receive incoming traffic that is not addressed to itself and this is the reason to enable IP forwarding.

The post Running pfSense as an Azure IaaS Virtual Machine appeared first on Vaggelis Kappas.


Recommended Comments

There are no comments to display.

Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...