FreedomBoxBlog

My FreedomBox internet module part 1

Rob van der Hoeven
Mon May 02 2011

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:

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.