Recently I updated some of my Debian servers to Jessie. There were no problems during and after the upgrade process and I rebooted my machines. After that I checked my processes and recognized that my dns server „Bind9“ wasn’t running anymore.

When I tried to manually start the service I got the error message that there were no permissions to create the log file and I started to think that the bind daemon hasn’t been started in a chroot environment.

I searched on many pages for a solution of this problem and finally found it here. Thanks for that helpful post. The solution is very easy.

If you started your bind9 daemon earlier with this parameter in your /etc/default/bind9:

OPTIONS="-u bind -t /var/lib/named"

Copy the default service file for bind9 to prevent that your changes on the original file are overriden on update:

cp -av /lib/systemd/system/bind9.service /etc/systemd/system/bind9.service

Now add the chroot paramter for systemd in this file:

ExecStart=/usr/sbin/named -f -u bind -t /var/lib/named

After that reload the systemd daemon:

systemctl daemon-reload

This is my new etherpad plugin to let users save a list of bookmarks of their pads in the browser’s local storage. It’s called ep_bookmark.

You can manually add the actual pad to the list of your bookmarks or click the option to automatically do that each time you’ll enter a pad.

The list is ordered descending beginning with the last pad you’ve visited. You can add a comment to each bookmark by clicking on the edit button and write something in the text field. To delete a bookmark you only have to click the delete button.

A click on the name of the pad/bookmark will switch you to this pad without reloading the website.
Read more

You can download the plugin with the plugin manager of your etherpad instance.

I recently migrated my servers from Debian squeeze with OpenVZ to Debian 7 with Xen. The reason is that debian wheezy doesn’t contain any packages of OpenVZ in the official repositories.
So I decided to migrate to Xen.

The steps to do that are:

  1. Save container in image files
  2. Install operating system (Debian)
  3. Install virtualization (Xen)
  4. Copy image files into newly created virtual machines
  5. Prepare vms

Here are the detailed steps:

1 Create image files
You have to create a image file for each container you have. The following code creates a 1GB image file:
dd if=/dev/zero of=~/tmp/image.img bs=1M count=1024
Change the count number and the file will be smaller or greater. At least the image file should be as large as your container.
To get the size of your container you can do:
du -sh /vz/root/$VEID/

Next you have to format your image file:
/sbin/mkfs.ext3 /tmp/image.img

and mount it in your file system:
mount -t ext3 -o loop /tmp/image.img /media/Imagemount

This will copy all files from container to your image file (-H is for hardlinks)
rsync -aAXHv --delete /vz/root/$VEID/* /media/Imagemount

2 Install operating system (Debian)
2.1 Format disk
If you are not able to install your debian normally, cause you have no physically access to the server, the next steps will prepare the installation with a rescue system:
First you have to boot into rescue system.
Next you will erase your whole disk and create new partitions:
fdisk /dev/sda

We want to create for partitions:

  1. Boot partition (300 MB)
  2. Data partition (20 GB)
  3. Swap space (double size of your ram)
  4. LVM space for your virtual machines

Hint:
To change the type of a partition to swap you have to enter „t“ and set the partition id to „82“ (partition id „8e“ for LVM).
Save your changes with „w“.

2.2 Install raid
This chapter is only neccessary if you want to install a RAID 1 (mirror).

Clone partition table to /dev/sdb
sfdisk -d /dev/sda | sfdisk --force /dev/sdb

Create raids
apt-get install mdadm
Create a raid for each partition:
mdadm -v --create /dev/md0 --level=mirror --raid-devices=2 /dev/sda1 /dev/sdb1
mdadm -v --create /dev/md1 --level=mirror --raid-devices=2 /dev/sda2 /dev/sdb2
mdadm -v --create /dev/md2 --level=mirror --raid-devices=2 /dev/sda3 /dev/sdb3
mdadm -v --create /dev/md3 --level=mirror --raid-devices=2 /dev/sda4 /dev/sdb4

Wait until synchronisation finished
watch cat /proc/mdstat

2.3 Format partitions
Create swap partition
mkswap /dev/md2

Format boot partion
mkfs.ext3 /dev/md0

Format data partition
mkfs.ext4 /dev/md1

Create lvm volume
apt-get install lvm2
pvcreate /dev/md3
vgcreate vg0 /dev/md3

Mount data partition and create main folders
mount /dev/md1/ /mnt/
cd /mnt
mkdir etc
mkdir boot
mkdir var
mkdir usr
mkdir tmp
mkdir home

Mount boot partition into filesystem
mount /dev/md0 boot/

Edit fstab file to mount partitions on boot:
vi /mnt/etc/fstab
Insert the following lines:
proc /proc proc defaults 0 0
/dev/md0 /boot ext3 defaults 0 2
/dev/md1 / ext3 defaults 0 1
/dev/md2 none swap defaults,pri=1 0 0

2.3 Installation of debian
Install debootstrap
apt-get install debootstrap
Download all sources from ftp.de.debian.org for debian wheezy and install it to /mnt/
debootstrap --arch amd64 wheezy /mnt/ http://ftp.de.debian.org/debian

Prepare to chroot into new debian
mount -t proc none /mnt/proc
mount -o bind /dev /mnt/dev
mount -o bind /sys /mnt/sys

chroot into system
chroot /mnt

Restore network settings.
vi /etc/network/interfaces

Set host name
vi /etc/hostname

Update system
apt-get update
apt-get install mdadm openssh-server lvm2 locales grub2 console-data

Set locales
dpkg-reconfigure locales

Installation of kernel
apt-get install linux-image-amd64

Installation of grub
grub-install --no-floppy /dev/md0

Change password with passwd
passwd

Reboot the system
exit
reboot

3 Install virtualization (Xen)
3.1 Prepare OS for xen
apt-get install bridge-utils

Create bridge interface
vi /etc/network/interfaces

You have to edit the lines with your internet connection interface
auto eth0
iface eth0 inet static
address 80.141.234.21
netmask 255.255.255.252
gateway 80.141.234.20

To something like that:
auto eth0
iface eth0 inet manual
auto xenbr0

iface xenbr0 inet static
bridge_ports eth0
address 80.141.234.21
netmask 255.255.255.252
gateway 80.141.234.20

3.2 Installation of xen
apt-get install xen-linux-system

Change boot order
dpkg-divert --divert /etc/grub.d/08_linux_xen --rename /etc/grub.d/20_linux_xen
update-grub

Reboot machine to run debian with debian-xen kernel
reboot

Install xen tools
apt-get install xen-tools

4 Copy image files into newly created virtual machines
You have to create your vms. The command for this is
xen-create-image

After your vm has been created you have to mount the disk to copy your files in it
mount /dev/vg0/test-disk /mnt/test-disk

Next you can copy the files from your image file to your virtual disk
rsync -aAXHv /path/to/your/mounted/image/file/* /mnt/test-disk/

Now you have to make a few changes:
Edit fstab to mount your disk.
vi /etc/fstab
The following lines should be fine for standard configuration:
proc /proc proc defaults 0 0
none /dev/pts devpts mode=0620 0 0
/dev/xvda1 none swap sw 0 0
/dev/xvda2 / ext4 noatime,nodiratime,errors=remount-ro 0 1

Edit inittab to load a console after boot
vi /etc/inittab
Add this line to the end:
1:2345:respawn:/sbin/getty 38400 hvc0

Now you can unmount (umount) your disk.

Edit the xen configuration file of your vm to add the bridge as your network interface.
vi /etc/xen/test.cfg
Change the line
vif = [ 'mac=xx:xx...xx']
to something like that
vif = [ 'mac=xx:xx...xx,bridge=xenbr0']

That’s it 🙂

Try to boot your vm with:
xm create -c /etc/xen/test.cfg

Now you’re ready to have fun with Xen 🙂

If you want to add a internal network (for example for all your virtual machines) you have to add a new bridge:
vi /etc/network/interfaces
Add these lines:
auto eth0.100
iface eth0.100 inet manual

auto xenbr1
iface xenbr1 inet static
bridge_ports eth0.100
address 10.10.0.1
netmask 255.255.255.0

Edit your vm cfg
vi /etc/xen/test.cfg
Add a new interface
vif = [ 'mac=xx:xx...xx,bridge=xenbr0', 'mac=xx:xx...xx,bridge=xenbr1']

Reboot your vm and add the new interface in your /etc/network/interfaces
vi /etc/network/interfaces
auto eth1
iface eth1 inet static
address 10.10.0.2
netmask 255.255.255.0

Sources (English and German):
http://blog.mellenthin.de/archives/2010/03/14/debian-lenny-auf-einem-rootserver-mit-raid-1-und-lvm/
http://wiki.xenproject.org/wiki/Xen_Beginners_Guide#Creating_a_Debian_PV_.28Paravirtualized.29_Guest
https://wiki.debian.org/Xen

Yesterday I released the first version of the plugin ep_new_pad. I got the idea for it from the old etherpad. It adds the page „randomPad“ on the root level of etherpad lite. If someone opens this site it will create a random string (between 8 and 15 characters), check if this string is already a pad name in the database and, if not, it will redirect the user to this REALLY new pad.

You can install this plugin on the admin page of your etherpad lite server.

Github
NPM

I recently published a plugin for etherpad lite.
It adds the possibility to send a message to all connected users on all pads.
You can download it via the plugin list on your etherpad lite instance and on https://npmjs.org/package/ep_message_all

Have fun 🙂

Etherpad-Lite is a very cool tool to write documents collaboratively in real-time in browser with others (http://etherpad.org)
I’m admin of a very big instance of it. The big problem what I have is that I can’t load-balance it, because if you have two servers with one database you have to make sure that one pad is handled by one Etherpad-Lite instance. If your requests to the same pad are handled by two instances every instance writes different datas into the database and will destroy it.

So I began to write an Etherpad-Lite reverse proxy with dynamic routing table in node.js.
This reverse proxy redirects requests to the server which is responsible for the pad request. The redirects will be saved in a routing table that’s why it is called dynamic reverse proxy.
It’s in an alpha stadium and there is a lot to do, but any help is appreciated 🙂

You can find my project on github:
https://github.com/Gared/eplite-reverse-proxy

Hier eine Anleitung zur Installation von Etherpad.
Wer die Team-Funktionalität von Etherpad nicht benötigt und das ganze schnell und einfach installieren möchte, der sollte sich Etherpad-Lite ansehen.

Die Installation von Etherpad wurde mit folgendem System durchgeführt:
OS: Debian Lenny 6.0.5
Etherpad: 1.1 (GIT-Version)

1 Installation der zusätzlichen Pakete und Software
1.1 Installation von git
apt-get install git

1.2 Java MySQL-Connector
Wird für die Verbindung mit der MySQL-Datenbank benötigt. Somit installieren wir sie:
apt-get install libmysql-java

1.3 Scala
Wir benutzen die Version aus dem Debian-Repository.
apt-get install scala scala-library
(Version 2.7.7 in meinem Fall)

1.4 Java
Ich benutze hier openjdk, da es in den Repositories liegt. Man kann auch beispielsweise das Java von Sun verwenden.
Fastjar wird für das generieren von gepacketen Jar-Dateien benötigt.
apt-get install openjdk-6-jdk openjdk-6-jre fastjar

2 MySQL-Datenbank installieren
apt-get install mysql-server mysql-client

Wir verbinden uns anschließend auf den MySQL-Server, um uns eine Datenbank und einen Benutzer anzulegen:
mysqladmin -u root -p create etherpad
mysql -u root -p
GRANT ALL PRIVILEGES ON etherpad.* TO 'etherpad'@'localhost' IDENTIFIED BY 'myPassword' WITH GRANT OPTION;

3 Etherpad einrichten
3.1 Download Etherpad Source Code
Auf Github finden wir die aktuelle Version von Etherpad: https://github.com/ether/pad
Sie wird schon seit längerem nicht mehr weiterentwickelt. Die Programmierer haben sich entschieden die Software in node.js neu zu schreiben, wie oben schon erwähnt: https://github.com/Pita/etherpad-lite/
Mit
git clone https://github.com/ether/pad.git
laden wir uns zunächst den aktuellen Stand herunter.

Danach wechseln wir in den Pad-Ordner und bauen Etherpad:
cd pad && bin/build.sh

3.2 Etherpad konfigurieren
In der Etherpad config müssen wir nun die richtigen Einstellungen eintragen. Diese befindet sich unter folgenden Pfad:
pad/etherpad/etc/etherpad.localdev-default.properties
Hier eine Erklärung der Config mit allen wichtigen Optionen:
# Verzeichnis der Module (Standardconfig sollte passen)
ajstdlibHome = ../infrastructure/framework-src/modules
# Verzeichnis der Appjet Dateien
appjetHome = ./data/appjet
# Entwicklungsmodus:
# true: Fehlermeldungen werden direkt auf der Website angezeigt und das Admin-Interface ist für jeden zugänglich (nicht für Produktivbetrieb empfohlen!)
# false: Für Produktivbetrieb
devMode = false
# Erlauben von ProAccounts (Erstellen von Subdomains)
etherpad.proAccounts = true
# Passwort für das Admin-Interface (https://domain.de/ep/admin/)
etherpad.adminPass = mySecretPw
etherpad.fakeProduction = false
etherpad.isProduction = true

# MySQL-Einstellungen
etherpad.SQL_JDBC_DRIVER = com.mysql.jdbc.Driver
etherpad.SQL_JDBC_URL = jdbc:mysql://127.0.0.1:3306/etherpad
etherpad.SQL_PASSWORD = mysqlPassword
etherpad.SQL_USERNAME = mysqlUser
# Maximale Threadanzahl, die Etherpad erstellen soll
#maxThreads = 512
# Zeige keine Portangaben in E-Mails, etc. an, falls diese vom Standard abweichen (z. B. wegen Reverse Proxy)
hidePorts = true
# Port für unverschlüsselte Übertragung
listen = 9000
# Port für SSL-Übertragung. Falls diese Option entfernt wird, wird kein Port für SSL-Übertragung geöffnet.
#listenSecure = 9001
# Verzeichnis in das die Logfiles geschrieben werden sollen
logDir = /var/log/etherpad/
# Verzeichnis der Module (Standardangabe)
modulePath = ./src
# Message-of-the-day (Standardmäßig die Seite mit zwei Buttons zum Erstellen eines Teams oder eines Pads)
motdPage = /ep/pad/view/ro.3PfHCD0ApLc/latest?fullScreen=1&slider=0&sidebar=0
# Hier müssen alle Domains und IPs eingetragen werden, mit der Etherpad aufgerufen können werden soll
topdomains = localhost,myDomain.de,otherDomain.org,192.168.1.10
# URL-Erweiterung, die Etherpad für Comet-Requests benutzen soll (Standardangabe)
transportPrefix = /comet
# Benutzen von zufällig generierten Subdomains für die Comet-Transaktionen (2031232.comet.subDomain.myDomain.de).
# Achtung: Führt zu Zertifikatsproblemen, da kein Zertifikat mit *.comet.*.myDomain.de erstellt werden kann. Ich habe dafür einen Fix erstellt: https://github.com/Gared/pad/commit/3157057d8f412f2533bdb75d1128d9eaea454d59
transportUseWildcardSubdomains = true
# Zwinge alle Benutzer HTTPS zu verwenden
useHttpsUrls = false
useVirtualFileRoot = ./src
# Standardtheme
# Themes findet man unter pad/etherpad/src/themes
theme = default
# OpenOffice Export-Service
/usr/bin/soffice
# Eigene Bezeichnung der Etherpad-Instanz
myEtherpad
# Eigene E-Mail Adresse
support@myDomain.de
# Anzeige von Lizenzen für den Text
showLinkandLicense = false
# Einstellungen für SSL-Zertifikat
# Die Anleitung für die Einrichtung von SSL befindet sich im Weiteren Verlauf der Anleitung
#sslKeyPassword =
#sslKeyStore = ./data/appjet/keystore
#sslStorePassword = myKeystorePassword
# Ausschließen von Log-Dateien
logExclude = # z.B. no-events,streaming-events
# Schaltet Shortpolling aus
disableShortPolling = false

3.3 Etherpad starten
Mit bin/run.sh starten wir Etherpad. Die Tabellen werden automatisch beim ersten Start eingerichtet.
Sollte alles funktioniert haben, erscheint die Zeile:
HTTP server listening on http://localhost:9000/
und wir können uns über die URL auf unser Pad verbinden.
Hurra geschafft! 🙂

4 Installation des OpenOffice Export-Services
Wer den Export und Import von PDF-, Word- und ODT-Dateien nutzen möchte, muss den OpenOffice-Service installieren.
Dazu ist die Installation der folgenden Pakete notwendig:
apt-get install openoffice.org-headless openoffice.org-java-common openoffice.org-writer openoffice.org-l10n-de
Der OpenOffice-Service wird automatisch gestartet, wenn Etherpad gestartet wird.

5 Etherpad mit https (SSL)
Java braucht einen Keystore um mit Zertifikaten umgehen zu können. Wir erstellen uns zunächst ein Zertifikat. Anleitungen dafür sollte es im Internet genügend geben. Wir erstellen uns ein Keystore und importieren dieses Zertifikat:
keytool -importcert -file /tmp/zertifikat.crt -keystore sslkeystore -storepass storePw -alias openssl -keypass keyPw
Mit folgenden Paramtern wird der Keystore in der Konfiguration eingerichtet:
sslKeyPassword = keyPw
sslKeyStore = ./data/appjet/sslkeystore
sslStorePassword = storePw

6 Init-Script
Folgt…

Ich habe an meinem heimischen Anschluss nur eine DSL Geschwindigkeit von 768 kbit/s, deshalb finde ich es immer sehr nervig wenn ich Videos laden muss. Noch nerviger ist es, wenn ich ein Video nach einem Neustart nochmal laden muss.
Bei meiner Suche nach einer Lösung, bin ich auf dieser Seite gelandet: http://code.google.com/p/youtube-cache/.
Da ich die Lösung mit Squid schon des öfteren in der Vergangenheit probiert hatte, habe ich die Lösung mit Nginx + Squid probiert.
Da Youtube nun nicht mehr die Videos in einem streamed, sondern nur noch in 1,7 MB Blöcken, musste ich die Nginx-Config etwas anpassen.

Nginx-Config:

server {
  listen       8081;

  location / {
    root /usr/local/www/nginx_cache/files;
    try_files "/id=$arg_id.itag=$arg_itag.range=$arg_range" @proxy_youtube;
  }

  location @proxy_youtube {
    resolver 8.8.8.8;

    proxy_pass http://$host$request_uri;
    proxy_temp_path "/usr/local/www/nginx_cache/tmp";
    proxy_store "/usr/local/www/nginx_cache/files/id=$arg_id.itag=$arg_itag.range=$arg_range";

    proxy_set_header X-YouTube-Cache "your.email@here";
    proxy_set_header Accept "video/*";
    proxy_set_header User-Agent "YouTube Cacher (nginx)";
    proxy_set_header Accept-Encoding "";
    proxy_set_header Accept-Language "";
    proxy_set_header Accept-Charset "";
    proxy_set_header Cache-Control "";
    proxy_set_header Content-Length "";
  }
}

Hier eine sofort verwendbare Squid-Config:

http_port 3128

acl all src all
http_access allow all
acl youtube_videos url_regex -i ^http://[^/]+\.youtube\.com/videoplayback\?
acl range_request req_header Range .
acl begin_param url_regex -i [?&]begin=
acl id_param url_regex -i [?&]id=
acl itag_param url_regex -i [?&]itag=
acl sver3_param url_regex -i [?&]sver=3
# Replace 127.0.0.1 with the IP/hostname of the YouTube caching proxy server.
cache_peer 127.0.0.1 parent 8081 0 proxy-only no-query connect-timeout=5
cache_peer_access 127.0.0.1 allow youtube_videos id_param itag_param sver3_param !begin_param !range_request
cache_peer_access 127.0.0.1 deny all

Das einzige Problem bei dieser tollen Caching-Config ist, dass die Requests, um die Streaming-Blöcke zu laden, anscheinend vom Nginx gecached werden und es deshalb zu Verzögerungen beim Laden kommt. Erweitert man die Nginx-Config um proxy_buffering off, werden die Streaming-Blöcke wieder schnell geladen, aber dadurch cached Nginx nicht mehr.

Wer eine brauchbare Lösung für dieses Problem findet, lasse mich das bitte wissen.

Initaler Blogpost

Blog myBlog = new Blog(„Stefan’s Entwicklerecke“);