http://neobiker.de/wiki/index.php?title=Spezial:Neue_Seiten&feed=atom&hideredirs=1&limit=50&offset=&namespace=0&username=&tagfilter=&size-mode=max&size=0
Neobikers Wiki - Neue Seiten [de]
2024-03-28T22:37:37Z
Aus Neobikers Wiki
MediaWiki 1.40.2
http://neobiker.de/wiki/Kopano_to_grommunio_HowTo
Kopano to grommunio HowTo
2024-01-02T12:19:07Z
<p>Neobiker: /* Mail Relay Server */</p>
<hr />
<div>= Installation auf Debian 12 =<br />
Eine fertige grommunio Appliance ist auf Basis von S.u.S.E. erstellt und steht u.a. als ISO download zur Verfügung. Da ich derzeit ausschliesslich Debian basierte Systeme verwende, bevorzuge ich eine grommunio Installation auf Debian 12 (bookworm).<br />
<br />
Im grommunio Forum findet sich ein Diskussionsthread für die [https://community.grommunio.com/d/447-debian-11-clean-install-script grommunio Installation auf Debian 12 durch ein Script]. Diese läuft auf einer neu erstellten VM auf Proxmox Server fehlerfrei durch. In einem LXC Container gab es Probleme, u.a. klemmte der POP3 Service.<br />
<br />
Im Anschluss an das Installationsskript habe ich noch folgendes Script unter '''Additions''' - ''Fix Grommunio Admin Live Status page'' ausgeführt, welches ebenfalls funktionierte und die entsprechende Seite im Web Interface reparierte.<br />
<br />
= Konfiguration =<br />
Kopano Core ist bei mir als Applikation auf meinem UCS File- und Mailserver installiert. Die Benutzerkonten und deren Konfiguration werden von UCS verwaltet und stehen per LDAP zur Verfügung.<br />
<br />
<pre># mein UCS-Kopano Server<br />
kopano_server=ucsmail<br />
echo "kopano_server=ucsmail" >> ~/.bashrc<br />
<br />
# ssh connections without prompts<br />
ssh-keygen<br />
ssh-copy-id $kopano_server<br />
<br />
# mount /var/lib/kopano/attachments per sshfs<br />
if [ -e /etc/debian_version ] then<br />
apt install sshfs screen<br />
else<br />
zypper in sshfs # (grommunio app/iso installation)<br />
fi<br />
mkdir -p /mnt/kopano_attachments<br />
sshfs $kopano_server:/var/lib/kopano/attachments /mnt/kopano_attachments<br />
</pre><br />
<br />
== Zertifikate ==<br />
Falls ein '''[https://help.univention.com/t/ssl-zertifikat-und-dns-alias/5780/7 Server Zertifikat von UCS]''' für den '''grommunio''' server erzeugt wurde kann das verwendet werden.<br />
<br />
Ich erstelle hier ein neues Zertifikat für den grommunio Server, der als DNS-Alternativen jeweils '''autodiscover''' (Outlook) und '''autoconfig''' (Android) Einträge für jede meiner Email Domains enthält. Damit erfolgt die Mail-Client Konfiguration automatisch, sofern der Rechner sich in einem '''lokalem''' Netzsegment befindet.<br />
<br />
Background:<br><br />
Meine Emails werden extern gehostet, ich importiere sie per Fetchmail. Daher bin ich nicht in der Lage diese Autodiscover/Autoconf Einträge im (externen) DNS meines Hosters zu erstellen. Die entsprechende '''lokale DNS Auflösung''' übernimmt mein '''Unbound DNS''' Server mittels '''Overwrite''' Einträgen, welche auf den grommunio Server verweisen. Daher müssen diese DNS Alias Namen in dessen Zertifikat vorhanden sein.<br />
<br />
<pre>ssh ucs # UCS Master!<br />
univention-certificate new -name grommunio.domain.de<br />
cd /etc/univention/ssl/grommunio.domain.de<br />
<br />
# add DNS Aliases<br />
vi openssl.cnf<br />
# subjectAltName = DNS:grommunio.domain.de, DNS:grommunio <br />
# add all your email domains autodiscover/autoconfig entries: DNS:autodiscover.email_domain.de, DNS:autoconfig.email_domain.de<br />
<br />
DEFAULT_CRL_DAYS="$(/usr/sbin/univention-config-registry get ssl/crl/validity)"<br />
DEFAULT_DAYS="$(/usr/sbin/univention-config-registry get ssl/default/days)"<br />
DEFAULT_MD="$(/usr/sbin/univention-config-registry get ssl/default/hashfunction)"<br />
DEFAULT_BITS="$(/usr/sbin/univention-config-registry get ssl/default/bits)"<br />
export DEFAULT_MD DEFAULT_BITS DEFAULT_CRL_DAYS DEFAULT_DAYS<br />
openssl req -new -config openssl.cnf -key private.key -out req.pem<br />
<br />
univention-certificate renew -name grommunio.domain.de -days $DEFAULT_DAYS<br />
</pre><br />
<br />
Damit funktioniert die Anmeldung am Webinterface auch per LDAP mit starttls, ansonsten nur LDAP ohne starttls oder halt mit SQL Accounts.<br />
<pre><br />
cd /etc/grommunio-common/ssl<br />
scp $kopano_server:/etc/univention/ssl/grommunio/cert.pem server-bundle.pem<br />
scp $kopano_server:/etc/univention/ssl/grommunio/private.key server.key<br />
chown gromox:gromox server*<br />
chmod 660 server*<br />
<br />
# Root CA<br />
if [ -e /etc/debian_version ] then<br />
scp $kopano_server:/etc/univention/ssl/ucsCA/CAcert.pem /usr/local/share/ca-certificates/my-custom-ca/<br />
else<br />
# SuSE appliance location<br />
scp $kopano_server:/etc/univention/ssl/ucsCA/CAcert.pem /etc/pki/trust/anchors/<br />
fi<br />
update-ca-certificates<br />
<br />
systemctl restart nginx<br />
<br />
# autodiscover Eintrag testen<br />
PASS='email_passwort' gromox-dscli -ve user@domainname<br />
</pre><br />
<br />
== LDAP ==<br />
Die LDAP Konfiguration kann mit dem UCS Template im Webinterface vorgenommen werden.<br />
Ich übernehme einige Kopano Werte:<br />
<pre><br />
ssh $kopano_server grep -e ^ldap_uri -e ^ldap_bind -e ^ldap_search_base -e ^ldap_user_search -e ^ldap_group_search /etc/kopano/ldap.cfg<br />
<br />
ldap_uri = ldap://ucsmail.domain.de:7389/<br />
ldap_bind_user = cn=ucsmail,cn=dc,cn=computers,dc=domain,dc=de<br />
ldap_bind_passwd = xxxxxxxxxxxxxx<br />
ldap_search_base = dc=domain,dc=de<br />
ldap_user_search_filter = (kopanoAccount=1)<br />
ldap_group_search_filter = (&(kopanoAccount=1)(objectClass=kopano-group))<br />
<br />
# configure LDAP accordingly<br />
grommunio-admin ldap configure<br />
<br />
# test: list users<br />
grommunio-admin ldap search<br />
ID Type E-Mail Name<br />
2222222222-11-10111-22222-3333333333 user user@domainname User Name<br />
</pre><br />
<br />
== Email Domains und User ==<br />
Debian: das Anlegen einer Domain im Web-Interface schlägt direkt fehl - "Bad Request".<br><br />
Nicht schlimm, aber vielleicht nehme ich doch lieber die fertige Appliance auf Basis von S.u.S.E. ?<br />
<br />
Per Kommandozeile funktioniert es jedenfalls.<br />
<pre><br />
domains=$(ssh $kopano_server ucr get mail/hosteddomains)<br />
users=$(grommunio-admin ldap search)<br />
<br />
# create email domains<br />
for domain in $domains; do<br />
u_cnt=$(echo "$users" | grep -c $domain)<br />
[ $u_cnt -gt 0 ] && grommunio-admin domain create -u $u_cnt $domain<br />
done<br />
<br />
# import and sync LDAP users<br />
grommunio-admin ldap downsync -c<br />
</pre><br />
Der Import der User funktioniert jedenfalls auch über das Webinterface.<br />
<br />
=== Export - Import via Outlook .pst ===<br />
Da ich nur 5 Konten habe, ist diese Methode auch nicht ganz abwegig:<br />
<br />
<pre>gromox-pff2mt /tmp/neobiker_outlook.pst | gromox-mt2exm -u neobiker@neobiker.de<br />
</pre><br />
<br />
=== Import von Emails aus Kopano ===<br />
Der Import landet (leider) in einem separatem Verzeichnis:<br />
[[Datei:Grommunio Import.jpg|mini]]<br />
<br />
Das ist nicht ganz das was ich mir für einen Import vorstelle: Jeder User muss alle seine Inhalte manuell auf dem Server in die Hauptverzeichnisse verschieben ... ?<br />
<br />
Ansonsten hat der Import prinzipiell für mein Neobiker Postfach funktioniert.<br />
<br />
<pre># gromox-kdb2mt — Utility for analysis/import of Kopano mailboxes<br />
# gromox-mt2exm — Utility for importing various mail items<br />
<br />
mkdir -p /mnt/kopano_attachments<br />
sshfs $kopano_server:/var/lib/kopano/attachments /mnt/kopano_attachments<br />
<br />
# detach (CTRL-A d) the SSH tunnel to SQL server (who only accepts localhost conections)<br />
screen ssh -L 12345:localhost:3306 "root@${kopano_server}"<br />
<br />
# EXAMPLE for user neobiker = neobiker@neobiker.de<br />
# ------------------------------------------------<br />
# ENVIRONMENT variable is used for SQL password<br />
# either EXPORT it or write in one line with cmd<br />
export_mbox="gromox-kdb2mt --sql-host 127.0.0.1 --sql-port 12345 --src-attach /mnt/kopano_attachments"<br />
SQLPASS=$(ssh $kopano_server cat /etc/mysql.secret)<br />
<br />
SQLPASS=$SQLPASS $export_mbox --mbox-mro neobiker | gromox-mt2exm -u neobiker@neobiker.de<br />
<br />
kdb2mt: No ACLs will be extracted.<br />
kdb Server GUID: xxxxxxxxxxxxxxxxxxxxxxxxxxx<br />
Database schema is kdb-118<br />
Store GUID for MRO "neobiker": xxxxxxxxxxxxxxxxxxxxxxxxx<br />
Processing folder "" (7 elements)...<br />
Processing folder "IPM_SUBTREE" (19 elements)...<br />
Processing folder "Posteingang" (791 elements)...<br />
Processing folder "Postausgang" (0 elements)...<br />
Processing folder "Gelöschte Objekte" (1 elements)...<br />
Processing folder "Gesendete Objekte" (1 elements)...<br />
Processing folder "Kontakte" (0 elements)...<br />
Processing folder "Kalender" (1 elements)...<br />
Processing folder "Entwürfe" (0 elements)...<br />
Processing folder "Journal" (0 elements)...<br />
Processing folder "Notizen" (0 elements)...<br />
Processing folder "Aufgaben" (0 elements)...<br />
Processing folder "Junk E-Mail" (44 elements)...<br />
Processing folder "RSS Feeds" (0 elements)...<br />
Processing folder "Konversationseinstellungen" (0 elements)...<br />
Processing folder "Quickstep Einstellungen" (0 elements)...<br />
Processing folder "Vorgeschlagene Kontakte" (0 elements)...<br />
Processing folder "Spambox" (0 elements)...<br />
Processing folder "Junk-E-Mail" (0 elements)...<br />
Processing folder "Gelöschte Elemente" (0 elements)...<br />
Processing folder "Gesendete Elemente" (0 elements)...<br />
Processing folder "IPM_COMMON_VIEWS" (2 elements)...<br />
Processing folder "IPM_VIEWS" (0 elements)...<br />
Processing folder "FINDER_ROOT" (0 elements)...<br />
Processing folder "Verknüpfung" (0 elements)...<br />
Processing folder "Schedule" (0 elements)...<br />
Processing folder "Freebusy Data" (1 elements)...<br />
</pre><br />
<br />
=== Import aller Email Konten ===<br />
<br />
<pre><br />
export_mbox="gromox-kdb2mt --sql-host 127.0.0.1 --sql-port 12345 --src-attach /mnt/kopano_attachments"<br />
SQLPASS=$(ssh $kopano_server cat /etc/mysql.secret)<br />
<br />
# LOOP over all email accounts (except SYSTEM)<br />
# --------------------------------------------<br />
users=$(ssh $kopano_server kopano-admin -l | awk '{print $1}' | tail -n +4 | grep -v SYSTEM)<br />
<br />
for user in ${users}; do<br />
<br />
details=$(ssh $kopano_server kopano-admin --details $user)<br />
email=$(echo "${details}" $user | awk '/Emailaddress:/ {print $2}')<br />
guid=$(echo "${details}" $user | awk '/Store GUID:/ {print $3}')<br />
<br />
SQLPASS=$SQLPASS $export_mbox --mbox-guid $guid | gromox-mt2exm -u $email<br />
<br />
done<br />
<br />
# stop ssh tunnel -> exit ssh on kopano server<br />
screen -r<br />
<br />
# unmount kopano attachments<br />
umount /mnt/kopano_attachments<br />
</pre><br />
<br />
== Datenablage ==<br />
Eventuell möchte ich ein separates Filesystem für die Daten verwenden.<br><br />
Die Daten liegen unter ''/var/lib/mysql*'' und ''/var/lib/grom*'' ?<br />
<br />
<pre>grommunio:/var/lib # ls mysql* grom*<br />
grommunio-admin-api:<br />
auth-private.pem auth-public.pem<br />
<br />
grommunio-antispam:<br />
110ec84de81cc98813b71d34d42dedbc199bd687.map 65b4e39783c10c8ed89dbec4983259f22418f34d.map ea942f35f2c82e84bdb7b8ceb34537f7dbe986eb.map stats.ucl<br />
2368c73b937d98513ed72c4b04f4247bda43fdb5.map 877aa38dd77ed707d20b2f77d46b905b69a6295a.map f3933e67d5f9574a9eaf78cd0a8e99140ecc502e.map<br />
2e66b2415ec9b99aaa155761c211e51def12016e.map 8fe64ecd161a46f91a78ece93609cb863f9f42f2.map rspamd.rrd<br />
3b1eab0b21b32c970b8fae4a9010a539879368e3.map cb5a8189726ac3a8880e1c44ed6220c6d794521b.map rspamd.sock<br />
<br />
grommunio-dav:<br />
<br />
grommunio-files:<br />
apps-external config data sessions tmp<br />
<br />
grommunio-web:<br />
session sqlite-index tmp<br />
<br />
gromox:<br />
domain queue timer.txt user<br />
<br />
mysql:<br />
aria_log.00000001 ddl_recovery.log grommunio ib_buffer_pool ib_logfile0 multi-master.info mysql_upgrade_info sys<br />
aria_log_control grofiles grommunio.pid ibdata1 ibtmp1 mysql performance_schema test<br />
<br />
mysql-files:<br />
</pre><br />
<br />
== Postfix ==<br />
Mail Delivery Agent (MDA) Konfiguration <br />
* zum versenden von Emails (external relay host)<br />
* Mailaddress rewritings (neobiker@local -> neobiker@neobiker.de)<br />
<br />
Vergleich der wichtigsten Konfigurationsparameter<br />
<pre>grep -v ^# /etc/postfix/main.cf | grep [[:alnum:]] | sed -e 's/^\W+//g' | sort > postfix_config_sorted_grommunio<br />
ssh $kopano_server "grep -v ^# /etc/postfix/main.cf | grep [[:alnum:]] | sed -e 's/^\W+//g' | sort" > postfix_config_sorted_kopano<br />
<br />
diff -y postfix_config<br />
...<br />
<br />
# most relevant entries (differs/unconfigured)<br />
masquerade_domains = $mydomain<br />
content_filter = smtp-amavis:[127.0.0.1]:10024<br />
disable_vrfy_command = no<br />
mailbox_size_limit<br />
message_size_limit<br />
relay_domains = $mydestination<br />
relayhost = smtp.mailhoster.de<br />
smtpd_tls_auth_only = yes<br />
smtpd_tls_cert_file = /etc/univention/ssl/ucsmail...<br />
smtpd_use_tls = yes<br />
smtp_sasl_password_maps = hash:/etc/postfix/smtp_auth<br />
smtp_sasl_security_options = noanonymous<br />
<br />
</pre><br />
Vermutlich muss ich mich nur um den externen Relay Host kümmern.<br />
<br />
<br />
=== Mail Relay Server ===<br />
Postfix can use a mail relay server.<br />
<br />
<pre>ssh $kopano_server ucr get mail/relayhost</pre><br />
<br />
<pre># authentification on relay host<br />
# format: FQDN-Relayhost username:password<br />
ssh $kopano_server cat /etc/postfix/smtp_auth >> /etc/postfix/sasl_passwd<br />
<br />
vi /etc/postfix/main.cf<br />
relayhost = [smtp.provider.de]<br />
smtp_sasl_auth_enable = yes<br />
smtp_sasl_security_options = noanonymous<br />
smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd`<br />
smtp_use_tls = yes<br />
<br />
postmap /etc/postfix/sasl_passwd<br />
systemctl restart postfix<br />
</pre><br />
Das hat funktioniert:<br />
* Email nach EXTERN ging raus.<br />
* Email nach intern -> keine Postfix Aktion (nur intern innerhalb grommunio)<br />
<br />
Doku grommunio: [https://docs.grommunio.com/admin/administration.html#adding-a-file relayhost]<br />
<br />
Eine andere Info dazu [https://andersgood.de/kurz-notiert/smtp-relayhost-in-grommunio-konfigurieren hier].<br />
<br />
'''ACHTUNG''': Appliance (SuSE) -> Ich vermute stark, dass ein versehentliches ''config.postfix'' auf dem server die Konfiguration zerschiesst, da man das wohl in der Setupdatei /etc/sysconfig/postfix (SuSE) eintragen sollte.<br />
Umso unverständlicher, warum die Doku zu Relay Server bei grommunio so schwach ist.<br />
<br />
=== Mail Address rewritings ===<br />
<br />
Nix zu tun, denke ich.<br />
<br />
== Fetchmail ==<br />
Fetchmail Konfiguration zum abholen der Emails von meinem Email Provider.<br />
Emails werden entweder von UCS '''oder ''' grommunio abgeholt und and Postfix übergeben!<br />
<br />
Auf UCS für jeden Benutzer deaktivieren <br><br />
-> ''Advanced settings ‣ Remote mail retrieval (single)''<br><br />
oder Postfix auf UCS zur weiterleitung an grommunio konfigurieren.<br />
<br />
<pre>systemctl stop fetchmail<br />
systemctl disable fetchmail<br />
ucr set fetchmail/autostart=false<br />
<br />
# fetchmail config and passwords<br />
cat /etc/fetchmailrc<br />
</pre><br />
<br />
== Proxy Konfiguration (Nginx) ==<br />
Ich habe für jede Email Domain einen deSEC (DynDNS) Eintrag auf mein Internetgateway (Nginx auf OPNSense) erstellt.<br />
Dafür verwende ich ein Let's Encrypt Zertifikat, welches die Domains als DNS Alternate Names beinhaltet.<br />
Das Webinterface von grommunio ist unter ''/web'' erreichbar, während in der Übergangszeit Kopano unter ''/webapp'' erreichbar bleibt.<br />
Active Sync für Mobile Devices (URL ist identisch) kann damit immerhin pro Email Domain separat umgestellt werden. Outlook ist bei mir derzeit nur intern erreichbar, also extern nur über VPN (oder halt das Webinterface).</div>
Neobiker
http://neobiker.de/wiki/PVE_mit_ZFS_und_native_encryption
PVE mit ZFS und native encryption
2023-12-21T13:24:45Z
<p>Neobiker: /* key_zfs.conf */</p>
<hr />
<div>[https://proxmox.com/ Proxmox Virtual Environment] hat meinen alten XEN Server abgelöst.<br />
Die Festplattenvolumes für virtuelle Server und Daten werden wieder verschlüsselt.<br />
<br />
= Installation von PVE mit ZFS =<br />
Die Installation erfolgte mittels ISO Datei auf einem USB-Stick. Als Filesystem wählte ich ZFS mit RAID 1 auf zwei SSD mit Standard Parametern.<br />
<br />
== Lokale Anpassungen ==<br />
<br />
=== Repository PVE-No-Subscription und Warnung ===<br />
Das Update Repository No-Subscription hinzufügen:<br />
<pre>. /etc/os-release && echo "deb http://download.proxmox.com/debian/pve $VERSION_CODENAME pve-no-subscription" >> /etc/apt/sources.list<br />
</pre><br />
<br />
Deaktivierung der nervigen Warnung über eine fehlende Subscription:<br />
Über ''/etc/rc.local'' starte ich ein kleines script ''remove-proxmox-subscription-notice.sh'' - siehe Files Sektion.<br />
<br />
=== Encrypted ZFS Volume ===<br />
Ich habe ein Verzeichnis '/etc/cryptkey' angelegt, dass alle zur Verschlüsselung notwendigen Dateien aufnimmt:<br />
* keymanager_zfs.sh - Key Management Tool<br />
* keyscript.sh - Startscript (Bootprozess) <br />
* key_zfs.conf - Konfigurationsdetails<br />
* root - ZFS KEY (SSL verschlüsselt)<br />
<br />
<pre>root# ls -l /etc/cryptkey<br />
-rwxr-x--- 1 root root 9542 Dec 19 22:40 keymanager_zfs.sh<br />
-rwxr-x--- 1 root root 680 Dec 19 20:49 keyscript_zfs.sh<br />
-r-------- 1 root root 859 Dec 19 21:46 key_zfs.conf<br />
-r-------- 1 root root 130 Dec 19 20:49 root<br />
</pre><br />
<br />
Das Key Management Tool ''keymanagement.sh'' habe ich in einem Forum gefunden. Damit wird ein zufälliger 64-Byte KEY mit SSL verschlüsselt und mit einem (SSL-) Passwort versehen abgespeichert.<br />
<br />
Dieser ZFS KEY (''/etc/cryptkey/root'') kann nur mit dem SSL Passwort ausgelesen werden. Das Passwort wird aber nicht auf der Festplatte gespeichert, die das ZFS Volume beherbergt. Trotzdem soll der Bootvorgang das ZFS Volume mit diesem KEY ohne (manuelle!) Eingabe des Passworts entschlüsseln können - aber nicht müssen.<br />
<br />
Die '''Lösung''': Der KEY wird nicht nur im File ''root'' mittels SSL verschlüsselt gespeichert, sondern auch auf einem USB-Stick. Dabei kann ein anderes Passwort verwendet werden - muss aber nicht. Ich verwende für jeden USB-Stick ein individuelles Passwort, welches ich nirgends extra speichern möchte. Als Passwort verwende ich daher die ID des USB-Sticks: ''/dev/disk/by-id/<usb-stick-id>''<br />
Dieses steht auf dem Server automatisch zur Verfügung, ohne das es irgendwo gespeichert ist.<br />
Der Server kann also das verschlüsselte ZFS Volume mit dem auf dem Stick gespeicherten, SSL verschlüsseltem KEY entschlüsseln, indem er als Passwort die USB-Stick ID verwendet.<br />
<br />
Steckt der USB-Stick nicht im Server, wird der KEY aus dem File ''root'' ausgelesen, was allerdings eine manuelle Eingabe des Passwortes erfordert. Das wird im Bootvorgang also fehlschlagen, der Server bootet, ohne das verschlüsselte ZFS Volume zu mounten.<br />
<br />
Ein Aufruf des Startscriptes ''keyscript_zfs.sh'' liest in diesem Falle den ZFS KEY aus dem File ''/etc/cryptkey/root'' aus, fragt dabei das Passwort manuell ab, und bindet das Volume in einem solchen Fall nachträglich ein.<br />
<br />
=== ZFS KEY anlegen ===<br />
ZFS KEY erzeugen, mit SSL verschlüsseln und speichern. Default ist 64BYTE mit Filename = <userid> (also ''root''). <br />
<pre>root# cd /etc/cryptkey<br />
./keymanager_zfs.sh makekey </pre><br />
<br />
=== encrypted ZFS Volume anlegen ===<br />
Verschlüsseltes ZFS Volume ''rpool/encrypted_data'' mit KEY (Default ist Filename = <userid>, also root) anlegen.<br />
<pre>./keymanager_zfs.sh zfscreate -v rpool/encrypted_data<br />
</pre><br />
<br />
=== Unlock encrypted ZFS Pool ===<br />
Verschlüsseltes ZFS Volume rpool/encrypted_data mit KEY (Default ist Filename = <userid>, also root) einbinden.<br />
<pre>./keyscript_zfs.sh<br />
<br />
zfs get keystatus<br />
NAME PROPERTY VALUE SOURCE<br />
rpool keystatus - -<br />
rpool/ROOT keystatus - -<br />
rpool/ROOT/pve-1 keystatus - -<br />
rpool/data keystatus - -<br />
rpool/encrypted_data keystatus available -<br />
</pre><br />
<br />
=== Install ZFS-KEY on USB-Stick ===<br />
Konfiguration lesen, ZFS Key mit anderem Passwort erneut verschlüsselt abspeichern und auf USB-Stick schreiben.<br />
<br />
<pre>. ./key_zfs.conf<br />
./keymanager_zfs.sh useradd -q ${USB-STICK} -m /run/.cryptkey/${USB-STICK}<br />
dd if=/run/.cryptkey/${USB-STICK} of=/dev/disk/by-id/${USB-STICK} bs=${USB_BSIZE} count=${USB_COUNT} seek=${USB_SKIP}<br />
</pre><br />
<br />
=== ZFS Volume in PVE Storage einbinden ===<br />
<pre>pvesm add zfspool encrypted-zfs -pool rpool/encrypted_data</pre><br />
<br />
= Files =<br />
== /root ==<br />
=== remove-proxmox-subscription-notice.sh ===<br />
Das Script ''remove-proxmox-subscription-notice.sh'' sdeaktiviert die Subscription Warnung im Webinterface. Ich starte es über ''/etc/rc.local''.<br />
<pre>#!/bin/sh<br />
sed -Ezi.bak "s/(Ext.Msg.show\(\{\s+title: gettext\('No valid sub)/void\(\{ \/\/\1/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service<br />
</pre><br />
<br />
== /etc/rc.local ==<br />
Deaktiviere Subscription Warnung, aktiviere das encrypted ZFS Volume.<br />
<pre>#!/bin/sh -e<br />
# local init script<br />
<br />
# load ZFS encryption key on boot from USB Stick<br />
if [ -r /etc/cryptkey/key_zfs.conf ]; then<br />
/etc/cryptkey/keyscript_zfs.sh<br />
fi<br />
<br />
/root/remove-proxmox-subscription-notice.sh<br />
<br />
# evtl. Sleepmodus für HDD Festplatten aktivieren<br />
#[ -e /dev/sda ] && hdparm -Y -S 242 /dev/sda || true<br />
#[ -e /dev/sdb ] && hdparm -Y -S 242 /dev/sdb || true<br />
<br />
mount -a<br />
<br />
exit 0<br />
</pre><br />
<br />
== /etc/cryptkey ==<br />
<br />
=== key_zfs.conf ===<br />
Definition wo auf dem USB Stick der ZFS KEY gespeichert wird, und wie das ZFS Volume heisst:<br />
* ENC_ZFSVOL - verschlüsselte(s) ZFS Volume(s)<br />
* USB_STICK - USB Stick Name (ID)<br />
<br />
<pre># config file for ZFS encryption with multiple keyfiles<br />
#<br />
# concept: the keyfile for ZFS encryption is stored<br />
# on an USB Stick, encrypted with a fixed password (used for booting)<br />
# on filesystem, encrypted with a different password (not in any script)<br />
#<br />
# this gives the possibility to load the ZFS encryption key<br />
# - at boot without password prompt ==> if the USB_STICK is connected<br />
# - manually with a different(!) password ==> if the USB_STICK is defect<br />
<br />
# name of encrypted ZFS volume<br />
ENC_ZFSVOL="rpool/encrypted_data hddpool/encrypted_data"<br />
<br />
# name of USB Stick on /dev/disk/by-id<br />
USB_STICK=usb-Memorybird_P_100074AE3400109-0:0<br />
<br />
# where the encrypted password is stored on USB Stick (raw data before 1st partition)<br />
USB_SKIP=2560<br />
USB_COUNT=130<br />
USB_BSIZE=1<br />
USB_PASSWORD=$USB_STICK<br />
</pre><br />
<br />
=== keyscript.sh ===<br />
Startscript für den Bootvorgang, wird aus ''/etc/rc.local'' gestartet.<br />
<pre>#!/bin/bash<br />
<br />
CONFIG=/etc/cryptkey/key_zfs.conf<br />
SCRIPT=/etc/cryptkey/keymanager_zfs.sh<br />
ENC_KEY=/run/.cryptkey/usb_key_zfs.enc<br />
<br />
[ -r $CONFIG ] || exit 0<br />
. $CONFIG<br />
<br />
for ZFSVOL in $ENC_ZFSVOL; do<br />
if [ -e /dev/disk/by-id/$USB_STICK ]; then<br />
<br />
# extract encrypted key from usb stick<br />
mkdir -p $(dirname $ENC_KEY)<br />
chmod 400 $(dirname $ENC_KEY)<br />
dd if=/dev/disk/by-id/$USB_STICK of=$ENC_KEY bs=$USB_BSIZE count=$USB_COUNT skip=$USB_SKIP >/dev/null 2>&1<br />
chmod 400 $ENC_KEY<br />
<br />
$SCRIPT zfsload -s $(dirname $ENC_KEY) -n $(basename $ENC_KEY) -p "$USB_STICK" -v $ZFSVOL || \<br />
$SCRIPT zfsload -s $(dirname $CONFIG) -v $ZFSVOL<br />
else<br />
$SCRIPT zfsload -s $(dirname $CONFIG) -v $ZFSVOL<br />
fi<br />
done<br />
</pre><br />
<br />
=== keymanager_zfs.sh ===<br />
Das Key Management Tool habe ich in einem Forum gefunden: [https://forums.gentoo.org/viewtopic-t-1122263-start-0.html keymanager.sh]<br />
<pre>#!/bin/bash<br />
# zfs multiple passwords<br />
# found at: https://forums.gentoo.org/viewtopic-t-1122263-start-0.html<br />
#<br />
# keymanager.sh<br />
<br />
case $1 in<br />
"makekey")<br />
#default values<br />
keysize=64<br />
keyname=$USER<br />
[ ! -z $SUDOUSER ] && keyname=$SUDOUSER<br />
store=.<br />
cnt=1<br />
ls=1<br />
for a in "$@"<br />
do<br />
let cnt+=1<br />
case $a in<br />
-k | --keysize)<br />
keysize=${!cnt}<br />
ls=1<br />
;;<br />
-s | --keystore)<br />
store=${!cnt}<br />
ls=1<br />
;;<br />
-n | --keyname)<br />
keyname=${!cnt}<br />
ls=1<br />
;;<br />
-p | --password)<br />
pass=${!cnt}<br />
ls=1<br />
;;<br />
-*)<br />
echo $1: unknown argument $a<br />
exit 255<br />
;;<br />
*)<br />
# if we get here twice in a row, something is wrong<br />
[ $ls = 0 ] && echo $1: unknown argument $a && exit 254<br />
ls=0<br />
;;<br />
esac<br />
done<br />
mkdir -p $store<br />
key=`openssl rand -base64 $keysize |tr -d '\n='`<br />
[ $? != 0 ] && echo "Keygeneration failed" && exit 3<br />
key="KEY${key:0:$keysize}"<br />
[ -e ${store}/${keyname} ] && echo Key exists. I will not overwrite ${store}/${keyname} && exit 252<br />
if [ -z $pass ] ; then<br />
openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 <<< ${key} > ${store}/${keyname}<br />
else<br />
openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -pass pass:${pass} <<< ${key} > ${store}/${keyname}<br />
fi<br />
[ $? != 0 ] && echo "Encryption failed" && rm ${store}/${keyname} && exit 4<br />
chmod 600 ${store}/${keyname}<br />
;;<br />
"zfscreate")<br />
#default values<br />
keyname=$USER<br />
[ ! -z $SUDOUSER ] && keyname=$SUDOUSER<br />
store=.<br />
opt=""<br />
cnt=1<br />
ls=1<br />
for a in "$@"<br />
do<br />
let cnt+=1<br />
case $a in<br />
-s | --keystore)<br />
store=${!cnt}<br />
ls=1<br />
;;<br />
-n | --keyname)<br />
keyname=${!cnt}<br />
ls=1<br />
;;<br />
-p | --password)<br />
pass=${!cnt}<br />
ls=1<br />
;;<br />
-v | --volname)<br />
vol=${!cnt}<br />
ls=1<br />
;;<br />
-o)<br />
opt="$opt -o ${!cnt}"<br />
ls=1<br />
;;<br />
-*)<br />
echo $1: unknown argument $a<br />
exit 255<br />
;;<br />
*)<br />
# if we get here twice in a row, something is wrong<br />
[ $ls = 0 ] && echo $1: unknown argument $a && exit 254<br />
ls=0<br />
;;<br />
esac<br />
done<br />
[ -z $vol ] && echo $1 needs volumeName. Use -v volumename<br />
[ ! -r ${store}/${keyname} ] && echo Key not accessible ${store}/${keyname} && exit 123<br />
if [ -z $pass ] ; then<br />
key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d < ${store}/${keyname}`<br />
else<br />
key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d -pass pass:${pass} < ${store}/${keyname}`<br />
fi<br />
[ "KEY" != ${key:0:3} ] && echo Key decrypt failed && exit 10<br />
defopt=""<br />
[[ "$opt" != *"encryption="* ]] && defopt="$defopt -o encryption=on"<br />
[[ "$opt" != *"keyformat="* ]] && defopt="$defopt -o keyformat=passphrase"<br />
zfs create $defopt $opt $vol <<< $key<br />
<br />
;;<br />
"zfsload")<br />
#default values<br />
keyname=$USER<br />
[ ! -z $SUDOUSER ] && keyname=$SUDOUSER<br />
store=.<br />
opt=""<br />
cnt=1<br />
ls=1<br />
for a in "$@"<br />
do<br />
let cnt+=1<br />
case $a in<br />
-s | --keystore)<br />
store=${!cnt}<br />
ls=1<br />
;;<br />
-n | --keyname)<br />
keyname=${!cnt}<br />
ls=1<br />
;;<br />
-p | --password)<br />
pass=${!cnt}<br />
ls=1<br />
;;<br />
-v | --volname)<br />
vol=${!cnt}<br />
ls=1<br />
;;<br />
-*)<br />
echo $1: unknown argument $a<br />
exit 255<br />
;;<br />
*)<br />
# if we get here twice in a row, something is wrong<br />
[ $ls = 0 ] && echo $1: unknown argument $a && exit 254<br />
ls=0<br />
;;<br />
esac<br />
done<br />
[ -z $vol ] && echo $1 needs volumeName. Use -v volumename<br />
zfs get keystatus |grep $vol |grep " available" && echo Key already loaded, nothing to do && exit 0<br />
[ ! -r ${store}/${keyname} ] && echo Key not accessible ${store}/${keyname} && exit 123<br />
if [ -z $pass ] ; then<br />
key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d < ${store}/${keyname}`<br />
else<br />
key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d -pass pass:${pass} < ${store}/${keyname}`<br />
fi<br />
[ "KEY" != "${key:0:3}" ] && echo Key decrypt failed && exit 10<br />
zfs load-key $vol <<< $key<br />
;;<br />
"useradd")<br />
#default values<br />
keyname=$USER<br />
[ ! -z $SUDOUSER ] && keyname=$SUDOUSER<br />
newkeyname=$USER<br />
[ ! -z $SUDOUSER ] && newkeyname=$SUDOUSER<br />
store=.<br />
opt=""<br />
cnt=1<br />
ls=1<br />
for a in "$@"<br />
do<br />
let cnt+=1<br />
case $a in<br />
-s | --keystore)<br />
store=${!cnt}<br />
ls=1<br />
;;<br />
-n | --keyname)<br />
keyname=${!cnt}<br />
ls=1<br />
;;<br />
-p | --password)<br />
pass=${!cnt}<br />
ls=1<br />
;;<br />
-m | --newkeyname)<br />
newkeyname=${!cnt}<br />
ls=1<br />
;;<br />
-q | --newpass)<br />
newpass=${!cnt}<br />
ls=1<br />
;;<br />
-*)<br />
echo $1: unknown argument $a<br />
exit 255<br />
;;<br />
*)<br />
# if we get here twice in a row, something is wrong<br />
[ $ls = 0 ] && echo $1: unknown argument $a && exit 254<br />
ls=0<br />
;;<br />
esac<br />
done<br />
[ ! -r ${store}/${keyname} ] && echo Key not accessible ${store}/${keyname} && exit 123<br />
if [ -z $pass ] ; then<br />
echo Decrypting key<br />
key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d < ${store}/${keyname}`<br />
else<br />
key=`openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -d -pass pass:${pass} < ${store}/${keyname}`<br />
fi<br />
[ "KEY" != ${key:0:3} ] && echo Key decrypt failed && exit 10<br />
<br />
[ -e ${store}/${newkeyname} ] && echo New key exists. I will not overwrite ${store}/${newkeyname} && exit 252<br />
if [ -z $newpass ] ; then<br />
echo Encrypting key<br />
openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 <<< ${key} > ${store}/${newkeyname}<br />
else<br />
openssl enc -aes-256-cbc -a -pbkdf2 -iter 1000000 -pass pass:${newpass} <<< ${key} > ${store}/${newkeyname}<br />
fi<br />
chmod 600 ${store}/${newkeyname}<br />
;;<br />
*)<br />
iam=`basename $0`<br />
echo Usage:<br />
echo "$iam makekey [-k keySize] [-s keystoreFolder] [-n keyname] [-p password]"<br />
echo " Generates at random string (base_64 characters) of length keySize "<br />
echo " encrypts it by password, and stores the encrypted string in"<br />
echo " folder keystoreFolder."<br />
echo " If password is not given, it will be requested from stdin."<br />
echo " If no keyname is given, the current username will be used as keyname."<br />
echo " If no keystoreFolder is given, the current folder will be used."<br />
echo " If no keysize is given, default 64 will be used"<br />
echo<br />
echo "$iam zfscreate [-s keystoreFolder] [-n keyname] [-p password] -v volumename [-o zfsoption [-o ....]]"<br />
echo " Creates a zfs volume named volumename encrypted with key"<br />
echo " previously generated by makekey."<br />
echo " Default zfsoption are -o encryption=on -o keyformat=passphrase"<br />
echo " Additional zfsoptions may be specified."<br />
echo " Password is used to decrypt key. If password is not given, it "<br />
echo " will be requested from stdin."<br />
echo " If no keyname is given, the current username will be used as keyname."<br />
echo " If no keystoreFolder is given, the current folder will be used."<br />
echo<br />
echo "$iam zfsload [-s keystoreFolder] [-n keyname] [-p password] -v volumename"<br />
echo " Decrypts key previously generated by makekey and executes zfs load-key"<br />
echo " Password is used to decrypt key. If password is not given, it "<br />
echo " will be requested from stdin."<br />
echo " If no keyname is given, the current username will be used as keyname."<br />
echo " If no keystoreFolder is given, the current folder will be used."<br />
echo<br />
echo "$iam useradd [-s keystoreFolder] [-n keyname] [-p password] [-m newkeyname] [-q newpass] "<br />
echo " Makes a key previously generated by makekey available to anotheruser."<br />
echo " That is, decrypts the key saved under keyname using password, then"<br />
echo " saves it under newkeyname encryoted by using newpass"<br />
echo " Password is used to decrypt key. If password is not given, it "<br />
echo " will be requested from stdin."<br />
echo " Newpassw is used to encrypt key. If newpass is not given, it "<br />
echo " will be requested from stdin."<br />
echo " If no keyname is given, the current username will be used as keyname."<br />
echo " If no newkeyname is given, the current username will be used as keyname."<br />
echo " If no keystoreFolder is given, the current folder will be used."<br />
;;<br />
esac<br />
</pre></div>
Neobiker