Category Archives: Techdocs Diverses
Let’s encrypt
letsencrypt ist eine Zertifizierungsstelle, welche es erlaubt Zertifikate vollautomatisch und GRATIS zu generieren. Damit entfällt endlich die müsahme manuelle Erstellung von Zertifikaten. Und so geht es:
Ich installiere letsencrypt auf einem Ubuntu 16.04 System mit installiertem Apache:
-
- Letsencrypt installieren
sudo apt install letsencrypt python-letsencrypt-apache
- Zertifikat generieren
Bevors mit dem Zertifikate erstellen losgeht, muss ich zuerst den Apache-Dienst stoppen, weil letsencryp einen standalone Server auf port 80 verwendet:sudo service apache2 stop
Nun generiere ich das Zertifikat mit “certonly”. Damit modifiziert mir letsencrypt nicht das Apache-Config File. Dieses möchte ich selber modifizieren… Für jede Domain kann dieser Befehl wiederholt werden:
sudo letsencrypt certonly --agree-tos --email postmaster@yourdomain.ch -d www.yourdomain.ch
Und voilà:
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/nextcloud.domain.ch/fullchain.pem. Your cert will expire on 2017-01-23. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - Some rewrite rules copied from /etc/apache2/conf- enabled/nextcloud.conf were disabled in the vhost for your HTTPS site located at /etc/apache2/conf-enabled/nextcloud-le-ssl.conf because they have the potential to create redirection loops.
Nun den Apache wieder starten:
sudo service apache2 start
- Das Script erstellt vollautomatisch die benötigten Zertifikate und legt diese ab unter
/etc/letsencrypt/live/your.domain.zz/
Das Zertifikat kann nun am conf-File des Apachen eingetragen werden
SSLCertificateKeyFile /etc/letsencrypt/live/your.domain.zz/privkey.pem SSLCertificateFile /etc/letsencrypt/live/your.domain.zz/cert.pem SSLCertificateChainFile /etc/letsencrypt/live/your.domain.zz/chain.pem
Renewal
Letsencrypt stellt Zertifikate aus, welche 90 Tage gültig sind. Es wird empfohlen, dass alle 60 Tage ein renewal durchgeführt wird. Dies kann am einfachsten über einen cron-job erledigt werden, der monatlich ausgeführt wird:
sudo vi /etc/cron.monthly/letsencrypt-renew
#!/bin/bash echo "Stop Apache2 Service" service apache2 stop echo "Renew letsencrypt certificates" letsencrypt --standalone renew echo "Restart Apache2 Service" service apache2 start exit 0
sudo chmod +x /etc/cron.monthly/letsencrypt-renew
- Letsencrypt installieren
Löschen
Mal erstellte Zertifikate, welche nicht mehr benötigt werden, können gelöscht werden:
sudo letsencrypt delete -d xx.domain.xx
WordPress Container auf Docker
Dieser Blog-Eintrag beschreibt, wie man auf WordPress auf einem Docker-Host installieren und damit mehrere WordPress-Instanzen auf einem Host betreiben kann.
Ich betreibe die Docker-Container hinter einem Proxy-Server, der aber nicht als Container läuft. Der Proxy-Server leitet die HTTPS-Requests an die entsprechenden Docker-Container weiter.
Dieser Beitrag setzt ein vorinstalliertes Photon 3.0 inkl. Docker und Docker-Compose voraus. Siehe hier.
Die Docker-Container können über diverse Befehle gemanaged werden. Siehe dazu eine kleine Übersicht hier.
WordPress installieren
Wir installieren WordPress mit Hilfe von Docker Compose. Dazu erstellen wir ein template:
mkdir wordpress cd wordpress vi docker-compose.yml
Im yml-Script erstellen wir eine WordPress- inkl. DB-Instanz.
WordPress-Instanz
- Die WordPress-Instanz hat eine Abhängigkeit zur DB.
- Die WordPress-Files werden unter /var/www/html abgelegt
- der Host-Port 80 wird zur wordpress-Instanz port 80 weitergeleitet (“80:80”)
- Die DB ist über Port 3306 anzusprechen (WORDPRESS_DB_HOST: db:3306)
- Der DB-User ist wordpress (WORDPRESS_DB_USER: wordpress)
- Das DB-Passowort ist zu setzen: WORDPRESS_DB_PASSWORD: <wordpress_db_password>
DB-Instanz
- Die DB-Files werden hier abgelegt: db_data:/var/lib/mysql
- Passort setzen: MYSQL_ROOT_PASSWORD: <mysql root password>
- Datenbank definieren: MYSQL_DATABASE: wordpress
- User definieren: MYSQL_USER <wordpress>
- DB-Passwort setzen: MYSQL_PASSWORD: (wordpress db password)
version: '3.3' services: wordpress: depends_on: - db image: wordpress:latest volumes: - wordpress_files:/var/www/html ports: - "8080:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: (wordpress_db_password) db: image: mysql:5.7 command: '--default-authentication-plugin=mysql_native_password' volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: (mysql root password) MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: (wordpress db password) volumes: wordpress_files: db_data:
Die letzten beiden Linien restellen lokale Verzeichnisse auf dem Photon-Host. Hier werden die WordPress- und SQL-Files abgespeichert. Diese Files überleben somit, wenn der container zerstört und neu generiert wird.
Die Volumes werden unter
cd /var/lib/docker/volumes
erstellt und bleiben bestehen. Dies solange bis die Volumes mittels
docker-compose down -v
zerstört werden.
WordPress Container starten
Nun kann der Container einfach gestartet werden. Dank Docker Compose braucht man nur noch einen Befehl. Docker Compose erkennt automatisch das YAML im aktuellen Verzeichnis, durchläuft die Konfiguration und startet die Container-Anwendung:
docker-compose up -d
Den Prozess kann man anzeigen lassen
docker ps
Nun ist über http://<ip>:8080 auf die WordPress-Instanz zugegriffen werden.
WordPress Container mit SSL erweitern
Das so bereitgestellte Container-Image bietet WordPress “out-of-the-Box” über Port 80 an. Port 443 ist nicht aktiviert. Man geht dabei davon aus, dass die Verschlüsselung (https) eine zusätzliche, neue Funktion darstellt und damit über einen weiteren Container abzubilden ist. Dazu kann ein Proxy-Container aufgebaut werden, für den es auch bereits fertige Docker-Images gibt. Architektonisch mag das Sinn machen.
Ich möchte das aber nicht so umsetzen. Ich betreibe bereits einen Proxy-Server und dieser soll auch so weiter beibehalten werden. Ich verzichte also auf einen Proxy-Container und erweitere das WordPress-Image durch die SSL-Funktionalität. Damit das geht, muss ich das docker-compose.yml bzw. die WordPress-Container Beschreibung erweitern.
Als erstes erstelle ich ein zusätzliches File
vi wordpress/wp-init.sh
!/usr/bin/env bash apt-get update apt-get install -y --no-install-recommends ssl-cert rm -r /var/lib/apt/lists/* a2enmod ssl a2dissite 000-default.conf a2ensite apache2-vhosts.conf docker-entrypoint.sh apache2-foreground
Dieses Bash-Script soll bei jedem Starten des Containers ausgeführt werden. Mittels diesem Script wird
– SSL nachinstalliert
– Die Default Konfig “000-default.conf” auf dem Apachen entfernt und stattdessen
– eine neue Konfig “apache2-vhosts.conf” installiert.
– Anschliessend wird der Apache neu gestartet.
Damit das Script funktioniert braucht es noch eine Apache-Config. Diese Config wird in den WordPress-Container gemappt und beim Container-Start aktiviert. Damit kann ich von ausserhalb des Containers, die Apache-Config manipulieren:
vi wordpress/apache2-vhosts.conf
NameVirtualHost * <VirtualHost *:443> ServerName domain.ch DocumentRoot /var/www/html/ DirectoryIndex index.php Options -Indexes SSLEngine On SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key SSLCACertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem </VirtualHost>
Nun ist das das docker-compose.yml zu erweitern (siehe die markierten Erweiterungen):
version: '3.3' services: wordpress: depends_on: - db_node image: wordpress:latest volumes: - wordpress_files:/var/www/html - ./wp-init.sh:/usr/local/bin/apache2-custom.sh - ./apache2-vhosts.conf:/etc/apache2/sites-available/apache2-vhosts.conf ports: - "8080:80" - "8443:443" restart: always environment: WORDPRESS_DB_HOST: db_node:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: (wordpress db password) container_name: wordpress_web command: "bash -c apache2-custom.sh" db_node: image: mysql:5.7 command: '--default-authentication-plugin=mysql_native_password' volumes: - db_data:/var/lib/mysql ports: - 6601:3306 restart: always environment: MYSQL_ROOT_PASSWORD: (wordpress root password) MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: (wordpress db password) container_name: wordpress_db volumes: wordpress_files: db_data:
Wie man sieht wird
– das wp-init.sh Skript in den Container gemappt
– Die Apache-Config apache2-vhosts.conf in den Container gemappt.
– Der Container um den Port 8443 erweitert, der Container-Intern auf 443 routet und
– Das Commando “bash -c apache2-custom.sh” bei starten ausgeführt.
Damit startet der Container ab sofort mit aktiviertem SSL und der Apache-Container kann über das File apache2-vhosts.conf konfiguriert werden.
Reverse Proxy
Auf dem Reverse-Proxy wird nun einfach eine Reverse-Rule für den Container eingeführt. Der Reverse-Proxy leitet die HTTPS-Anfragen intern an den Container-Host mit Port 8443 weiter. Diese kann so aussehen:
<VirtualHost serverIp:80> ServerAdmin info@domain.ch ServerName www.domain.ch ServerAlias domain.ch RewriteEngine on ReWriteCond %{SERVER_PORT} !^443$ RewriteRule ^/(.*) https://www.domain.ch/$1 [NC,R,L] </VirtualHost> <VirtualHost serverIp:443> ServerAdmin info@domain.ch ServerName www.domain.ch #aktiviert SSL Unterstuetzung SSLEngine On SSLProxyEngine on SSLProxyVerify none SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off SSLCertificateKeyFile /etc/letsencrypt/live/www.domain.ch/privkey.pem SSLCertificateFile /etc/letsencrypt/live/www.domain.ch/cert.pem SSLCertificateChainFile /etc/letsencrypt/live/www.domain.ch/chain.pem # Regeln zum umleiten auf den internen Server ProxyPreserveHost On ProxyRequests Off ProxyPass / https://www.domain.ch:8443/ ProxyPassReverse / https://www.domain.ch:8443/ RequestHeader unset Accept-Encoding ErrorLog /var/log/apache2/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/log/apache2/access.log combined ServerSignature On </VirtualHost>
SMTP auf WordPress-Container
Ich betreibe einen eigenen Mailserver. Ich stellte rasch fest, dass WordPress keine Mails über diesen Server versenden kann. Dies, weil das WordPress-Image einerseits grundsätzlich keinen SMTP-Agent mit dabei hat und andererseits mein Mailserver auch nicht aus dem Container heraus erreichbar war:
- https://github.com/docker-library/php/issues/135
- https://github.com/docker-library/wordpress/issues/30
Um das Problem zu lösen habe ich mir einfach das Plugin “WP Mail SMTP” installiert. Dieses erweitert WordPress um die Mailfunktion. Das Connectivity-Problem konnte ich mit einer einfach Erweiterung von /etc/hosts lösen:
192.168.xx.xx mx.domain.ch
Man beachte, dass ich die interne IP des Mailservers verwende.
Damit diese Erweiterung auch bei einem neuen Create des Containers übernommen wird, muss wordpress/wp-init.sh noch modifiziert werden:
#!/usr/bin/env bash # modify /etc/hosts with mx.intelli.ch cat >> /etc/hosts <<-EOF /* mx.intelli.ch */ 192.168.xx.xx mx.domain.ch EOF apt-get update apt-get install -y --no-install-recommends ssl-cert # SSL rm -r /var/lib/apt/lists/* a2enmod ssl a2dissite 000-default.conf a2ensite apache2-vhosts.conf # finally execute default command docker-entrypoint.sh apache2-foreground
Links
Nextcloud Sync mit Ftp-Server
Hier habe ich beschrieben, wie man auf Nextcloud einen FTP-Server als externen Speicher konfigurieren kann. Mit einem kleinen Hack ist es damit möglich Files von einem FTP-Server auf Nextcloud zu “pushen”. Wirklich funktioniert hat das bei mir nicht zufriedenstellend. – Das wird so von Nextcloud/Owncloud auch nicht offiziell supported. Zeit für einen zweiten Anlauf, der nun seit einem knappen Jahr für mich zufriedenstellend funktioniert:
Der Use-Case ist immer noch derselbe:
- Mein Drucker kann auf einen FTP-Server scannen, nicht aber in ein Webdav Verzeichnis
- Ich möchte die gescannten Dokumente aber direkt in Nextcloud haben und mich nicht noch zusätzlich mühsam auf den FTP-Server connecten um die Dokumente abzuholen.
Meine Lösung:
- Ich betreibe einen eigenen FTP Server.
- Statt in Nextcloud diesen FTP Server als externen Speicher hinzuzufügen, mounte ich auf dem FTP-Server selber das Nextcloud-Verzeichnis mittels davfs2 (also mit WebDav):
- Dazu richte ich auf Nextcloud einen speziellen User (Scan) ein, der nur für das Scanning verwendet wird. Dieser Nextcloud-User hält das Verzeichnis in welches gescannt wird.
- Dieses Verzeichnis wird dann mit allen Nextcloud-Usern geteilt, welche über das “Scan-Feature” verfügen möchten (über Verzeichnis teilen).
- Auf dem FTP Server mounte ich das Nextcloud Scan-Verzeichnis des Users “Scan” mittels davfs und konfiguriere das Ziel-Scanverzeichnis des FTP Servers auf eben dieses Verzeichnis des Scan-Users. Damit verwende ich das offiziell von Nextcloud unterstützte WebDav Protokoll um vom FTP Server nach Nextcloud zu speichern.
Und los geht’s:
davfs2 installieren
Auf dem FTP-Server “webdav” installieren:
sudo apt-get install davfs2
Nextcloud Webdav als root mounten
Der mount kann folgendermassen durchgeführt werden:
sudo mount -t davfs https://nextcloud/remote.php/webdav/ /home/user/nextcloudScan/ -o uid=<userid>,gid=<groupid>,file_mode=775,dir_mode=775
Damit dies automatisch beim Systemstart passiert, trage ich dies in /etc/fstab ein. Bitte beachten, dass ich zusätzlich die Option “noauto” hinzufüge. Ein direktes mounten beim booten (auto) schlägt fehl, weil das Netzwerk zu diesem Zeitpunkt noch nicht aufgebaut ist. Das automatische mounten kommt später.
https://nextcloud/remote.php/webdav/ /home/user/nextcloudScan/ davfs noauto,uid=<userid>,gid=<groupid>,file_mode=775,dir_mode=775 0 0
Nun wird jeweils noch der Webdav-User inkl. Passwort abgefragt. Diese Infos kann man im file /etc/davfs2/secrets hinterlegen:
/home/user/nextcloudScan <nextcloudUser> <nextcloudPasswort>
Nun sollte ein mount automatisch funktionierten:
sudo mount /home/user/nextcloudScan
Der Trick liegt nun dabei, dass das der FTP-Server in das Verzeichnis nextcloudScan schreibt. Meinen FTP Drucker konfiguriere ich entsprechend. Damit schreibt der Drucker indirekt nach Nextcloud.
Automatisch beim booten mounten
Das file /etc/rc.local
wird nach dem booten ausgeführt. Hier hinterlege ich nun noch meinen mount-Befehl:
vi /etc/rc.local mount /home/user/nextcloudScan
…Voilà, jetzt werden alle Einträge in der fstab gemounted.
Alternative: Das lokale FTP-Verzeichnis mit rsync nach nextcloud synchen
Ansonsten könnte man auch das FTP-Verzeichnis auf dem FTP-Server mit rsync synchronisieren. Das ist aber mit obiger Lösung so nicht mehr nötig.
rsync -rutv --inplace scan/ nextcloudScan/
Referenzen
FTP-Scanning nach Nextcloud
Dieser Beitrag ist deprecated. Siehe hier für neue Lösung.
Ich habe zuhause einen schönen Drucker/Scanner stehen. Dieser Drucker/Scanner kann Dokumente einscannen und direkt an einen FTP-Server senden. Tolle Sache. Nun möchte ich aber, dass der Drucker direkt nach Owncloud scant. Owncloud selber hat keinen integrierten FTP-Server. Aber man kann in Owncloud einen FTP-Server als externen Speicher hinzufügen (siehe hier). Continue reading
Hot-Backup von ESXi VMs
Um Backups von ESXi VMs im laufenden Zustand machen zu können, braucht es
- Verständnis was VmWare unter einem Snapshot versteht
- Das Scipt ghettoVCB.sh => ghettoVCB
Exkurs VMWare-Snapshot
Bei einem VMware Snapshot wird eine weitere Festplattendatei erstellt welche ab Zeitpunkt des Snapshots alle geänderten Blöcke aufnimmt. Gleichzeitig wird der Exklusiv Zugriff auf die Basis Festplatte aufgehoben so das andere Prozesse lesen koennen.
Dieses “lesen” kann ein Kopierbefehl einens Backupprogramms sein. Da keine Schreibzugriffe mehr in die Datei erfolgen ist der Zustand also konsistent. Snapshots sind also keine Backups. Ein Snapshot “friert” lediglich einen Zustand ein (Basis Festplatte) und schreibt alle ab diesem Zeitpunkt anfallenden Änderungen in eine neue Snapshot Datei (Delta).
- Die Basisplatte und der bzw. die Snapshots zusammen ergeben den akt. Stand. Fehlt ein Element in der Kette ist kein vollstaendiges Restore mehr moeglich. Beides muss zur gleichen Zeiten fuer den HOST zugaenglich sein.
- Snapshots wachsen bis zur max. konfigurierten Festplattengroesse heran. Die Groesse des Datastores ist also zu ueberwachen.
- Beim löeschen von mehr als 2 Snapshots ist zu bedenken das ein Helper angelegt wird und immer die Groesse der zusammen zufuehrenden Snaps benoetigt wird.
- Laufende Snaps kosten ein wenig Performance. Die Gefahr von Fragmentierierung ignorieren wir da die Snaps immer in 16MB Bloecken wachsen.
- Grosse Snaps loeschen, hier versteht VMware das einpflegen der Aenderungen, dauert lange
Beispiel:
- Basisplatte
- Snapshot1
- Snapshot2
- Snapshot3
- Snapshotx
Löscht man jetzt Snapshotx wird dieser (und damit alle davorigen Snapshots) in die Basisplatte eingepflegt.
Löscht man Snapshot2 wird dessen Zustand und der von Snapshot1 in die Basisplatte eingepflegt und Snapshot3 usw. werden zu Snapshot1 usw,
Die .VMDK-Files (Virtuell Maschine Disk Files) können im laufenden Betrieb nicht kopiert oder verschoben werden, da sie ja in Gebrauch sind. Dies sieht aber nach einem Snapshot anders aus. Bei einem Snapshot werden die .VMDK-Files im Prinzip gekappt und neue Files (VMSN und VMSD) angelegt, in welche die kompletten Änderungen des Snapshots geschrieben werden. Wenn man ein Snapshot der VM macht, wird die Basis-Festplatte in den Read-Only Modus gesetzt, wordurch diese nun, da konsisten, kopiert werden kann. Das Verhalten von Snapshots kann also ausgenutzt werden um Backups im laufenden System erstellen zu können (Hilfsmittel zum Backup):
Komplettbackup 1
- Das Konfigurations-File der VM sichern/kopieren (VMX-File)-> nach dem Snaphsot der vituellen Maschine ändern sich die Verweise in der Konfiguration.
- Man erstellt einen ersten Snapshot einer VM. Es bestehen anonsten keine Snapshots dieser VM. Der Snapshot wird also gemacht, und die Basis-Festplatte kopiert. Anschliessend den Snapshot wieder loeschen. Dieses Vorgehen benötigt entsprechend viel Platz, wenn mehrere Backups der gleichen VM notwendig sind.
Komplettbackup 2
- Man macht täglich einen Snapshot und sicherst den Snapshot des Vortages. Bedeutet weniger Platz da quasi nur Aenderungen dann noch anfallen. Aber ein Restore erfordert Knowhow und dein ESX wird mehr belastet.
Soweit der Exkurs… Um ein Backup zu erstellen, können wir das mit den Snapshots manuell machen oder aber mit dem ghettoVCB-Script arbeiten. Das macht nämlich genau das oben beschriebene.
Installation von ghettoVCB
Die Installation ist simple. Einfach ein Verzeichnis auf dem ESXi-Datastore erstellen und die ghettoVCB-Scripts hineinkopieren. Das wird ganz schön auf Youtube gezeigt: http://www.youtube.com/watch?v=mVrjxzKEEu4
ghettoVCB konfigurieren und Backup durchführen
Die Konfigurationsmölgichkeiten findet man hier: http://communities.vmware.com/docs/DOC-8760
ghettoVCB.conf File
Ich habe mein ghettoVCB.conf File folgendermassen konfiguriert (ist eingentlich alles Standard):
VM_BACKUP_VOLUME=/vmfs/volumes/65d7a6db-6bc8d65a/VmBackups DISK_BACKUP_FORMAT=thin VM_BACKUP_ROTATION_COUNT=1 POWER_VM_DOWN_BEFORE_BACKUP=0 ENABLE_HARD_POWER_OFF=0 ITER_TO_WAIT_SHUTDOWN=3 POWER_DOWN_TIMEOUT=5 ENABLE_COMPRESSION=0 VM_SNAPSHOT_MEMORY=0 VM_SNAPSHOT_QUIESCE=0 SNAPSHOT_TIMEOUT=15
VMs zum Backup
Habe ein File “vms_to_backup” erstellt, welches eine Liste der Namen der VMs beinhaltet. Bei den Namen handelt es sich um die Namen, welche auch im vSphereClient angezeigt werden:
TestVM32Bit
Backup run
Nun kann die VM im laufenden Zustand gebackuped werden (Option -d dryrun führt einen Testlauf durch):
./ghettoVCB.sh -f vms_to_backup -g ./ghettoVCB.conf -d dryrun
Backup automatisch durchführen (Cron-Tab)
Um das Backup automatisch durchzuführen, kann dies in der Cron-Tab von ESXi konfiguriert werden:
In Crontab registrieren, Job soll jeden Donnerstag um 17:00 Uhr durchgeführt werden
echo "0 17 * * 4 /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/ghettoVCB.sh -f /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/vms_to_backup -g /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/ghettoVCB.conf > /tmp/ghettoVCB.log" >> /var/spool/cron/crontabs/root
Wenn man dies Ausführt, wird der crontab automatisch an die richtige Datei angehängt.
Nun muss crond neu gestartet werden:
ESXi 4.1
/bin/kill $(cat /var/run/crond.pid)
/bin/busybox crond
Die Cron-Tab von ESXi wird bei jedem Start wieder neu geschrieben. Um die Zeile deswegen bei jedem Start auszuführen, muss diese noch in die /etc/rc.local eingetragen werden. Meine rc.local sieht anschliessend so aus:
vi /etc/rc.local
#! /bin/ash export PATH=/sbin:/bin log() { echo "$1" logger init "$1" } #execute all service retgistered in /etc/rc.local.d if [ -d /etc/rc.local.d ]; then for filename in `find /etc/rc.local.d/ | sort` do if [ -f $filename ] && [ -x $filename ]; then log "running $filename" $filename fi done fi /bin/kill $(cat /var/run/crond.pid) /bin/echo "0 17 * * 4 /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/ghettoVCB.sh -f /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/vms_to_backup -g /vmfs/volumes/4a6bb65f-eb654b7b-2525-d8d385ab5bd2/ghettoVCB/ghettoVCB.conf > /tmp/ghettoVCB.log" >> /var/spool/cron/crontabs/root crond
ESXi 5.5
kill $(cat /var/run/crond.pid)
crond
Die Cron-Tab von ESXi wird bei jedem Start wieder neu geschrieben. Um die Zeile deswegen bei jedem Start auszuführen, muss diese noch in die /etc/rc.local eingetragen werden. Meine rc.local sieht anschliessend so aus:
vi /etc/rc.local.d/local.sh
#!/bin/sh # local configuration options # Note: modify at your own risk! If you do/use anything in this # script that is not part of a stable API (relying on files to be in # specific places, specific tools, specific output, etc) there is a # possibility you will end up with a broken system after patching or # upgrading. Changes are not supported unless under direction of # VMware support. /bin/kill $(cat /var/run/crond.pid) echo "0 17 * * 4 /vmfs/volumes/54016b12-54a601dc-1d3c-d43d7e942aae/ghettoVCB/ghettoVCB.sh -f /vmfs/volumes/54016b12-54a601dc-1d3c-d43d7e942aae/ghettoVCB/vms_to_backup -g /vmfs/volumes/54016b12-54a601dc-1d3c-d43d7e942aae/ghettoVCB/ghettoVCB.conf > /tmp/ghettoVCB.log" >> /var/spool/cron/crontabs/root crond exit 0
Nun nur noch autobackup durchführen, das ganze in der ESXi Konfuguration zu speichern:
/sbin/auto-backup.sh
Das wars! Jetzt werden die VMs automatisch regelmässig gesichert.
Restore durchführen
Um einen Restore druchzuführen, habe ich ein file vms_to_restore erstellt, wobei dieses pro Linie einen Restore-Parameter mit folgendem Format enthalten muss:
";;" # DISK_FORMATS # 1 = zeroedthick # 2 = 2gbsparse # 3 = thin # 4 = eagerzeroedthick
z.B.:
"/vmfs/volumes/QnapTSDatastore/VmBackups/TestVM32Bit/TestVM32Bit-2013-01-03_13-25-54;/vmfs/volumes/ESXi Raid1/TestVM;3"
Anschliessend kann das Restore folgendermassen gestartet werden (Option -d 2 = Dryrun):
./ghettoVCB-restore.sh -c vms_to_restore -d 2
Dies stellt das von ghettoVCB erstellte Backup “TestVM32Bit-2013-01-03_13-25-54” unter dem Pfad “/vmfs/volumes/ESXi Raid1/TestVM” her bzw. kopiert diese dahin und registriert die VM neu beim ESXi-Host.
Die Fileformate
zeroedthick (default)
vmdk wird in voller Groesse angelegt – dieser Typ wird bei der Erstellung nicht mit Nullen ueberschrieben – das passiert erst spaeter im Betrieb
eagerzeroedthick
vmdk wird in voller Groesse angelegt – dieser Typ wird bei der Erstellung mit Nullen ueberschrieben
thick
vmdk wird in voller Groesse angelegt – und nie genullt
thin
vmdk waechst nach Bedarf – dies ist ein Feature des VMFS dateisystems – und ist auf den meisten NFS-servern nicht moeglich
2gbsparsed
vmdk wird in maximal 2 Gb grosse Stuecke aufgeteilt – die jeweils nach Bedarf wachsen – dieses Format ist it Workstation kompatibel
JDBC-Verbindung über SSL auf Mysql-Server (Tomcat)
Hier wurde erklärt, wie man den MySQL-Server konfiguriert, so dass in MySQL-Client SSL Verbindungen zum Server aufbauen kann.
Nun möchte ich die SSL-Verbindung in einer Java-Applikation, welche in einem Tomcat läuft, verwenden. Dazu wird eine JDBC-Connection über SSL zum MySQL Server aufgebaut.
Die Server- und Client-Zertifikate wurden hier bereits erstellt.
Dieser Beitrag basiert auf Link
KeyStore
Tomcat-Applikationen müssen die Zertifikate in einem Keystore gespeichert halten.
Client Packet
Ein Paket mit client Zertifikat und client key erstellen
openssl pkcs12 -export -inkey client-key.pem -in client-cert.pem -out client.packet
MyKS.jks
Einen neuen KeyStore “MyKS.jks” erstellen, der das erstellte client paket und die CA Zertifikate enthält. Als Passwort wähle ich immer das gleiche.
sudo keytool -importkeystore -deststorepass password -destkeypass password -destkeystore myKS.jks -srckeystore client.packet -srcstoretype PKCS12 -srcstorepass password -alias tomcat
sudo keytool -importcert -alias mysqlCA -trustcacerts -file /root/ca-cert.pem -keystore myKS.jks
Nicht vergessen die Berechtigung adäquat anzupassen
chmod 440 myKS.jks
Tomcat konfigurieren
JAVA_OPTS
Keystore in Tomcat-Verzeichnis kopieren. SSL konfigurieren und den keystore anmelden. Hierzu ist auch die Angabe des oben genutzen Passwortes notwendig, so dass der Keystore gelesen werden kann. Diese Properties können z.B. in catalina.sh exportiert werden (export).
In Ubuntu 14.04 findet man das startup-File von Tomcat unter
/etc/default/tomcat7
export JAVA_OPTS="-Djavax.net.ssl.keyStore=/usr/local/etc/tomcat/certs/myKS.jks -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=/usr/local/etc/tomcat/certs/myKS.jks -Djavax.net.ssl.trustStorePassword=password"
oder als Java-Parameter:
-Djavax.net.ssl.keyStore=path_to_keystore_file -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=path_to_truststore_file -Djavax.net.ssl.trustStorePassword=password
oder man könnte dies auch in der Tomcat-Applikation als System-Properties definieren:
System.setProperty("javax.net.ssl.keyStore","path_to_keystore_file"); System.setProperty("javax.net.ssl.keyStorePassword","password"); System.setProperty("javax.net.ssl.trustStore","path_to_truststore_file"); System.setProperty("javax.net.ssl.trustStorePassword","password");
JDBC URL
Dann muss noch die Connection so angepasst werden, dass SSL verwendet wird (useSSL). Dies kann über einen connection-parameter gemacht werden.
Das kann entweder über die URL mit useSSL=true oder aber über die java.util.Properties (propertyuseSSL to true) Instanz, welche dem DriverManager.getConnection() mitgegeben wird, gemacht werden.
jdbc:mysql://mysql.server.com/database?verifyServerCertificate=false&useSSL=true&requireSSL=true
CHECK
Überprüfen ob die Verbindung auch wirklich verschlüsselt daher kommt:
sudo tcpdump -i any -vv -X src port 3306
Vorher
13:56:05.099198 IP (tos 0x8, ttl 64, id 6943, offset 0, flags [DF], proto TCP (6), length 63) localhost.mysql > localhost.50479: Flags [P.], cksum 0xfe33 (incorrect -> 0xab2d), seq 3174702966:3174702977, ack 903431479, win 800, options [nop,nop,TS val 2444442 ecr 2444442], length 11 0x0000: 4508 003f 1b1f 4000 4006 2190 7f00 0001 E..?..@.@.!..... 0x0010: 7f00 0001 0cea c52f bd3a 1f76 35d9 4537 ......./.:.v5.E7 0x0020: 8018 0320 fe33 0000 0101 080a 0025 4c9a .....3.......%L. 0x0030: 0025 4c9a 0700 0001 0000 0000 0000 00 .%L............ 13:56:05.100525 IP (tos 0x8, ttl 64, id 6944, offset 0, flags [DF], proto TCP (6), length 129) localhost.mysql > localhost.50479: Flags [P.], cksum 0xfe75 (incorrect -> 0xec2b), seq 11:88, ack 35, win 800, options [nop,nop,TS val 2444442 ecr 2444442], length 77 0x0000: 4508 0081 1b20 4000 4006 214d 7f00 0001 E.....@.@.!M.... 0x0010: 7f00 0001 0cea c52f bd3a 1f81 35d9 4559 ......./.:..5.EY 0x0020: 8018 0320 fe75 0000 0101 080a 0025 4c9a .....u.......%L. 0x0030: 0025 4c9a 0100 0001 012c 0000 0203 6465 .%L......,....de 0x0040: 6600 0000 1640 4073 6573 7369 6f6e 2e74 f....@@session.t 0x0050: 785f 7265 6164 5f6f 6e6c 7900 0c3f 0001 x_read_only..?.. 0x0060: 0000 0008 8000 0000 0005 0000 03fe 0000 ................ 0x0070: 0000 0200 0004 0130 0500 0005 fe00 0000 .......0........ 0x0080: 00 . 13:56:05.105052 IP (tos 0x8, ttl 64, id 6945, offset 0, flags [DF], proto TCP (6), length 1781) localhost.mysql > localhost.50479: Flags [P.], cksum 0x04ea (incorrect -> 0x7756), seq 88:1817, ack 143, win 800, options [nop,nop,TS val 2444443 ecr 2444442], length 1729 0x0000: 4508 06f5 1b21 4000 4006 1ad8 7f00 0001 E....!@.@....... 0x0010: 7f00 0001 0cea c52f bd3a 1fce 35d9 45c5 ......./.:..5.E. 0x0020: 8018 0320 04ea 0000 0101 080a 0025 4c9b .............%L. 0x0030: 0025 4c9a 0100 0001 0638 0000 0203 6465 .%L......8....de 0x0040: 6604 7076 7332 0d74 656d 705f 6361 7465 f.pvs2.temp_cate 0x0050: 676f 7279 0d74 656d 705f 6361 7465 676f gory.temp_catego 0x0060: 7279 0269 6402 6964 0c3f 000b 0000 0003 ry.id.id.?...... 0x0070: 0000 0000 003c 0000 0303 6465 6604 7076 .....<....def.pv 0x0080: 7332 0d74 656d 705f 6361 7465 676f 7279 s2.temp_category 0x0090: 0d74 656d 705f 6361 7465 676f 7279 046e .temp_category.n 0x00a0: 616d 6504 6e61 6d65 0c3f 00ff ffff fffc ame.name.?...... 0x00b0: 9000 0000 003c 0000 0403 6465 6604 7076 .....<....def.pv 0x00c0: 7332 0d74 656d 705f 6361 7465 676f 7279 s2.temp_category
Nachher
13:59:58.645194 IP (tos 0x8, ttl 64, id 60639, offset 0, flags [DF], proto TCP (6), length 52) localhost.mysql > localhost.50483: Flags [.], cksum 0xfe28 (incorrect -> 0xf2c8), seq 2669811453, ack 3878597006, win 851, options [nop,nop,TS val 2502828 ecr 2502828], length 0 0x0000: 4508 0034 ecdf 4000 4006 4fda 7f00 0001 E..4..@.@.O..... 0x0010: 7f00 0001 0cea c533 9f22 16fd e72e b18e .......3."...... 0x0020: 8010 0353 fe28 0000 0101 080a 0026 30ac ...S.(.......&0. 0x0030: 0026 30ac .&0. 13:59:58.645264 IP (tos 0x8, ttl 64, id 60640, offset 0, flags [DF], proto TCP (6), length 105) localhost.mysql > localhost.50483: Flags [P.], cksum 0xfe5d (incorrect -> 0xbe29), seq 0:53, ack 1, win 851, options [nop,nop,TS val 2502828 ecr 2502828], length 53 0x0000: 4508 0069 ece0 4000 4006 4fa4 7f00 0001 E..i..@.@.O..... 0x0010: 7f00 0001 0cea c533 9f22 16fd e72e b18e .......3."...... 0x0020: 8018 0353 fe5d 0000 0101 080a 0026 30ac ...S.].......&0. 0x0030: 0026 30ac 1703 0100 300c 3524 6529 b225 .&0.....0.5$e).% 0x0040: 01dd ed3f 7cb5 085f 3c80 4a51 c362 e980 ...?|.._<.JQ.b.. 0x0050: 1884 4e40 0d58 d0a3 69a1 b3c1 c979 b142 ..N@.X..i....y.B 0x0060: 09b6 3603 b43c 8a22 9d ..6..<.". 13:59:58.646125 IP (tos 0x8, ttl 64, id 60641, offset 0, flags [DF], proto TCP (6), length 52) localhost.mysql > localhost.50483: Flags [.], cksum 0xfe28 (incorrect -> 0xf227), seq 53, ack 107, win 851, options [nop,nop,TS val 2502829 ecr 2502829], length 0 0x0000: 4508 0034 ece1 4000 4006 4fd8 7f00 0001 E..4..@.@.O..... 0x0010: 7f00 0001 0cea c533 9f22 1732 e72e b1f8 .......3.".2.... 0x0020: 8010 0353 fe28 0000 0101 080a 0026 30ad ...S.(.......&0. 0x0030: 0026 30ad .&0. 13:59:58.646188 IP (tos 0x8, ttl 64, id 60642, offset 0, flags [DF], proto TCP (6), length 169) localhost.mysql > localhost.50483: Flags [P.], cksum 0xfe9d (incorrect -> 0x6a73), seq 53:170, ack 107, win 851, options [nop,nop,TS val 2502829 ecr 2502829], length 117 0x0000: 4508 00a9 ece2 4000 4006 4f62 7f00 0001 E.....@.@.Ob.... 0x0010: 7f00 0001 0cea c533 9f22 1732 e72e b1f8 .......3.".2.... 0x0020: 8018 0353 fe9d 0000 0101 080a 0026 30ad ...S.........&0. 0x0030: 0026 30ad 1703 0100 7074 359c b82a c838 .&0.....pt5..*.8 0x0040: 3a69 85b9 b43f 7648 5fe0 88c6 972c 576a :i...?vH_....,Wj 0x0050: 84ac c7ac 58f0 ed0c a79c 0c12 1c51 9714 ....X........Q.. 0x0060: 45d3 80ac 1fb6 fbbb 7665 9782 a61f cf0a E.......ve...... 0x0070: 0b19 1e4e a679 6d1d 3a7b db6d 02f7 2dba ...N.ym.:{.m..-. 0x0080: 4c0b 2cfb ad6f b516 2128 2596 9f5f 6ab2 L.,..o..!(%.._j. 0x0090: 640b 1876 2d52 1d4b ffcf 6a25 08d6 b985 d..v-R.K..j%.... 0x00a0: cdf0 cd62 cacc 84e1 9a ...b..... 13:59:58.646838 IP (tos 0x8, ttl 64, id 60643, offset 0, flags [DF], proto TCP (6), length 52) localhost.mysql > localhost.50483: Flags [.], cksum 0xfe28 (incorrect -> 0xf0f8), seq 170, ack 277, win 867, options [nop,nop,TS val 2502829 ecr 2502829], length 0 0x0000: 4508 0034 ece3 4000 4006 4fd6 7f00 0001 E..4..@.@.O.....
MySQL Verbindungen mit SSL verschlüsseln – Ubuntu 14.04 / 18.04 / Mysql 5.6.28
Hier wird erklärt, wie ein MySQL Client eine verschlüsselte Verbindung zu einem MySQL Server, der mit Ubuntu 14.04 und Mysql-Server 5.6.28 betrieben wird, aufgebaut werden kann.
SSL Zertifikate erstellen
Es werden Zertifikate mit 2048 Bits und einer Gültigkeit von 3650 Tagen erstellt. Nach diesem Zeitraum müssen die Zertifikate verlängert oder neu erstellt werden.
Bitte nicht vergessen, dass der Common Name (CN) vom Client und Server Zertifikat unterschiedlich ist. z.B. servername.intelli.ch und client.intelli.ch
cd /etc/mysql/
# Generate a CA key and certificate with SHA1 digest openssl genrsa 2048 > ca-key.pem openssl req -sha1 -new -x509 -nodes -days 3650 -key ca-key.pem > ca-cert.pem # Create server key and certficate with SHA1 digest, sign it and convert # the RSA key from PKCS #8 (OpenSSL 1.0 and newer) to the old PKCS #1 format openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem > server-req.pem openssl x509 -sha1 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem openssl rsa -in server-key.pem -out server-key.pem # Create client key and certificate with SHA digest, sign it and convert # the RSA key from PKCS #8 (OpenSSL 1.0 and newer) to the old PKCS #1 format openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem > client-req.pem openssl x509 -sha1 -req -in client-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem openssl rsa -in client-key.pem -out client-key.pem
chmod 400 /etc/mysql/*.pem chown mysql /etc/mysql/*.pem
SSL Konfiguration aktivieren
In der MySQL Konfiguration (/etc/mysql/my.cnf
) muss SSL mit den zugehörigen Zertifikaten aktiviert werden.
ssl-ca=/etc/mysql/ca-cert.pem ssl-cert=/etc/mysql/server-cert.pem ssl-key=/etc/mysql/server-key.pem
Nun MySql-Server neu starten
sudo service mysql restart
Es kann auf der DB überprüft werden, ob die Konfiguration richtig übernommen wurde:
mysql > show variables like '%ssl%'; +---------------+----------------------------------+ | Variable_name | Value | +---------------+----------------------------------+ | have_openssl | YES | | have_ssl | YES | | ssl_ca | /etc/mysql/ca-cert.pem | | ssl_capath | | | ssl_cert | /etc/mysql/server-cert.pem | | ssl_cipher | | | ssl_key | /etc/mysql/server-key.pem | +---------------+----------------------------------+
SSL Verschlüsselung für MySQL User aktivieren
Es gibt folgende Möglichkeiten bei der Rechtevergabe für Benutzer in Bezug auf SSL:
- REQUIRE X509: ein beliebiges gültiges SSL Client Zertifikat kann verwendet werden
- REQUIRE ISSUER / REQUIRE SUBJECT: ein beliebiges gültiges SSL Client Zertifikat reicht nicht aus, es muss von einer mit ISSUER spezifizierten CA kommen und/oder ein bestimmtes SUBJECT enthalten.
- REQUIRE SSL: die Verbindung muss über SSL verschlüsselt aufgebaut werden, die Authenfizierung kann sowohl via Passwort als auch über ein SSL Client Zertifikat erfolgen.
Im Folgenden Beispiel wird der User “ssluser” erstellt der alle Rechte (ALL PRIVILEGES) auf alle Datenbanken (*.*) am “localhost” hat und ein gültiges SSL Client Zertifikat vorweisen muss.
GRANT ALL PRIVILEGES ON *.* TO 'ssluser'@'localhost' IDENTIFIED BY 'topsecret' REQUIRE X509;
Client SSL erzwingen
grant all privileges on database.* to 'username'@'hostaddress' identified by 'password' require SSL; oder GRANT USAGE ON *.* TO 'ralph'@'%' REQUIRE SSL;
Verschlüsselte MySQL Verbindung testen
cd /etc/mysql/ mysql -u ssluser -p --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem
Hint: Auf Ubuntu 18.04 schlug dieser Befehl mit dem Feher “SSL connection error: SSL_CTX_set_default_verify_paths failed” fehl. Das liegt daran, weil der lokale User mit dem dieser mysql-Befehl ausgeführt wird, keine Berechtigung auf die Zertifikate hat. Um den Test trotzdem machen zu können, kann der Befehl mit sudo ausgeführt werden.
Die SSL Keys müssen wenn der Zugriff von einem entfernten Host aus erfolgen soll natürlich vorher dorthin kopiert werden.
Mittels dem Befehl SHOW STATUS LIKE 'Ssl_cipher';
kann sich der Verschlüsselungsstatus des verbundenen MySQL Clients angezeigt werden lassen.
mysql > SHOW STATUS LIKE 'Ssl_cipher'; +---------------+--------------------+ | Variable_name | Value | +---------------+--------------------+ | Ssl_cipher | DHE-RSA-AES256-SHA | +---------------+--------------------+ 1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'Ssl_version'; +---------------+---------+ | Variable_name | Value | +---------------+---------+ | Ssl_version | TLSv1.1 | +---------------+---------+ 1 row in set (0.01 sec)
Überprüfe alle Server-Connections
Es kann auch überprüft werden ob ALLE Verbindungen zum Mysql-Server auch wirklich mit SSL Connecten.
Mit folgendem Befehl kann überprüft werden ob und welche User mit SSL mit dem Mysql-Server kommunizieren:
SELECT sbt.variable_value AS tls_version, t2.variable_value AS cipher, processlist_user AS user, processlist_host AS host FROM performance_schema.status_by_thread AS sbt JOIN performance_schema.threads AS t ON t.thread_id = sbt.thread_id JOIN performance_schema.status_by_thread AS t2 ON t2.thread_id = t.thread_id WHERE sbt.variable_name = 'Ssl_version' and t2.variable_name = 'Ssl_cipher' ORDER BY tls_version;
Links
- Bei diesem Beitrag handelt es sich um eine Erweiterung des Beitrags von Christoph Mitasch. Siehe auch https://www.thomas-krenn.com/de/wiki/MySQL_Verbindungen_mit_SSL_verschl%C3%BCsseln
- https://www.howtoforge.com/tutorial/how-to-enable-ssl-and-remote-connections-for-mysql-on-centos-7/
- https://www.percona.com/blog/2016/02/23/mysql-connection-using-ssl-or-not/
Firefox Lesezeichen synchronisierung
Firefox Security
Plugins
Folgende Plugins sind für Firefox empfehlenswert um spurenarmer zu surfen:
- μBlock Origin (Empfehlung: Wie das Addon eingestellt werden sollte)
- NoScript
- Cookie Controller
- HTTPS-Everywhere
- Smart Referer
- CanvasBlocker
- Privacy Settings => dort »Full Privacy« aktivieren
Firefox about:config Anpassungen
Suchfeld rechts oben wieder anzeigen
browser.search.widget.inNavBar = true
Anzeige von Vorschlägen bei der Eingabe deaktivieren
browser.urlbar.suggest.searches = false browser.urlbar.suggest.openpage = false
Suchvorschläge deaktivieren
browser.urlbar.suggest.bookmark = false browser.urlbar.suggest.history = false
Unterbinden, dass Firefox nach Hause telefoniert um festzustellen aus welchem Land man stammt. Das benutzt Firefox um zu entscheiden, welche Suchmaschine standardmässig genutzt werden soll (USA = Yahoo und alle anderen mit Google)
browser.search.countryCode = CH browser.search.geoSpecificDefaults = false browser.search.geoip.url = "" (leerer String)