Reverse ssh tunnel mit autossh

Eigentlich ist das Port-Forwarding im Router so eingestellt, dass der Remote Zugriff auf den Heimserver problemlos funktioniert. Leider hat der Provider aber die Möglichkeit den Router neu zu initialisieren (und damit meine Forward-Regeln zu löschen) und er macht auch massiv Gebrauch davon. Zwar kann der Server dann weiterhin mit dem Internet kommunizieren (und so auch als nagios-Server andere Server überwachen), der Zugriff von außen funktioniert aber nicht mehr.

Mit einem Server im Internet lässt sich dem Problem ein Schnippchen schlagen, in dem man den Heimserver anweist einen reverse ssh tunnel aufzubauen. Über diesen kann man später auf das Heimnetz zugreifen und die Port-Forwarding Regeln neu einspielen. Damit der Tunnel nach der Unterbrechung durch den Provider wieder hergestellt wird hilft autossh. Mit folgendem Eintrag in /etc/rc.local (Ubuntu Server):

sudo -u meinuser /usr/bin/autossh \
  -R 17777:localhost:22 -N meinserver.tld &

bleibt die Verbindung immer offen. Hier noch kurz die Erklärung der Einzelheiten:

  • sudo -u meinuser: Die Datei /etc/rc.local wird als root ausgeführt, der SSH-Tunnel soll aber unter meinem User aufgebaut werden
  • autossh -R 17777:localhost:22: autossh übergibt alle Parameter an ssh. Hier wird der reverse Tunnel auf Port 17777 zum Port 22 der lokalen Maschine hergestellt.
  • -N: ssh soll keine Shell starten, nur den Tunnel bereit stellen

Natürlich müssen die ssh-Schlüssel für den eigenen Account mit dem Server meinserver.tld zuerst ausgetausch werden, damit ein login ohne Passwort möglich ist. Anschließend kann man mit den Kommandos

ssh meinuser@meinserver.tld
ssh -p 17777 localhost

vom Internet aus auf den Heimserver zugreifen. Der Port 17777 ist dabei nur für Benutzer am Server meinserver.tld zugängig.

Server-backup mit duplicity auf Amazon S3

Das Backup für PCs und Laptops macht Backuppc sehr fein, aber für die Root-Server braucht es eine andere Lösung.

Duplicity macht gpg-verschlüsselte Backups und unterstützt die unterschiedlichsten Endpunkte wie ftp, rsync, scp, ssh, webdav[s] und auch Amazon S3. Hier mein Mini-Bash-Skript mit dem ich meine Server dorthin sichere:

#!/bin/bash

BDIRS="/etc /home /"
LOGDIR='/var/log/duplicity'
BAC="s3+http://ihr_bucket_name.s3.amazonaws.com"
# symmetrische verschluesselung fuer gpg
export PASSPHRASE='einelangeschwierigepassphrase'
export AWS_SECRET_ACCESS_KEY="amazon_aws_secret_access_key"
export AWS_ACCESS_KEY_ID="amazon_aws_access_key"
##### end of config ##########

BCLIENT=$(hostname);
for FULL_DIR in $BDIRS
do
  DIR=$(basename $FULL_DIR)
  if [ $DIR == "/" ]
  then
    DIR="root"
  fi
  EXCLUDELIST="/usr/local/etc/duplicity-exclude-$DIR.conf"
  if [ -f $EXCLUDELIST ]; then
    EXCLUDE="--exclude-filelist $EXCLUDELIST"
  else
    EXCLUDE=''
  fi
  duplicity remove-older-than 60D -v3 --force $BAC/$BCLIENT_$DIR >> $LOGDIR/$DIR.log
  duplicity --full-if-older-than 30D -v3 $EXCLUDE $FULL_DIR $BAC/$BCLIENT-$DIR 
    >> $LOGDIR/$DIR.log
done

export PASSPHRASE=""
export AWS_SECRET_ACCESS_KEY=""
export AWS_ACCESS_KEY_ID=""

exit 0

Das Skript entstand in Anlehnung an ein Backup-Skript von Hetzner, wobei ich es noch weiter vereinfacht und auf S3 umgestellt habe. Backups werden 60 Tage aufbewahrt, wobei alle 30 Tage ein volles Backup gemacht wird. In den Zeilen 3 bis 9 sind die entsprechenden Anpassungen zu machen. Aufgerufen wird das Skript jede Nacht von cron:

root@yourhost:/root $ cat /etc/cron.d/duplicity 
# /etc/cron.d/duplicity: crontab fragment for backup
# backup at 4 in the morning
55 3 * * * root /usr/local/sbin/backup.sh >/dev/null 2>&1
root@yourhost:/root $

Server-Migration

Es hat sich so ergeben, dass ich circa alle zwei Jahre meine Server auf neue Hardware verlege. Bei den gemieteten root-servern kommen dabei immer neue IP-Adressen ins Spiel. Da das Update der DNS-Einträge ein wenig zeitversetzt geschieht und das den Zeitpunkt der Umstellung nicht ganz genau planen lässt, ist es günstig alle Anfragen von der alten IP-Adresse auf die neue umzuleiten. Mit iptables ist das sehr einfach, hier das Skript, das nicht nur Webanfragen, sondern auch Mailserver (SMTP und IMAP/POP) umleitet. Das Skript muss am alten Server ausgeführt werden, wobei 10.0.0.1 hier die IP-Adresse des neuen Servers ist.

echo 1 > /proc/sys/net/ipv4/ip_forward
# http/https
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 10.0.0.1
# imap/imaps
iptables -t nat -A PREROUTING -p tcp --dport 143 -j DNAT --to-destination 10.0.0.1
iptables -t nat -A PREROUTING -p tcp --dport 995 -j DNAT --to-destination 10.0.0.1
# SMTP
iptables -t nat -A PREROUTING -p tcp --dport 25 -j DNAT --to-destination 10.0.0.1
# POP3/POP3s
iptables -t nat -A PREROUTING -p tcp --dport 110 -j DNAT --to-destination 10.0.0.1
iptables -t nat -A PREROUTING -p tcp --dport 995 -j DNAT --to-destination 10.0.0.1
iptables -t nat -A POSTROUTING -j MASQUERADE

Zum Anzeigen der NAT-Tabellen eignet sich dieses Kommando (credits):

iptables -nvL -t nat

Damit kann man die Servermigration mit einem Schalter umlegen.

Update:
Da dieser tolle Trick so gut funktioniert, besteht die Gefahr, dass man nicht alle DNS-Einträge auf die neue IP korrigiert hat. Nachdem der Server vom Provider Netz genommen wurde kamen die ersten Beschwerden … Deshalb das nächste mal vorher die Server-Abschaltung selbst testen.