05 May 2012

Ubuntu Server 12.04 installation

Server hardware

In my cabinet I had a stripped Acer Travelmate A800 laptop with a Intel Pentium M 1.7 GHz processor and 512 MB of memory. It has no keyboard and screen but it was fully functional. I had kept it to have spare parts for my home server, another Acer Travelmate A800. But I decided to set it up as server to be able to use my current server (with a keyboard and a screen) for other purposes.

Server software

I have installed Ubuntu Server 12.04 Precise Pangolin LTS. I have chosen the server roles SMB server and Virtual Machine host.
Additional packages:
  • SSH daemon
        marc@server:~$ sudo apt-get install openssh-server    
  • Web server with PHP
        marc@server:~$ sudo apt-get install nginx php5-fpm php5-cli php5-mcrypt   
    • APC for PHP opcode cache
          marc@server:~$ sudo apt-get install php-apc php5-gd    
  • MySQL
        marc@server:~$ sudo apt-get install mysql-server php5-mysql    
  • Exim mailserver
        marc@server:~$ sudo apt-get install exim4    
  • Munin monitoring tool
        marc@server:~$ sudo apt-get install munin munin-plugins-extra munin-libvirt-plugins

Configuration

SSH

To keep my machine safe I have set up public/private key authentication.
I am using that for years now. But here is how you do it:
  • Create a public/private keypair on the desktop you are using generally and enter through the defaults (but provide a passphrase for security reasons)
        marc@client:~$ mkdir -p -m 700 ~/.ssh
        marc@client:~$ ssh-keygen
        
  • Add the public key to your server
        marc@server:~$ mkdir -p -m 700 ~/.ssh
        marc@client:~$ echo `cat ~/.ssh/id_rsa.pub` | ssh marc@server 'cat - >> ~/.ssh/authorized_keys'    
  • Try login and check that it does not ask your server password but your key passphrase
        marc@client:~$ ssh marc@server    
  • Lock down access to public/private key authentication only
        marc@server:~$ sudo vi /etc/ssh/sshd_config
        /^[# \t]*PasswordAuthentication
        /PasswordAuthentication
        d^
        w
        cw
        no
        <Esc>
        :wq
        marc@server:~$ sudo service ssh force-reload    

Firewall

To limit access and thus improving security I have set up a firewall too: UFW.
  • Added rules to keep SSH access; do not forget to add your own rules
        marc@server:~$ sudo ufw allow from 127.0.0.0/8 to any app OpenSSH
        marc@server:~$ sudo ufw allow from 192.168.0.0/16 to any app OpenSSH    
  • Enabled the firewall
        marc@server:~$ sudo ufw enable    
  • I added some rules to test my webserver
        marc@server:~$ sudo ufw allow from 127.0.0.0/8 to any app 'Nginx Full'
        marc@server:~$ sudo ufw allow from 192.168.0.0/16 to any app 'Nginx Full'    

Webserver

The webserver Nginx is installed already and it must be visitable locally due to the firewall rules. It should show "Welcome to nginx!"
  • Created web dir and a PHP file
        marc@server:~$ sudo mkdir -p /var/www/com/example/www
        marc@server:~$ sudo chown marc:marc /var/www/com/example/www
        marc@server:~$ echo '' > /var/www/com/example/www/index.php   
  • Created config file and enabled it
        marc@server:~$ sudo vi /etc/nginx/sites-available/com.example-zzz
        i
        server {
            server_name *.example.com;
            rewrite ^ $scheme://example.com$request_uri permanent;
        }
        server {
            root /var/www/com/example/www;
            index index.php index.html index.htm;
    
            server_name example.com
    
           location ~ \.php(/.*)?$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
            }
        }       
        <Esc>
        :wq
        marc@server:~$ cd /etc/nginx/sites-enabled/
        marc@server:sites-enabled$ sudo ln -s /etc/nginx/sites-available/com.example-zzz
        marc@server:sites-enabled$ cd
        marc@server:~$ sudo service nginx reload    
  • http://example.com/ is visitable now if the DNS or your /etc/hosts file points to your servers IP address.

Admin site

Created an admin site for phpMyAdmin and other admin pages.
  • Created the dir
        marc@server:~$ sudo mkdir -p /var/www/admin
  • Added the sections below to /etc/nginx/sites-available/default
            location /nginx_status {
                    stub_status on;
                    access_log   off;
                    allow 127.0.0.0/8;
                    allow 192.168.0.0/16;
                    deny all;
            }
    
            location /admin/ {
                    alias /var/www/admin/;
                    index index.html index.htm index.php;
                    autoindex on;
                    allow 127.0.0.0/8;
                    allow 192.168.0.0/16;
                    deny all;
            }
            location ~ ^(/admin/.*\.php)(/.*)?$ {
                    alias /var/www$1;
                    fastcgi_pass 127.0.0.1:9000;
                    fastcgi_index index.php;
                    fastcgi_split_path_info ^(.+\.php)(/.+)$;
                    fastcgi_param PATH_INFO $fastcgi_path_info;
                    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
                    include fastcgi_params;
            }
  • Reloaded Nginx config
        marc@server:~$ sudo service nginx reload
  • Created phpinfo script
        marc@server:~$ sudo bash -c 'echo "" > /var/www/admin/phpinfo.php'
  • Installed phpMyAdmin
        marc@server:~$ wget -O phpMyAdmin-3.5.0-all-languages.tar.bz2 'http://downloads.sourceforge.net/project/phpmyadmin/phpMyAdmin/3.5.0/phpMyAdmin-3.5.0-all-languages.tar.bz2?r=http%3A%2F%2Fwww.phpmyadmin.net%2Fhome_page%2Fdownloads.php&ts=1334868700&use_mirror=ignum'
        marc@server:~$ tar -xjvf phpMyAdmin-3.5.0-all-languages.tar.bz2
        marc@server:~$ sudo mv phpMyAdmin-3.5.0-all-languages /var/www/admin/.phpMyAdmin-3.5.0-all-languages
        marc@server:~$ cd /var/www/admin/
        marc@server:admin$ sudo ln -s .phpMyAdmin-3.5.0-all-languages/ pma
        marc@server:admin$ cd
        marc@server:~$ rm phpMyAdmin-3.5.0-all-languages.tar.bz2
    
  • phpMyAdmin should work now on http://server/pma/. Login with the MySQL credentials and follow the phpMyAdmin instructions

Exim

I have configured exim4 because it does not send email by default. And I want to get at least some alerts from my server.
  • Called config util
        marc@server:~$ sudo dpkg-reconfigure exim4-config
    And answered the questions:
    • internet site; email is sent and received using SMTP
    • mail name: server.example.com
    • only listen for local connections
    • accept email for: server.example.com
    • forward email for domains: example.com
    • forward email for systems: 127.0.0.0/8
    • no minimal DNS requests
    • deliver local email in mbox-format
    • no splitting of config file

Munin

To avoid munin is creating graphs every 5 minutes (produces high load on my old, tiny server) I produced them on demand. If you want to see the graphs then you have to wait some seconds, but it keeps your server fast. I have used a munin wiki page to find out how to configure this in nginx.
  • Set graph strategy and configured email
        marc@server:~$ sudo vi /etc/munin/munin.conf
        /^#graph_strategy cgi
        x
        /^#cgiurl_graph
        x
        /#contact\.
        $
        a
        <Enter>
        contact.marc.command mail -s "Munin notification" marc@example.com
        contact.marc.max_messages 5
        <Esc>
        :wq
  • Installed spawn-fcgi and the Perl CGI::Fast module
        marc@server:~$ sudo apt-get install spawn-fcgi libcgi-fast-perl
  • Added fastCGI process to startup
        marc@server:~$ sudo vi /etc/rc.local
        /^exit
        k
        $
        a
        <Enter>
        spawn-fcgi -s /var/run/munin/munin-fastcgi-graph.sock -U www-data -u munin -g munin /usr/lib/cgi-bin/munin-cgi-graph
        <Esc>
        :wq
  • Added the sections below to /etc/nginx/sites-available/default
                location ^~ /cgi-bin/munin-cgi-graph/ {
            fastcgi_split_path_info ^(/cgi-bin/munin-cgi-graph)(.*);
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_pass unix:/var/run/munin/munin-fastcgi-graph.sock;
            include fastcgi_params;
        }
  • Published munin pages on a web readable location
        marc@server:~$ sudo ln -s /var/cache/munin/www/ /var/www/admin/munin
  • Reloaded nginx
        marc@server:~$ sudo service nginx reload
  • Enabled nginx and other useful plugins
        marc@server:~$ sudo ln -s /usr/share/munin/plugins/nginx_* /etc/munin/plugins/
        marc@server:~$ sudo ln -s /usr/share/munin/plugins/mysql_* /etc/munin/plugins/
        marc@server:~$ sudo ln -s /usr/share/munin/plugins/users /etc/munin/plugins/
        marc@server:~$ sudo ln -s /usr/share/munin/plugins/libvirt_* /etc/munin/plugins/
        marc@server:~$ sudo service munin-node restart

Finally...

Remember to make your site world-visitable if you have finished setting up your PHP site
        marc@server:~$ sudo ufw allow from any to any app 'Nginx Full'
    marc@server:~$ sudo ufw delete allow from 127.0.0.0/8 to any app 'Nginx Full'    
    marc@server:~$ sudo ufw delete allow from 192.168.0.0/16 to any app 'Nginx Full'