Raspberry Pi: First Config and Services Configuration

What is the Raspberry Pi ?

I think there's no need to present the Pi anymore. This is basically a whole computer embed on chip based on ARM. It has been designed by David Braben. The official site is the following: http://www.raspberrypi.org/

Initial configuration

Here is a small memo of the things I do when I configure a Pi for the first time. The first thing is to connect to the Pi using ssh the default login is pi and the password is raspberrySo this will be the first thing to change !
sudo su
passwd Set a root passwd which is not the case by default.
passwd pi Change the pi passwd ! (you might also delete the user and create a new one)
visudo Remove pi from sudoers
aptitude update
aptitude safe-upgrade
aptitude install vim host htop

# Network Configuration vim /etc/hostname
vim /etc/network/interfaces
#iface eth0 inet static
#     address 192.168.0.5
#     network 192.168.0.0
#     netmask 255.255.255.0
#     broadcast 192.168.0.255
#     gateway 192.168.0.1
vim /etc/resolv.conf
raspi-config #To enlarge the filesystem, disable X, and change timezone

The default package repository (mirrordirector.raspbian.org) is not really reliable, and an update should sometimes in my case be relaunch few times to get through. So I use another package repository:
echo 'deb http://mirrors.ircam.fr/pub/raspbian/raspbian/ wheezy main contrib non-free rpi' > /etc/apt/sources.list

SSH Key exchange

For more simplicity I have put the public key of my main computer in the ssh authorized hosts of the pi to login automatically, here are the few steps to do.

On the local host:
  • ssh-keygen -t rsa
  • scp .ssh/id_rsa.pub pi@192.168.0.5:~/
  • echo 'alias copi="ssh pi@192.168.0.5 -X" ' >> ~/.bashrc
On the pi:
  • cat id_rsa.pub >> .ssh/authorized_keys
  • chmod 600 .ssh/authorized_keys

Services configuration

Small memo of the operations to perform to configure some services on the Raspberry.


OpenVPN

The following tutorial is really perfect: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=36&t=21566
Note: instead of copy/pasting the server.conf given, copy the one located in /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz


Etherpad-lite

Etherpad-lite is a collaborative text editor written in node.js. The installation and configuration is made easy by the usage of a script available on Github here.
The script is called install_raspi_etherpad-lite.sh. I am used to change the port in the file to 8081 so that I keep the 8080 for proxy stuff.

./install_raspi_etherpad-lite.sh

Now etherpad should be installed if no errors occurs. Except few things:
ln -s /usr/bin/nodejs /usr/bin/node (cause etherpad intent to launch node while the package install a binary called nodejs)
Then you can start the application with /etc/init.d/etherpad-lite start (The first time you launch it. It can take a while to install all the dependencies and due to the low performance of the Pi)


Libreplan

Libreplan is a wonderful project management web application. http://www.libreplan.com/
Libreplan is not available in package repositories but .deb packages are provided on the official website. The only problem is that there is no package for armhf. The application itself is just a tomcat application so there is no reason for it not to work on arm platforms. We will just need to tweak the .deb package to replace the architecture to armhf. The commands to perform are:

wget http://sourceforge.net/projects/libreplan/files/LibrePlan/libreplan_1.3.3-1_i386.deb
ar vx libreplan_1.3.3-1_i386.deb
mkdir -p libreplan_1.2.3-1_armhf/DEBIAN
tar -C libreplan_1.2.3-1_armhf/DEBIAN/ -xvf control.tar.gz
tar -C libreplan_1.2.3-1_armhf -xvf data.tar.gz
sed -i 's/Architecture: .*/Architecture: armhf/' libreplan_1.2.3-1_armhf/DEBIAN/control
dpkg-deb --build libreplan_1.2.3-1_armhf/
aptitude install libpg-java postgresql cutycapt postgresql-client xvfb dbconfig-common ucf tomcat6
dpkg -i libreplan_1.2.3-1_armhf.deb

To resume what commands does. We first download the i386 version of Libreplan, then we extract the .deb and we recreate the directory structure of the package. We replace the architecture into the file control using sed and we rebuild the package with dpkg-deb. Then we just have to install the package dependencies and to install our brand new package. And it works ;)
The server is now listening on the port 8080, and is accessible on http://192.168.0.5:8080/libreplan. Be sure to change the admin password and be patient the pi will certainly suffer of the load ^^.

Note: I prefer launching this kind of service on demand so I remove it from startup with : update-rc.d tomcat6 remove


Codiad IDE

Codiad IDE is a web based IDE, which allow to create workspace and support many functionnalities like code coloration etc. It is pretty light and does not require any DB. There is no difficulties in installing Codiad.
The following steps allow to install Codiad:

wget https://github.com/Codiad/Codiad/zipball/master
unzip master
cd Codiad-Codiad-961e711/ #Adapt to the current github commit
mkdir /var/www/codiad
cp -r * /var/www/codiad/
mv /var/www/codiad/config.example.php /var/www/codiad/config.php
chmod o+w /var/www/codiad/config.php /var/www/codiad/data/ /var/www/codiad/workspace/

Then there is to possibilities, either you modify the config file to modify the root path of codiad either you create a VirtualHost.
1st method:
  • sed -i 's/^\$rel.*/\$rel = \"\/codiad\"\;/ /var/wwww/codiad/config.php
  • touch /var/www/codiad/plugins.php
2nd method:
  • touch /var/www/codiad/plugins.php
  • echo "Listen 8081" >> /etc/apache2/ports.conf
  • vim > /etc/apache2/sites-available/codiad
    <VirtualHost *:8081>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/codiad
        <Directory />
            Options FollowSymLinks
            AllowOverride None
        </Directory>
        <Directory /var/www/codiad>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            allow from all
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
    
  • a2ensite codiad
  • service apache2 reload


OpenMediaVault

OpenMediaVault is a NAS that allow to get a good control on the system which allow to transform the pi into a fully featured NAS. There is no package available and the OMV package repository should be added to the sources.list and to add the key of the repository.

echo 'deb http://packages.omv-plugins.org fedaykin main' >/etc/apt/sources.list.d/omv-plugins-org-fedaykin.list
echo 'deb http://packages.omv-plugins.org fedaykin-armhf main' >/etc/apt/sources.list.d/omv-plugins-org-fedaykin-armhf.list
wget -O - http://packages.omv-plugins.org/apt/99omv-plugins-org > /etc/apt/preferences.d/99omv-plugins-org
wget -O - http://packages.omv-plugins.org/omv-plugins.pub|apt-key add -

Then openmediavault can be installed. (If the installation fail due to tftpd-hpa change TFTP_OPTIONS to TFTP_OPTIONS="--secure --ipv4" in /etc/default/tftpd-hpa)
aptitude install openmediavault

You can also directly install OMV plugins from aptitude here are the available ones:
  • openmediavault-autoshutdown - OpenMediaVault AutoShutdown
  • openmediavault-clamav - OpenMediaVault ClamAV p openmediavault-cups - OpenMediaVault CUPS (network printer server)
  • openmediavault-dnsmasq - OpenMediaVault dnsmasq (local DNS and DHCP server)
  • openmediavault-forkeddaapd - OpenMediaVault forked-daapd (DAAP server)
  • openmediavault-git - OpenMediaVault Git (Git server)
  • openmediavault-iscsitarget - OpenMediaVault iSCSI Enterprise Target
  • openmediavault-ldap - OpenMediaVault Lightweight Directory Access Protocol (LDAP)
  • openmediavault-lvm2 - OpenMediaVault Logical Volume Manager (LVM2)
  • openmediavault-minidlna - OpenMediaVault miniDLNA (DLNA server)
  • openmediavault-mysql - OpenMediaVault MySQL (MySQL database server)
  • openmediavault-netatalk - OpenMediaVault netatalk (AppleTalk Protocol Suite)
  • openmediavault-nut - OpenMediaVault Network UPS Tools (NUT)
  • openmediavault-omvpluginsorg - OMV-Plugins.org Package Repositories for OpenMediaVault
  • openmediavault-openvpn - OpenMediaVault OpenVPN (VPN server) plugin
  • openmediavault-processlist - OpenMediaVault process list panel
  • openmediavault-route - OpenMediaVault IP routing table
  • openmediavault-subversion - OpenMediaVault Subversion (SVN server)
  • openmediavault-transmissionbt - OpenMediaVault Transmission (BitTorrent client)
  • openmediavault-virtualbox - OpenMediaVault VirtualBox
  • openmediavault-website - OpenMediaVault Website plugin
I also like to make it listen on a specific port so I do the following:
echo 'Listen 8080' >> /etc/apache2/ports.conf
sed -i 's/<VirtualHost \*:80>/<VirtualHost \*:8080>/' /etc/apache2/sites-available/openmediavault-webgui



Owncloud

Owncloud is an amazing private cloud, easy to be set up. The following commands show how to install and configure it with SSL.

aptitude install apache2 php5 php5-json php5-gd php5-sqlite curl libcurl3 libcurl4-openssl-dev php5-curl php5-gd php5-cgi php-pear php5-dev build-essential libpcre3-dev libapache2-mod-php5 php-apc

pecl install apc
echo "apc.enabled=1" >> /etc/php5/cgi/conf.d/20-apc.ini
echo "apc.shm_size=30" >> /etc/php5/cgi/conf.d/20-apc.ini


vim /etc/php5/apache2/php.ini
#Change upload_max_size
#Add extension=apc.so

a2enmod rewrite
a2enmod headers

openssl genrsa -des3 -out server.key 2048
openssl rsa -in server.key -out server.key.insecure
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
cp server.crt /etc/ssl/certs
cp server.key /etc/ssl/private
a2enmod ssl
a2ensite default-ssl

wget http://download.owncloud.org/community/owncloud-5.0.5.tar.bz2
tar xvf owncloud-5.0.5.tar.bz2
cp -r owncloud /var/www/
chown -R www-data:www-data /var/www/owncloud/


Useful links

OS Programming (Cambridge)

Kasiski-Babbage Cryptanalysis in Python

This blog post shows a basic python implementation of the Kasiski-Babbage Cryptanalysis algorithm for solving a basic Vigenere crypto challenge.

 Principle

The Kasiski-Babbagge method is based on the fact that once we have found the key length found the clear text is reduced to find the clear text of a ceaser ciphered text (which is really easy).

Another principle of the method is that 3 or more characters at two different position in the ciphered text are most likely to have been ciphered with the same 3 or more characters of the key. Based on this fact the distance between the two suite of characters is very likely to be a multiple of the key length. Example:

As we can see on the picture above there is 3 patterns with a respective distance of 70, 40 and 10. So we can easily state that the key length is a multiple of the three distances which is 10. So, we can suppose that key is 10 characters long.

The key idea is then to split the text in 10 sub-texts with every ten characters in order to create 10 samples where the frequency of chars can be analyzed with a classical ceaser scheme.

Code !

The input file used for this example can be downloaded here

Now the key part of the cryptanalysis is to develop the algorithm to find all the tuples throughout the text calculate theirs distance and the divisors of it. So the first function to write is a function that calculate all the divisors of a value. The function below do the job and for the given integer return a list of all the divisors.

Get all the divisors of a given number
1
2
3
4
5
6
def getDivisors(n):
    l = []
    for i in range(2,n):
        if n % i == 0:
            l.append(i)
    return l

Now let’s move to the core function that find all the tuples. This function return two values that are the number of tuples found and a dirty list of the divisors of all tuples. (You will see later how it will be used).

Find identical patterns in list (size > 3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#l argument should be a list containing all bytes of the file (read with toList)
def getTuples(l):
    res = {}
    freq =[]
    count = 0
    i = 0
    while i < len(l): # Loop through all the list
        elt= l[i:i+3] # Take at least 3-character length for tuples
        long = len(elt)
        if long == 3: #should be 3 if not means we are at the end of the list
            for j in range(i+1,len(l)): #Find further in the list for the same pattern
                if l[i:i+long] == l[j:j+long]: #If match the 3-char check for more
                    while l[i:i+long] == l[j:j+long]:
                        long = long + 1
                    long = long -1
                    elt = l[i:i+long] # Now we have a tuple 
                    diff = j - i # Compute the distance
                    freq.extend(getDivisors(diff)) #Add the divisors to the list 
                    print ("%s\ti:%s\tj:%s\tdiff:%s\t\tDivisors:%s" % (elt,i,j, diff,getDivisors(diff))) #Print information about the tuple (can be deleted)
                    count = count +1
                    j = j + long + 1
            i = i + long -3 +1
        else:
            i = i + 1
    return count, freq

The next step is to make the count each divisors and sort them in descending order. The following function return a list sorted containing a tupe of the divisor number and the number of hits.

1
2
3
4
5
6
7
8
def countOcc(l): # return list with (decimal_char, occ) 
    d={}
    for elt in l:
        if d.has_key(elt):
            d[elt] += 1
        else:
            d[elt] = 1
    return sorted(d.items(),key=lambda x: x[1], reverse=True)

The list returned by this function is: [(2, 143), (5, 142), (10, 138), (4, 72), (20, 69), (6, 42), (3, 42), (15, 41), (8, 39), (30, 39), (40, 36), (7, 29), (14, 29), (35, 29), (25, 28), (50, 24), (70, 24), (12, 20), (60, 20)]

In this example we can see that 2 is a divisor for 138 tuple etc. But there is also 5 and 10 that are close and 4 is far behind. Moreover 2 and 5 are also divisors of 10 so this is obvious that the key is 10 characters long.

Now that we “know” the key length we just have to split the ciphered list into 10 sub-lists modulo 10. The function below return take in argument the key length and the original list and return a dictionnary that use the position as key (ex: 1 to 10) and all the sub-lists as items.

Split file in sublist of 10 chars
1
2
3
4
5
6
7
8
9
10
11
def explode(key,li):
    dic = {}
    for e in range(1,key+1):
        dic[e] = []
    i = 0
    for index in range(len(li)):
        if i == key:
            i = 0
        dic[i+1].append(li[index])
        i = i + 1
    return dic

The next step is the second delicate step. Indeed we need to find the shift for each sub-list. To find it we can do a frequency analysis considering the space as the most frequent character like it used to be in english. So what we will do here is do a frequency analysis for each sub-list. For each sub-list we consider the most frequent character as a space and then apply the associated shift to all character. And then we recreate the original list with all decipher sub-list and then recreate the text. Once it’s done we can easily identify if for one of the sub-list the space was not the most frequent and then we can try with the second most frequent and so on. The first function we need to acomplish this task is a function that decipher a list with a given shift:

1
2
3
4
5
6
7
8
9
def decipher(l,diff):
    newl = list()
    for e in l:
        val = e - diff
        if val < 0:
            newl.append(256 + (val % -256))
        else:
            newl.append(val)
    return newl

Now we need a function that do the reverse of the explode function. So this function takes back the dictionnary returned by explode and recreate the list.

1
2
3
4
5
6
7
8
9
10
11
def recreate(dic):
    i = 0
    output = []
    try:
        while 1:
            for l in dic.values():
                output.append(l[i])
            i = i + 1
    except:
        pass
    return output

To finish the following piece of code explode the original list, makes a frequency analysis decipher all the sub-list, then recreate the list and end up by reconverting every decimal character into character in order to print the result.

final code to trigger the all
1
2
3
4
5
6
7
8
9
res = explode(10, l) #We consider in this exemple a key length of 10 and l the original list
for i in range(1,10+1): #For each sub-list
    occ = countOcc(res[i]) #Make a frequency analysis
    shift = (occ[0][0] - 32) % 256 # Consider the most frequent element of being a space(32 in decimal)
    print ("Frequency analysis for the index: %s\tshift:%s\n%s\n" % (i,shift,occ)) #Print informations (can be deleted)
    res[i] = decipher(res[i],shift) #Try do decipher using a classical ceaser function and the determined shift

final = recreate(res) #Once we have processed all sub-list recreate a list with all the sub-lists.
print ''.join([chr(x) for x in final]) #Print the result