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:

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:

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.

Comments: 0

Installing LXC, DHCP and DNS on my FreedomBox

Rob van der Hoeven
Sun Apr 24 2011

Linux Containers (LXC) are the basic building blocks of my FreedomBox architecture. This article shows how the network must be configured in order to support LXC. It further shows how DHCP and DNS are used to support the LXC infrastructure. After installing LXC a simple script can be run to create LXC containers which are fully integrated into a local DNS domain (you can use: ssh root@containername.freedom.box).

Requirements.

My FreedomBox uses Debian GNU/Linux in combination with LXC virtual machines. This article only describes a Debian configuration.

This article describes the installation of a local DHCP/DNS combination which must be the only DHCP/DNS service in the configured network segment. All other DHCP/DNS services (hint: on the router) must be disabled. The FreedomBox must be able to use a static IP address.

Disclaimer.

Some of the procedures in this article are not without risks and I cannot guaranty the accuracy of all the information in this article. If you follow any of the procedures mentioned in this article, you do so at your own risk.

The main risk is loosing the network connection to your box. If this happens and if ssh is the only way you can connect to your box, then the only way to correct this problem is to take out the HD and connect it to another Linux machine so you can edit the network configuration.

Preparing the network interface.

Each LXC container adds a virtual networking interface (card) to your system. In order to connect multiple networking interfaces you have to create a network bridge. Network bridges are very simple, if one network card does not know how to reach a specific IP address it asks all the other cards in the bridge if they can reach the IP address. A positive response is remembered by the bridge. If no card can reach the IP address, the gateway is used.

You can create a network bridge by:

Installing bridge-utils.

apt-get install bridge-utils

Edit /etc/network/interfaces

before:

# The loopback network interface

auto lo
    iface lo inet loopback

# The primary network interface

allow-hotplug eth0
    iface eth0 inet dhcp

after:

# The loopback network interface

auto lo
    iface lo inet loopback

# The primary network interface

auto br0
    iface br0 inet static
    bridge_ports eth0
    bridge_fd 0
    address 192.168.1.3
    netmask 255.255.255.0
    network 192.168.1.0
    broadcast 192.168.1.255
    gateway 192.168.1.1

I am using the 192.168.1.0/24 network. Remember to change this if your router is using another network.

WARNING: Double-check /etc/network/interfaces. Restarting the network makes you lose your connection. Mistakes in the configuration may prevent you from connecting to your box again. If this happens you have to connect the HD to another GNU/Linux computer in order to correct the problem.

Restart the network.

/etc/init.d/networking restart

You lose your network connection...

Connect to the new address.

ssh root@192.168.1.3

Installing DHCP/DNS.

I like domain names. What I want for my local LXC network is an integrated DHCP/DNS combination. After the DHCP server handout an address, the address must be communicated to a DNS server that binds it to a domain name. Fortunately there is a package that can do this: dnsmasq. It's ideal – lightweight, powerful and very easy to configure!

Installation.

apt-get install dnsmasq

Edit /etc/dnsmasq.conf

Find the following #settings and replace them by the settings on the next line:

#resolv-file=
resolv-file=/etc/resolv_router.conf

#local=/localnet/
local=/box/

#expand-hosts
expand-hosts

#domain=thekelleys.org.uk
domain=freedom.box

#dhcp-range=192.168.0.50,192.168.0.150,12h
dhcp-range=192.168.1.50,192.168.1.250,12h

#dhcp-option=3,1.2.3.4
dhcp-option=3,192.168.1.1

Change the name-server.

cd /etc

cp resolv.conf resolv_router.conf

edit resolv.conf change the IP address to: 192.168.1.3

Restart dnsmasq.

/etc/init.d/dnsmasq restart

This configuration creates the freedom.box domain. If you use my LXC installation script to create a LXC container with a name of “helloworld”, you can use helloworld.freedom.box to get it's IP address.

Install LXC.

The LXC technology depends on a Linux kernel feature called cgroups. In order to use this feature you must do the following:

Create a /cgroup directory

mkdir /cgroup

Edit /etc/fstab, add the line:

cgroup /cgroup cgroup defaults 0 0

Mount the /cgroup directory.

mount -a

Install LXC.

apt-get install lxc

Check the installation.

lxc-checkconfig

Everything should be enabled except the cgroup memory controler. This feature has some performance issues and is not compiled into the kernel by default.

You can find some documentation in: /usr/share/doc/lxc.

In /usr/lib/lxc/templates you can find scripts to install containers with various GNU/Linux distributions.

In order to create a Debian container you have to install debootstrap first:

apt-get install debootstrap

The LXC utilities expect the containers to be created in subdirectories of /var/lib/lxc. This is hardcoded, so don't try to use another directory. To create a container you can do the following:

(this works, but don't do this. Use my slightly modified script... )

cd /var/lib/lxc

mkdir mycontainer

/usr/lib/lxc/templates/lxc-debian -n mycontainer -p /var/lib/lxc/mycontainer

After you have created the container you can start the container in two ways:

Daemon mode.

lxc-start -n mycontainer -d

Terminal mode.

lxc-start -n mycontainer

In daemon mode you can use ssh to connect to the container. The lxc-debian script does not give the container a domain name. You have to find the IP address of the container yourself.

In terminal mode you can use the standard password (root) to work inside the container. The terminal mode is “Hotel California” - you can check in any time you want, but you can never leave. To leave terminal mode you must use another terminal and issue the command:

lxc-stop -n mycontainer

If you use the lxc-debian script that comes with Squeeze you are in for a surprise. This script creates Lenny containers! In order to create Squeeze containers and give them a nice domain name I made a slightly modified version of the lxc-debian script. Download this lxc-debian-box script and put it into /usr/lib/lxc/templates.

Create a test container and have some fun.

Now everything is in place to start using LXC containers. Let's create one:

cd /var/lib/lxc

mkdir test

/usr/lib/lxc/templates/lxc-debian-box -n test -p /var/lib/lxc/test

Start the container as a daemon.

lxc-start -n test -d
lxc-info -n test

ssh root@test.freedom.box (default password: root)

passwd
dpkg-reconfigure tzdata

apt-get update
apt-get upgrade
apt-get install lynx

lynx freedomboxblog.nl

Comments: 1

Installing Debian GNU/Linux on my FreedomBox

Rob van der Hoeven
Sun Apr 24 2011

One of the best things I did with my QNAP TS-119 NAS was installing Debian onto it. The software on my QNAP was excellent for a NAS, but I knew the hardware could be more than just a NAS. I wanted the box to be a full GNU/Linux server. Fortunately Debian fully supports the QNAP TS 11x series and has a really nice and well documented installer.

You can install Debian by following the link below. Installation is very smooth, and I have only some small remarks.

Comments: 0

Free hardware for the FreedomBox software

Rob van der Hoeven
Fri Apr 15 2011

Every time you read an article about the FreedomBox it mentions that the hardware is very cheap and will become even cheaper in the future. This emphasis on cheap hardware worries me. After all, the FreedomBox is a server that must run reliably 24/7 for years. Cheap and server are not always compatible. If you ask the box builders to build something that is cheap you get what you ask for, but you probably won't get a server.

I think the FreedomBox movement must be very careful about the recommended hardware. Devices that are crap are a danger to the reputation of the FreedomBox. Once the FreedomBox gets a bad reputation it's over and out.

The Plug Computer is the hardware mentioned in all articles about the FreedomBox. If you do some research you come up with some serious problems (heat, availability, broken boxes). These problems can be fixed, but the reputation of these devices is in my opinion beyond repair. You can get a good indication of the quality of a device (and its manufacturer) by looking at the warranty period. Globalscale Technologies the maker of the SheevaPlug, GuruPlug and DreamPlug offers a warranty period of one month. One month! Would you buy a “normal” server with a warranty period of one month? In The Netherlands where I live a warranty period of one month for a $99 device is illegal.

The FreedomBox is a server and should have quality requirements for its hardware. A good (first) requirement would be a warranty period of one year for a device that operates 24/7. Devices that have a shorter warranty period should be removed from the targeted hardware list.

But, but, but.....

If you require such an outrageous warranty period our targeted hardware list becomes empty and then we have nothing to play with!!! Calm down, things are not as bad as they seem. There are plenty of interesting devices that can be used for the FreedomBox. Depending on how you look at it, the price of these devices can be zero. Let's give an example:

Before I had even heard of the FreedomBox I bought an QNAP TS 119 NAS. I needed its functionality and had no problem with the price (300 euro). When I heard about the FreedomBox and got exited about it, I decided to upgrade my NAS to a “NAS FreedomBox edition”. This FreedomBox edition still has all the NAS functionality so I did not loose anything. You can say I got the FreedomBox part for free.

There are many people who like me need a NAS. Wouldn't it be nice if we could give them free software that would turn their NAS into a "NAS FreedomBox edition"? Maybe we could do the same for a router? Both NAS-ses and routers are designed to run 24/7 and bad apples don't stand a change in today's competitive market. Availability is excellent too.

I think the FreedomBox project should work together with builders of NAS and router equipment. Both markets are very competitive and I think the option to run FreedomBox software on their devices would give their devices extra value. It's a win-win-win situation. The manufacturer can make their product more interesting than the competition (maybe they can sell some FreedomBox addon's). The customer gets extra FreedomBox functionality for free. The FreedomBox community gets serious hardware to play with and benefits from the marketing of the manufacturers.

Comments: 0

A software architecture for the FreedomBox

Rob van der Hoeven
Wed Apr 13 2011

This posting describes the software architecture I want to use for my FreedomBox. A software architecture is about “the big picture”. How are we going to integrate the various software packages into a working FreedomBox? What infrastructure do we need?

Before a software architecture can be specified there first must be a “big picture view” of the desired system. What requirements must be met? For my system I made the following list:

Requirements:

I'm from the church of CBD and believe that systems should be modular. Each module should have its own (unique) function, its own data and its own configuration. In a modular system there is a clear boundary between the modules making it easy to:

I believe that these properties of a modular design are essential for a successful FreedomBox architecture. Before I work out my architecture I want to give you an example of an FreedomBox module, just to make things less abstract.

The FreedomBox should have a Wordpress blog module. This module consists of a default Wordpress installation including MySQL and Apache/PHP. After installing this module everything inside the module (Wordpress/MySQL/Apache/PHP) is fully configured and ready to go. If the user wants to host Wordpress on another FreedomBox than he/she can simply export/import the Wordpress data. For this the module has a data interface that is called from the FreedomBox user interface.

The design.

Looking at the requirements I realized that many requirements could be met by using so called Virtual Machines (VM's). Virtual Machines are natural modules, they support resource sharing and isolation of services. The isolation a VM provides offers security benefits too.

Traditionally the biggest problem with VM's is the heavy resource requirements. Fortunately with GNU/Linux there is a virtualization technique called Linux Containers (LXC). With Linux Containers the same kernel is shared between VM's. This drastically lowers memory usage and also reduces the performance penalty that normal virtualization has.

After experimenting with LXC (see below) I decided to make the technology an integral part of my FreedomBox architecture. Most modules are housed inside a Linux Container.

Back to the design. Modular design is all about giving the modules a unique function. Let's make a list of the unique functions inside the FreedomBox architecture.

Each module should have a data interface that can be called from the User-Management module. The data interface must be able to export all the data from a module so that it can be used as an import for a freshly installed module.

That's it. All that's left are implementation details. (OK things are not that easy.... :-)).

My FreedomBox.

To make the architecture less abstract I give you an overview of my own FreedomBox. Don't expect a fully developed system, it's a work in progress. My first goal is to give my box virtual web server capabilities. Hosting multiple isolated VM's, each with an Apache2 web-server, full SSH access and (web) mail. This is what I got now: (click image for a bigger picture)

Picture of FreedomBox architecture

My FreedomBox is a former QNAP TS 119 NAS that was upgraded to Debian GNU/Linux (thank you Martin Michlmayr and Debian community!)

The most important component in this system is the Network VM. This VM distributes incoming request to the services in the other VM's. All access from the internet is routed through this VM.

All the other VM's are used to host Wordpress blogs. They have the possibility to send/receive mail via Exim4. The combination of mail server and web server is not ideal so i will investigate the possibility to place the mail server in its own VM.

To give you an idea about the memory requirements of my VM based system, here is the output of a pstree command followed by the free command:

init─┬─apache2─┬─4*[apache2───17*[{apache2}]]
     │         └─5*[apache2]
     ├─atd
     ├─cron
     ├─dbus-daemon
     ├─getty
     ├─inetd
     ├─lxc-start───init─┬─apache2───2*[apache2]
     │                  ├─5*[getty]
     │                  ├─mysqld_safe─┬─logger
     │                  │             └─mysqld───15*[{mysqld}]
     │                  └─sshd
     ├─lxc-start───init─┬─apache2───3*[apache2]
     │                  ├─cron
     │                  ├─exim4
     │                  ├─4*[getty]
     │                  ├─mysqld_safe─┬─logger
     │                  │             └─mysqld───11*[{mysqld}]
     │                  └─sshd
     ├─lxc-start───init─┬─courierd───courierd─┬─courierdsn
     │                  │                     ├─courieresmtp
     │                  │                     ├─courierfax
     │                  │                     ├─courierlocal
     │                  │                     └─courieruucp
     │                  ├─courierfilter
     │                  ├─courierlogger───authdaemond───5*[authdaemond]
     │                  ├─2*[courierlogger]
     │                  ├─couriertcpd
     │                  ├─cron
     │                  ├─5*[getty]
     │                  ├─nginx───nginx
     │                  └─sshd
     ├─lxc-start───init─┬─apache2───9*[apache2]
     │                  ├─cron
     │                  ├─exim4
     │                  ├─5*[getty]
     │                  ├─mysqld_safe─┬─logger
     │                  │             └─mysqld───14*[{mysqld}]
     │                  └─sshd
     ├─nmbd
     ├─ntpd
     ├─portmap
     ├─rpc.idmapd
     ├─rpc.mountd
     ├─rpc.statd
     ├─rsyslogd───2*[{rsyslogd}]
     ├─smbd───smbd
     ├─sshd───sshd───bash───pstree
     ├─udevd───2*[udevd]
     └─winbindd───3*[winbindd]

             total       used       free     shared    buffers     cached
Mem:        515572     462720      52852          0      65164     208052

-/+ buffers/cache:     189504     326068

Swap:      1508344      24776    1483568

Apart from the 4 LXC containers there are many other programs running. Memory usage is still very low. I hope you like my architecture. Please don't hesitate to ask questions. Suggestions are welcome too.

Comments: 0