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.
/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:
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).
Copy this code into a new file and save it as nginx in the directory: /etc/init.d
Check if everything works:
If you browse to http://internet.freedom.box you should see the Nginx welcome message.
Make the script run at startup:
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.
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 email@example.com).
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.
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:
apt-get install bridge-utils
# The loopback network interface
iface lo inet loopback
# The primary network interface
iface eth0 inet dhcp
# The loopback network interface
iface lo inet loopback
# The primary network interface
iface br0 inet static
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.
You lose your network connection...
Connect to the new address.
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!
apt-get install dnsmasq
Find the following #settings and replace them by the settings on the next line:
cp resolv.conf resolv_router.conf
edit resolv.conf change the IP address to: 192.168.1.3
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.
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
Edit /etc/fstab, add the line:
cgroup /cgroup cgroup defaults 0 0
Mount the /cgroup directory.
apt-get install lxc
Check the installation.
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... )
/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:
lxc-start -n mycontainer -d
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:
/usr/lib/lxc/templates/lxc-debian-box -n test -p /var/lib/lxc/test
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.
You don't need a USB stick to save the backup of the original firmware. Just save it somewhere on the HD and use a gFTP SSH connection to copy the backup to your local HD.
The default root directory format is EXT3. I changed this to EXT4. (used defaults for /boot and swap).
The default software configuration does not include a SSH server. This puzzled me. SSH is the only way to connect to my box. Add the SSH server to the software that must be installed.
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.
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:
Security. The FreedomBox is connected to the internet so security is very important.
Multiple users. It should be possible to share your FreedomBox with your family and friends.
Isolation of services. A service is private. Users should only be allowed to access their own services. Services should not share data or settings.
Resource sharing. Many resources must be shared. There is only one IP address, one HD, little memory and limited processor power.
User friendliness. Installation and management of services must be very easy.
Flexibility. Many desired functions of the FreedomBox are still in development or don't exist yet It should be no problem to add new services, or to select only the services that you want.
These requirements are nothing special and can be met by any GNU/Linux system. However, if you build a system using standard GNU/Linux you end up with a highly specialized configuration that is not very flexible.
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:
Upgrade or replace a module.
Configure a module.
Import/export the data of a module.
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.
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.
Network proxy. The FreedomBox only has one IP address that must be shared between multiple users and services. For this we need a module that can distribute network traffic. Because all traffic passes this module it should also provide some basic network security (firewall) to the services.
VM management. This module can install/de-install and start/pause/stop virtual machines. It also must manage the resources like processor time, disk space, memory and network bandwidth that each VM can use. Installation should hook a VM up to the network proxy, de-installation must do the opposite of course.
User management. Provides a web based user interface that can be used to: add/remove users, give a user access to VM management, gives the user options to backup/transfer the data and configuration of a VM to another FreedomBox.
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.... :-)).
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)
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.
Nginx is used as a proxy to other VM's with web servers. In the future I hope to use Nginx as a proxy for IMAP and POP3 mail.
Courier MTA should forward SMTP requests to other VM's with a MTA (Exim4). At the moment I have not been able to test this because my ISP seems to block my incoming port 25.
The SSH daemon should give SSH access to the other VM's (not implemented yet).
I should probably add DHCP and DNS services to 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:
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.