My FreedomBox architecture is built from isolated LXC modules, each having it’s own local IP address. A FreedomBox only has one internet address so there must be a component to route traffic from the internet to the various FreedomBox modules. This internet module is a vital part of the architecture.
On my FreedomBox I want the internet module to route traffic to the following services:
- Web-server modules. Example: A WordPress module.
- SSH servers. Some modules may support ssh access.
- E-Mail modules. SMTP / POP / IMAP and Webmail.
- Storage modules. I want to give family and friends some space on my FreedomBox for (encrypted) backups.
At the moment I have only implemented routing from the internet to web-server modules. The other routing functions of the internet module are still being researched. Building the internet module with web-server routing consists of the following steps:
- Create a LXC container to house the module.
- Instruct the DHCP server to give the container a static IP address.
- Start the container and continue installation.
- Install Nginx as reverse proxy.
- Adjust the router settings.
Read this first.
This article is one in a series that describes the building of my FreedomBox. Information from the previous articles like network and software configuration is not repeated.
Create the LXC internet container.
cd /var/lib/lxc mkdir internet /usr/lib/lxc/templates/lxc-debian-box -n internet -p /var/lib/lxc/internet
Give the internet container a static IP address.
edit /etc/dnsmasq.conf find the #commented line and replace with the next:
#dhcp-host=bert,192.168.0.70,infinite dhcp-host=internet,192.168.1.10,infinite
NOTE: make sure that the address is within the specified dhcp-range setting.
Restart dnsmasq:
/etc/init.d/dnsmasq restart
Start the container and continue installation.
lxc-start -n internet -d
Login: (password = root)
ssh root@internet.freedom.box
Inside the container issue the following commands:
passwd dpkg-reconfigure tzdata dpkg-reconfigure locales apt-get update atp-get upgrade ifconfig
Choose both a locale and default locale (my system: es_US.UTF-8).
The IP address that ifconfig reports should be the one specified in dnsmasq.conf.
Install Nginx as a reverse proxy.
Nginx has great features that makes it ideal to act as a reverse proxy (a proxy from the internet to the system) inside the internet module. It supports HTTP, SMTP, POP3, IMAP and uWSGI. These are all things that I want.
Unfortunately Debian only has a legacy version (0.7.67) in its repository. This version does not support the uwsgi protocol that is used by Python powered websites. The lack of Python support and the fact that version 0.7.67 is basically a two year old version that is bugfixed made me decide to compile the newest version (1.0.0).
Compiling is simple and painless:
apt-get install wget apt-get install gcc apt-get install make apt-get install libpcre3 libpcre3-dev apt-get install openssl libssl-dev cd /usr/src wget http://nginx.org/download/nginx-1.0.0.tar.gz tar xfvz nginx-1.0.0.tar.gz cd nginx-1.0.0 ./configure \ --conf-path=/etc/nginx/nginx.conf \ --lock-path=/var/lock/nginx.lock \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --pid-path=/var/run/nginx.pid \ --http-client-body-temp-path=/var/run/nginx/client_body_temp \ --http-proxy-temp-path=/var/run/nginx/proxy_temp \ --http-fastcgi-temp-path=/var/run/nginx/fastcgi_temp \ --http-uwsgi-temp-path=/var/run/nginx/uwsgi_temp \ --http-scgi-temp-path=/var/run/nginx/scgi_temp \ --with-mail \ --with-mail_ssl_module \ --with-http_ssl_module \ --user=www-data \ --group=www-data \ --with-cc-opt="-DNGX_HAVE_ACCEPT4=0" make make install mkdir -p /var/run/nginx/client_body_temp mkdir -p /var/run/nginx/proxy_temp mkdir -p /var/run/nginx/fastcgi_temp mkdir -p /var/run/nginx/uwsgi_temp mkdir -p /var/run/nginx/scgi_temp
These commands install Nginx in /usr/local/nginx/sbin. The only thing that’s missing now is an init.d script. I use the following (too simple?) script:
#! /bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the nginx web server
# Description: starts nginx using start-stop-daemon
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/nginx/sbin/nginx
NAME=nginx
DESC=nginx
# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
. /etc/default/nginx
fi
test -x $DAEMON || exit 0
set -e
. /lib/lsb/init-functions
case "$1" in
start)
echo -n "Starting $DESC: "
$DAEMON
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
$DAEMON -s stop
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
$DAEMON -s stop
sleep 1
$DAEMON
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
$DAEMON -s reload
echo "$NAME."
;;
configtest)
echo -n "Testing $DESC configuration: "
$DAEMON -t
;;
status)
status_of_proc -p /var/run/$NAME.pid "$DAEMON" nginx && exit 0 || exit $?
;;
*)
echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest}" >&2
exit 1
;;
esac
exit 0
Copy this code into a new file and save it as nginx in the directory: /etc/init.d
Check if everything works:
/etc/init.d/nginx start
If you browse to http://internet.freedom.box you should see the Nginx welcome message.
Make the script run at startup:
cd /etc/init.d update-rc.d nginx defaults
Adjust the router settings.
The router can now forward requests to the internet module. This is not very interesting at the moment (you will only see the Nginx welcome message). In the next article I will build a WordPress module and connect this module to the internet module.