NB: Before you begin following this article you’ll need to understand how to use vi, as we’ll be working at a command-line interface with this as the only text editor at our disposal. If you don’t know how to do basic text editing in vi I suggest you read a few articles and familiarize yourself with it otherwise you won’t have a good time Also if you’re on an IPv6 network, you can follow this article if you want but it’s all inIPv4 so..you’ve been warned
Today I’ll take you through the set-up of a secure (HTTPS) server on a FreeBSD virtual machine which you can use to host your own website for dev purposes, or for educational purposes, or whatever.
We’re going to be using VirtualBox, which can be downloaded here and FreeBSD 10.2 which is the latest stable release at time of writing, although you probably won’t have any problems using a newer release.
The web server we’re going to use is NginX, which is a highly configurable, simple, fast, secure and powerful web server.
What are the advantages of using a virtual machine?
Glad you asked that question. I’ll start with the disadvantages: A virtual machine runs software slightly slower and consumes some more resources than the host machine it’s running on. The advantages are…everything else.
What are the advantages of using a FreeBSD?
FreeBSD is a industrial-grade operating system that is extremely secure, fast, and surprisingly simple to use. Ever used OSX? You’re using FreeBSD. Yeah. OSX is basically FreeBSD with lots of `skinning’. Ever played a PS4? It’s operating system is a modified FreeBSD, same with the PS3. It’s also used for mission-critical high-traffic networking equipment such as load balancers, firewalls, email servers and webservers, basically any really important application where Linux is just not “up to the job”.
And speaking of webservers, that’s what what we’re going to be doing.
If you haven’t already done it, install VirtualBox on your Mac, Windows or Linux machine.

Next you’ll need to head over to FreeBSD.org and grab the 64-bit ISO disk image of the 10.2 release, Click Production 10.2, scroll down to ftp, click on the first link, which is this, then click on the 64-bit CD image, which is this, and let it start downloading.

Go back into VirtualBox, and click the New icon to start creating your virtual machine. When you create something, a lot of times the first thing you do is give it a name, and creating a VirtaulBox virt is no exception. In this case I’ve gone for `BSDBox’, but you’re free to use anything you like, as long as it doesn’t contain any illegal characters so go on, pick something wacky, type in your crazy name then select `BSD’ under type and `FreeBSD (64-bit)’ under version.

Next you choose how much of your computer’s memory will be allocated for this virt, in this case I’ve gone for 512MB which I’m hoping will be enough to run NginX and get me through this article. Feel free to use more if you can afford it, but not less, please.

Next we create a virtual Hard Drive… do what the picture says.

Do what the picture says.

Again.

Again.

Wait, might take a while…

Ok now we’ve got a virt set up with an 8GB harddrive and 512 MB of memory but no operating system.

If you click `Start’ you’ll get something like this. FYI, when you do this VirtualBox might ask you if you want mouse pointer integration which is supported on most modern operating systems (ie. operating systems that are capable of knowing that they’re running on a virtual machine), and the best choice is to pick yes. This `traps’ the mouse pointer inside the VirtualBox window which just makes it feel more like a real computer. The mouse pointer can be released by pressing the right ctrl key.
![BSDBox [Running] - Oracle VM VirtualBox_016](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_016.png?w=300)
Installing FreeBSD
Next we insert our virtual CD into our virtual CD drive and install the operating system. Open up the settings window for your virt, click `Storage’, highlight the DVD drive under `Storage Type’, click the picture of a DVD on the far right, click `Choose a virtual CD or DVD file…’, browse to the one you downloaded from FreeBSD.org, or if it’s not downloaded yet, wait.

Click Ok, then click Start to start up your virt. Hit enter when you see the black screen
![BSDBox [Running] - Oracle VM VirtualBox_020](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_020.png?w=300)
Hit Enter to install
![BSDBox [Running] - Oracle VM VirtualBox_021](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_021.png?w=300)
Choose a keymap, test it, then choose the first option to Continue
![BSDBox [Running] - Oracle VM VirtualBox_022](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_022.png?w=300)
![BSDBox [Running] - Oracle VM VirtualBox_023](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_023.png?w=300)
Type in the same name you chose for your virt as the hostname, hit Enter
![BSDBox [Running] - Oracle VM VirtualBox_024](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_024.png?w=300)
For speed just choose 32-bit compatibility libraries and ports tree, hit Enter
![BSDBox [Running] - Oracle VM VirtualBox_026](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_026.png?w=300)
Choose guided disk setup.
![BSDBox [Running] - Oracle VM VirtualBox_027](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_027.png?w=300)
Entire disk.
![BSDBox [Running] - Oracle VM VirtualBox_028](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_028.png?w=300)
GUID Partition Table.
![BSDBox [Running] - Oracle VM VirtualBox_029](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_029.png?w=300)
Enter
![BSDBox [Running] - Oracle VM VirtualBox_030](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_030.png?w=300)
Enter.
![BSDBox [Running] - Oracle VM VirtualBox_031](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_031.png?w=300)
Wait.
![BSDBox [Running] - Oracle VM VirtualBox_033](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_033.png?w=300)
Choose a root password. BSD isn’t very picky here, in fact I think you may be able to press Enter here and leave it without a root password so type carefully.
![BSDBox [Running] - Oracle VM VirtualBox_034](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_034.png?w=300)
The next screen you see will be asking you about configuring network interfaces. Just press Esc to take you to a main menu then press enter to exit the installer.
![BSDBox [Running] - Oracle VM VirtualBox_035](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_035.png?w=300)
![BSDBox [Running] - Oracle VM VirtualBox_037](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_037.png?w=300)
After a few seconds it will ask you if you want to make any final changes, choose `No’, wait for a few seconds and the virt should shut down. If not, choose “ACPI shutdown” from the Machine menu. Wait for the machine to go into the stopped state. Now remove the virtual disk from the virtual drive otherwise when you switch it on it will run the installer again.
Networking
At this point we have got a fresh install of FreeBSD on our virtual hard drive and the next step is to configure VirtualBox such that the FreeBSD virt has it’s own IP address on the same network the host machine is on. This means we can open a web browser and browse to a page that’s hosted on the virt from our host machine, or from any machine on the network. VirtualBox has lots of options for configuring networking and the default one is `NAT’. Click Settings then click Network to bring up the network settings.

As you can see `NAT’ is selected which means VirtualBox will run a sort of “virtual router” which the guest OS (FreeBSD) thinks is a real router, so when you start up a virt, the guest OS sends a DHCP request over it’s virtual network card, which is picked up by the virtual router which responds by giving it an IP address, subnet mask, gateway address and DNS address(es). Next, when a packet is sent from the virt to the virtual router, the virtual router changes the source address of the packet (and possibly the port) to be the address of the host machine then forwards it off to the real router to get to it’s final destination. When a response comes back VirtualBox again translates the destination address (and possibly the port) of the packet to match the address and port from which the first packet was sent.
This is convenient and fairly secure for tasks such as web browsing and email but not if we want to run a server since we want others on the network to be able to contact us directly, this is achieved by something called a `Bridged Adapter’, so change from NAT to bridged adapter and click OK.

Start up the virtual machine again. A bridged adapter sends the packets emitted from the virt directly to the host machine’s network card, circumventing the host’s TCP/IP stack. The network card handles the Ethernet protocol only and has no clue about what is inside any of the packets it’s transmitting and receiving so VirtualBox can just inject packets generated by the virt so it’s mixed in with the traffic from the host machine, the network card forwards them to the nearest router, the router may or may not notice that there are now 2 IP addresses associated with the same MAC address, and almost certainly won’t care, and will forward them on and deliver back the responses.
When the responses come back in, VirtualBox will be sniffing all the packets and will grab any that have the virt’s IP address as a destination. At the same time the host machine’s TCP/IP stack will ignore any packets that don’t have it’s IP address.
![BSDBox [Running] - Oracle VM VirtualBox_041](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_041.png?w=300)
When you see the login screen type `root’ as the login and the password you chose earlier. Once you’re logged in type
# ping www.google.com
You should get a message indicating that the host couldn’t be found. That’s to be expected. What we’re going to do now is enable DHCP on the virt and reboot the machine, when it reboots it should get an IP address (and the rest) from the host machine’s DHCP server, which is probably also the gateway. Once we get this IP address and test our network connection and if it works, (ie. we can ping google.com), we’ll make a note of the IP address/netmask/gateway, etc then set them manually so the virt will always use these settings. This means we don’t have to go to the bother of checking what kind of network we’re on, although chances are you’re just on a standard 192.168.x.y, some people have weird network configurations, but more importantly we’ll have a static IP address which will persist across reboots which is essential for running our webserver.
Type the following command:
# echo 'ifconfig_em0="DHCP"' >> /etc/rc.conf
Then this:
# reboot now
This adds a command at startup which configures the network interface (em0) to get it’s address via DHCP. Wait for the virt to reboot, log in again and try pinging google.com. You should get replies. Press Ctrl-C to break out of ping. Now we need to determine the virt’s IP address, netmask, gateway and DNS servers. Type ifconfig
and you should see something like this:
![BSDBox [Running] - Oracle VM VirtualBox_046](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_046.png?w=300)
Make a note of the inet and netmask in the em0 section, in my case they are 192.168.1.16 and 0xffffff00. We’ll have to convert the netmask to dotted decimal notation, this can be done by stripping off the 0x then grouping the eight remaining digits into groups of two to give ff.ff.ff.00, finally use a hex calculator to convert each of these bytes into decimal, to give 255.255.255.0
That’s the IP and netmask sorted. To get the gateway address type the command
# netstat -r -f inet
which will display the local routing table. There should be 4 columns, the first tow of which are Destination and Gateway. Look under Destination and look for default, check what is listed in the corresponding Gateway column, and… that’s your gateway address!
Finally you need your DNS address(es). Type
# cat /etc/resolv.conf
You should see something like
nameserver X.X.X.X
...
There’s a high probability that there’s only one nameserver listed and it has the same address as your gateway. Whether this is true or not, it doesn’t matter, because the good news is you can just leave this file alone and it will continue to be used as the nameservers. Next you’ll want to open the file /etc/rc.conf
in vi
# vi /etc/rc.conf
Remove the last line and replace it with
ifconfig_em0="inet X.X.X.X netmask Y.Y.Y.Y"
defaultrouter="Z.Z.Z.Z"
of course replacing X.X.X…. with your IP address, netmask and gateway respectively. Save and close the file and reboot your virt again. When you log in, do another ping test to check that you’re online, if you get replies, fantastic. While you’re at it, open a command prompt on your host OS and type
$ ping bsdbox
Or whatever name you chose for your virt. You should also get replies. As a final step, we’re going to edit our hosts file so it has the hostname-to-IP mapping. Sendmail was giving me problems on my virt and it probably will on yours too if you don’t take this step, so to do it all in one go type (CAREFULLY):
# echo 192.168.1.3 bsdbox >> /etc/hosts
inserting your own IP address and hostname instead. Restart the virt again. It would be no harm to do this on your host machine and any other machine(s) you plan on accessing the webserver from. It’s done the same way in Linux (as root), for OSX and Windows google “editing hosts file in (OSX/Windows)” and you should find tons of info on how to do it.
Installing NginX
Now it’s time to install our web server. First you’ll need to enter this command to get FreeBSD to update it’s ports tree
# portsnap update
This will take a few minutes, next you’ll need
# portsnap extract
This will take even more time. What’s happening here is a directory tree, rooted at /usr/ports is being built for the entire FreeBSD ports collection. That is: software that’s been ported to FreeBSD and has been tested and is known to work on FreeBSD. The ports collection is divided into categories for different types of software: such as development, games, web, math, multimedia, and so on.
When that’s done, and it will take a while, you’ll want to navigate to the /usr/ports/www/nginx
directory. Now we’re going to compile NginX. If you type ls
you’ll notice a Makefile in there, so type
# make install clean
to begin building NginX. After a while you should see a blue screen asking what features of NginX you want, Just make sure HTTP_SSL is selected, then hit Enter to continue the install.
![BSDBox [Running] - Oracle VM VirtualBox_048](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_048.png?w=300)
When all that is finished, NginX should be installed on your virt. Before we reboot again, we’re going to set NginX to start up automatically on boot, that means adding one line to rc.conf:
# echo nginx_enable="YES" >> /etc/rc.conf
reboot the virt again and wait till you see the login screen. By this time NginX should have started a basic HTTP server listening on port 80. Open a web browser and into the address bar type http://<hostname>
, using your hostname of course. You should see something like this:

So we’ve got a webserver up and running serving normal unencrypted HTTP traffic. Getting there..
Generating SSL Certificate and Key
Navigate to the /etc/ssl
directory of your BSD system. Issue the following commands to create two directories:
# mkdir keys
# mkdir certs
Now we’ll create a private key, remember to substitute the name of your host in place of `bsdbox’:
# openssl genrsa -aes128 -out keys/bsdbox.key 2048
This generates an RSA private key with a 2048-bit modulus, which is considered secure at time of writing. You’ll also be asked for a passphrase for your key. Choose a strong password and make a note of it. Next we’ll secure this file by making it unreadable to anybody but root:
# chmod 400 keys/bsdbox.key
Next we’ll make a certificate signing request:
# openssl req -new -key keys/bsdbox.key -out bsdbox.csr
You’ll be asked for some information on your `Company’, fill in the details; for the FQDN use your hostname, and for email address use root@<your hostname>. Finally we’ll create and self-sign the certificate which contains our public key and is valid for the next 365 days:
# openssl x509 -req -days 365 -in bsdbox.csr -signkey keys/bsdbox.key -out certs/bsdbox.crt
You can delete bsdbox.csr
file now as it’s no longer needed.
Configuring NginX
We’re nearly there. Open up /usr/local/etc/nginx/nginx.conf
in vi. This is the main config file for NginX and is hierarchical in structure. Observe that there’s a http { ...}
section which encompasses all the settings and inside that there’s a server{ ... }
section which holds all the settings for the default website on our server. We’re only going to be editing what’s inside the server{ ... }
section.
Firstly you’ll see
listen 80;
Change this to
listen 443 ssl;
Next change server_name
from localhost
to <yourhostname>;
Don’t forget the semicolon!, (you need a semicolon after everything in NginX configs) then under that add the following 3 lines:
ssl on;
ssl_certificate /etc/ssl/certs/<yourhostname>.crt;
ssl_certificate /etc/ssl/keys/<yourhostname>.key;
Here’s a picture of my vi screen afer making these changes:
![BSDBox [Running] - Oracle VM VirtualBox_053](https://computersciencealgorithms.files.wordpress.com/2015/10/bsdbox-running-oracle-vm-virtualbox_053.png?w=300)
These are the minimal changes you need to make to have a HTTPS server up-and-running. Save the file and exit. You’ll now need to restart NginX, you can either use the command
# nginx -s reload
or if you’re like me you can just reboot the virt. Whichever you do, at some stage you’ll be asked to provide the passphrase for your private key so NginX can use it. Type it in, and wait for the server to start.
Testing Your Server
Open a browser window and enter the address https://<yourhostname>, you should see a warning telling you it’s unsafe to proceed, or that this connection is untrusted.

Follow these instructions to view the page
Firefox: “I understand the risks”, “Add exception”, “Confirm security exception”
Chrome: “Advanced” , “Proceed to…”

And there it is in all it’s glory! A very secure webserver using 2048-bit RSA encryption hosted inside a virtual FreeBSD instance. Of course to keep it secure you’ll need to log out of FreeBSD every time you leave the computer alone since there’s only one root user, but ignoring the “physical” risks, this server is pretty much unhackable. An output from nmap on my Linux host machine:
root@CodeCook:~/ca# nmap bsdbox
Starting Nmap 6.40 ( http://nmap.org ) at 2015-10-21 08:44 IST
Nmap scan report for bsdbox (192.168.1.3)
Host is up (0.00059s latency).
rDNS record for 192.168.1.3: BSDBox
Not shown: 999 closed ports
PORT STATE SERVICE
443/tcp open https
MAC Address: 08:00:27:52:60:43 (Cadmus Computer Systems)
Nmap done: 1 IP address (1 host up) scanned in 44.05 seconds
As you can see the only open port is 443 because that’s the only software we installed. FreeBSD assumes nothing about what you’re going to do with it and errs on the side of caution. It’s a generic operating system just built to work and nothing else.
I’ll follow up this article with one where we will create our own certificate authority and install a Root cert on the client browser(s) so we can access our secure server without all the annoying warnings.