SYSVOL Replikation – Migration von FRS zu DFS Replikation

Der Begriff SYSVOL (%SystemRoot%SYSVOL) bezieht sich auf einen Satz von Dateien und Ordnern, die auf der lokalen Festplatte jedes Domänencontrollers in einer Domäne gespeichert sind und durch den Dateireplikationsdienst (File Replication Service/FRS) repliziert werden. Netzwerkclients greifen über die folgenden freigegebenen Ordner auf den Inhalt der Struktur SYSVOL zu:

  • NETLOGON
  • SYSVOL

Der Dateireplikationsdienst (File Replication Service, FRS) synchronisiert Ordner mit Dateiservern, die den Dateireplikationsdienst anstelle der neueren DFS-Replikationstechnologie verwenden.

DFS-Replikation ermöglicht das Synchronisieren von Ordnern auf mehreren Servern über LAN- oder WAN-Netzwerkverbindungen. Dieser Dienst verwendet das RDC-Protokoll (Remote Differential Compression), um nur die Teile der Dateien zu aktualisieren, die seit der letzten Replikation geändert wurden.

In den alten Windows Server Verionen < 2003 R2 wurde FRS für die Replikation des SYSVOL Ordners auf andere Domain Controller verwendet. Ab Server 2008 wird primär DFS für die Replikation verwendet. FRS wird allerdings immer noch unterstützt.

Für die Migration von FRS zu DFS wird das Tool “Dfsrmig.exe” genutzt. Damit die Migration funktioniert muss die Domäne mindestens auf dem Funktionslevel von Server 2008 sein.

Ob FRS genutzt wird oder nicht findet man via Powershell

dfsrmig /getglobalstate

heraus.

Die Ausgabe sagt aus, dass die DFS-Replakations-Migration noch nicht eingeleitet wurde.

Die Migration an sich hat vier verschiedene Stati:

  1. Status 0 – Starten
  2. Status 1 – Vorbereitet
  3. Status 2 – Umgeleitet
  4. Status 3 – Entfernt

Status 0

Hierbei wird der Sysvol Ordner auf alle Domain Controller repliziert, um einen konsistenten Status auf allen Systemen zu erreichen.

Status 1

FRS repliziert weiterhin den Ordner. Zusätzlich legt DFS eine Kopie an, die sich unter %SystemRoot%SYSVOL_DFRS befindet. Allerdings ist dieses Verzeichnis inaktiv. FRS ist weiterhin der primäre Dienst.

Status 2

Hier ist es andersherum. DFS antwortet auf die Anfragen und FSR ist inaktiv, repliziert sich allerdings weiterhin.

Status 3

Hier wird der FSR Dienst gestoppt und Windows entfernt den Original Sysvol Ordner. Ab diesem Punkt ist kein Rollback mehr möglich.

Migration

Die Migration wird hier unter Powershell durchgeführt. Man muss Mitglied der Rolle Domänen- oder Enterprise Admin sein.

Wurde die DFSR-Migration noch nicht initialisiert, kann dies mit dem Befehl

dfsrmig /setglobalstate 0

gestartet werden.

Anschließend wird in den Status Vorbereitet gewechselt:

dfsrmig /setglobalstate 1

Durch Eingabe von

dfsrmig /getmigrationstate

kann man sich den aktuellen Status der Migration anschauen.

Wenn der Stand konsistent ist, kann weiter gemacht werden.

dfsrmig /setglobalstate 2

dfsrmig /setglobalstate 3

Abschließend sollte nun nicht nur der FRS Dienst gestoppt und deaktiviert sein, sondern ebenfalls die Sysvol Shares auf das neue Verzeichnis gemappt sein.

Durch

net share

werden die Netzlaufwerke angezeigt.

Subversion SVN Migration Dump Autoimport

Bei der Migration von Subversion auf einen neuen und aktuelleren Server steht irgendwann auch die Migration der Repositories an. Je nach Umfang und Anzahl kann das einige Zeit und Handarbeit in Anspruch nehmen.

Um den Ablauf zu vereinfachen und zu automatisieren, kann man folgendermaßen vorgehen:

Migration der Dumps

Die Repositories können als Dump abgespeichert werden und dienen als Container, um sie auf dem neuen System wieder einspielen zu können. Ich gehe jetzt hier davon aus, dass die Dumps regelmäßig auf dem Produktivserver erstellt werden und sich immer am gleichen Platz befinden.

Hier liegen die Dumps unter /data/backups/svn liegen. In meinem Fall mit Datumsangaben und “_dump_” Bezeichnung im Namen:

Die Struktur des neues Subversion Systems ist die selbe. Die Pfade unterscheiden sich also nicht.

Um die Dumps vom alten System auf das neue zu migrieren, wird folgendes Rsync-Kommando als Cronjob abgesetzt.

rm /data/backups/copy-from-svn.log && sshpass -p "***" rsync -ru --delete-after --progress root@subversion-server:/data/backups/svn /data/backups  >> /data/backups/copy-from-svn.log 2>&1

Hierbei wird zunächst das Log des letztes Kopiervorgangs entfernt und sich dann via SSH auf dem alten System angemeldet. Mittels sshpass werden die notwendigen Anmeldedaten mitgegeben. Es wird der Ordner “/data/backups/svn” vom alten System nach “/data/backups” auf das neue System kopiert. Ebenfalls werden alte Dumps, die in der Quelle nicht mehr vorhanden sind, auf dem Zielsystem entfernt

Die Resultate werden nach “/data/backups/copy-from-svn.log” geschrieben:

[...]
1,767,145,472 99% 30.51MB/s 0:00:00
1,767,177,519 100% 17.95MB/s 0:01:33 (xfr#4, to-chk=47/133)
svn/XXX_dump_20170220_221113_164.svn

0 0% 0.00kB/s 0:00:00
16,252,928 12% 11.18MB/s 0:00:10
31,162,368 23% 12.36MB/s 0:00:08
34,308,096 25% 9.59MB/s 0:00:09
44,269,568 33% 9.53MB/s 0:00:09
51,085,312 38% 7.96MB/s 0:00:09
58,490,880 44% 6.28MB/s 0:00:11
62,095,360 46% 6.17MB/s 0:00:11
63,143,936 47% 4.20MB/s 0:00:16
64,192,512 48% 2.81MB/s 0:00:23
64,978,944 49% 1.29MB/s 0:00:50
66,289,664 50% 839.52kB/s 0:01:18
68,648,960 51% 1.07MB/s 0:00:58
108,888,064 82% 9.26MB/s 0:00:02
132,429,452 100% 8.32MB/s 0:00:15 (xfr#5, to-chk=6/133)
0 files...
100 files...
deleting svn/XXX_dump_20170217_202748_150.svn
deleting svn/CCC_dump_20170112_204550_269.svn
deleting svn/AAA_dump_20170216_202115_2703.svn
deleting svn/BBB_dump_20170219_200018_4552.svn
deleting svn/VVV_dump_20170125_200906_990.svn

Nachdem der neue Server damit auf dem neusten Stand ist, kann das Import Skript ausgeführt werden.

Import der Dumps

cd /tmp
nano restore-all-dumps.sh (Inhalte rein und speichern)
chmod +x restore-all-dumps.sh

Inhalt des Skripts:

#!/bin/bash
rm /tmp/dumps
find "/data/backups/svn" -type f | sort >> "/tmp/dumps"
COUNT=1
SVNROOT="/data/srv/svn-parent"

sed -i -e '1d' "/tmp/dumps" # Wegschneiden der ersten Zeile
NUMBEROFDUMPS=$(cat /tmp/dumps | wc -l)

while read p; do
#String ohne _dump...
NEW=$(echo $p | sed s/"_dump.*"/""/)
#anfang pfad abschneiden
REPO=${NEW:18}
echo "### $COUNT von $NUMBEROFDUMPS###"
#kompletter Pfad
echo "Backupfile: $p"
#Pfad ohne das Ende _dump...
#echo $NEW
#Pfad vorne abgeschnitten, also nur Name des Repos
echo "Repository: $REPO"

echo "Pruefe aktuelles Repository gegen den letzten Copy Job"
for fn in `cat /data/backups/copy-from-svn.log | grep "svn/" | grep -v "deleting"`; do
        if [[ $fn == *"svn/$REPO"* ]]; then
                echo "* Aktuelles Repository in der Liste gefunden!"
                echo "* String im Log:        $fn"
                echo "* Passendes Repository: $REPO"
                echo "* Repository muss neu erstellt werden, loesche die alte Version"
                rm -R $SVNROOT/$REPO
                if [ ! -d "$SVNROOT/$REPO" ]; then
                        echo "* Alte Version geloescht"
                fi
        fi
done

if [ -d "$SVNROOT/$REPO" ]; then
        echo "Der Pfad zum aktuellen Repository besteht. Es gibt keine neuere Version."
fi

#Wenn Pfad vom Repo nicht vorhanden, dann direkt erstellen
if [ ! -d "$SVNROOT/$REPO" ]; then
        echo "Repository noch nicht vorhanden, starte Import"
        svnadmin create $SVNROOT/$REPO
        chown www-data:www-data -R $SVNROOT/$REPO
        gunzip -c  $p | svnadmin load $SVNROOT/$REPO > restore_log.log
        cp $SVNROOT/pre-commit_ $SVNROOT/$REPO/hooks/pre-commit
        chmod +x $SVNROOT/$REPO/hooks/pre-commit
        chown www-data:www-data -R $SVNROOT/$REPO
fi

((COUNT++))
done < /tmp/dumps
echo "Durchlauf abgeschlossen"

Was passiert hier?

  • Zeile 2-3: Die alte Datei, die die Auflistung der Dumps enthält wird gelöscht und anschließend wird sie neu erstellt (Liste aller Dateien, die im Verzeichnis gefunden wurden)
  • Zeile 6: Die erste Zeile der Datei wird entfernt, da dort das Verzeichnis an sich aufgeführt wird, was allerdings kein Repository wiederspiegelt.
  • Zeile 8-53: Loop über die erstellte Datei
  • Zeile 9-19: Bearbeiten der Zeilenrückgaben, die den Pfad und Namen des Dumps beinhalten, sodass am Ende nur der Name des Repositories erreicht wird
  • Zeile 21-34: Das aktuelle Repository $REPO wird mit den Inhalten des RSYNC Logs abgeglichen, wenn ein Repository vorhanden ist, welches allerdings einen neuen Dump besitzt, wird es gelöscht.
  • Zeile 40-50: Wenn das Verzeichnis des aktuellen Repositories nicht vorhanden ist, wird der Dump importiert.

So werden bestehende Repositories übersprungen, neue angelegt und aktualisierte Dumps, die auf dem alten Server in neuer Version vorliegen und kopiert wurden, neu angelegt, damit der Stand nach dem Durchlauf auf beiden Systemen gleich ist.

Seit den neusten SVN Versionen muss der Apache Dienst nach einem Dump-Import neu gestartet werden, da es sonst zu diversen Fehlern im Repository kommt.
Diese könnten sein:

  • Corrupt node-revision
  • Corrupt representation
  • svnadmin: E160004: r1516’s root node’s predecessor is r1514 but should be r1515
  • filesystem corrupt

service apache2 restart

Nach dem Ausführen des Skripts sieht es in etwa so aus:

bzw.

Jira Umstellung auf SSL unter Linux

Um Jira auf SSL umzustellen, benötigt man im Grunde nur ein valides SSL Zertifikat und muss eine Anpassung in der server.xml vornehmen.

Die nachfolgende Durchführung ist Linux bezogen.

Die Jira-Pfade lauten:

  • Java Home: /opt/atlassian/jira/jre/bin/keytool
  • Jira Home: /var/atlassian/application-data/jira
  • Jira Install: /opt/atlassian/jira/

Erstellen des SSL Zertifikat (selbst signiert)

Jira speichert die Zertifikate im eigenen Java Keystore.

/opt/atlassian/jira/jre/bin/keytool -genkey -alias jira -keyalg RSA -keystore /var/atlassian/application-data/jira/jira.jks

Hier wird anschließend das Passwort des Zertifikatsspeichers hinterlegt sowie die Informationen, welche im Zertifikat hinterlegt sein sollen.

Wer sein Zertifikat von einer CA signieren lassen will, findet hier weitere Infos.

Anschließend kann man verifizieren, dass das Zertifikat vorliegt:

/opt/atlassian/jira/jre/bin/keytool -list -alias jira -keystore /var/atlassian/application-data/jira/jira.jks

Der Eintrag sollen einen “PrivateKeyEntry” beinhalten.

jira, 17.02.2017, PrivateKeyEntry,
Zertifikat-Fingerprint (SHA1): FF:09:6F:4D:CA:B4:2D:D3:EF:F8:D9:CC:51:AA:66:F8:22:B9:97:CA

Tomcat Anpassungen (server.xml)

Die Konfiguration des Tomcat Webservers befindet sich in folgender Datei: <JIRA_INSTALL>/conf/server.xml

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
maxHttpHeaderSize="8192" SSLEnabled="true"
maxThreads="150" minSpareThreads="25"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" useBodyEncodingForURI="true"
keyAlias="jira" keystoreFile="<JIRA_HOME>/jira.jks" keystorePass="changeit" keystoreType="JKS"/>

Anschließend kann Jira neu gestartet werden und die sichere Verbindung unter https://jira.domain.whatever:8443 abgerufen werden.

Anpassungen des ReverseProxys

Da Jira unter Linux nicht auf den bekannten http-Ports 80 und 443 laufen kann, wird im Normalfall ein Proxy vorgeschaltet.

Dieser muss für die neue Konfiguration angepasst werden:

<VirtualHost *:80>
ServerName jira.domain.de
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
</VirtualHost>
<VirtualHost *:443>
ServerName jira.domain.de

ErrorDocument 502 /502/index.html
ErrorDocument 503 /503/index.html

SSLEngine On
SSLProxyEngine On
SSLCertificateFile /etc/myssl/cert.pem
SSLCertificateKeyFile /etc/myssl/cert.key
SSLCertificateChainFile /etc/myssl/intermediate.crt

ProxyPreserveHost on
ProxyPass /503 !
ProxyPass /502 !
<Location />
Deny from all
Allow from 172.30
ProxyPass https://172.30.18.51:8443/
ProxyPassReverse https://172.30.18.51:8443/
</Location>
<Location /servicedesk>
ProxyPass https://172.30.18.51:8443/servicedesk
ProxyPassReverse https://172.30.18.51:8443/servicedesk
</Location>
</VirtualHost>

Die HTTP-Verbindungen werden mit o.g. Konfiguration auf HTTPS umgeleitet, sodass kein direkter, unverschlüsselter Zugriff mehr möglich ist. Ebenfalls werden eigene Error-Dokumente für die Fehler 502 und 503 hinterlegt, welche direkt auf dem Proxy liegen und daher nicht umgeleitet werden sollen. In meinem Fall wird der Zugriff auf die Haupt-Jira-Instanz nur aus einem bestimmten IP-Subnet zugelassen. Die Servicedesk-Seiten sollen allerdings von überall aus erreichbar sein.

Apache Dienst neustarten und fertig.

Powershellverbindung mit Exchange Online / Office365

Die neben der GUI weitaus mächtigere Möglichkeit seinen Exchange zu administrieren bietet die Powershell. Die aus lokalen Exchange Installationen bekannte Powershell Remote Session funktioniert ebenfalls für Office365 Exchange Umgebungen.

Zunächst hinterlegt man seine Anmeldeinformationen,

$UserCredential = Get-Credential

um anschließend eine Session mit Exchange Online herzustellen:

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection

Mit

Import-PSSession $Session

wird die Session gestartet und mit

Remove-PSSession $Session

wieder beendet.

Die ab jetzt verfügbaren Cmdlets werden temporär zwischengespeichert:

Über den Befehl

Get-Command | ? {$_.source -eq "NAME"}

lassen sich alle neuen Funktionen anzeigen (wobei “NAME” in dem Fall für  “tmp_4e4tlvte.bjc” steht.

Vagrant Windows 7/10 Base Box erstellen

Vagrant ist eine freie- und Open-Source Ruby-Anwendung zum Erstellen und Verwalten von virtuellen Maschinen. Vagrant ermöglicht einfaches Deployment insbesondere in der Software- und Webentwicklung und dient als Wrapper zwischen Virtualisierungssoftware wie VirtualBox, VMware und Hyper-V und Software-Configuration-Management-Anwendungen beziehungsweise Systemkonfigurationswerkzeugen wie Chef, Saltstack und Puppet.

Wikipedia

Was ist das Ziel?

Es soll eine Windows 7 VM aus einer Vorlage erstellt werden, auf der in diesem Fall die Software LabVIEW (es geht auch jede andere Software) automatisch installiert werden soll.

Was benötigt man dazu?

Will man die Maschine längerfristig nutzen, braucht man selbstverständlich einen Lizenzschlüssel.

Erstellen der Vagrant Box

Der Erstellvorgang einer Box besteht aus 4 Schritten:

  1. Virtuelle Maschine erstellen
  2. Windows installieren
  3. Windows konfigurieren
  4. Box paketieren und exportieren mit Vagrant

1. Virtuelle Maschine erstellen

Man erstellt wie gewohnt eine VM. Werte wie Arbeitsspeicher und CPU sind frei wählbar, da sie später über die Vagrant Konfigurationsdatei angepasst werden kann. Am besten erstellt man die Base Box natürlich so schlank wie möglich, um viel Raum für Erweiterungen im späteren Verlauf zu lassen.

Diese Optionen in Virtual Box können durch die Konfigurationsdatei angepasst werden: Virtual Box Konfiguration

2. Windows installieren

Die VM wird gestartet und Windows installiert.

Vagrant wird sich später mit der Maschine verbinden müssen. Das passiert durch WinRM (Windows Remote Management). Dazu muss ein User existieren, über den der Zugriff realisiert wird. Standardmäßig nutz Vagrant den Benutzer “vagrant” mit dem Passwort “vagrant”. Sollte ein anderer Benutzer gewünscht sein, so muss er später in der Konfigurationsdatei angegeben werden. So oder so muss der Benutzer als Admin angelegt werden.

[fusion_tooltip title=”Info” class=”” id=”” placement=”top” trigger=”hover”]Man sollte bei der Netzwerkverbindung “privat” auswählen. Das öffentliche Profil bewirkt Probleme mit winrm in den nächsten Punkten.[/fusion_tooltip]

 

3. Windows konfigurieren

  • Virtual Box Tools installieren
  • UAC ausschalten in der Systemsteuerung oder via cmd:
    reg add HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionPoliciesSystem /v EnableLUA /d 0 /t REG_DWORD /f /reg:64
  • Konfigurieren und Einschalten des WinRM Dienstes durch eine cmd mit Adminrechten:
    winrm quickconfig -q
    winrm set winrm/config/winrs @{MaxMemoryPerShellMB="512"}
    winrm set winrm/config @{MaxTimeoutms="1800000"}
    winrm set winrm/config/service @{AllowUnencrypted="true"}
    winrm set winrm/config/service/auth @{Basic="true"}
    sc config WinRM start= auto
  • Powershell Executionpolicy minimieren:
    Set-ExecutionPolicy Unrestricted
  • RDP einschalten und zulassen: Systemsteuerung – System – Erweiterte Systemeinstellungen – Remote
  • Updates installieren
  • Festplatte säubern, damit die Boxgröße etwas reduziert werden kann
    C:WindowsSystem32cleanmgr.exe /d c:
    Mit dem Sysinternals Sdelete Tool kann der freie Platz genullt werden
    sdelete.exe -z c:

4. Box paketieren und exportieren mit Vagrant

Zunächst erstellt man ein neues Verzeichnis und initialisiert es:

vagrant init

Das erstellte Vagrantfile wird dann an die Ansprüche angepasst:


# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|

#Was ist die Basebox?
config.vm.box = "w7box"

#Vagrant mitteilen, dass es eine Windows Box ist und WinRM als Kontrollinstrument genutzt wird
config.vm.guest = :windows
config.vm.communicator = "winrm"
config.vm.boot_timeout = 600
config.vm.graceful_halt_timeout = 600

#Skripte, die nach Erstellen ausgeführt werden sollen
config.vm.provision :shell, path: "scripts/labview.cmd"

#Alternativer Benutzer für WinRM, wenn "vagrant" nicht genutzt werden soll
config.winrm.username = "admin"
config.winrm.password = "123456"

# Verbindung zu WinRM über Port 7889 und RDP via 7888
config.vm.network :forwarded_port, guest: 3389, host: 7888
config.vm.network :forwarded_port, guest: 5985, host: 7889, id: "winrm", auto_correct: true
config.vm.provider "virtualbox" do |vb|

#Name der VM in VB
vb.name = "Win7Std2"
end
end

Als nächstes wird die Base Box exportiert:

vagrant package --base VirtualBoxVMName --output "PfadzurBoxwindows.box" --vagrantfile "PfadzurVagrantfile"

  • VirtualBoxVMName: Wie heißt die VM in Virtual Box?
  • PfadzurBoxwindows.box: Wo soll die Box abgelegt werden?
  • PfadzurVagrantfile: Wo liegt die initiale Konfiguration von oben (kann auch weggelassen werden, dann wird die Konfiguration später angelegt)?
==> default: Clearing any previously set forwarded ports...
==> default: Exporting VM...
==> default: Compressing package to: PfadzurBoxwindows.box
==> default: Packaging additional file: Vagrantfile

Box benutzen

Damit die Box genutzt werden kann, muss sie zur Umgebung hinzugefügt werden:

vagrant box add PfadzurBoxwindows.box --name NameDerBox

Dabei wird die Box komplett auf die lokale Festplatte kopiert.

Entweder hat man die Umgebung vorher initialisiert und das Vagrantfile angegeben, dann kann man via

vagrant up

die VM erstellen lassen.

Sollte man mehrere Boxen haben oder das Vagrantfile nicht angegeben haben, so muss man mit

vagrant init NameDerBox

das Verzeichnis erstellen und ggf. das Vagrantfile dort abändern. Mit

vagrant up

wird dann auch diese VM erstellt.

In diesem Fall wurde noch ein Skript aufgerufen, was eine Software nachinstalliert hat.

Exchange Relay als Smarthost für Postfix

Um mich ein wenig mehr mit dem Thema Exchange auseinander zu setzen, habe ich bei Microsoft einen Exchange angemietet. Nach der Einrichtung ergibt sich allerdings folgendes Problem:

Der Exchange besitzt nur mich als einzigen Benutzer. Die bisher angelegten Konten auf meinem Postfix-Server können allerdings nicht einfach umgezogen werden bzw. sollen es auch nicht, da jedes weitere Konto eben Geld kostet. Daher soll der Exchange lediglich meine E-Mails verwalten und alle anderen Adressen sollen weiterhin über Postfix laufen.

Dazu muss aber zum Einen der Exchange wissen, dass er bestimmte Mails weiterleiten soll und zum Anderen muss Postfix seine Mails über den Exchange raus schicken.

1. Verwalten akzeptierter Domänen in Exchange Online

Zunächst definiert man im Exchange, die Domäne, die von ihm akzeptiert werden soll. Dabei gibt es zwei unterschiedliche Typen von akzeptierten Domänen: autorisierende und interne relayakzeptierte Domänen, die wie folgt definiert werden.

Autorisierend: Wenn man diese Option auswählt, werden E-Mails an E-Mail-Adressen zugestellt, die in Office 365 für Empfänger für diese Domäne aufgeführt sind. E-Mails für unbekannte Empfänger werden abgelehnt.

Internes Relay: Wenn man diese Option auswählt, bedeutet dies, dass sich Empfänger für diese Domäne in Office 365 oder auf dem eigenen E-Mail-Server befinden können. E-Mails werden an bekannte Empfänger in Office 365 zugestellt oder an den eigenen E-Mail-Server geleitet, wenn die Empfänger Office 365 unbekannt sind.

Der Exchange muss also als Relay fungieren und alle unbekannten Empfänger, die er nicht kennt, weiterleiten. Postfix ist dann die letzte Instanz und gibt einen NDR zurück, falls auch er das Postfach nicht kennt.

Anschließend müssen zwei Konnektoren erstellt werden, die die Mails weiterleiten und von Postfix als Relay empfangen können.

2. Wie funktionieren Office 365-Konnektoren mit meinem eigenen (lokalen) Server?

Um den Nachrichtenfluss in beide Richtungen zu ermöglichen, müssen Konnektoren eingerichtet werden.

Die nachstehende Abbildung zeigt, wie die Konnektoren mit dem eigenen E-Mail-Server funktionieren.

In diesem Beispiel sind John und Bob Mitarbeiter in Ihrem Unternehmen. John hat ein Postfach auf einem E-Mail-Server, den Sie verwalten, und Bob verfügt über ein Postfach in Office 365. John und Bob tauschen E-Mails mit Sun aus, einem Kunden mit einem Internet-E-Mail-Konto:

  • Zum Senden von E-Mails zwischen John und Bob sind Connectors erforderlich.

  • Zum Senden von E-Mails zwischen John und Sun sind Connectors erforderlich. (Sämtliche Internet-E-Mails werden über Office 365 übermittelt.)

  • Zum Senden von E-Mails zwischen Bob und Sun ist kein Connector erforderlich.

Quelle: Microsoft

3. Einrichten eines Konnektors von Office 365 zum E-Mail-Server

Unter “Nachrichtenfluss – Connectors” können die Konnektoren angelegt werden.

Anschließend kann der MX Record auf die Office365 DNS Einstellungen geändert werden.

4. Einrichten eines Konnektors vom E-Mail-Server zu Office 365

Es wird ein weiterer Konnektor angelegt:

Anschließend muss man Postfix so vorbereiten, dass er die ausgehenden Mails auch über Office365 als Relay verschickt.

Dazu genügt prinzipiell der Eintrag “relayhost” in der main.cf:

relayhost = [tjbraun.mail.protection.outlook.com]

Dienst neustarten und fertig.

Ab jetzt sollten alle ausgehenden Mails über das Relay verschickt werden und eingehende Mails landen beim Exchange und werden bei Bedarf weitergeleitet.

Problem beim Versand vom Mailserver

Das Problem ist nun allerdings, dass zwar externe Domains problemlos von Postfix angesprochen und erreicht werden können, allerdings wird eine Mail an das Exchange Konto immer lokal in Postfix zugestellt und nicht an den Exchange weitergeleitet. Ebenfalls können Mails an unbekannte Adressen der eigenen Domain nicht verschickt werden.

Das liegt daran, dass Postfix seine eigene Domain natürlich versucht lokal zuzustellen. Daher muss man ihm klar machen, dass manche Adressen nicht lokal vorhanden sind bzw. diese Mails so oder so über das Relay gehen, damit sie den Exchange überhaupt erreichen.

Dazu gibt es die Transport Lookup-Tabelle. In diese Lookup-Tabelle wird für jede Zieladresse (vollständige Emailadresse oder Domain) der sogenannte Next Hop eingetragen.

Die Tabelle kann z. B. so aussehen:

xyz@tj-braun.de smtp:[tjbraun.mail.protection.outlook.com]
abc@tj-braun.de smtp:[tjbraun.mail.protection.outlook.com]

Die Tabelle hat das Format: Adresse Transporttyp:Next Hop. Adresse kann sowohl eine vollständige Emailadresse als auch nur der Domainteil sein. Der Transporttyp ist beim Weitertransport an einen anderen Mailserver immer smtp. Der Next Hop ist der neue Zielhost. Für den Zielhost kann eine IP-Adresse, ein Hostname oder eine Domain eingetragen werden. Wird ein Host- oder Domainname eingetragen, dann wird auf diesen Namen eine MX-Abfrage durchgeführt. Soll keine MX-Abfrage durchgeführt werden, muß der Name in eckige Klammern gestellt werden. Generell bedeutet ein Eintrag in der Transport Lookup-Tabelle immer eine Art Ausnahme von dem normalen Zustellweg den Postfix sonst versuchen würde.

Würde hier die Domäne an sich angegeben werden, würden sich Postfix und Exchange die Mails bis in alle Ewigkeiten hin und her schieben. Daher werden fixe Adressen definiert, die der Exchange auch kennt und aufgrund der Domänen Regelung von vorhin auch nicht weiterleiten wird.

Nun muss noch die neue Lookup-Tabelle in Datenbanken umgewandelt werden:

postmap transport

Danach muß die main.cf noch geändert werden:

transport_maps = hash:/etc/postfix/transport

Und der Dienst neugestartet werden.

Ab jetzt werden Mails von Postfix an das Relay weitergeleitet, wenn die Adresse in der Transport Tabelle steht. Alle anderen werden lokal zugestellt.

Linux gdrive: Upload zu Google Drive über Command Line

Ich habe nach einer einfachen Möglichkeit gesucht, meine Dateien (in diesem Fall die Datenbank Backups) in meinem Google Drive zu sichern. Dazu müssen die Dateien aber von meinem Ubuntu Server via CLI in mein Drive geladen werden. Gdrive – kein offizielles Tool von Google – macht genau das.

Installation

Download der Linux Version von gdrive von GitHub.

wget https://docs.google.com/uc?id=0B3X9GlR6EmbnWksyTEtCM0VfaFE&export=download

Umbenennen der Datei.

mv uc?id=0B3X9GlR6EmbnWksyTEtCM0VfaFE gdrive

Ausführbar machen.

chmod +x gdrive

Und abschließend installieren.

install gdrive /usr/local/bin/gdrive

Verification Code hinterlegen

Damit der Google Drive Zugriff funktioniert, muss gdrive dafür berechtigt werden. Bei der ersten Ausführung eines gdrive Befehls wird nach dem Verification Code von Google gefragt.

Also einfach ein Auflisten der Dateien initiieren und den Anweisungen folgen. Der Link muss in den Browser kopiert werden, damit der Code generiert werden kann, welcher anschließend übergeben werden muss.

gdrive list

gdrive verification code

Die vollständige Befehlsübersicht gibt es hier.

Upload Ordner erstellen und ID bestimmen

Die hochgeladenen Dateien sollen in einen bestimmten Ordner hochgeladen werden. Gdrive benötigt dazu die ID dieses Ordners. Also wird in Google Drive händisch ein Ordner angelegt namens “DB Backups”. Um die ID dieses Ordners herauszufinden, kann danach gesucht werden.

gdrive list -q "name='DB Backups'"

gdrive search

Upload der Dateien mit gdrive

Dann kann initial die Datei hochgeladen werden.

gdrive upload backup.sql -p 0B8BrwyjZT63ISDdkOU4wNV85Vzg
Uploading backup.sql
Uploaded 0B8BrwyjZT63IcEJCc21jN3FfeGc at 27.5 KB/s, total 35.4 KB

Dabei definiert “-p” den Überordner des Dateiuploads. In dieses Verzeichnis wird die Datei hochgeladen.

Update von Dateien mit gdrive

Da Google Drive mit den IDs arbeitet und nicht mit Dateinamen, werden neu hochgeladene Dateien, die den gleichen Namen haben nicht überschrieben, sondern neu angelegt. Die Datei würde also mehrfach vorhanden sein. Dafür gibt es den “update” Befehl.

Nach dem initialen Upload hat man die IDs der jeweiligen Dateien und kann so das Update der Datei durchführen.

gdrive update 0B8BrwyjZT63INEZxT3RLMHgtcGc backup.sql
Uploading backup.sql
Updated 0B8BrwyjZT63INEZxT3RLMHgtcGc at 25.8 KB/s, total 35.4 KB

Dadurch wird eine neue Revision der Datei angelegt, die von Google 30 Tage lang vorgehalten wird.

Skript für das automatische Backup & den Upload mit gdrive

Mit folgendem Bash Skript werden die Datenbanken gesichert, hochgeladen und anschließend mit dem aktuellen Datum im Namen versehen. Dumps, die älter als 10 Tage sind, werden gelöscht.


#!/bin/bash
now=$(date +"%Y_%m_%d")
echo "Doing database backup with" $now "as date reference"
echo "Saving WordPress"
mysqldump wp -u root -p > /var/backups/wp.sql
echo "Saving Nextcloud"
mysqldump nc -u root -p > /var/backups/nc.sql
echo "Saving Piwik"
mysqldump piwik -u root -p > /var/backups/piwik.sql
echo "Saving Rainloop"
mysqldump rainloop -u root -p > /var/backups/rainloop.sql
echo "Saving Vmail"
mysqldump vmail -u root -p > /var/backups/vmail.sql
echo "Saving done"

echo "Upload to Drive"
gdrive update 0B8BrwyjZT63IT2V0Ymp2NEpCV28 /var/backups/wp.sql
gdrive update 0B8BrwyjZT63IaTRxemx6TTM0akk /var/backups/nc.sql
gdrive update 0B8BrwyjZT63ISUVhMFF1Nzk5R2M /var/backups/piwik.sql
gdrive update 0B8BrwyjZT63IMk5SWXpKclFZekk /var/backups/vmail.sql
gdrive update 0B8BrwyjZT63INGh3YUxYQ2Rkcmc /var/backups/rainloop.sql

echo "Moving dumps to name with timestamp"
mv /var/backups/wp.sql /var/backups/wp-$now.sql
mv /var/backups/nc.sql /var/backups/nc-$now.sql
mv /var/backups/piwik.sql /var/backups/piwik-$now.sql
mv /var/backups/rainloop.sql /var/backups/rainloop-$now.sql
mv /var/backups/vmail.sql /var/backups/vmail-$now.sql

echo "Deleting dumps older than 10 days"
find /var/backups/*.sql -mtime +10 -type f -delete -print
echo "done."

OpenVPN Server unter Ubuntu aufsetzen

Wie setzt man einen OpenVPN Server auf, um sich z.B. im öffentlichen WLAN abzusichern?

OpenVPN ist ein Programm zOpenVPN Logoum Aufbau eines Virtuellen Privaten Netzwerkes (VPN) über eine verschlüsselte TLS-Verbindung. Zur Verschlüsselung werden die Bibliotheken des Programmes OpenSSL benutzt. Es verwendet wahlweise UDP oder TCP zum Transport.

OpenVPN ist freie Software unter der GNU GPL und unterstützt die Betriebssysteme Linux, Solaris, OpenBSD, FreeBSD, NetBSD, Mac OS X, QNX, Windows 2000/XP/Vista/7/8, Android, iOS, Maemo und MeeGo sowie das Router-Linux OpenWRT, weiterhin stehen angepasste Implementierungen für eine Vielzahl von Linux-basierten Endgeräten, wie z. B. Settop-Boxen der Firma Dream Multimedia oder für Router der FRITZ!Box-Linie der Firma AVM zur Verfügung.

— Artikel in Wikipedia

Download des openvpn-install.sh Skripts

wget https://git.io/vpn -O openvpn-install.sh
--2016-12-21 10:24:08-- https://git.io/vpn
Resolving git.io (git.io)... 23.23.117.228, 107.21.206.81, 107.21.249.214, ...
Connecting to git.io (git.io)|23.23.117.228|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.github.com/Nyr/openvpn-install/master/openvpn-install.sh [following]
--2016-12-21 10:24:10-- https://raw.github.com/Nyr/openvpn-install/master/openvpn-install.sh
Resolving raw.github.com (raw.github.com)... 151.101.12.133
Connecting to raw.github.com (raw.github.com)|151.101.12.133|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://raw.githubusercontent.com/Nyr/openvpn-install/master/openvpn-install.sh [following]
--2016-12-21 10:24:11-- https://raw.githubusercontent.com/Nyr/openvpn-install/master/openvpn-install.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.12.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.12.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 13211 (13K) [text/plain]
Saving to: ‘openvpn-install.sh’
100%[======>] 13.211 --.-K/s in 0,01s
2016-12-21 10:24:11 (960 KB/s) - ‘openvpn-install.sh’ saved [13211/13211]

Nun wird das Skript ausführbar gemacht und ausgeführt.

chmod +x openvpn-install.sh
./openvpn-install.sh
Welcome to this quick OpenVPN "road warrior" installer
I need to ask you a few questions before starting the setup
You can leave the default options and just press enter if you are ok with them
First I need to know the IPv4 address of the network interface you want OpenVPN
listening to.
IP address: 1.2.3.4
What port do you want for OpenVPN?
Port: 1337
What DNS do you want to use with the VPN?
1) Current system resolvers
2) Google
3) OpenDNS
4) NTT
5) Hurricane Electric
6) Verisign
DNS [1-6]: 2
Finally, tell me your name for the client cert
Please, use one word only, no special characters
Client name: pixel
Okay, that was all I needed. We are ready to setup your OpenVPN server now
Press any key to continue...

Anschließend werden die Schlüssel generiert und der Serverdienst eingerichtet.

Um die VPN Verbindung bspw. über Android aufzubauen, können die kostenlosen Apps benutzt werden. Bspw. OpenVPN for Android

Zum Einrichten wird nur die Konfigurationsdatei (.ovpn) aus dem Userverzeichnis benötigt, die durch das Skript angelegt wurde.

OpenVPN unter Android
OpenVPN unter Android

Die aktuellen Verbindungen lassen sich der Status Logdatei unter /etc/openvpn/openvpn-status.log entnehmen:

OpenVPN CLIENT LIST
Updated,Wed Dec 21 10:32:24 2016
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
pixel,1.2.3.4:25655,774387,2387112,Wed Dec 21 10:30:23 2016
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
10.8.0.2,pixel,1.2.3.4:25655,Wed Dec 21 10:32:22 2016
GLOBAL STATS
Max bcast/mcast queue length,0

Nextcloud Undefined Function simplexml_load_file()

Um die neuste NC Version 11 nutzen zu können, muss mindestens PHP 5.6 installiert sein. Nach einem Upgrade der PHP Version von PHP 5.5 auf PHP 7.0 und dem teilweisen Upgrade auf Nextcloud 11 tritt folgender Fehler auf:

{"reqId":"0XX1AddR7FoxNPEzqO0d","remoteAddr":"","app":"PHP","message":"Error: Call to undefined function OC\App\simplexml_load_file() at /var/www/nextcloud/lib/private/App/InfoParser.php#61","level":3,"time":"2016-12-14T08:50:08+01:00","method":"GET","url":"/status.php","user":"--","version":"11.0.0.10"}
{"reqId":"6XpZ9rkTys2hBE9ffhYx","remoteAddr":"","app":"PHP","message":"Error: Call to undefined function OC\App\simplexml_load_file() at /var/www/nextcloud/lib/private/App/InfoParser.php#61","level":3,"time":"2016-12-14T08:50:40+01:00","method":"GET","url":"/status.php","user":"--","version":"11.0.0.10"}

Es fehlen nach dem PHP Upgrade noch weitere Module:
apt-get install php7.0-xml
apt-get install php7.0-zip
apt-get install php7.0-cURL
apt-get install php7.0-gd
service apache2 restart

Anschließend kann auch das Upgrade von Nextcloud durchlaufen:
su - www-data -s /bin/bash -c 'php /var/www/nextcloud/occ upgrade'

Upgrade php5.5 auf 7.0 unter Ubuntu

PHP in der aktuell installierten Version kann man sich via php -v anzeigen lassen.

Um ein Upgrade auf eine neue Version von PHP durchzuführen, kann man Ondřej Surý’s PPA nutzen. Er pflegt die PHP Pakete unter Debian. Die PPA installiert man wie folgt:

apt-get install software-properties-common
add-apt-repository ppa:ondrej/php
apt-get update
apt-get install php7.0

Nutzt man MySQL, muss dieses Paket ebenfalls auf die neue Version gebracht werden:

apt-get install php7.0-mysql

Webserver anpassen

Die alte PHP Version ist immer noch installiert. Um dem Apache mitzuteilen, dass er die neue Version nutzen soll, muss das alte PHP-Modul deaktiviert und das neue aktiviert werden:

a2dismod php5
a2enmod php7.0

Webserver neu starten und fertig.

service apache2 restart

Zum Testen kann man wieder php -v eingeben oder aber die info.php anlegen und sich die aktuellen Einstellungen anzeigen lassen:

<?php
phpinfo();
?>