Setting up NGINX on FreeBSD with SSL

Khris Byrd
Aug 31, 2018 · 4 min read
“gray laptop computer turned on” by Rich Tervet on Unsplash

The choice of NGINX

Even though I have a fair and familiar background on using the Apache web server, I’ve decided to use NGINX to host this site, as well as be the web server of choice of this FreeBSD installation. Given that this resides on a fairly low powered droplet from DigitalOcean, I felt it best to use the given web server that has made a name for itself as one of, if not thee, de facto lightweight, light resource web server. The fact that it also has made a name for itself as being a great proxy and reverse proxy server is just icing on the cake. I’m sure these features will come in handy pending future small web applications I deploy on this box.

Installation

FreeBSD provides multiple paths to installing software, giving you whatever options you may need. You can use the Ports system to build and compile the application with whatever features you may need, or you can simply use the pkg command to install an already compiled binary of it. As this version of NGINX has essentially everything we’d need (and want), the binary will be just fine.

# pkg install nginx

Once it’s installed, you can find its configuration files under /usr/local/etc/nginx/, and its default web files under /usr/local/www/nginx/.

To enable the service (ensuring it restarts automatically every time the system reboots), run

# echo 'nginx_enable="YES"' >> /etc/rc.conf

And finally, to start the service, run

# service nginx start

With the default configuration, you should be able to go to http://your_server.com and see the default NGINX page.

Making it useful

Open the /usr/local/etc/nginx/nginx.conf file in your preferred editor (vim, always) and comment out/remove the content displayed in the current server {} section.

The primary content we need to enter in here is as follows:

server {
listen 80;
server_name mydomain.net www.mydomain.net;
return 301 https://$server_name$request_uri;
}

This does the following:

  • Tells the server to listen on port 80 (the default web service port).
  • Sets the $server_name variable to mydomain.net. Any requests coming in for this domain name will be handled by this server block’s rules.
  • Instructs the server to reply with HTTP server code 301; which means it should go to the following url to reach the requested content. In this case, that url is constructed of an HTTPS request to the variable $server_name, which contains the server’s hostname (mydomain.net) as well as $request_uri, which appends the url requested from the server.

This basically says “Listen for requests over port 80 and tell them to use HTTPS”. This is preferred over completely disabling HTTP because most people and their systems don’t default to HTTPS requests. This way they’re gently redirected instead of getting a timeout error or something else unfavorable.

Now we need to actually set up the HTTPS server. Below the above server block within the nginx.conf file, add the following server block:

server {
listen 443 ssl;
server_name mydomain.net www.mydomain.net;
ssl_certificate /usr/local/path/to/your/ssl/cert.pem;
ssl_certificate /usr/local/path/to/your/ssl/key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /usr/local/www/html;
index index.html index.htm;
}
}

This is certainly a bit more than the first server block, but it’s pretty easy to unpack.

We:

  • Tell the server to listen on port 443 and expect ssl connections.
  • Set the server_name directive again, as this is separate listener.
  • Provide the path to the ssl certificate for mydomain.net.
  • Provide the path to the ssl certificate key for mydomain.net.
  • Set the ssl session cache to 1 megabyte. This is an optimization that, if you don’t want it, doesn’t need to be set. This tells the server to use a shared ssl cache for all the worker processes, and the cache size should be equal to 1 megabyte. According to NGINX’s documentation, this should be enough to store approximately 4000 sessions.
  • Set the ssl session timeout to 10 minutes. This is another optimization. One of the most resource intensive actions a low power machine can take on is creating/managing ssl connections. By increasing the timeout time (default: 5m) we can slightly decrease the amount of extra work that goes into each connection.
  • Set the allowed SSL ciphers to use. The values we have set are the same ones currently used by default; so if you want to be less verbose and direct, feel free to remove this line.
  • Set the preference of using the server directed ciphers instead of the client directed ciphers.

The location {} block specifies the location of the web root on the server (in this case, /usr/local/www/html/). This is where you should put your website files.

  • Finally, tell the server to look for the either index.html or index.htm as the index file of this directory.

After doing the above, take this time to populate your web root with your HTML content. You should then be able to restart NGINX via service nginx restart. It will check the configuration of the files to ensure there are no errors, then start accordingly.

If you run into issues such as not being able to view the site, or getting 404 errors, be sure your paths are correct and your firewall isn’t blocking access to ports 80 or 443.

Feel free to contact me if you have any questions or concerts.

Khris Byrd

Written by

Just another sudoer trying to su — root.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade