If you run multiple websites, then running each one in a jail is an easy way to isolate the configs and the websites from each other. Other than running a proxy server, which we will show you how to set up, there is little to no complicated setups. First you need a FreeBSD server set up. Once the FreeBSD server is running then you need to install bastille to manage your jails. Below is the steps to install and configure bastille:
# pkg install git
# pkg install sudo
# git clone https://github.com/BastilleBSD/bastille.git
# make install
# bastille
[INFO] Configuration file not found. Do you want to create it with default values? [y/N]
y
# bastille bootstrap 14.2-RELEASE
Now we have bastille set up and ready to build jails. First let us build a proxy server.
# bastille create -V proxy 14.2-RELEASE 0.0.0.0/24 ue0
# bastille list all
JID Boot Prio State IP Address Published Ports Hostname Release Path
2 on 99 Up 192.168.69.81 - proxy 14.2-RELEASE /usr/local/bastille/jails/proxy/root
Now let us build some jails for each of my domains. Obviously insert your domains and naming scheme. I name
my jails based on the domain name to make it easy for me to track which one is running what domain. Below is
my exact commands to create vnet jails with dhcp addresses for the jails. I manage all my ip addresses on my
OPNSense firewall so I never set a static ip on a server. I have ONE source of truth for IP addresses. Less
chance to mess it up that way.
# bastille create -V maildragon 14.2-RELEASE 0.0.0.0/24 ue0 # bastille create -V snarfingcode666 14.2-RELEASE 0.0.0.0/24 ue0 # bastille create -V rmdesigns 14.2-RELEASE 0.0.0.0/24 ue0 # bastille create -V remotesimplicity 14.2-RELEASE 0.0.0.0/24 ue0 root@raspberrypi1:/home/bmccormick/bastille # bastille list all JID Boot Prio State IP Address Published Ports Hostname Release Path
4 on 99 Up 192.168.69.82 - maildragon 14.2-RELEASE /usr/local/bastille/jails/maildragon/root 2 on 99 Up 192.168.69.81 - proxy 14.2-RELEASE /usr/local/bastille/jails/proxy/root 10 on 99 Up 192.168.69.85 - remotesimplicity 14.2-RELEASE /usr/local/bastille/jails/remotesimplicity/root 8 on 99 Up 192.168.69.84 - rmdesigns 14.2-RELEASE /usr/local/bastille/jails/rmdesigns/root 6 on 99 Up 192.168.69.83 - snarfingcode666 14.2-RELEASE /usr/local/bastille/jails/snarfingcode666/root
Now from the output of bastille list all you see the 5 jails I created. One proxy and four domains. Now we need NGINX installed on all of the "servers"(jails). This is where the ALL switch for commands comes in handy. We can run one command and install NGINX on all servers. Now this assumes you don't have any other jails running, so if you do then you need to target each of them by name, or you might end up with NGINX on places you don't want it. Also I install vim on all jails so I can edit the config files with vim rather than vanilla vi.
# bastille pkg ALL install nginx# bastille pkg ALL install -y vim
Next we need to configure the hosting jails to serve up the websites. I will show one of my configs and you can set all yours up using mine as an example.
# /usr/local/etc/nginx/nginx.conf
#user nobody; worker_processes 1; events { worker_connections 1024; } http { include mime.types;< default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name maildragon.com; location / { root /usr/local/www/maildragon/; location /roundcube { proxy_pass http://192.168.69.87; } # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/local/www/nginx-dist; } } }
As you see it is a very simple setup for the websites. The only caveat is that on this one I am redirecting the maildragon.com/roundcube to my mail server. Notice no SSL or certs. The proxy server handles all the outside requests and deals with the certs. All the communication to the webservers is internal and not exposed to the Internet. So no security issue there. All browswers will see the certs and accept them from the proxy.
So next we move on to the proxy server. A proxy server simply takes all the incoming requests and sends them to the right place. In this case it looks at requests and sees which domain it is for and sends the request to the right server for that domain. Below is the nginx config for the proxy server. All the lines labeled managed by certbot will be put in when you run the certbot.
# /usr/local/etc/nginx/nginx.conf #user nobody; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; # HTTPS server # server { server_name rainmadekennels.com www.rainmadekennels.com; location / { proxy_pass http://192.168.69.88; } listen 443 ssl; # managed by Certbot ssl_certificate /usr/local/etc/letsencrypt/live/rainmadekennels.com/fullchain.pem; # managed by Certbot ssl_certificate_key /usr/local/etc/letsencrypt/live/rainmadekennels.com/privkey.pem; # managed by Certbot include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { server_name maildragon.com www.maildragon.com; location / { proxy_pass http://192.168.69.82; } listen 443 ssl; # managed by Certbot ssl_certificate /usr/local/etc/letsencrypt/live/maildragon.com/fullchain.pem; # managed by Certbot ssl_certificate_key /usr/local/etc/letsencrypt/live/maildragon.com/privkey.pem; # managed by Certbot include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { server_name remotesimplicity.com www.remotesimplicity.com; location / { proxy_pass http://192.168.69.85; } listen 443 ssl; # managed by Certbot ssl_certificate /usr/local/etc/letsencrypt/live/remotesimplicity.com/fullchain.pem; # managed by Certbot ssl_certificate_key /usr/local/etc/letsencrypt/live/remotesimplicity.com/privkey.pem; # managed by Certbot include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { server_name snarfingcode666.com www.snarfingcode666.com; location / { proxy_pass http://192.168.69.83; } listen 443 ssl; # managed by Certbot ssl_certificate /usr/local/etc/letsencrypt/live/snarfingcode666.com/fullchain.pem; # managed by Certbot ssl_certificate_key /usr/local/etc/letsencrypt/live/snarfingcode666.com/privkey.pem; # managed by Certbot include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { server_name mail.maildragon.com; location / { proxy_pass http://192.168.69.87; } listen 443 ssl; # managed by Certbot ssl_certificate /usr/local/etc/letsencrypt/live/mail.maildragon.com/fullchain.pem; # managed by Certbot ssl_certificate_key /usr/local/etc/letsencrypt/live/mail.maildragon.com/privkey.pem; # managed by Certbot include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { server_name rainmadedesigns.com www.rainmadedesigns.com; location / { proxy_pass http://192.168.69.84; } listen 443 ssl; # managed by Certbot ssl_certificate /usr/local/etc/letsencrypt/live/rainmadedesigns.com/fullchain.pem; # managed by Certbot ssl_certificate_key /usr/local/etc/letsencrypt/live/rainmadedesigns.com/privkey.pem; # managed by Certbot include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = www.snarfingcode666.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = snarfingcode666.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name snarfingcode666.com www.snarfingcode666.com; return 404; # managed by Certbot } server { if ($host = www.maildragon.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = maildragon.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name maildragon.com www.maildragon.com; return 404; # managed by Certbot } server { if ($host = www.remotesimplicity.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = remotesimplicity.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name remotesimplicity.com www.remotesimplicity.com; return 404; # managed by Certbot } server { if ($host = www.rainmadedesigns.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = rainmadedesigns.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name rainmadedesigns.com www.rainmadedesigns.com; return 404; # managed by Certbot } server { if ($host = www.rainmadekennels.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = rainmadekennels.com) { return 301 https://$host$request_uri; } # managed by Certbot server_name rainmadekennels.com www.rainmadekennels.com; listen 80; return 404; # managed by Certbot } server { if ($host = mail.maildragon.com) { return 301 https://$host$request_uri; } # managed by Certbot server_name mail.maildragon.com; listen 80; return 404; # managed by Certbot }}
Next we need to discuss certs. In this day and age you cannot really run a website without SSL certs. They are
free to get using LetsEncrypt.org. Now, I have used certbot that I have listed below for years. It has until an
incident in the last couple of weeks worked for me. On a mail server the permissions were messed up on the certs
and caused some problems figuring it out. You might want to investigate ACME scripts for Let's Encrypt. They have
zero dependencies and work flawlessly. When I built this server system I used certbot so I will continue to
document it with Certbot.
Since we are running nginx we need not only the certbot itself, but the nginx plugin for certbot. Below is
the two commands to install them both on the proxy jail:
# pkg install py311-certbot
# pkg install py311-certbot-nginx
Once this is done we need to run the certbot to retrieve the certs.
certbot --nginx -d mail.maildragon.com
Once this is done and completes successfully, you should have a cert for your domain on the proxy server and certbot added the proper lines to your config. Now if you hit the proxy server with the correct domain name you should get your website.