I’ve added a Your IP tab at the top of the site that will bring you to a page that displays your current IP address as well as some other http connection-related information. A geeky little task I’ve been meaning to do for awhile now. Here’s the code I hacked together for it. As always, please report any problems you encounter with it, and any suggestions you may have for ways to improve the code and/or experience.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
FreeNAS is an open source storage platform based on FreeBSD that supports file sharing across Windows, Apple, and Unix/Linux systems. rsync is an open source file copying utility for Linux/Unix systems. It’s famous for its “delta-transfer” algorithm, which reduces the amount of data sent over the network by sending only the differences between the source files and the existing files in the destination. It offers a large number of options, including the ability to copy locally, to/from another host over any remote shell, or to/from a remote rsync daemon; and, the ability to preserve symbolic links, hard links, file ownership, permissions, devices and times.
In this post I will describe how to configure FreeBSD, FreeNAS and rsync to securely backup files located on FreeNAS to a FreeBSD machine located at a remote location. All steps involved assume you have a running implementation of FreeBSD and FreeNAS. The software versions used in this post were as follows:
FreeBSD 9.0-RELEASE (x64)
FreeNAS v0.7.1 Shere (revision 5127)
rsync v3.0.9
Configure FreeNAS
There are two ways for the FreeBSD machine to contact FreeNAS using rsync: using a remote-shell program as the transport (such as ssh or rsh) or contacting an rsync daemon directly via TCP. We’re going to use ssh as our transport method. We’ll also create a new user account in FreeNAS named “rsync,” which we will enable access to via ssh but limit its use solely for the purpose of backing up files using rsync.
Begin by logging into the FreeNAS web interface, navigate to Access->Users and Groups->Users and select the “+” icon to create a new user account. The following parameters will need to be configured:
Name – This is the login name of the new user. You’re welcome to use any user name you’d like here. For purposes of our example though let’s enter rsync.
Full Name – This field should match the Name field, so enter rsync again here.
Password – Our plans include generating and using ssh keys to authenticate the FreeBSD machine to the FreeNAS machine and not passwords, so leave these fields blank.
User ID – Unless you have a specific reason to change the User ID you should retain whatever FreeNAS has chosen for you here, typically UID 1001 if this is your first new user account on FreeNAS.
Shell – This parameter specifies the login shell for our new user rsync. The nologin option should not be selected as it will not permit access to the account. For purposes of our example, we’ll select the good old sh shell.
Primary group – This parameter sets the primary group that the user rsync will belong to. Unless you have a specific reason to change the group, the default group Guest should be retained here.
Additional group – No other group memberships need be selected.
Home directory – Here’s where we’ll enter the path to the home directory for the rsync user, which for purposes of our example should be set to /usr/home/rsync.
When complete, the configuration should resemble Figure 1. Now select “Add” to accept the changes and add rsync as a new user.
Figure 1
Now let’s configure and activate the rsync service in FreeNAS. Navigate to Services->Rsync->Server->Settings and check the “Enable” box, then click on the drop down list under “Map to user” and select rsync. The remaining fields can remain at their default settings. When complete, the configuration should resemble Figure 2. Now select “Save and Restart” to accept the changes and start the rsync server.
Figure 2
Next, we need to ensure the ssh service is running in FreeNAS. Navigate to Services->SSH and check the “Enable” box. To help improve security, we’ll avoid using the default TCP port 22 and, for purposes of our example, use port 13725 instead. Check the “Permit root login” box and ensure that “Password authentication” box is checked. When complete, the configuration should resemble Figure 3. Now select “Save and Restart” to accept the changes and start the ssh server.
Figure 3
Finally, connect via ssh to the the root account of the FreeNAS machine and create the directory /usr/home/rsync/.ssh, which we’ll use to hold the public RSA key that we’ll eventually generate and copy from the FreeBSD machine. Note: Alternatively, you can create this directory using FreeNAS’s built-in file management tools by navigating to Advanced->File Manager. Make sure to provide the correct local IP address or host name of the FreeNAS machine. If this machine is located on another network, then make sure to provide the correct IP address or URL of the network where the FreeNAS machine is located, as well as ensure that any NAT gateway is configured to pass TCP port 13725 traffic to the correct host:
1
2
ssh-p13725root@<freenas-ip-address>
mkdir/usr/home/rsync/.ssh
Okay, we’re finished with thr FreeNAS configuration for now. Let’s move on and configure the FreeBSD machine.
Configure FreeBSD
The following steps assume you have the FreeBSD Ports Collection installed. If not, you can install it by using the following commands:
1
2
portsnap fetch
portsnap extract
If the Ports Collection is already installed, make sure to update it:
1
portsnap fetch update
Navigate to the rsync port and build it, accepting the default configuration options:
1
2
cd/usr/ports/net/rsync
make install clean
Next, we’ll choose a location that will be used to backup the FreeNAS files. For purposes of our example, we will create the subdirectory backup within the primary user’s home directory on the FreeBSD machine:
1
mkdir/home/iceflatline/backup
Then make sure the user owns this directory, as well as any files and subdirectories within it:
1
chown-Riceflatline/home/iceflatline/backup
Recall that we shunned conventional password authentication when creating the rsync user account on FreeNAS. Instead, we’re going to generate an RSA public/private key pair on the FreeBSD machine, and copy the public key to the FreeNAS machine. rsync will be able to login and authenticate itself to the FreeNAS machine without the need for a password because the FreeBSD machine has the corresponding private key. rsync can now run autonomously because it will not be prompted for a password each time it attempts to login:
1
ssh-keygen–q–trsa
By default the RSA keys are 2048 bits. If you’re really paranoid you can increase this to 4096 bits if desired with the -b flag:
1
ssh-keygen–q–trsa–b4096
You’ll be asked by the ssh-keygen script where it should store the keys (~/.ssh is the default), and then asked to enter and confirm a password for the private key that will be stored in this machine. In our particular case, we don’t want to be prompted for a password so simply press enter. The private key (id_rsa) and the public key (id_rsa.pub) are generated and then stored in ~/.ssh (if you accepted the default directory). Now that our keys are generated, let’s copy the public key to the FreeNAS machine using the venerable secure copy command:
Note that in the case of the scp command we must designate the ssh port number using the upper-case -P option, and pass to it the same ssh port number that was designated when we configured FreeNAS. Here again, make sure to provide the correct local IP address or host name of the FreeNAS machine or, if this machine is located on another network, the correct IP address or URL of the network where the FreeNAS machine is located. When you successfully connect you’ll likely receive a message concerning the authenticity of the FreeNAS machine, along with a fingerprint of its public RSA key, and asked if you’re sure you want to continue connecting. Accept by typing yes and you’ll be presented with a password prompt for the root user on the FreeNAS machine. Enter the password and the public key will be copied.
Now let’s connect again via ssh to the root account of the FreeNAS machine and copy the public key to /home/rsync/.ssh/authorized_keys so that rsync can securely connect to FreeNAS without the need for a password. We’ll also take this opportunity to remove the public key from the root account:
Then lock down permissions and make sure the user rsync owns of all files and subdirectories within its home directory:
1
2
3
chmod700/home/rsync/.ssh
chmod600/home/rsync/.ssh/authorized_keys
chown-Rrsync/home/rsync
Finally, let’s make sure we can connect to the rsync account on FreeNAS using only public/private key authentication:
1
ssh-p13725rsync@<freenas-ip-address>
When you successfully connect you’ll once again receive a message concerning the authenticity of the FreeNAS machine. Accept by typing yes and you’ll be securely connected to the rsync user’s home directory (/home/rsync/) on FreeNAS without the need to enter a password.
Okay, let’s move on and configure rsync.
Configure rsync
For purposes of example, let’s assume that on the FreeNAS machines there is directory /mnt/files/foo containing a number of files along with two subdirectories – /mnt/files/foo/bar1 and /mnt/files/foo/bar2 – that we wish to backup on a routine basis to the FreeBSD machine. You could issue the following command to the FreeBSD machine accomplish that:
Long command, right? Let’s walk through it. First, we invoke the rsync command and pass to it the following options:
-a – Specifies that the files are transferred in “archive” mode, which ensures that any symbolic links, devices, attributes, permissions, ownerships etc are preserved.
-v – Increases the verbosity of the command so that you know in a little more detail what rsync is/is not doing.
-z – Specifies that rsync should use compression to reduce the size of data portions of its file transfers.
–delete – Specifies that rsync should delete files in the destination that no longer exist on the source side. This helps to keep the file systems specified in the source and destination synchronized.
Then we tell rsync that we’d like to use ssh and port 13725 by using the “-e ssh -p 13725” option. Finally, we tell rsync what the source and destination file systems are.
Another rsync option that I find handy is –exclude. Let’s say that for whatever reason you’d like to exclude the subdirectory /mnt/files/foo/bar2 and all the files therein. You’d use the following command to accomplish that:
Please consult the rsync man pages for further information on what rsync options are available for your specific needs.
Once you get the rsync command configured the way you’d like it, then it’s time to add it to cron on the FreeBSD machine so that it will perform backups on a routine basis. cron is a *nix utility that allows tasks to be automatically run in the background at regular intervals by the cron daemon. These tasks are typically referred to as “cron jobs.” A “crontab” is a file which contains one or more cron job entries to be run at specified times. You can create a new crontab (or edit an exiting one) using the system’s default command line editor by using the command crontab -e under your user account. Here’s some example cron job entries using our rsync command. You could add one or many rsync cron job entries to your crontab depending on your needs, then simply uncomment the one you want to use. Also, cron will attempt to email to the user the output of the commands it runs. To silence this, we’ll redirect the command output to /dev/null:
While placing the full rsync command in the crontab works just fine, it can become a bit unwieldy, particularly if the command is lengthy. A more elegant approach is to capture the command and associated options in a shell script and invoke the script in a crontab instead of the full command. Here’s what a basic shell script might look like, again utilizing our example rsync command:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/sh
# A bit about RSYNC_ARGS:
# -a=archive, -v=verbose, -z=compress with syncing
# --delete means it will delete in LPATH anything not in RPATH
# Adding the option -- exclude will exclude specified directories.
# The trailing / specifies the entire directory and all files within.
# For example, RSYNC_ARGS="-avz --delete --exclude bar2/" will
# exclude the directory bar2 and all its files.
### START OF SCRIPT
RSYNC=/usr/local/bin/rsync
RSYNC_ARGS="-avz --delete --exclude bar2/"
RSYNC_PORT="-e ssh -p 13725"
RUSER=rsync
RHOST="freenas-ip-address"
RPATH=/mnt/files/foo/
LPATH=/home/iceflatline/backup
DATE=/bin/date
LOG=/home/iceflatline/cronlog
# Let's create a blank line between
# log entries so their not all bunched together
echo"">>$LOG
# And precede each log entry with the current date/time
# Finally, let's mark the end of our log entry with a delimiter
echo"**********">>$LOG
### END OF SCRIPT
You’ll notice that in addition to running the rsync command, the script will also create the log file /home/iceflatline/cronlog and append the date/time and a brief summary of what transpired to it every time script runs. To use this script, modify its values to suit your particular need, including the correct IP address or URL for the FreeNAS machine, and give it a name, say for example rsync-freenas. Then create a bin/ subdirectory in the home directory on the FreeBSD machine, copy the file to that location, and make it executable:
1
2
mkdir/home/iceflatline/bin
chmod+x/home/iceflatline/bin/rsync-freenas
Now then, a crontab entry invoking this script would look like this; i.e., a whole lot less complex:
1
2
#Backup at the top of every hour
0****/home/iceflatline/bin/rsync-freenas
Final Steps
Now that we have everything configured, login again to the FreeNAS web interface. Navigate to Services->SSH and uncheck both the “Permit root login” and “Password authentication” boxes. When complete, select “Save and Restart” to accept the changes and restart the ssh server.
Tips
Here’s a few of tips that may help improve your experience when using rsync in the manner described in this post
There’s no requirement that the machine you’re backing up FreeNAS files to be based on FreeBSD. You could just as easily use a machine based on a Linux distribution for example. Simply download and install rsync via the distribution’s package manager or compile it from source. The remaining steps should work as described.
Regardless of which operating system you use, backing up to a separate partition or, better yet, a separate hard disk(s) is recommended. This partition or disk can simply be mounted at a location in your file system, for example the /home/iceflatline/backup we used in our example, then, if something should require you to reinstall the OS, your files would still be intact. I prefer using a separate hard disk. That way, if/when I need to restore some or all of the files to FreeNAS, I need only unmount the drive from the FreeBSD machine, mount it in FreeNAS and have access again to the files.
Depending on the quantity and size of the files you want to backup, you may wish to consider initially locating the FreeBSD machine on the same network as the FreeNAS machine. The initial backup will likely go much faster on a 100 Mbps or 1000 Mbps local area network than it would over a wide area network. Once the initial backup is complete, then the FreeBSD machine can be moved to a remote location to start performing incremental backups.
A VPN (“Virtual Private Network”) can be setup between the FreeNAS and FreeBSD machine, thus perhaps eliminating the need to use a non-standard ssh port. Another benefit of using a VPN to connect the two machines is the ability to easily connect to the FreeBSD machine from within the FreeNAS machine’s network; handy if/when you want to quickly retrieve a file or perform routine maintenance on the FreeBSD machine.
Occasionally, you may add large and/or numerous files to FreeNAS where the time it takes to incrementally back them up to FreeBSD exceeds the time specified between cron jobs in the crontab. For example, if the cron job runs the rsync script or command every 60 minutes, but it takes 75 minutes to incrementally backup the new files added to FreeNAS, then errors will occur when the cron job triggers rsync to run again. To avoid this problem, you can edit the crontab to lengthen the time between cron jobs, or stop the cron job from running by commenting it out in the crontab and run rsync manually instead. Once rsync has fully backed up you can use the crontab again.
Conclusion
This concludes the post on how to remotely and securely backup and synchronize files located on a FreeNAS machine to a FreeBSD-based machine, using rsync, a fast and versatile file copying tool.
(20170504 — The steps in this post were amended to address changes in recent versions of software — iceflatline)
In a previous post, I described how to install and setup pfSense in a home network. In this post I will describe how to configure pfSense to act as an Network Time Protocol (“NTP”) server, as well as how to configure various hosts in your network to synchronize their local clock to this server.
pfSense is a customized version of FreeBSD tailored specifically for use as a perimeter firewall and router. It can be managed almost entirely from a web-based GUI. In addition to being a firewall and routing platform, pfSense includes a long list of other features, as well as a package system allowing its capabilities to be expanded even further. pfSense is free, open source software distributed under the BSD license.
Originally designed by David L. Mills of the University of Delaware circa 1985, NTP is a protocol for synchronizing the clocks of computer systems over packet-switched, variable-latency data networks, and one of the oldest Internet protocols still in use. NTP uses User Datagram Protocol (UDP) port number 123. pfSense uses OpenNTPD, a free, easy to use implementation of NTP.
The versions for the software used in this post were as follows:
FreeBSD 11.0-RELEASE
pfSense 2.3.3-RELEASE-p1
Ubuntu 16.04.2 LTS
Windows 7 Professional (x64)
Configure OpenNTPD in pfSense
Before configuring the OpenNTP server, it’s a good idea to ensure that pfSense itself is keeping accurate time. The best way to do that is to have it synchronize its clock with one or more remote NTP servers. First though, you should make sure that the clock in the machine hosting pfSense is set to something close to accurate – if the difference is too great, pfSense will not synchronize properly with the remote NTP server.
Login to the pfSense machine using its “webConfigurator” (webGUI) interface. Navigate to System->General Setup and select the timezone that matches the physical location of the pfSense machine from among the options under “Timezone.” Next, enter the host name or IP address for the remote NTP server under “Timeservers” (Remember to add at least one DNS server under “DNS Servers” if you decide to use a host name instead of an IP address). Most likely you’ll find this field is already populated with one or more default remote NTP server(s) such as 0.pfsense.pool.ntp.org, 1.pfsense.pool.ntp.org, etc. These servers will work just fine in most cases, however you may get more accurate results if you use one of the continental zone servers (e.g., europe., north-america., oceania., or asia.pool.ntp.org), and even more accurate time if you choose to use one of the country zone servers (e.g., us.pool.ntp.org in the United States). For all of these zones, you can use the 0, 1 or 2 prefix, like 0.us.pool.ntp.org, to distinguish between servers from a particular region or country. (See the NTP Pool Project web site for more information on how to use pool.ntp.org servers). Like 0.pfsense.pool.ntp.org, these server entries will pick random NTP servers from a pool of known good ones. Also, while one NTP server is sufficient, you can improve reliability by adding more. Just make sure their host names or IP addresses are separated by a space.
Now that the pfSense machine is on its way to keeping accurate time, let’s configure its OpenNTPD server. Navigate to Services->NTP and pick which interface OpenNTPD should listen on. This will typically be the “LAN” interface. When complete select “Save.” The OpenNTPD server will start immediately, however there may a delay of several minutes before it is ready to service NTP requests as it must first ensure that its own time is accurate. That’s all there is to it. You’ll find the OpenNTPD logs under by selecting the ‘NTP” tab under Status->System Logs->NTP.
Configure Hosts
Windows
After configuring the OpenNTPD server in pfSense, let’s configure a Windows host to synchronize its local clock to this server. Right-click on the time (usually located in the lower right corner of the desktop) and select “Adjust date/time.” Select the “Internet Time” tab, then select “Change settings.” Check the “Synchronize with an Internet time server” box, enter the host name or IP address of the pfSense machine, then select “Update now.” It’s not uncommon to get error message the first time you attempt to update. Wait a few seconds and try again; you should receive a “The clock was successfully synchronized…” message.
Linux
Many Linux distributions feature two utilities to help the local clock maintain its accuracy: ntpdate and/or ntpd (Note: Linux systems using systemd-timesyncd are discussed below). The ntpdate utility is typically included in Linux distributions as a default package, but if yours does not you can install it using your distribution’s package manager, for example:
1
sudo apt-get install ntpdate
ntpdate typically runs once at boot time and will synchronize the local clock with a default NTP server defined by the distribution. However what if this machine isn’t rebooted often, say in the case of a server for example? And what about using the OpenNTPD server in the pfSense machine? We can address both of those issues by occasionally running ntpdate using the following command. For this and subsequent examples we’ll assume the IP address assigned to the LAN interface in the pfSense machine is 192.168.1.1:
1
sudo ntpdate192.168.1.1
Perhaps a more effective approach though is to use cron, a utility that allows tasks to be automatically run in the background at regular intervals by the cron daemon. These tasks are typically referred to as “cron jobs.” A “crontab” is a file which contains one or more cron job entries to be run at specified times. You can create a new crontab (or edit an exiting one) using the command crontab -e under your user account. Because ntpdate needs to be run by the system’s root user we’ll create the crontab using the command sudo crontab -e. Here’s some example cron job entries using the ntpdate command. Note that cron will attempt to email to the user the output of the commands it runs. To silence this, you can redirect the command output to /dev/null:
While using ntpdate will certainly work well, the utility ntpd on the other hand is considerably more sophisticated. It continually runs, calculating the drift of the local clock and then adjusting its time on an ongoing basis by synchronizing with one or more NTP servers. By default ntpd acts as a NTP client, querying NTP servers to set the local clock, however it also can act as a NTP server, providing time service to other clients. Alas though, nothing is free, and using ntpd will result in yet one more system process that may not otherwise be running in your system, consuming both CPU and memory resources, albeit modestly.
Like ntpdate many Linux distributions include ntpd by default. If yours does not, you can install it using your distribution’s package manager, for example:
1
sudo apt-get install ntp
The installation process should add ntpd to the requisite run levels and start its daemon automatically. Now we need to configure it so that it acts as a NTP client only and not as a NTP server. After all, that’s what we’re going to use the pfSense machine for right?
ntpd is configured using the file /etc/ntp.conf. Open this file and comment out the existing ntp pool servers, then add the IP address assigned to the LAN interface on the pfSense machine. Again, we’ll assume this address is 192.168.1.1. Appending the “iburst” option to the address will provide for faster initial synchronisation. We’ll also want to comment out the NTP server-related options that allow the local machine to exchange time with other host devices on the network and interrogate the local NTP server. The remaining options can remain at their default settings:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
driftfile/var/lib/ntp/ntp.drift
# Enable this if you want statistics to be logged.
#statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# Specify one or more NTP servers.
# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
#server 0.ubuntu.pool.ntp.org
#server 1.ubuntu.pool.ntp.org
#server 2.ubuntu.pool.ntp.org
#server 3.ubuntu.pool.ntp.org
server192.168.1.1iburst
# Use Ubuntu's ntp server as a fallback.
#server ntp.ubuntu.com
# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
# details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
# might also be helpful.
#
# Note that "restrict" applies to both servers and clients, so a configuration
# that might be intended to block requests from certain clients could also end
# up blocking replies from your own upstream servers.
# By default, exchange time with everybody, but don't allow configuration.
#restrict -4 default kod notrap nomodify nopeer noquery
#restrict -6 default kod notrap nomodify nopeer noquery
# Local users may interrogate the ntp server more closely.
#restrict 127.0.0.1
#restrict ::1
# Clients from this (example!) subnet have unlimited access, but only if
# If you want to provide time to your local subnet, change the next line.
# (Again, the address is an example only.)
#broadcast 192.168.123.255
# If you want to listen to time broadcasts on your local subnet, de-comment the
# next lines. Please do this only if you trust everybody on the network!
#disable auth
#broadcastclient
A comment about the driftfile option: this file is used to store the local clock’s frequency offset. ntpd uses this file to automatically compensate for the local clock’s natural time drift, allowing it to maintain reasonably accurate time even if it cannot communicate with the pfSense machine for some period of time.
While not required, you can run the ntpdate command one time to fully synchronize the local clock with the OpenNTPD server in pfSense, then restart ntpd.
1
2
3
sudo/etc/init.d/ntp stop
sudo ntpdate192.168.1.1
sudo/etc/init.d/ntp start
In recent Linux releases using systemd-timesyncd, timedatectl replaces ntpdate and timesyncd replaces the client portion of ntpd. By default timedatectl syncs the time by querying one or more NTP servers once on boot and later on uses socket activation to recheck once network connections become active. timesyncd on the other hand regularly queries the NTP server(s) to keep the time in sync. It also stores time updates locally, so that after reboots monotonically advances if applicable.
The NTP server(s) used to sync time for timedatectl and timesyncd from can be specified in /etc/systemd/timesyncd.conf. By default the system will rely upon the default NTP server(s) defined by the distribution and specified by FallbackNTP= in the “[Time]” section of the file. To use the OpenNTPD server in the pfSense machine, uncomment NTP= and append the IP address assigned to the LAN interface on the pfSense machine. Again, assuming this address is 192.168.1.1:
1
2
3
[Time]
NTP=192.168.1.1
#FallbackNTP=ntp.ubuntu.com
You can specify additional NTP servers by listing their host names or IP addresses separated by a space on these lines. Now run the following command:
1
timedatectl set-ntp yes
The current status of time and time configuration via timedatectl and timesyncd can be checked with the command timedatectl status:
1
2
3
4
5
6
7
8
$timedatectl status
Local time:Tue2017-04-2517:41:04EDT
Universal time:Tue2017-04-2521:41:04UTC
RTC time:Tue2017-04-2521:41:04
Time zone:America/New_York(EDT,-0400)
Network time on:yes
NTP synchronized:yes
RTC inlocal TZ:no
FreeBSD
ntpdate and ntpd are installed in FreeBSD by default, however ntpd is not configured to start at boot time.
Similar to Linux, we can run ntpdate manually as root to synchronize with the OpenNTP server running in the pfSense machine. Again, we’ll assume 192.168.1.1 is the IP address assigned to the LAN interface on the pfSense machine.
1
ntpdate192.168.1.1
ntpdate can also be made to run at boot time in FreeBSD by using the sysrc command to add the following lines to /etc/rc.conf:
1
2
sysrc ntpdate_enable=YES
sysrc ntpdate_hosts=192.168.1.1
We can also use cron under FreeBSD to run ntpdate. You can create a new crontab (or edit an exiting one) using the command crontab -e as root. The example cron job entries provided above under Linux will also work under FreeBSD.
To enable ntpd under FreeBSD, open /etc/ntp.conf and comment out the existing ntp pool servers and add the IP address assigned to the LAN interface on the pfSense machine. The remaining options can remain at their default settings:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#
# The following three servers will give you a random set of three
# NTP servers geographically close to you.
# See http://www.pool.ntp.org/ for details. Note, the pool encourages
# users with a static IP and good upstream NTP servers to add a server
# to the pool. See http://www.pool.ntp.org/join.html if you are interested.
#
# The option `iburst' is used for faster initial synchronisation.
#
#server 0.freebsd.pool.ntp.org iburst
#server 1.freebsd.pool.ntp.org iburst
#server 2.freebsd.pool.ntp.org iburst
#server 3.freebsd.pool.ntp.org iburst
server192.168.1.1iburst
#
# If you want to pick yourself which country's public NTP server
# you want sync against, comment out the above servers, uncomment
# the next ones and replace CC with the country's abbreviation.
# Make sure that the hostnames resolve to a proper IP address!
#
# server 0.CC.pool.ntp.org iburst
# server 1.CC.pool.ntp.org iburst
# server 2.CC.pool.ntp.org iburst
#
# Security: Only accept NTP traffic from the following hosts.
# The following configuration example only accepts traffic from the
# above defined servers.
#
# Please note that this example doesn't work for the servers in
# the pool.ntp.org domain since they return multiple A records.
# (This is the reason that by default they are commented out)
Now use sysrc to add the following two lines to /etc/rc.conf. The first line enables ntpd. The second tells the system to perform a one time sync at boot time:
1
2
sysrc ntpd_enable=YES
sysrc ntpd_sync_on_start=YES
Run the ntpdate command one time to synchronize the local clock with the OpenNTPD server in pfSense, then start ntpd.
1
2
ntpdate192.168.1.1
service ntpd start
Conclusion
This concludes the post on how to how to configure your pfSense machine to also act as a NTP server. The OpenNTPD service in pfSense will listen for requests from FreeBSD, Linux and Windows hosts and allow them to synchronize their local clock with that of the OpenNTPD server in pfsense. Using pfSense as a NTP server in your network ensures that your hosts always have consistent accurate time and reduces the load on the Internet’s NTP servers. Configuring Windows hosts to utilize this server is straightforward, while configuration under FreeBSD and Linux requires a bit more work.
(20180430 – The steps in this post were amended to address changes in recent versions of software. Minor editorial corrections were also made — iceflatline)
In my previous post, I described how to install and setup pfSense in a home network and offered some configuration recommendations based on my own experiences. In this post, I will describe how to set up Virtual Private Network (“VPN”) access in pfSense using OpenVPN. Once configured, you’ll be able to use an OpenVPN client in Windows or Linux to securely access your home network remotely using either X.509 PKI authentication (public key infrastructure using X.509-based certificates and private keys) or pre-shared private key authentication.
pfSense (i.e., “making sense of packet filtering”) is a customized version of FreeBSD tailored specifically for use as a perimeter firewall and router, and can be managed entirely from a web-based or command line interface. In addition to being a firewall and routing platform, pfSense includes a long list of other features, as well as a package system allowing its capabilities to be expanded even further. pfSense is free, open source software distributed under the BSD license.
OpenVPN is a lightweight VPN software application supporting both remote access and site-to-site VPN configurations. It uses SSL/TLS security for encryption and is capable of traversing network address translation devices and firewalls. The OpenVPN community edition is free, open source software and portable to most major operating systems, including Linux, Windows 2000/XP/Vista/7, OpenBSD, FreeBSD, NetBSD, Mac OS X, and Solaris. It is distributed under the GPL license version 2.
The versions for the software used in this post were as follows:
easy-rsa for Ubuntu, easy-rsa_2.2.2-2_all.deb
OpenVPN for Ubuntu, openvpn_2.4.4-2ubuntu1_amd64.deb
OpenVPN for Windows, 2.4.6
pfSense 2.4.3
Ubuntu Server 18.04 LTS
Windows 7 Professional
OpenVPN Authentication
Before walking through the steps necessary to configure the OpenVPN server in pfSense and OpenVPN client software in Windows and Linux, let’s discuss the differences between the two methods used by OpenVPN in most situations to authenticate peers (clients and servers) to one another: X.509 PKI and pre-shared private keys.
In the X.509 PKI authentication method, the private keys of the peers are kept secret and its public key made publicly available via “certificates” based on the ITU-T X.509 standard. The goal of a certificate is to certify that a public key belongs to the person or entity claiming to be its owner, or more accurately, the person/entity owning the corresponding private key. To achieve this certification, a certificate is signed by an authority that can be trusted by everyone: the Certification Authority (“CA”). In OpenVPN, a CA certificate and its corresponding private key is generated locally, as well as individual certificates and private keys for the OpenVPN server (located in pfSense in our case) and each OpenVPN client. The CA and its associated private key are then used to sign the server and client certificates during the process of generating them. Then, when a VPN session is established, both server and client will authenticate the other by, among other things, verifying that the certificate each presents to the other was signed by the CA.
The X.509 PKI method has a number of advantages compared to the pre-shared key approach. First, the server only needs its own signed certificate and private key – it doesn’t need to know anything about the certificates associated with the client(s), only that they were signed by the CA certificate. Second, because the server can perform this signature verification without needing access to the CA private key, the CA key can be stored somewhere safe and secure. Finally, individual clients can be disabled simply be adding their certificates to a CRL (“Certification Revocation List”) located on the server. The Certification Revocation List allows compromised certificates to be selectively rejected without requiring that the entire PKI be rebuilt. This is the primary reason that X.509 PKI is considered the preferred method for implementing remote client access using OpenVPN – the ability to revoke access to individual machines. Alas though, there are some issues to be considered when using this approach. One of course is the integrity of the CA private key, which ensures the security of the PKI. Anyone with access to the this key can generate certificates to be used to gain VPN access to a network, so it must be kept secure and never distributed to clients or servers. Another is that creating and managing OpenVPN certificates and private keys may be a bit tedious, particularly if all you want to do is setup personal VPN access to your home network.
In the pre-shared key authentication method, a single static 2048-bit private RSA key is generated and copied to the OpenVPN server and client. This shared key approach is typically used for site-to-site connections involving, say, two pfSense machines located at a main office and a remote office, with one acting as the OpenVPN server and the other as the client. However, it also offers the simplest setup for getting a VPN connection to your network up and running quickly with minimal configuration. There are some shortcomings with this method though that should be considered before using it. First, it doesn’t scale terribly well. Each client needing VPN access must have a unique OpenVPN server and TCP or UDP port defined in pfSense. This can be a pain to manage as the number of clients grows. This pain can be blunted a bit if you issue the same shared key to each client, but if the key is compromised, a new key must be generated and securely provided to the OpenVPN server and all clients. Another problem with this method is that these keys exist in plaintext on each OpenVPN client (it also exists in plain text in pfSense but presumably access to that machine is further restricted) resulting in security that’s perhaps less than desirable.
In summary then, the X.509 PKI method offers scalability and arguably better security, but may be cumbersome for some to setup and manage; while the pre-shared key method is easier to setup, and likely just fine for implementations with a limited number of remote VPN clients. The remainder of this post will discuss how to configure a VPN using either method, but you’ll need to determine which approach best meets your needs.
Installing OpenVPN
OpenVPN comes pre-installed in pfSense so we’ll begin by installing OpenVPN on Windows and Linux, then use it to generate the necessary client and server keys and certificates. OpenVPN provides a set of batch files/scripts based on OpenSSL collectively called “easy-rsa” that will make the task of generating these certificates and keys much easier. To help explain the steps involved, we’ll generate the following certificates and keys:
Then we’ll copy these keys to the machines that need them and put them to work to create an OpenVPN connection to a home network that uses the subnet 192.168.10.0/24. Doing so will involve creating another subnet, 192.168.20.0/24, for our OpenVPN server and clients, and designating UDP port 13725 for the OpenVPN server to use to listen on for incoming VPN requests (See Figure 1).
Figure 1
Installing OpenVPN and creating certificates and keys in Windows
OpenVPN for Windows is available from OpenVPN community downloads. During the install, accept the existing default options, and ensure that “EasyRSA 2 Certificate Management Scripts” is selected. The “Advance” section provides some usability options which you can select/deselect based on your preferences. Once installed, OpenVPN will associate itself with files having the .ovpn extension.
Now we’re ready to generate the various certificates and keys. Open a command prompt and change folders to C:\Program Files\OpenVPN\easy-rsa\. Run the following batch file, which will copy the file vars.bat.sample to vars.bat. Note that this will overwrite any preexisting vars.bat file:
1
init-config.bat
Open the file C:\Program Files\OpenVPN\easy-rsa\vars.bat and take a look at the values associated with the variables KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL. Assigning values to these variables helps speed the process of generating the various certificates and keys by initializing these common variables when the various easy-rsa batch files are invoked. You may leave them at their default values or change them if desired, however, don’t leave any blank. Now, make sure you’re at C:\Program Files\OpenVPN\easy-rsa\, then run the following batch files:
1
2
vars.bat
clean-all.bat
Running this sequence of commands for the first time will create the folder C:\Program Files\OpenVPN\easy-rsa\keys\, which serves to hold the certificates and keys we generate (Note that you can define the location of this folder using the variable KEY_DIR in vars.bat). You may receive a message indicating that “The system cannot find the file specified”, however this message can safely be ignored. Also note that from now on, each time you run this sequence to create new certificates and keys, any existing certificates and keys in the keys folder will be deleted.
Okay then, let’s generate the CA certificate and CA private key. The only value which must be explicitly entered when requested is for the variable “Common Name”, which is set to “openvpn-ca” in the following example. An optional “Organization Unit Name” and “Name” value is also requested and may be modified if desired:
You are about tobe asked toenter information that will be incorporated
into your certificate request.
What you are about toenter iswhat iscalledaDistinguished Name oraDN.
There are quiteafew fields but you can leave some blank
Forsome fields there will beadefaultvalue,
Ifyou enter'.',the field will be left blank.
-----
Country Name(2letter code)[US]:
State orProvince Name(full name)[CA]:
Locality Name(eg,city)[SanFrancisco]:
Organization Name(eg,company)[OpenVPN]:
Organizational Unit Name(eg,section)[changeme]:
Common Name(eg,your name oryour server'shostname)[changeme]:openvpn-ca
Name[changeme]:
Email Address[mail@host.domain]:
C:\Program Files\OpenVPN\easy-rsa>
Navigate to C:\Program Files\OpenVPN\easy-rsa\keys\, you should see the newly minted CA certificate (ca.crt) and CA private key (ca.key) files.
Next, we’ll generate a certificate and private key for the OpenVPN server that resides in pfSense. Here we’ll need to pass a text string to the batch file when invoking it. That text string then becomes the name for the server’s certificate and private key. In this example, we’ll use the text string “pfsense”. As in the previous step, most values will be automatically initialized by vars.bat. Once again, the value for Common Name must be explicitly entered, which we’ll set to “pfsense” to match the name of the server key. This batch file will also seek to define some additional optional attributes, including the “challenge password”, used in certificate revocation, which we’ll leave blank, and the “company name”, which you may fill in if desired. Finally, you’ll be asked to sign the server’s certificate using the CA certificate. Review the server certificate carefully, then select “y” to sign and then to commit the signature:
Finally, let’s generate our client certificate and key following steps similar to the ones we used above for creating the server certificate and key. This time, however, the text string we pass to the batch file will become the name for the client certificate and key. In this example, we’ll use the text string “bob”, and set the Common Name value to be the same. Review the client certificate carefully, then select “y” to sign and then to commit the signature. You’ll need to run this same batch file for each client you want to grant VPN access to – and remember, you’ll need to use a unique key name/Common Name combination for each one:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
C:\Program Files\OpenVPN\easy-rsa>vars.bat
C:\Program Files\OpenVPN\easy-rsa>build-key.bat bob
Generatinga4096bit RSA privatekey
...........................++++++
....++++++
writing newprivatekey to'keys\bob.key'
-----
You are about tobe asked toenter information that will be incorporated
into your certificate request.
What you are about toenter iswhat iscalledaDistinguished Name oraDN.
There are quiteafew fields but you can leave some blank
Forsome fields there will beadefaultvalue,
Ifyou enter'.',the field will be left blank.
-----
Country Name(2letter code)[US]:
State orProvince Name(full name)[CA]:
Locality Name(eg,city)[SanFrancisco]:
Organization Name(eg,company)[OpenVPN]:
Organizational Unit Name(eg,section)[changeme]:
Common Name(eg,your name oryour server's hostname) [changeme]:bob
Name [changeme]:
Email Address [mail@host.domain]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from openssl-1.0.0.cnf
Loading 'screen' into random state - done
Check that the request matches the signature
Signature ok
The Subject'sDistinguished Name isasfollows
countryName:PRINTABLE:'US'
stateOrProvinceName:PRINTABLE:'CA'
localityName:PRINTABLE:'SanFrancisco'
organizationName:PRINTABLE:'OpenVPN'
organizationalUnitName:PRINTABLE:'changeme'
commonName:PRINTABLE:'bob'
name:PRINTABLE:'changeme'
emailAddress:IA5STRING:'mail@host.domain'
Certificate istobe certified until Jan1816:14:392022GMT(3650days)
To further protect OpenVPN access, you may wish to password-protect the client’s private key. To do this we’ll need use the build-key-pass.bat batch file. When used you’ll be prompted to to enter a password that will be used in conjunction with generating the private key. Now, anyone (including you) wishing to use this key when starting the OpenVPN connection will need to enter the correct password.
That’s it for installing OpenVPN and building your X.509 PKI in Windows. If you plan to use the pre-shared private key authentication method, you need only to generate a single RSA key that will be used in both the OpenVPN server and client(s). In this example, we’ll use “static-bob” as the key file name and place it in the same folder our other certificates and keys are located:
1
2
cdc:\Program Files\OpenVPN\easy-rsa\keys\
openvpn--genkey--secret static-bob.key
Installing OpenVPN and creating certificates and keys in Linux
If you’ve been following the installation and configuration of OpenVPN under Windows to this point, the steps used under Linux will seem familiar. To begin, download and install OpenVPN and easy-rsa using the distribution’s package manager. Using the Debian-based Ubuntu as an example:
1
2
sudo apt-get update
sudo apt-get install openvpn easy-rsa
Now copy the OpenVPN scripts used to generate the various certificates and keys into a new directory:
Then make a symbolic link to latest version of openssl.cnf contained in /etc/openvpn/easy-rsa. In this example the latest version is openssl-1.0.0.cnf:
1
2
cd/etc/openvpn/easy-rsa/
ln-sopenssl-1.0.0.cnfopenssl.cnf
We’re now ready to generate the various certificates and keys. Start by opening the file /etc/openvpn/easy-rsa/vars with your text editor and take a look at the variables KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL. Assigning values to these variables in vars helps speed the process of generating the various certificates and keys by initializing these common variables in the various easy-rsa scripts. You may leave them at their default values or change them if desired, however, don’t leave any blank.
Change to the root user:
1
sudo su
Now, open a terminal, and run the following:
1
2
cd/etc/openvpn/easy-rsa/
source vars&&./clean-all
Running this sequence of commands for the first time will create the directory /etc/openvpn/easy-rsa/keys/, which will hold the certificates and keys we generate (Not that you can define the location of this directory using the variable KEY_DIR in vars). Also note that from now on, each time you run the clean-all script any existing certificates and keys in the keys directory will be deleted.
Okay then, let’s generate the CA private key and CA certificate. The build-ca script uses the “Organization Name” value as the default value for “Common Name”; however, we’ll change this to “openvpn-ca” in the following example. Values for “Organization Unit Name” and “Name” will also be requested and may be modified if desired:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
root@ubuntu-vbox:/etc/openvpn/easy-rsa# source vars && ./build-ca
You are about tobe asked toenter information that will be incorporated
into your certificate request.
What you are about toenter iswhat iscalledaDistinguished Name oraDN.
There are quiteafew fields but you can leave some blank
Forsome fields there will beadefaultvalue,
Ifyou enter'.',the field will be left blank.
-----
Country Name(2letter code)[US]:
State orProvince Name(full name)[CA]:
Locality Name(eg,city)[SanFrancisco]:
Organization Name(eg,company)[Fort-Funston]:
Organizational Unit Name(eg,section)[MyOrganizationalUnit]:
Common Name(eg,your name oryour server'shostname)[Fort-Funston CA]:openvpn-ca
Name[EasyRSA]:
Email Address[me@myhost.mydomain]:
root@ubuntu-vbox:/etc/openvpn/easy-rsa#
Now, if you navigate to /etc/openvpn/easy-rsa/keys/, you should see the newly minted CA certificate (ca.crt) and CA private key (ca.key) files.
Next, we’ll generate a certificate and private key for the OpenVPN server that resides in pfSense. Here we’ll need to pass a text string to the script when invoking it. That text string then becomes the name for the server’s certificate and private key. In this example, we’ll use the text string “pfsense”. As in the previous step, most values will be automatically initialized by the file vars. We’ll leave the Common Name value at the default “pfsense” to match the name of the server key. This script will also seek to define some optional attributes, including the “challenge password”, which we will leave blank, and the “company name”, which may be filled in if desired. Finally, you’ll be asked to sign the server’s certificate using the CA certificate. Review the values in the server certificate carefully, then select “y” to sign and then to commit the signature:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
root@ubuntu-vbox:/etc/openvpn/easy-rsa# source vars
NOTE:Ifyou run./clean-all,Iwill be doingarm-rf on/etc/openvpn/easy-rsa/keys
You are about tobe asked toenter information that will be incorporated
into your certificate request.
What you are about toenter iswhat iscalledaDistinguished Name oraDN.
There are quiteafew fields but you can leave some blank
Forsome fields there will beadefaultvalue,
Ifyou enter'.',the field will be left blank.
-----
Country Name(2letter code)[US]:
State orProvince Name(full name)[CA]:
Locality Name(eg,city)[SanFrancisco]:
Organization Name(eg,company)[Fort-Funston]:
Organizational Unit Name(eg,section)[MyOrganizationalUnit]:
Common Name(eg,your name oryour server's hostname) [pfsense]:pfsense
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
Can'topen/etc/openvpn/easy-rsa/keys/index.txt.attr forreading,No such file ordirectory
139782511055296:error:02001002:system library:fopen:No such file ordirectory:../crypto/bio/bss_file.c:74:fopen('/etc/openvpn/easy-rsa/keys/index.txt.attr','r')
139782511055296:error:2006D080:BIO routines:BIO_new_file:no such file:../crypto/bio/bss_file.c:81:
Finally, let’s generate our client certificate and key following steps similar to the ones we used above for creating the server certificate and key. This time, however, the text string we pass to the script will become the default name for the client certificate and key. In this example, we’ll use the text string “bob”, which will also become the default value for the Common Name. Review the client certificate carefully, then select “y” to sign and then to commit the signature. You’ll need run the this same script for each client you want to grant access to – and remember, you’ll need to use a unique key name/Common Name combination for each one:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
root@ubuntu-vbox:/etc/openvpn/easy-rsa# source vars
NOTE:Ifyou run./clean-all,Iwill be doingarm-rf on/etc/openvpn/easy-rsa/keys
root@ubuntu-vbox:/etc/openvpn/easy-rsa# ./build-key bob
Certificate istobe certified until Apr2614:29:262028GMT(3650days)
Sign the certificate?[y/n]:
CERTIFICATE WILL NOTBE CERTIFIED
root@ubuntu-vbox:/etc/openvpn/easy-rsa#
To further protect OpenVPN access, you may wish to password-protect the client’s private key. To do this simply run the build-key-pass script instead instead of build-key. You will be prompted to enter a password that will be used in conjunction with generating the private key. Now, anyone (including you) wishing to use this key will need to enter the correct password.
That’s it for installing OpenVPN and building your X.509 PKI in Linux. If you plan to use the pre-shared private key authentication method instead, you need only to generate a single RSA key that will be used in both the OpenVPN server and client(s). In this example, we’ll use “static-bob” as the key file name and place it in the same directory our other certificates and keys are located:
1
2
cd/etc/openvpn/easy-rsa/keys/
openvpn--genkey--secret static-bob.key
* Note: when you’re finished using easy-rsa make sure to exit out of being the root user.
Configuring OpenVPN: X.509 PKI Authentication
Now that we’ve installed OpenVPN client software in Windows and Linux, and generated the various certificates and keys, let’s move on and discuss how to configure these clients and the OpenVPN server in pfSense for VPN access into our home network using the X.509 PKI authentication method. Before we do though, now would be a good time to move the file ca.key to a secure location. Recall, that the privacy of this key is what ensures the security of your entire OpenVPN PKI.
OpenVPN Server configuration in pfSense for X.509 PKI authentication
To configure the OpenVPN server in pfSense for X.509 PKI authentication, we’ll start by importing the server certificate and private key we created, as well as our CA certificate.
Log into your pfSense box’s “webConfigurator” interface and navigate to System->Cert. Manager->CAs. To import a new CA, select the “+ Add” icon. Add a name for your CA (e.g., “OpenVPN Server CA #1”) under “Desriptive name”, then click on the drop down list under “Method” and ensure that “Import an existing Certficate Authority” is selected. Carefully and securely copy the contents of the ca.crt file from the machine you generated it on and paste it into the “Certificate data” field, then select “Save”.
Now, navigate to System->Cert. Manager->Certificates and select the “+ Add/Sign” icon to import a new certificate and its private key. Ensure that “Import an existing Certificate” is selected under Method”, then add a name for your certificate (e.g., “OpenVPN Server Cert #1”) under “Descriptive name”. Carefully and securely copy the contents of the pfsense.crt file from the machine you generated it on and paste it into the “Certificate data” field, and the contents of pfsense.key into the “Private key data” field. Finish by selecting “Save”.
The information you copy from your pfsense.crt and pfsense.key files will no longer appear in these fields after you select Save. Rest assured, however, that they are stored in pfSense. In fact, you will find them stored as server1.cert and server1.key respectively, along with server1.ca, in /var/etc/openvpn after the OpenVPN server is created.
Next we’ll configure the various OpenVPN server parameters. Navigate to VPN->OpenVPN->Server and click on the “+ Add” icon to add a new OpenVPN server (See Figure 2).
Figure 2
Most of the parameters will be left at their default settings, however the following will need to be configured:
Server mode – We’re using the X.509 PKI authentication method for this example so we should select “Remote Access(SSL/TLS)” here.
Local port – This is the logical port that the OpenVPN server will listen on for VPN connections. To help improve security, we’ll avoid using OpenVPN’s default port 1194 and use port 13725 instead.
Description – Enter a description here for your reference. This field is optional but helpful.
TLS Configuration – Using this feature is beyond the scope of this post so for now uncheck “Use a TLS Key”. If you would like to learn more about using TLS authentication, consult the hardening OpenVPN security section of the OpenVPN documentation.
Peer Certificate Authority – Ensure that the CA you imported under System->Cert. Manager->CA (e.g., “OpenVPN Server CA #1”) is selected here.
Server certificate – Ensure that the certificate you imported under System->Cert Manager->Certificates (e.g., “OpenVPN Server Cert #1”) is selected here.
DH Parameter Length – Change this setting to “2048 bit” to match the default DH key length OpenVPN uses to generate the keys and certificates.
Encryption Algorithm – Set this to “AES-256-GCM”, a good strong algorithm that also matches the default NCP algorithm.
IPv4 Tunnel Network – This is the IPv4 subnet from which the OpenVPN server will assign IP addresses. The server will automatically assign the first host address from this subnet to itself, while the remaining host addresses will be used for remote VPN clients. Our example VPN network will use subnet 192.168.20.0/24 so enter that here.
IPv4 Local Network(s) – This is the subnet that will be accessable from the VPN; in other words, your home network’s subnet. Our example home network has the subnet 192.168.10.0/24 so enter that here.
Compression – Setting this parameter will result in compressing the traffic traversing your VPN connection, making more efficient use of your available bandwidth. LZO and LZ4 are different compression algorithms, with LZ4 generally offering the best performance with least CPU usage. Let’s use “LZ4 Compression v2 [compress lz4-v2]”.
In addition to the parameters above, there are several others you might be interested in depending upon your specific requirements. These are optional, but may help improve your OpenVPN experience:
Dynamic IP – This setting allows connected clients to retain their connections if their IP address changes.
Provide a default domain name to clients – This setting allows you to specify a domain name to be assigned to your VPN clients. You should enter the same domain name you entered in the “Domain” field under System -> General Setup.
DNS Server enable – This setting allows you to specify one or more DNS servers to be used by the OpenVPN clients while connected. If you’re using pfSense as your DNS forwarder, then enter the pfSense LAN IP address here, else enter the IP address(s) of the DNS servers you entered in the “DNS servers” fields under System -> General Setup.
NTP Server enable – This setting allows you to specify the NTP server(s) to be used by the OpenVPN clients while connected. If you’re using pfSense as your NTP server then enter the pfSense LAN IP address here, else enter the IP address(s) of the DNS servers you entered in the “DNS servers” fields under System -> General Setup.
NetBIOS enable – If you need Microsoft’s NetBIOS protocol then selecting this will ensure it is propogated over your VPN connection.
Verbosity level – I suggest changing this to “3 (Recommended)” to reduce the number of log entries.
When you’re finished making changes, select “Save” at the bottom of the page to complete the configuration.
Next, we’ll need to create two new firewall rules to allow our incoming OpenVPN connection to pass through to the OpenVPN server on the port it’s listening on. First, navigate to em>Firewall -> Rules, select the “Add” icon to add a rule to the bottom of the list and define following parameters:
Action: Pass
Interface: WAN
Protocol: UDP
Destination: WAN address
Destination port range: Custom 13725 To Custom 13725
Description: OpenVPN
When you’re finished making changes, select “Save” and “Apply Changes”.
Now navigate to Firewall -> Rules -> OpenVPN, select the “Add” icon and define following parameters:
Protocol: Any
Description: OpenVPN
Finally, we’ll need to add the openvpn() interface, which pfSense automatically creates when it enables the OpenVPN server. Navigate to Intefaces -> Assignments and add this interface, then select “Save” (See Figure 3).
Figure 3
OpenVPN client configuration in Windows for X.509 PKI authentication
To configure your Windows OpenVPN client for X.509 PKI authentication, copy the client certificate and key, as well as the CA certificate from C:\Program Files\OpenVPN\easy-rsa\keys\ to C:\Program Files\OpenVPN\config\. You’ll recall these files were bob.crt, bob.key, and ca.crt.
Next, we need to create an client configuration file so our OpenVPN client knows how to connect to the server. Fortunately, OpenVPN includes a sample client configuration file so we don’t have to create one from scratch. Copy the file C:\Program Files\OpenVPN\sample-config\client.ovpn to C:\Program Files\OpenVPN\config\. You can rename the file if desired, however, make sure to retain the *.ovpn extension. Open this file in your text editor and modify the remote line so that it specifies either the FQDN (“Fully Qualified Domain Name”) or WAN IP address of your pfSense box, followed by the port number the OpenVPN server is listening on, which in our case is port 13725:
We need to modify the cert and key lines so they point to our certificate and key file names:
1
2
3
4
5
6
7
8
9
# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
ca ca.crt
cert bob.crt
key bob.key
Since we’re not using a TLS key in this configuration let’s disable this feature. Comment out the line tls-auth ta.key 1:
1
2
3
# If a tls-auth key is used on the server
# then every client must also have the key.
;tls-auth ta.key1
We also need to tell the client which cryptographic algorithm to use. This should match the algorithm we configured in the OpenVPN server. Assuming you used the AES-256-GCM algorithm there then modify the cipher line so that it looks like the following:
1
2
3
4
# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
cipher AES-256-GCM
Since we’ve enabled LZ4 v2 compression in the OpenVPN server let’s ensure that algorithm is also used in the client:
1
2
3
4
# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
compress lz4-v2
Finally, let’s uncomment the auth-nocache parameter to strengthen security a bit:
1
2
3
# Configuration can cache passwords in memory.
# Use the auth-nocache option to prevent this.
auth-nocache
Now we’re ready to make our first OpenVPN connection. First, if you’re using Window’s firewall, make sure it is configured to allow VPN traffic to pass to/from the TAP-Windows adapter installed by OpenVPN. Now, open the Windows Start menu and select “OpenVPN”, then “OpenVPN GUI”, The OpenVPN GUI will launch and automatically minimize to the task tray. Right-click on the icon and select connect. If you elected to use a password to protect the client private key you’ll be asked to enter that password before OpenVPN will proceed with the connection (See Figure 3). After the OpenVPN client connects with the server in pfSense, the GUI will once again minimize to the task tray. Now try to ping the IP address of a host on the home network’s subnet. If the ping succeeds, congratulations! You’re now securily connected through your pfSense box to your home network using OpenVPN and X509 PKI authentication.
Figure 4
By the way, there are a couple of other ways you can start your OpenVPN connection in Windows. You can simply right click on an OpenVPN configuration file and selecting “Start OpenVPN on this config file.” You can also start it by using the command openvpn at a command prompt – you’ll need to be in the folder c:\Program Files\OpenVPN\config for this to work (else make the appropriate adjustments to your PATH environmental variable). Using the F4 key will terminate the connection.
OpenVPN client configuration in Linux for X.509 PKI authentication
To configure your Linux OpenVPN client in Linux for X.509 PKI authentication, move the client certificate and key files, as well as the CA certificate from /etc/openvpn/easy-rsa/keys/ to /etc/openvpn/. You’ll recall these files were bob.crt, bob.key, and ca.crt.
1
2
cd/etc/openvpn/
sudomveasy-rsa/keys/{bob.crt,bob.key,ca.crt}.
Next, we need to create a client configuration file so our OpenVPN client knows how to connect to the server. Fortunately, OpenVPN for Linux includes a sample configuration file so we don’t have to create one from scratch. Copy the file /usr/share/doc/openvpn/examples/sample-config-files/client.conf to /etc/openvpn/. You can rename the file if desired, however, make sure to retain the *.conf extension. Now open this file in your text editor and make the same changes as descibed above for the OpenVPN client configuration file in Windows. Remember to save your changes. Now we’re ready to make our first VPN connection. Open a terminal and use the following commands, replacing client.conf with the name of your configuration file if you changed it:
1
2
cd/etc/openvpn/
sudo openvpn client.conf
If you elected to use a password to protect the client private key, then you’ll be asked to enter that password before OpenVPN will proceed with the connection, which will end with a “Initialization Sequence Completed” message. Now, open another terminal, and try to ping the IP address of a host on the home network’s subnet. If the ping succeeds, congratulations! You’re now securily connected through your pfSense box to your home network using OpenVPN and X509 PKI authentication.
To simplify troubleshooting, it’s best to initially start the OpenVPN client from the command line as described above. However, once you know it can reliably connect to the server, then you can start it as a daemon. However, if you’ve elected to password protect the client key (e.g., bob.key) when generating it using the ./build-key-pass script, you may need to first add the password to some type of Linux password agent. For example, to add the password to Ubuntu’s password agent systemd-tty-ask-password-agent:
When executed, OpenVPN will scan for any configuration files (i.e. *.conf) in /etc/openvpn/, and will attempt to start a separate daemon for each one it finds.
Having previously gone through the steps necessary to configure the OpenVPN server and clients for OpenVPN access into our home network using the X.509 PKI authentication method, it’s time now to discuss how to configure these same components for OpenVPN access using pre-shared private key authentication. Once again, to help explain the steps involved, we’ll assume there is an existing home network that is currently using the IP subnet 192.168.10.0/24; we’ll use the subnet 192.168.20.0/24 for our VPN; and, we’ll designate UDP port 13725 as the port the OpenVPN server will listen on (See Figure 1).
OpenVPN server configuration in pfSense for pre-shared private key authentication
Log into your pfSense box’s “webConfigurator” interface navigate to VPN->OpenVPN->Server and click on the “+ Add” icon to add a new OpenVPN server (See Figure 2). Most of the options will be left at their default settings, however the following will need to be configured:
Server mode – We’re using the pre-shared private key authentication method in this example so we should select “Peer to Peer (Shared Key)” here.
Local port – This is the logical port that the OpenVPN server will listen on for VPN connections. To help improve security, we’ll avoid using OpenVPN’s default port 1194 and use port 13725 instead.
Description – Enter a description here for your reference. This field is optional but helpful.
Shared Key – Uncheck the “Automatically generate a shared key” box and then carefully and securely copy the contents of the static-bob.key file from the machine you generated it and paste it into the provided field.
Encryption algorithm – This is the cipher that OpenVPN will use to secure your VPN traffic. Since GCM encryption algorithms can’t be used with shared key server mode let’s use AES-256-CBC.
IPv4 Tunnel Network – This is the subnet from which the OpenVPN server will assign IP addresses. The server will automatically assign the first host address from this subnet to itself, while the remaining host addresses will be used for remote VPN clients. Our example VPN network will use subnet 192.168.20.0/24 so enter that here.
IPv4 Remote network(s) – This is the subnet that will be accessable from through the VPN; in other words, your home network’s subnet. Our example home network has the subnet 192.168.10.0/24 so enter that here.
Compression – Setting this parameter will result in compressing the traffic traversing your VPN connection, making more efficient use of your available bandwidth. LZO and LZ4 are different compression algorithms, with LZ4 generally offering the best performance with least CPU usage. Let’s use “LZ4 Compression v2 [compress lz4-v2]”.
Verbosity level – I suggest changing this to “3 (Recommended)” to reduce the number of log entries.
When you’re finished making changes, select “Save” at the bottom of the page to complete the configuration.
Next, we’ll need to create two new firewall rules to allow our incoming OpenVPN connection to pass through to the OpenVPN server on the port it’s listening on. First, navigate to em>Firewall -> Rules, select the “Add” icon to add a rule to the bottom of the list and define following parameters:
Action: Pass
Interface: WAN
Protocol: UDP
Destination: WAN address
Destination port range: Custom 13725 To Custom 13725
Description: OpenVPN
When you’re finished making changes, select “Save” and “Apply Changes”.
Now navigate to Firewall -> Rules -> OpenVPN, select the “Add” icon and define following parameters:
Protocol: Any
Description: OpenVPN
Finally, we’ll need to add the openvpn() interface, which pfSense automatically creates when it enables the OpenVPN server. Navigate to Intefaces -> Assignments and add this interface, then select “Save” (See Figure 3).
OpenVPN client configuration in Windows for pre-shared private key authentication
To configure your Windows client for pre-shared private key authentication, copy the key file static-bob.key from c:\Program Files\OpenVPN\easy-rsa\keys\ to c:\Program Files\OpenVPN\config\. Now we need to create an client configuration file so our OpenVPN client knows how to connect to the server. Since OpenVPN for Windows doesn’t include a sample client configuration file for the pre-shared private key authentication method, we’ll use the following, which is based on the sample static-home configuration file included with the OpenVPN installation in Linux. Copy and paste this text into your text editor and modify the remote line so that it specifies either the FQDN (“Fully Qualified Domain Name”) or WAN IP address of the pfSense box, followed by the port number the OpenVPN server is listening on, which in our example case is port 13725. The secret line specifies the name of our static key file, which in our case is static-bob.key. Save the file as client.ovpn and copy it to c:\Program Files\OpenVPN\config\. You can rename the file if desired, however, make sure to retain the *.ovpn extension:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
### README
#
# Date:
# Description: Client configuration for shared private key authentication
# Author:
# Process(s): openvpn
# Configuration:
#
### START OF CONFIGURATION
# '#' or ';' may be used to delimit comments.
# Use a dynamic tun device.
# OpenVPN also supports virtual
# ethernet "tap" devices.
;dev tap
dev tun
# Our OpenVPN peer is the OpenVPN server in our pfSense box
# 192.168.20.1 will be our OpenVPN server endpoint
# 192.168.20.2 will be our local OpenVPN endpoint
ifconfig192.168.20.2192.168.20.1
# The route to our local network
route192.168.10.0255.255.255.0
# Add a route to our home network subnet
route192.168.10.0255.255.255.0
# Our pre-shared private key
secret static-bob.key
# Compression to use
compress lz4-v2
# Cipher to use
cipher AES-256-CBC
# Send a UDP ping to remote once
# every 15 seconds to keep
# stateful firewall connection
# alive. Uncomment this
# out if you are using a stateful
# firewall.
;ping15
# Uncomment this section for a more reliable detection when a system
# loses its connection. For example, dial-ups or laptops that
# travel to other locations.
;ping15
;ping-restart45
;ping-timer-rem
;persist-tun
;persist-key
# Log file verbosity
verb3
# Configuration can cache passwords in memory.
# Use the auth-nocache option to prevent this.
auth-nocache
If you would like to specify a domain name to be assigned to your VPN client, add the following line to your client configuration file. You should enter the same domain name you entered in the “Domain” field under System -> General Setup.
1
dhcp-option DOMAIN<em>your-domain-name>
If you would like to specify the DNS server(s) to be used by your OpenVPN client while connected, add the following line to your client configuration file. If you’re using pfSense as your DNS forwarder, then specify the pfSense LAN IP address here, else specify the IP address(s) of the DNS servers you entered in the “DNS servers” fields under System -> General Setup.
1
dhcp-option DNS<your-DNS-IP-address>
Now we’re ready to make our OpenVPN connection. First, if you’re using Window’s firewall, make sure it is configured to allow VPN traffic to pass to/from the TAP-Windows adapter installed by OpenVPN. Now, open the Windows Start menu and select “OpenVPN”, then “OpenVPN GUI.” The OpenVPN GUI will launch and automatically minimize to the task tray. Right-click on the icon and select connect. After the OpenVPN client connects with the server in pfSense, the GUI will once again minimize to the task tray. Now try to ping the IP address of a host on the home network’s subnet. If the ping succeeds, congratulations! You’re now securily connected through your pfSense box to your home network using OpenVPN and pre-shared private key authentication.
OpenVPN client configuration in Linux for pre-shared private key authentication
To configure your Linux OpenVPN client in Linux for pre-shared private key authentication, copy the key file static-bob.key from /etc/openvpn/easy-rsa/keys/ to /etc/openvpn/. Then, copy the sample configuration file discussed above in the Windows section to /etc/openvpn/ (Alternatively you can use the sample configuration file included with OpenVPN for Linux. See /usr/share/doc/openvpn/examples/sample-config-files/static-home.conf). You can rename the file if desired, however, make sure to retain the *.conf extension. Now, open the file in your text editor and make the appropriate changes to the remote and secret lines as discussed above for the Windows configuration file. Remember to save your work.
Now we’re ready to make our VPN connection. Open a terminal and use the following commands, replacing client.conf with the name of your config file if you changed it:
1
2
cd/etc/openvpn/
sudo openvpn client.conf
To simplify troubleshooting, it’s best to initially start the OpenVPN client from the command line as described above. However, once you know it can reliably connect to the server, then you can start it as a daemon:
1
sudo service openvpn start
Now, open another terminal, and try to ping the IP address of a host on the home network’s subnet. If the ping succeeds, congratulations! You’re now securily connected through your pfSense box to your home network using OpenVPN and pre-shared private key authentication.
Conclusion
This concludes the post on how to configure secure remote access to your home network using pfSense and OpenVPN. Two methods are typically used by OpenVPN to authenticate the server and remote clients to one another: X.509 PKI or pre-shared private keys. The X.509 PKI method offers scalability and arguably better security, but may be overkill for those that want single-user VPN access to their home network. Conversly, the pre-shared key method does not scale well beyond one or two users, but is easier to setup and likely just fine for a small network with a limited number of remote VPN clients. For a full list of all the configuration options and other information I encourage you to visit the OpenVPN community software web site.
(20180226 – This post has been amended to reflect changes in pfSense version 2.4.2 — iceflatline)
This post will describe how to install and perform initial configuration of pfSense for use in a home network. pfSense (i.e., “making sense of packet filtering”) is a customized version of FreeBSD tailored specifically for use as a perimeter firewall and router, and managed almost entirely from a web-based GUI (“webConfigurator”). In addition to being a firewall and router, pfSense includes a long list of other features, as well as a package system allowing its capabilities to be expanded even further. pfSense is free and open source and its source code is released under the BSD license.
So, let’s get started…
Hardware Considerations
Minimum requirements
The minimum hardware requirements for pfSense include a 500 MHz CPU, 512 MB of system RAM, 1 GB hard drive, and a minimum of two Network Interface Controllers (NIC). You’ll also need a CD-ROM drive or bootable USB drive in order to install pfSense to the hard drive. These requirements are extremely modest, but unless your data throughput requirements are fairly small, you’re likely going to want to use hardware offering a little better performance. Since a major contributor to throughput performance is the system’s CPU, let’s start there. pfSense published guidelines for CPU sizing recommends the following:
10-20 Mbps – a modern (less than 4 year old) Intel or AMD CPU clocked at at least 500MHz
21-50 Mbps – a modern 1.0 GHz Intel or AMD CPU
51-200 Mbps – No less than a modern Intel or AMD CPU clocked at 2.0 GHz. Server class hardware with PCI-e network adapters, or newer desktop hardware with PCI-e network adapters
201-500 Mbps – server class hardware with PCI-X or PCI-e network adapters, or newer desktop hardware with PCI-e network adapters. No less than 2.0 GHz CPU
501+ Mbps – Multiple cores at > 2.0GHz are required. Server class hardware with PCI-e network adapters
Your choice of NICs will also have a significant impact on reliability and throughput performance. Low cost NICs, notwithstanding the potential long term reliability concerns, tend to rely much more on the system CPU to process segments and packets compared to their higher priced counterparts. Consequently, the better the NIC, the better the throughput performance you can expect from a given CPU. In short, don’t be too frugal when it comes to the NICs you use. Intel NICs are well supported under FreeBSD and always a good choice. If possible use discreet NICs rather than the on-board ones featured on many motherboards.
You should also ensure you have enough system memory. The pfSense hardware requirements recommend 1 GB of RAM. Whether or not you’ll need more will depend largely on how you decide to operate pfSense. Some of the add-on packages for example will increase RAM requirements significantly. Another factor to keep in mind when considering memory requirements is the number of active network connections. pfSense keeps track of active connections using a state table. The default state table size is 10,000 entries, each requiring ~1 KB of RAM or ~10 MB in total – likely more than adequate for handling most home networks. But, if you require a significantly larger state table, keep system memory requirements in mind.
Compatibility
pfSense is purportedly compatible with any hardware supported by the FreeBSD version a particular pfSense build is based upon. pfSense version 2.4.2 for example is based upon FreeBSD 11.1-RELEASE. It’s always a good idea, however, to check the hardware you’re planning to use against the information contained in the FreeBSD 11.1-RELEASE hardware notes and the hardware compatibility section of the Frequently Asked Questions for FreeBSD 10.x and 11.x. The pfSense forums are another good resource, useful for gleaning the hardware compatibility experiences of others.
Installation
Performing a full installation of pfSense is a straight forward; however, before you get started there are a couple of preliminary steps I recommend. First, make a note of the Media Access Control (“MAC”) address for each NIC you’re installing in the system as well as its physical location in the motherboard. If your memory is as bad as mine, this will save you from wondering later “…now which NIC did I assign as the LAN interface?…” Second, disconnect the NICs from any LAN and WAN devices until you have the box up and running and configured to your requirements. Finally, if you have other hard drives in the system I recommend disconnecting them until the installation is complete so as to not accidentally install to the wrong drive.
Download a copy of the pfSense installer and burn it to a CD or place it on a bootable USB drive. After booting the system using the CD or USB drive and accepting the copyright and distribution notice, you’ll arrive at the initial installation screen (See Figure 1).
Figure 1
Select “OK” to continue. The pfSense installer will ask whether it should continue with the default U.S. keyboard key map or use a different one (See Figure 2).
Figure 2
After configuring the keymap, the installer will ask and whether it should partition the hard drive using the UFS or ZFS file system. I advise using ZFS if possible (See Figure 3).
Figure 3
Unless your requirements call for something different, the default ZFS configuration options will work just fine (See Figure 4).
Figure 4
Next, the installer will ask you select a ZFS virtual device type. The steps in this post assume you’ll be installing pfSense on a single hard drive. The stripe option is the correct choice in this case. If your requirements call for installing pfSense using two or more hard drives then you have the option of selecting a mirror or one of the raidz virtual devices types (See Figure 5).
Figure 5
The installer will then ask you to confirm the choice of hard drives (See Figure 6).
Figure 6
Finally, the installer will offer one last chance before destroying any previous content contained on the hard drive and continuing with the installation. If you’re satisfied with your configuration choices select “YES” to proceed (See Figure 7).
Figure 7
After the installer finishes the installation you’ll be offer the opportunity to open a shell session in order to make any modifications manually (See Figure 9).
Figure 8
If no further changes are required select “No” the installation will be complete and the system will ask to be rebooted (See Figure 9).
Figure 9
Configuration
After pfSense is installed and the system rebooted, you’ll arrive at the pfSense console menu (See Figure 10).
Figure 10
Note that in this example pfSense has chosen the NIC assigned the device name em1 as the WAN interface, and em2 as the LAN interface (I have a third NIC in this system, which is why you see an em0 device). If you’d like to reassign these interfaces or simply want to know which MAC address belongs to each NIC, then select “Assign Interfaces” (menu option 1). Note also that pfSense initially assigns the LAN interface the default static IPv4 address of 192.168.1.1, and configures the WAN interface to use DHCP so you will not see an IP address assigned to that interface.
Select “Set interface(s) IP address” (menu option 2) to configure pfSense’s LAN interface IPv4 address to one that will fall within the subnet you plan to use for your network. In this example we’ve configured the IPv4 address to 192.168.10.1, assuming that the subnet will be 192.168.10.0/24.
Figure 11
This menu option also allows you to activate pfSense’s DHCP server and define a range of IPv4 addresses for the server to use. In this example we’ve configured the DHCP address range to be 192.168.10.101 to 192.168.10.254 (See Figure 12)
Figure 12
Once the IPv4 address and DHCP server are configured, you’ll be asked if I want to revert to HTTP as the webConfigurator protocol (as opposed to using to using HTTPS). I recommend declining this option to improve login security. After these steps are completed you will be returned to the console menu.
Now, connect to the LAN interface, fire up your web browser, and navigate to IPv4 address you assign to the LAN interface to access the pfSense webConfigurator. The webConfigurator login is password protected – the default login is admin and the password is pfsense. The first time you login to a new installation of pfSense, you ne greeted with the pfSense setup wizard to perform an initial configuration (See Figure 13).
Figure 13
The setup wizard starts by asking you to define the hostname for your new pfSense system, the domain where it will reside, and primary and secondary DNS servers. You can use any hostname you’d like but be aware of the following constraints: the hostname you choose must start with a letter, and after that contain only letters, numbers or a hyphen (e.g., “firewall” or “firewall-1”). The “Domain” field can be filled in with any fully qualified domain (e.g., “mysite.org”) or a name of your choice (e.g., “homenet”). The hostname and domain fields are combined to create the fully qualified domain name of your pfSense box (e.g., “firewall.mysite.org” or “firewall.homenet”). If your service provider provisions your service using DHCP, then the DNS fields will be likely be filled in automatically when you connect to your provider. If you plan to use a static WAN IP address, or simply prefer to use alternative DNS providers, then you should provide at least a primary DNS address at this point (See Figure 14).
Figure 14
The next wizard screen is where a time server hostname and timezone are defined. I recommend using the default host 0.pfsense.pool.ntp.org, which results in a random server from a pool of known good NTP servers to be chosen automatically (See Figure 15).
Figure 15
Next, you’ll be taken to the WAN section of the setup wizard. If your service provider provisions your service using DHCP, then you simply need to select “DHCP” from drop-down list, otherwise chose the appropriate service type. The “MAC Address” field under “General configuration” can be used to enter a MAC address that will pose as the MAC address of your WAN interface NIC. The “Block RFC1918 Private Networks” and “Block bogon networks” sections are selected by default in order to block invalid traffic from entering your network. The remaining sections in this portion of the setup wizard are specific to WAN service type chosen (See Figure 16)
Figure 16
After the WAN section, you’ll encounter the final two sections of the setup wizard. These provide the opportunity to change, if desired, the LAN IP address as well as the default password for the admin user account. Note that this password also serves as the password for SSH access as well as the console menu (should you decide to password protect it).
At the conclusion of the setup wizard, you’ll select “Reload” and after a few moments be returned to the pfSense webConfigurator. At this point basic connection options are configured enough to allow the pfSense box to be safely connected to the service provider and LAN. However, before bringing pfSense online in your network there are a couple of optional changes to its configuration you may wish to consider.
Disable webConfigurator login autocomplete
By default login credentials for the webConfigurator may be saved by a web browser. Navigate to System->Advanced->Admin Access and select “Disable webConfigurator login autocomplete” to disable autocomplete on the login form so that browsers will not prompt to save credentials (Note that some browsers do not respect this option). When complete, select “Save”.
Password protect the console menu
While pfSense is managed almost entirely from its webConfigurator, it does allow some configuration management through its console menu (See Figure 10). By default, pfSense does not secure this menu, therefore, anyone who can physically connect a monitor to the pfSense machine will have root level shell access. To prevent this (or at least make it more difficult), navigate to System->Advanced->Admin Access and select “Password protect the console menu.” When complete, select “Save.” You’ll need to reboot the system for this change to take effect. Note that the user name for the console menu is always admin or root and the password will be “pfSense” by default, or the one you chose if you elected to change the default admin password when running the setup wizard. It’s also worth noting here that if you create a new user, this new user will only be allowed access to a command line prompt at the terminal, not the console menu itself, even if you add them to the system’s admins group (See System->User Manager).
NAT Reflection mode for port forwards
By default pfSense prevents hosts within the LAN from accessing your public IP addresses. This can be inconvenient at times, particular when testing port forwarding from within the LAN. To change this, navigate to System->Advanced->Firewall & NAT and, depending on your requirements, select either “NAT + proxy” or “Pure NAT” from among the options in the drop down list under “NAT Reflection mode for port forwards”. When complete, select “Save”. A reboot is not needed when selecting this option so you can use it on an as-needed basis if desired.
Packages
As mentioned, pfSense offers a fairly extensive package system allowing you to extend its capabilities. To find a list of packages that can be added, navigate to System->Package Manager->Available Packages to view the available software packages.
Firewall
Setting up NAT port forwarding and firewall rules in pfSense can be a bit daunting at first. Once you get the hang of it though you’ll realize just how flexible and powerful the system is. Options for configuring port forwarding and firewall rules can be found under Firewall->NAT and Firewall->Rules respectively. I recommend setting up any port forwarding rules you may have first. Then, for each port forwarding rule, you’ll need to set up an associated firewall rule. When complete, select “Save”, then “Apply changes”.
DHCP
Options for configuring the DHCP server on the LAN interface can be found under Services->DHCP server. If you’re deploying pfSense in a typical home network where the availability of IP addresses is not a concern, one option you may want to consider changing is the default lease time of 7200 seconds (two hours) in order to reduce the number of lease requests in the network. This is also the section where you can assign static IP addresses to hosts, if desired. For example, you may wish to assign static IP addresses to servers and network devices (managed switches, network printers, etc.), as well as to any hosts you intend to build long-term port forwarding rules for.
UPnP
If you have game consoles like Microsoft Xbox, you know what a pain it can be at times to get them to connect reliability to services like Xbox Live through your home network gateway/firewall. A common solution is to forward the necessary ports to these devices, but what if you have more than one? If you want one or more game consoles to have reliable access to their respective services, the only real solution is to use Universal Plug and Play (UPnP). Fortunately, pfSense’s UPnP service works remarkable well. To activate it, navigate to Services->UPnP & NAT PMP and select “Enable UPnP & NAT PMP” and “Allow UPnP Port Mapping” then ensure that the LAN interface is selected under “Interfaces”. When complete, select “Save”. That’s it. Your game consoles will discover pfSense’s UPnP server and the necessary port forwarding rules will be built automatically as needed. You can check which ports have been forwarded by navigating to Status->UPnP & NAT PMP.
Wake on LAN
The Wake on LAN in feature in pfSense allows you to instruct it to send the Wake on LAN “magic packet” to a network host you need to power up. To setup Wake on LAN, navigate to Services->Wake-on-LAN and select the “+ Add” icon. Select the LAN interface and enter the MAC addresses for the host you’d like to send magic packets to. When complete, select “Save”.
System Logs
You may wish to have log entries arranged so that the newest entries appear first. To do that, navigate to Status->System Logs->Settings and select “Show log entries in reverse order (newest entries on top)”. When complete, select “Save”.
Remote Access
pfSense’s webConfigurator uses HTTPS and port 443 by default, and accessing it remotely is simply a matter of navigating to your WAN address. Unfortunately, many ISPs block incoming port 443 traffic. You can chose an alternate incoming TCP port by navigating to System->Advanced->Admin Access and entering the port number in the “TCP port” field. When complete, select “Save”. You will also need to create a new firewall rule under Firewall->Rules that will allow a connection on the WAN interface to pass through to pfSense’s webConfigurator server on the port you specify. At a minimum, this rule should define following parameters:
Action: Pass
Interface: WAN
TCP/IP Version: IPv4
Protocol: TCP
Destination: WAN address
Destination port range: your alternate webConfigurator port selection
Description: web admin
pfSense’s SSH server may also be enabled to allow remote access to the console menu via an SSH client. To enable the SSH server, navigate to System->Advanced and select “Enable Secure Shell”. For improved security, I recommend using an incoming port other than 22 and a key-based login instead of a password. To use a key-based login, select “Disable password login for Secure Shell (RSA/DSA key only)” and select “Save”. Then navigate to System->User Manager and paste your public key into the “Authorized SSH Keys” field. When complete, select “Save”. Note that your public SSH key is stored in /root/.ssh/authorized_keys. Should you need help generating a public/private key pair please see my post Remote Access To Your Ubuntu Server Using PuTTY, Hamachi and SSH. Don’t forget to create a new firewall rule under Firewall->Rules that will allow a connection on the WAN interface to pass through to pfSense’s SSH server should you decide to use an alternate SSH port.
Conclusion
This concludes the post on how to install and configure pfSense on your home network. pfSense isn’t hard to configure nor complicated to manage, and proves to be a nice open source package for implementing a robust and scalable perimeter firewall and router.