HowTo: Ubuntu home LAN server

So this past week I re-installed my server, and I decided to write a howto for others who would like to have their own web/files/etc server at home. I decided to use Dapper, since it is the stable and well tested release. It contains recent enough software to be patched, and since it's the Long Term Support release, it'll still have security updates coming out for the next 5 years.

My setup at home is something like this:

  • LAMP server with virtual hosts for site development
  • Desktop PCs with server-assigned IP addresses
  • Server dials up to the Internet (Dialup, not ADSL)
  • Server shares directories with the desktops (web, music, etc)

So this is the server that I'm going to set up: LAMP, vhosts with DNS, dynamic server-assigned IP addresses, automatic dialup to the internet every evening, automatic disconnection every morning, and shared folders.

Preparation:

  1. Get an Ubuntu Dapper CD in any means you are able to (I downloaded the ISO at work and burnt it to CD, since I only have dialup at home)
  2. Backup any data on your server that you want to keep. All data will be erased when you install Ubuntu.
  3. Decide on a network naming convention. Mine is the Muppets, with my server being called kermit.
  4. Decide on an IP address range. I chose 192.168.1.X.
  5. Decide on an IP address for your server's main network interface. I chose 192.168.1.254 (255 is the broadcast address).

Initial installation:

  1. Pop the CD in, and reboot the server.
  2. Choose the LAMP installation at the boot menu.
  3. Walk through the installation. Use the settings that we decided in the preparation phase when you are prompted. Most options here are fairly straightforward and self explanatory. If not, should provide some help.

The LAMP installation provides us with a web server (since that's what mine is for, site development), but now let's install some more software. Make sure the CD is back in the CD-ROM.

DHCP server (dynamically assigned IP addresses):

  1. Type in sudo apt-get install dhcp3-server to install the DHCP server. (Type in your password if it prompts you for a password.)
  2. Edit your configuration file by typing in sudo vi /etc/dhcp3/dhcpd.conf.
  3. Change the following lines to match your setup.
    # "lan" is the name of my internal network
    # all domain names end in .lan
    option domain-name "lan";

    # ns.lan is what our domain name server will be called
    option domain-name-servers ns.lan;
    option broadcast-address 192.168.1.255;
  4. I also changed my lease times. I wanted fairly long leases.
    default-lease-time 1209600; # 14 days
    max-lease-time 2419200; # 28 days
  5. Uncomment the following line (remove the #):
    authoritative;
  6. Let's add the section specifically for dishing out address to the network computers:
    subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.10 192.168.1.240;
    }
    Note: The subnet directive tells the DHCP server the base IP address of the network, and the netmask directive tells it the full range of IP addresses in the network. The range directive tells the server to dish out IP adresses within that subrange.
  7. Now restart the DHCP server by typing sudo /etc/init.d/dhcpd restart.

DNS server (domain names, important for virtual hosting):

  1. Type in sudo apt-get install bind9 to install the BIND name server.
  2. There is no need to edit the main configuration, so leave that.
  3. Edit the "local" conf file: sudo vi /etc/bind/named.conf.local.
  4. Add the following lines to that file, which will define our domain names for the virtual hosting:
    zone "lan.labs" {
    type master;
    file "/etc/bind/zones/lan.labs.zone";
    };
    zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/1.168.192.in-addr.arpa.zone";
    };
  5. Save and close the file.
  6. Edit the options file: sudo vi /etc/bind/named.conf.options.
  7. Uncomment the "forward" lines, and replace the address there with the IP address of an upstream DNS server. The easiest way to get that is to connect to the internet, and then take the top IP address from your resolv.conf file.
    forwarders {
    x.x.x.x; # replace with your upstream DNS server
    };
  8. Now we need to create our zone files. Type sudo mkdir /etc/bind/zones.
  9. Create and edit the forward zone file. Type sudo vi /etc/bind/zones/lan.zone and then write this in it:
    ; ; BIND data file for "lan" network
    ;
    $TTL 604800
    @ IN SOA lan. root.server.lan. (
    101 ; Serial
    604800 ; Refresh
    86400 ; Retry
    2419200 ; Expire
    604800 ; Negative Cache TTL
    )
    ;
    IN NS ns
    ;
    ns IN A 192.168.1.254
    server IN A 192.168.1.254
  10. Create and edit the reverse zone file. Type sudo vi /etc/bind/zones/1.168.192.in-addr.arpa.zone and then write this in it:
    ;
    ; BIND reverse data file for "lan" network
    ;
    $TTL 604800
    @ IN SOA lan. root.server.lan. (
    102 ; Serial
    604800 ; Refresh
    86400 ; Retry
    2419200 ; Expire
    604800 ; Negative Cache TTL
    )
    ;
    IN NS ns
    254 IN PTR server
  11. Now restart bind by typing sudo /etc/init.d/bind9 restart.

Apache Virtual Hosting

Next we want to set up Apache for virtual hosting.

  1. Create a directory for all the virtual hosts: sudo mkdir /home/www-data.
  2. Set the owner and the group to the web server user: sudo chown www-data:www-data /home/www-data.
  3. Now edit the Apache main configuration file: sudo vi /etc/apache2/apache2.conf.
  4. Scroll down to the bottom of the file and add the following lines above the line that includes the virtual host files:
    # Name of the server
    ServerName server.lan
    # NameVirtualHost
    NameVirtualHost *
  5. Then create a "skeleton" directory: sudo mkdir /etc/apache2/skel.
  6. Create and edit our skeleton virtual host configuration file: sudo /etc/apache2/skel/skel.domain

    DocumentRoot /home/www-data/skel/www
    ServerAdmin
    ServerName skel.domain
    ServerSignature on


    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    Allow from all


    ScriptAlias /cgi-bin/ /home/www-data/skel/cgi-bin/

    AllowOverride None
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    Order allow,deny
    Allow from all


    ErrorLog /home/www-data/skel/logs/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /home/www-data/skel/logs/access.log combined
  7. Also, edit your default server configuration file: sudo vi /etc/apache2/sites-available/default.
  8. Remove the line at the top of the file that says NameVirtualHost *.

What I also did was to create a script that would do all the necessary for me in order to create new virtual hosts. I wrote the script to be quite configurable.

  1. Create and edit the file: sudo vi /usr/bin/make_vhost
    #!/bin/bash
    # Raoul's Make Virtual Host script
    # Copyright (c) 2006-2007 Raoul Snyman
    # Licensed under the GNU GPL v2.0
    # Script variables
    DOMAIN="lan"
    WEBROOT="/home/www-data"
    FWDZONE="/etc/bind/zones/lan.zone"
    REVZONE="/etc/bind/zones/1.168.192.in-addr.arpa.zone"
    SKELFILE="/etc/apache2/skel/skel.domain"
    SITESDIR="/etc/apache2/sites-available"
    WEBUSER="www-data"
    WEBGROUP="www-data"
    FWDIP="192.168.1.254"
    REVIP="254"
    DNSRELOAD="/etc/init.d/bind9 reload"
    WEBRELOAD="/etc/init.d/apache2 reload"
    # Make our directories
    mkdir $WEBROOT/$1
    mkdir $WEBROOT/$1/www
    mkdir $WEBROOT/$1/logs
    mkdir $WEBROOT/$1/cgi-bin
    chown -R $WEBUSER:$WEBGROUP $WEBROOT/$1
    # Copy the skeleton file and enable it
    sed s/skel/$1/ $SKELFILE | sed s/domain/$DOMAIN/ > $SITESDIR/$1.$DOMAIN
    a2ensite $1.$DOMAIN
    # Create the entry in the forward zone file
    echo ";" >> $FWDZONE
    echo "; `date`" >> $FWDZONE
    echo "$1 IN A $FWDIP" >> $FWDZONE
    # Create the entry in the reverse zone file
    echo ";" >> $REVZONE
    echo "; `date`" >> $REVZONE
    echo "$REVIP IN PTR $1" >> $REVZONE
    #Restart the services
    $DNSRELOAD
    $WEBRELOAD
  2. Set it's executable bits: sudo chmod a+x /usr/bin/make_vhost.
  3. Usage: make_vhost example

This script then creates a directory called "example" in the /home/www-data directory, with 3 subdirectories; www, logs, cgi-bin. All your files go in www and all your CGI scripts go in cgi-bin. Log files for that host are then created and stored in logs. The entries are added to the zones files, and the virtual host is enabled and the servers are restarted.

File sharing with SAMBA

Lastly, I want to access the files from my desktop machines. I have one dual boot Windows/Linux machine (1 or two Windows apps that I still need) and another Linux desktop. I decided to standardise on Samba for file sharing.

  1. Install Samba: sudo apt-get install samba.
  2. Create a "samba" user for file sharing: sudo adduser samba (just fill in whatever you want to as you go through the options).
  3. Add the new user to Samba's list of users: sudo smbpasswd -a samba.
  4. Create additional directories for file sharing:
    sudo mkdir /home/samba/music
    sudo mkdir /home/samba/images
  5. Change directory ownership for the new directories: sudo chown -R samba:samba /home/samba.
  6. Edit the samba configuration file: sudo /etc/samba/smb.conf.
  7. Change the workgroup to fit your system.
  8. Uncomment unix password sync and set it to yes.
  9. Add the following to the bottom of the file to setup the shares:
    [www-data]
    comment = Web server
    writeable = yes
    browseable = yes
    readonly = no
    path = /home/www-data
    valid users = samba
    force user = www-data
    force group = www-data
  10. Reload samba: sudo /etc/init.d/samba reload.

Now when you connect to the server, use the "samba" user account. Even for the web root, the user will be forced to the www-data user. Lastly, I needed to set up my dialup internet. So I connected my modem, and got stuck into editing the config files for pppd. The LAMP setup comes with pppd pre-installed, so we don't need to use apt-get. I also added some cron jobs to start and stop my internet connection.

  1. Edit the provider file: sudo vi /etc/ppp/peers/provider.
  2. Find the user line and set your account username there.
  3. Find the connect line, and at the end where there are stars, change those stars to your dialup phone number.
  4. I had to change the line that says /dev/modem to /dev/ttyS0.
  5. Add a line at the bottom of the file that simply says defaultroute.
  6. Now edit your password file: sudo vi /etc/ppp/pap-secrets.
  7. Add a line at the bottom of the file:
    "username"   *       "password" 
  8. Type export EDITOR=vi to set vi as your default editor.
  9. Edit the crontab: sudo crontab -e.
  10. Add the following lines:
    55      6       *       *       1-5     poff   #disconnects at 6:55 in the morning, Mondays through Friday
    5 19 * * 1-5 pon #connects at 19:05 in the evening, Monday through Friday

Protect the server with a firewall

We also need to set up our firewall, for blocking incoming snoopers and forwarding traffic from our network outside (for surfing and the like). I have used Arno's Firewall Script, and it works like a charm, so let's use that one again.

  1. Download Arno's Firewall Script from his site: wget http://rocky.eld.leidenuniv.nl/iptables-firewall/arno-iptables-firewall_1.8.8c.tar.gz. Make sure you get the latest version! This is the latest version at the time of writing, but it will most probably not be after a few days :-).
  2. Unzip it: tar -xvf arno-iptables-firewall_1.8.8c.tar.gz.
  3. Change to the directory you unzipped it to: cd arno-iptables-firewall_1.8.8c.
  4. Copy the main files to /etc/init.d:
    sudo cp arno-fwfilter /etc/init.d
    sudo cp arno-iptables-firewall /etc/init.d
  5. Copy the config files to /etc: sudo cp etc /.
  6. Edit the configuration file: sudo vi /etc/arno-iptables-firewall/firewall.conf.
  7. Uncomment the line that says #EXT_IF="ppp+".
  8. Set the internal network interface: INT_IF="eth0" (find that line).
  9. Uncomment the line that says #INTERNAL_NET="192.168.0.0/24" and set it to your internal network (in our case 192.168.1.0/24).
  10. Scroll down to the line that says, NAT=0 and change it to say, NAT=1.
  11. The rest of the file should be fine. You can scroll down and change additional settings if you know what you're doing.
  12. Now let's add the firewall to our startup: sudo update-rc.d arno-iptables-firewall defaults.
  13. And start the firewall: sudo /etc/init.d/arno-iptables-firewall.

Remotely access the server with SSH

Lastly, we want to be able to access our server from any one of our desktop PCs. So we need ssh.

  1. Install the OpenSSH server: sudo apt-get install openssh-server.

Right. Now you're done! You've set up your virtual hosts, Bind9 helping out there, you've set up dhcp for dynamic IP addresses, you've set up Samba for file sharing, and you've set up your dialup Internet connection, which will then automatically connect and disconnect. You can now log into your server via ssh from any desktop machine, and create virtual hosts galore, all nicely automated.

There are other things you can do, additional things you can do on the server, but I'll leave that up to you. Oh, and don't forget the Ubuntu wiki: http://help.ubuntu.com/UserDocumentation