
In einem früheren Artikel wurde das Design der NAS-Softwareplattform beschrieben.
Es ist Zeit, es umzusetzen.
Überprüfen Sie
Überprüfen Sie vor dem Start unbedingt den Zustand des Pools:
zpool status -v
Der Pool und alle darin enthaltenen Festplatten müssen ONLINE sein.
Außerdem gehe ich davon aus, dass in der vorherigen Phase alles gemäß den Anweisungen durchgeführt wurde und es funktioniert, oder dass Sie selbst gut verstehen, was Sie tun.
Ausstattung
Zuallererst lohnt es sich, auf eine bequeme Verwaltung zu achten, wenn Sie dies nicht von Anfang an getan haben.
Es wird benötigt:
- SSH-Server:
apt-get install openssh-server
. Wenn Sie nicht wissen, wie Sie SSH konfigurieren, NAS unter Linux ist zu früh Sie können die Funktionen der Verwendung in diesem Artikel lesen und dann eines der Handbücher verwenden . - tmux oder screen :
apt-get install tmux
. So speichern Sie die Sitzung, wenn Sie sich über SSH anmelden und mehrere Fenster verwenden.
Nach der Installation von SSH müssen Sie einen Benutzer hinzufügen, um sich nicht über SSH als root anzumelden (die Eingabe ist standardmäßig deaktiviert und muss nicht aktiviert werden):
zfs create rpool/home/user adduser user cp -a /etc/skel/.[!.]* /home/user chown -R user:user /home/user
Für die Fernverwaltung ist dies ein ausreichendes Minimum.
Während Sie die Tastatur und den Monitor in Verbindung halten müssen, wie Sie müssen auch einen Neustart durchführen, wenn Sie den Kernel aktualisieren und um sicherzustellen, dass alles sofort nach dem Laden funktioniert.
Eine Alternative ist die Verwendung von Virtual KVM, das IME bereitstellt. Dort gibt es eine Konsole, obwohl sie in meinem Fall als Java-Applet implementiert ist, was nicht sehr praktisch ist.
Anpassung
Cache-Vorbereitung
Soweit Sie sich erinnern, gibt es in der von mir beschriebenen Konfiguration eine separate SSD unter L2ARC, die noch nicht verwendet wird, sondern "für Wachstum" verwendet wird.
Optional, aber es ist ratsam, diese SSD mit zufälligen Daten zu füllen (im Fall von Samsung EVO wird sie nach Ausführung von blkdiscard immer noch mit Nullen gefüllt, jedoch nicht auf allen SSDs wie dieser):
dd if=/dev/urandom of=/dev/disk/by-id/ata-Samsung_SSD_850_EVO bs=4M && blkdiscard /dev/disk/by-id/ata-Samsung_SSD_850_EVO
Deaktivieren der Protokollkomprimierung
In ZFS wird die Komprimierung bereits verwendet, da die Protokollkomprimierung über gzip eindeutig überflüssig ist.
Ausschalten:
for file in /etc/logrotate.d/* ; do if grep -Eq "(^|[^#y])compress" "$file" ; then sed -i -r "s/(^|[^#y])(compress)/\1#\2/" "$file" fi done
Systemaktualisierung
Hier ist alles einfach:
apt-get dist-upgrade --yes reboot
Erstellen eines Snapshots für einen neuen Status
Nach dem Neustart müssen Sie den ersten Snapshot neu schreiben, um den neuen Arbeitsstatus zu beheben:
zfs destroy rpool/ROOT/debian@install zfs snapshot rpool/ROOT/debian@install
Organisation des Dateisystems
Partitionierung für SLOG
Das erste, was Sie tun müssen, um eine normale ZFS-Leistung zu erzielen, ist, SLOG auf die SSD zu setzen.
Ich möchte Sie daran erinnern, dass SLOG in der verwendeten Konfiguration auf zwei SSDs dupliziert wird: Dafür werden Geräte auf LUKS-XTS über dem 4. Abschnitt jeder SSD erstellt:
dd if=/dev/urandom of=/etc/keys/slog.key bs=1 count=4096 cryptsetup --verbose --cipher "aes-xts-plain64:sha512" --key-size 512 --key-file /etc/keys/slog.key luksFormat /dev/disk/by-id/ata-Samsung_SSD_850_PRO-part4 cryptsetup --verbose --cipher "aes-xts-plain64:sha512" --key-size 512 --key-file /etc/keys/slog.key luksFormat /dev/disk/by-id/ata-Micron_1100-part4 echo "slog0_crypt1 /dev/disk/by-id/ata-Samsung_SSD_850_PRO-part4 /etc/keys/slog.key luks,discard" >> /etc/crypttab echo "slog0_crypt2 /dev/disk/by-id/ata-Micron_1100-part4 /etc/keys/slog.key luks,discard" >> /etc/crypttab
Partitionierung für L2ARC und Swap
Zuerst müssen Sie Partitionen unter swap und l2arc erstellen:
sgdisk -n1:0:48G -t1:8200 -c1:part_swap -n2::196G -t2:8200 -c2:part_l2arc /dev/disk/by-id/ata-Samsung_SSD_850_EVO
Die Swap-Partition und L2ARC werden auf einem zufälligen Schlüssel verschlüsselt Nach einem Neustart sind sie nicht erforderlich und können jederzeit neu erstellt werden.
Daher wird in crypttab eine Zeile zum Ver- / Entschlüsseln von Partitionen im einfachen Modus geschrieben:
echo swap_crypt /dev/disk/by-id/ata-Samsung_SSD_850_EVO-part1 /dev/urandom swap,cipher=aes-xts-plain64:sha512,size=512 >> /etc/crypttab echo l2arc_crypt /dev/disk/by-id/ata-Samsung_SSD_850_EVO-part2 /dev/urandom cipher=aes-xts-plain64:sha512,size=512 >> /etc/crypttab
Dann müssen Sie die Daemons neu starten und Swap aktivieren:
echo 'vm.swappiness = 10' >> /etc/sysctl.conf sysctl vm.swappiness=10 systemctl daemon-reload systemctl start systemd-cryptsetup@swap_crypt.service echo /dev/mapper/swap_crypt none swap sw,discard 0 0 >> /etc/fstab swapon -av
Weil swapiness
wird auf der SSD nicht aktiv verwendet, der swapiness
Parameter, der standardmäßig 60 ist, muss auf 10 gesetzt werden.
L2ARC wird derzeit noch nicht verwendet, aber der Abschnitt dafür ist bereits fertig:
$ ls /dev/mapper/ control l2arc_crypt root_crypt1 root_crypt2 slog0_crypt1 slog0_crypt2 swap_crypt tank0_crypt0 tank0_crypt1 tank0_crypt2 tank0_crypt3
Pools tankN
Die Erstellung des tank0
Pools wird beschrieben, tank1
wird analog erstellt.
Um nicht dieselben Partitionen manuell zu erstellen und Fehler zu vermeiden, habe ich ein Skript zum Erstellen verschlüsselter Partitionen für Pools geschrieben:
Mit diesem Skript müssen Sie nun einen Pool zum Speichern von Daten erstellen:
./create_crypt_pool.sh zpool create -o ashift=12 -O atime=off -O compression=lz4 -O normalization=formD tank0 raidz1 /dev/disk/by-id/dm-name-tank0_crypt*
Hinweise zum Parameter ashift=12
finden Sie in meinen vorherigen Artikeln und Kommentaren dazu.
Nachdem ich den Pool erstellt habe, habe ich sein Protokoll auf der SSD gelöscht:
zpool add tank0 log mirror /dev/disk/by-id/dm-name-slog0_crypt1 /dev/disk/by-id/dm-name-slog0_crypt2
In Zukunft können mit installierter und konfigurierter OMV Pools über die GUI erstellt werden:

Aktivieren des Poolimports und der automatischen Bereitstellung von Volumes beim Booten
Führen Sie die folgenden Befehle aus, um die Aktivierung von Pools mit automatischer Bereitstellung zu gewährleisten:
rm /etc/zfs/zpool.cache systemctl enable zfs-import-scan.service systemctl enable zfs-mount.service systemctl enable zfs-import-cache.service
Zu diesem Zeitpunkt ist die Konfiguration des Festplattensubsystems abgeschlossen.
Operationssystem
Der erste Schritt besteht darin, OMV zu installieren und zu konfigurieren, um endlich eine Grundlage für das NAS zu erhalten.
Installieren Sie OMV
OMV wird als Deb-Paket installiert. Zu diesem Zweck können die offiziellen Anweisungen verwendet werden .
Das Skript add_repo.sh
fügt das OMV Arrakis-Repository zu /etc/apt/ sources.list.d
sodass das Batch-System das Repository sieht.
add_repo.sh cat <<EOF >> /etc/apt/sources.list.d/openmediavault.list deb http://packages.openmediavault.org/public arrakis main
Bitte beachten Sie, dass im Vergleich zum Original das Partner-Repository enthalten ist.
Um zu installieren und zu initialisieren, müssen Sie die folgenden Befehle ausführen.
Befehle zum Installieren von OMV. ./add_repo.sh export LANG=C export DEBIAN_FRONTEND=noninteractive export APT_LISTCHANGES_FRONTEND=none apt-get update apt-get --allow-unauthenticated install openmediavault-keyring apt-get update apt-get --yes --auto-remove --show-upgraded \ --allow-downgrades --allow-change-held-packages \ --no-install-recommends \ --option Dpkg::Options::="--force-confdef" \ --option DPkg::Options::="--force-confold" \ install postfix openmediavault
OMV installiert. Es verwendet einen eigenen Kernel und nach der Installation kann ein Neustart erforderlich sein.
Nach dem Neustart ist die OpenMediaVault-Schnittstelle an Port 80 verfügbar (rufen Sie den Browser auf dem NAS nach IP-Adresse auf):

Der Standardbenutzername / das Standardkennwort lautet admin/openmediavault
.
Konfigurieren Sie OMV
Darüber hinaus wird der größte Teil der Konfiguration über die WEB-GUI ausgeführt.
Stellen Sie eine sichere Verbindung her
Jetzt müssen Sie das Kennwort des WEB-Administrators ändern und ein Zertifikat für den NAS generieren, um in Zukunft an HTTPS arbeiten zu können.
Das Passwort wird auf der Registerkarte "System-> Allgemeine Einstellungen-> Webadministratorkennwort" geändert .
Um ein Zertifikat auf der Registerkarte "System-> Zertifikate-> SSL" zu generieren , wählen Sie "Hinzufügen-> Erstellen" .
Das erstellte Zertifikat wird auf derselben Registerkarte angezeigt:

Aktivieren Sie nach dem Erstellen des Zertifikats auf der Registerkarte "System-> Allgemeine Einstellungen" das Kontrollkästchen "SSL / TLS aktivieren " .
Vor Abschluss der Konfiguration ist ein Zertifikat erforderlich. Die endgültige Version verwendet ein signiertes Zertifikat, um OMV zu kontaktieren.
Jetzt müssen Sie sich bei OMV anmelden, Port 443 oder einfach das Präfix https://
IP im Browser zuweisen.
Wenn Sie sich angemeldet haben , müssen Sie auf der Registerkarte "System-> Allgemeine Einstellungen" das Kontrollkästchen "SSL / TLS erzwingen" aktivieren .
Ändern Sie die Ports 80 und 443 in 10080 und 10443 .
Versuchen Sie, sich unter der folgenden Adresse https://IP_NAS:10443
.
Das Ändern der Ports ist wichtig, da die Ports 80 und 443 den Docker-Container mit nginx-reverse-proxy verwenden.
Primäre Einstellungen
Die Mindesteinstellungen, die zuerst vorgenommen werden müssen:
- Überprüfen Sie auf der Registerkarte "System-> Datum und Uhrzeit" den Zeitzonenwert und stellen Sie den NTP-Server ein.
- Aktivieren Sie auf der Registerkarte "System-> Überwachung" die Erfassung von Leistungsstatistiken.
- Auf der Registerkarte "System-> Energiemanagement" lohnt es sich wahrscheinlich, "Überwachung" auszuschalten, damit OMV nicht versucht, die Lüfter zu steuern.
Netzwerk
Wenn die zweite NAS-Netzwerkschnittstelle noch nicht verbunden ist, verbinden Sie sie mit dem Router.
Dann:
- Setzen Sie auf der Registerkarte "System-> Netzwerk" den Hostnamen auf "nas" (oder was auch immer Sie möchten ).
- Richten Sie die Verbindung für die Schnittstellen wie in der folgenden Abbildung gezeigt ein: "System-> Netzwerk-> Schnittstellen-> Hinzufügen-> Verbindung" .
- Fügen Sie auf der Registerkarte "System-> Netzwerk-> Firewall" die erforderlichen Firewall-Regeln hinzu. Erstens sind der Zugriff auf die Ports 10443, 10080, 443, 80, 22 für SSH und die Berechtigung zum Empfangen / Senden von ICMP ausreichend.

Infolgedessen sollten die Schnittstellen in Bonding angezeigt werden, die der Router als eine Schnittstelle sieht und ihm eine IP-Adresse zuweist:

Falls gewünscht, ist es möglich, SSH zusätzlich über die WEB-GUI zu konfigurieren:

Repositories und Module
Aktivieren Sie auf der Registerkarte "System-> Update Management-> Einstellungen" "Von der Community unterstützte Updates".
Fügen Sie zunächst OMV-Extras-Repositorys hinzu .
Dies kann einfach durch Installieren des Plugins oder Pakets erfolgen, wie im Forum angegeben .
Auf der Seite "System-> Plugins" müssen Sie das Plugin "openmediavault-omvextrasorg" finden und installieren.
Infolgedessen erscheint das Symbol "OMV-Extras" im Systemmenü (es ist in den Screenshots zu sehen).
Gehen Sie dorthin und aktivieren Sie die folgenden Repositorys:
- OMV-Extras.org. Ein stabiles Repository mit vielen Plugins.
- OMV-Extras.org Testen. Einige Plugins aus diesem Repository befinden sich nicht im stabilen Repository.
- Docker CE. Eigentlich Docker.
Auf der Registerkarte "System-> OMV Extras-> Kernel" können Sie den gewünschten Kernel auswählen, einschließlich des Kernels von Proxmox (ich habe ihn nicht selbst installiert, da ich ihn noch nicht benötige, daher empfehle ich ihn nicht):

Installieren Sie die erforderlichen Plugins ( fett, unbedingt erforderlich, kursiv - optional, was ich nicht installiert habe):
Liste der Plugins.- openmediavault-apttool. Mindest-GUI für die Arbeit mit einem Batch-System. Fügt "Services-> Apttool" hinzu .
- openmediavault-anacron. Fügt die Möglichkeit hinzu, über die GUI mit einem asynchronen Scheduler zu arbeiten. Fügt "System-> Anacron" hinzu .
- openmediavault-backup. Bietet ein Backup-System im Speicher. Fügt eine Seite "System-> Backup" hinzu .
- openmediavault-diskstats. Wird benötigt, um Statistiken zur Festplattenleistung zu sammeln.
- openmediavault-dnsmasq . Ermöglicht das Erhöhen des DNS-Servers und des DHCP auf dem NAS. Da ich dies auf einem Router mache, brauche ich es nicht.
- openmediavault-docker-gui . Docker Container Management-Schnittstelle. Fügt "Services-> Docker" hinzu .
- openmediavault-ldap . Unterstützung für die Authentifizierung über LDAP. Fügt "Rechteverwaltung -> Verzeichnisdienst" hinzu .
- openmediavault-letsencrypt . Unterstützung für Let's Encrypt über die GUI. Es wird nicht benötigt, da es die Einbettung in den Nginx-Reverse-Proxy-Container verwendet.
- openmediavault-luksencryption . LUKS-Verschlüsselungsunterstützung. Es ist erforderlich, dass verschlüsselte Festplatten in der OMV-Schnittstelle sichtbar sind. Fügt "Speicher-> Verschlüsselung" hinzu .
- openmediavault-Mutter . USV-Unterstützung. Fügt "Services-> UPS" hinzu .
- openmediavault-omvextrasorg . OMV Extras sollten bereits installiert sein.
- openmediavault-resetperms. Ermöglicht das Zurücksetzen von Berechtigungen und das Zurücksetzen von Zugriffssteuerungslisten für freigegebene Verzeichnisse. Fügt "Zugriffssteuerung -> Allgemeine Verzeichnisse -> Berechtigungen zurücksetzen" hinzu .
- openmediavault-route. Nützliches Plugin für das Routing-Management. Fügt "System-> Netzwerk-> Statische Route" hinzu .
- openmediavault-symlinks. Bietet die Möglichkeit, symbolische Links zu erstellen. Fügt die Seite "Dienste-> Symlinks" hinzu .
- openmediavault-unionfilesystems. UnionFS-Unterstützung. Dies kann in Zukunft nützlich sein, obwohl der Docker ZFS als Backend verwendet. Fügt "Speicher-> Union-Dateisysteme" hinzu .
- openmediavault-virtualbox . Es kann verwendet werden, um Verwaltungsfunktionen für virtuelle Maschinen in die GUI einzubetten.
- openmediavault-zfs . Das Plugin erweitert OpenMediaVault um ZFS-Unterstützung. Nach der Installation wird die Seite "Speicher-> ZFS" angezeigt .
Festplatten
Alle Festplatten im System müssen OMV sichtbar sein. Stellen Sie dies sicher, indem Sie auf die Registerkarte "Speicher-> Festplatten" klicken . Wenn nicht alle Discs sichtbar sind, führen Sie einen Scan durch.

Dort muss auf allen Festplatten das Schreib-Caching aktiviert sein (indem Sie auf eine Festplatte aus der Liste klicken und auf die Schaltfläche "Bearbeiten" klicken).
Stellen Sie sicher, dass alle verschlüsselten Abschnitte auf der Registerkarte "Speicher-> Verschlüsselung" sichtbar sind:

Jetzt ist es an der Zeit, SMART zu konfigurieren, um die Zuverlässigkeit zu erhöhen:
- Gehen Sie zur Registerkarte "Speicher-> SMART-> Einstellungen" . Schalten Sie SMART ein.
- Wählen Sie an derselben Stelle die Werte der Temperaturniveaus der Festplatten aus (kritisch, normalerweise 60 ° C, und das optimale Temperaturregime der Festplatte 15-45 ° C).
- Gehen Sie zur Registerkarte "Speicher-> SMART-> Geräte" . Aktivieren Sie die Überwachung für jedes Laufwerk.

- Gehen Sie zur Registerkarte "Speicher-> SMART-> Geplante Tests" . Fügen Sie einmal täglich einen kurzen Selbsttest für jede Festplatte und einmal im Monat einen langen Selbsttest hinzu. Darüber hinaus, damit sich Selbsttestperioden nicht überschneiden.

In diesem Fall kann die Festplattenkonfiguration als abgeschlossen betrachtet werden.
Dateisysteme und freigegebene Verzeichnisse
Sie müssen Dateisysteme für vordefinierte Verzeichnisse erstellen.
Dies kann über die Konsole oder über die OMV WEB-Schnittstelle erfolgen ( Speicher-> ZFS-> Pooltank auswählen0-> Schaltfläche Hinzufügen -> Dateisystem ).
Befehle zum Erstellen von FS. zfs create -o utf8only=on -o normalization=formD -p tank0/user_data/books zfs create -o utf8only=on -o normalization=formD -p tank0/user_data/music zfs create -o utf8only=on -o normalization=formD -p tank0/user_data/pictures zfs create -o utf8only=on -o normalization=formD -p tank0/user_data/downloads zfs create -o compression=off -o utf8only=on -o normalization=formD -p tank0/user_data/videos
Das Ergebnis sollte die folgende Verzeichnisstruktur sein:

Fügen Sie anschließend die erstellten FSs als freigegebene Verzeichnisse auf der Seite "Zugriffsrechte verwalten-> Allgemeine Verzeichnisse-> Hinzufügen" hinzu .
Beachten Sie, dass der Parameter "Device" dem Pfad zum in ZFS erstellten Dateisystem entspricht und der Parameter "Path" für alle Verzeichnisse "/" ist.

Backup
Die Sicherung erfolgt mit zwei Tools:
- OMV Backup Plugin . OMV-Plugin für die Systemsicherung.
- zfs-auto-snapshot . Ein Skript zum automatischen Erstellen von ZFS-Snapshots nach einem Zeitplan und zum Löschen alter Snapshots.
Wenn Sie das Plugin verwenden, erhalten Sie höchstwahrscheinlich eine Fehlermeldung:
lsblk: /dev/block/0:22: not a block device
Um dies zu beheben, wie von OMV-Entwicklern in dieser "sehr ungewöhnlichen Konfiguration" festgestellt, wäre es möglich, das Plugin abzulehnen und die ZFS-Tools in Form von zfs send/receive
.
Oder geben Sie den Parameter "Root-Gerät" explizit in Form eines physischen Geräts an, von dem der Download erfolgt.
Es ist für mich bequemer, das Plugin zu verwenden und das Betriebssystem über die Benutzeroberfläche zu sichern, anstatt etwas Eigenes mit zfs send zu erstellen. Daher bevorzuge ich die zweite Option.

Damit die Sicherung funktioniert, erstellen tank0/apps/backup
zuerst das tank0/apps/backup
über ZFS, klicken Sie dann im Menü "System-> Sicherung " im Parameterfeld "Öffentlicher Ordner" auf "+" und fügen Sie das erstellte Gerät als Ziel und das Feld "Pfad" hinzu auf "/" setzen.
Es gibt auch Probleme mit zfs-auto-snapshot. Wenn nicht konfiguriert, macht sie ein Jahr lang jede Stunde, jeden Tag, jede Woche, jeden Monat Bilder.
Das Ergebnis ist das, was auf dem Screenshot zu sehen ist:

Wenn Sie bereits darauf gestoßen sind, führen Sie den folgenden Code aus, um automatische Snapshots zu entfernen:
zfs list -t snapshot -o name -S creation | grep "@zfs-auto-snap" | tail -n +1500 | xargs -n 1 zfs destroy -vr
Konfigurieren Sie dann zfs-auto-snapshot für die Ausführung in cron.
Um zu beginnen, löschen Sie einfach /etc/cron.hourly/zfs-auto-snapshot
wenn Sie nicht jede Stunde Bilder aufnehmen müssen.
E-Mail-Benachrichtigungen
Die Benachrichtigung per E-Mail wurde als eines der Mittel zur Erreichung der Zuverlässigkeit angegeben.
Daher müssen Sie jetzt die E-Mail-Benachrichtigung konfigurieren.
Registrieren Sie dazu ein Feld auf einem der öffentlichen Server (oder konfigurieren Sie den SMTP-Server selbst, wenn Sie wirklich Gründe dafür haben).
Dann müssen Sie auf die Seite "System-> Benachrichtigung" gehen und Folgendes eingeben:
- SMTP-Serveradresse.
- SMTP-Server-Port.
- Benutzername.
- Absenderadresse (normalerweise stimmt die erste Komponente der Adresse mit dem Namen überein).
- Benutzerpasswort
- Im Feld "Empfänger" Ihre übliche Adresse, an die der NAS Benachrichtigungen sendet.
Es wird dringend empfohlen, SSL / TLS zu aktivieren.
Ein Beispiel-Setup für Yandex ist im Screenshot dargestellt:

Netzwerkeinrichtung außerhalb des NAS
IP-Adresse
Ich verwende eine weiße statische IP-Adresse, die plus 100 Rubel pro Monat kostet. Wenn Sie nicht zahlen möchten und Ihre Adresse dynamisch ist, jedoch nicht für NAT, können Sie externe DNS-Einträge über die API des ausgewählten Dienstes anpassen.
Es ist jedoch zu beachten, dass eine Nicht-NAT-Adresse plötzlich zu einer NAT-Adresse werden kann: Anbieter geben in der Regel keine Garantie.
Router
Als Router habe ich ein Mikrotik RouterBoard , ähnlich dem im Bild unten.

Auf dem Router sind drei Dinge erforderlich:
- Konfigurieren Sie statische Adressen für den NAS. In meinem Fall werden die Adressen über DHCP ausgegeben, und ich muss sicherstellen, dass die Adapter mit einer bestimmten MAC-Adresse immer dieselbe IP-Adresse erhalten. In RouterOS erfolgt dies auf der Registerkarte "IP-> DHCP-Server" mit der Schaltfläche "Statisch machen" .
- Konfigurieren Sie den DNS-Server so, dass für den Namen "nas" sowie für Namen, die mit ".nas" und ".NAS.cloudns.cc" enden (wobei "NAS" die Zone auf ClouDNS oder einem ähnlichen Dienst ist) das IP-System angegeben wird. Wo dies in RouterOS zu tun ist, sehen Sie im folgenden Screenshot. In meinem Fall wird dies implementiert, indem der Name mit einem regulären Ausdruck
^.*\.nas$|^nas$|^.*\.NAS.cloudns.cc$
: " ^.*\.nas$|^nas$|^.*\.NAS.cloudns.cc$
" - Konfigurieren Sie die Portweiterleitung. In RouterOS erfolgt dies auf der Registerkarte "IP-> Firewall". Darauf werde ich nicht weiter eingehen .

ClouDNS
CLouDNS ist einfach. Konto erstellen, bestätigen. NS-Datensätze werden bereits bei Ihnen registriert. Als nächstes ist eine minimale Einrichtung erforderlich.
Zuerst müssen Sie die erforderlichen Zonen erstellen (die Zone mit dem im Screenshot rot hervorgehobenen Namen NAS sollte natürlich mit einem anderen Namen erstellt werden).

Zweitens sollten Sie in dieser Zone die folgenden A-Datensätze registrieren :
- nas , www , omv , control und ein leerer name . Zugriff auf die OMV-Schnittstelle.
- ldap . PhpLdapAdmin-Schnittstelle
- ssp . Schnittstelle zum Ändern von Benutzerkennwörtern.
- Test . Server testen.
Die verbleibenden Domainnamen werden hinzugefügt, wenn Dienste hinzugefügt werden.
Klicken Sie auf die Zone und dann auf "Neuen Datensatz hinzufügen" , wählen Sie den A-Typ aus, geben Sie den Zonennamen und die IP-Adresse des Routers ein, hinter dem sich der NAS befindet.

Zweitens müssen Sie auf die API zugreifen. In ClouDNS wird es bezahlt, also müssen Sie zuerst dafür bezahlen. Bei anderen Diensten ist es kostenlos. Wenn Sie wissen, was besser ist und dies von Lexicon unterstützt wird, schreiben Sie bitte in die Kommentare.
Nachdem Sie Zugriff auf die API erhalten haben, müssen Sie dort einen neuen API-Benutzer hinzufügen.

"IP address" IP : , API. , , API, auth-id auth-password . Lexicon, .

ClouDNS .
Docker
openmediavault-docker-gui, docker-ce .
, docker-compose , :
apt-get install docker-compose
:
zfs create -p /tank0/docker/services
, /var/lib/docker
. ( , SSD), , , .
..,
. .

, .
, GUI , : , .. , .
/var/lib
:
service docker stop zfs create -o com.sun:auto-snapshot=false -p /tank0/docker/lib rm -rf /var/lib/docker ln -s /tank0/docker/lib /var/lib/docker service docker start
:
$ ls -l /var/lib/docker lrwxrwxrwx 1 root root 17 Apr 7 12:35 /var/lib/docker -> /tank0/docker/lib
:
docker network create docker0
Docker .
nginx-reverse-proxy
Docker , .
, .
: nginx-proxy letsencrypt-dns .
, OMV 10080 10443, 80 443.
/tank0/docker/services/nginx-proxy/docker-compose.yml version: '2' networks: docker0: external: name: docker0 services: nginx-proxy: networks: - docker0 restart: always image: jwilder/nginx-proxy ports: - "80:80" - "443:443" volumes: - ./certs:/etc/nginx/certs:ro - ./vhost.d:/etc/nginx/vhost.d - ./html:/usr/share/nginx/html - /var/run/docker.sock:/tmp/docker.sock:ro - ./local-config:/etc/nginx/conf.d - ./nginx.tmpl:/app/nginx.tmpl labels: - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true" letsencrypt-dns: image: adferrand/letsencrypt-dns volumes: - ./certs/letsencrypt:/etc/letsencrypt environment: - "LETSENCRYPT_USER_MAIL=MAIL@MAIL.COM" - "LEXICON_PROVIDER=cloudns" - "LEXICON_OPTIONS=--delegated NAS.cloudns.cc" - "LEXICON_PROVIDER_OPTIONS=--auth-id=CLOUDNS_ID --auth-password=CLOUDNS_PASSWORD"
:
- nginx-reverse-proxy — c .
- letsencrypt-dns — ACME Let's Encrypt.
nginx-reverse-proxy jwilder/nginx-proxy .
docker0
— , , docker-compose.
nginx-proxy
— , . docker0. , 80 443 ports (, , docker0, ).
restart: always
, .
:
certs
/etc/nginx/certs
— , , Let's Encrypt. ACME ../vhost.d:/etc/nginx/vhost.d
— . ../html:/usr/share/nginx/html
— . ./var/run/docker.sock
, /tmp/docker.sock
— Docker . docker-gen ../local-config
, /etc/nginx/conf.d
— nginx. , ../nginx.tmpl
, /app/nginx.tmpl
— nginx, docker-gen .
letsencrypt-dns adferrand/letsencrypt-dns . ACME Lexicon, DNS .
certs/letsencrypt
/etc/letsencrypt
.
, :
LETSENCRYPT_USER_MAIL=MAIL@MAIL.COM
— Let's Encrypt. , .LEXICON_PROVIDER=cloudns
— Lexicon. — cloudns
.LEXICON_PROVIDER_OPTIONS=--auth-id=CLOUDNS_ID --auth-password=CLOUDNS_PASSWORD --delegated=NAS.cloudns.cc
— CLOUDNS_ID ClouDNS . CLOUDNS_PASSWORD — , API. NAS.cloudns.cc, NAS — DNS . cloudns , (cloudns.cc), ClouDNS API .
: .
, , , , Let's encrypt:
$ ls ./certs/letsencrypt/ accounts archive csr domains.conf keys live renewal renewal-hooks
, , .
/tank0/docker/services/nginx-proxy/nginx.tmpl {{ $CurrentContainer := where $ .Docker.CurrentContainerID | first }} {{ define }} {{ if .Address }} {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} {{ if and .Container.Node.ID .Address.HostPort }} # {{ .Container.Node.Name }}/{{ .Container.Name }} server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }}; {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}} {{ else if .Network }} # {{ .Container.Name }} server {{ .Network.IP }}:{{ .Address.Port }}; {{ end }} {{ else if .Network }} # {{ .Container.Name }} {{ if .Network.IP }} server {{ .Network.IP }} down; {{ else }} server 127.0.0.1 down; {{ end }} {{ end }} {{ end }} # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the # scheme used to connect to this server map $http_x_forwarded_proto $proxy_x_forwarded_proto { default $http_x_forwarded_proto; '' $scheme; } # If we receive X-Forwarded-Port, pass it through; otherwise, pass along the # server port the client connected to map $http_x_forwarded_port $proxy_x_forwarded_port { default $http_x_forwarded_port; '' $server_port; } # If we receive Upgrade, set Connection to ; otherwise, delete any # Connection header that may have been passed to this server map $http_upgrade $proxy_connection { default upgrade; '' close; } # Apply fix for very long server names server_names_hash_bucket_size 128; # Default dhparam {{ if (exists ) }} ssl_dhparam /etc/nginx/dhparam/dhparam.pem; {{ end }} # Set appropriate X-Forwarded-Ssl header map $scheme $proxy_x_forwarded_ssl { default off; https on; } gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; log_format vhost '$host $remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; access_log off; {{ if $.Env.RESOLVERS }} resolver {{ $.Env.RESOLVERS }}; {{ end }} {{ if (exists ) }} include /etc/nginx/proxy.conf; {{ else }} # HTTP 1.1 support proxy_http_version 1.1; proxy_buffering off; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ; {{ end }} {{ $enable_ipv6 := eq (or ($.Env.ENABLE_IPV6) ) }} server { server_name _; # This is just an invalid value which will never trigger on a real hostname. listen 80; {{ if $enable_ipv6 }} listen [::]:80; {{ end }} access_log /var/log/nginx/access.log vhost; return 503; } {{ if (and (exists ) (exists )) }} server { server_name _; # This is just an invalid value which will never trigger on a real hostname. listen 443 ssl http2; {{ if $enable_ipv6 }} listen [::]:443 ssl http2; {{ end }} access_log /var/log/nginx/access.log vhost; return 503; ssl_session_tickets off; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key; } {{ end }} {{ range $host, $containers := groupByMulti $ }} {{ $host := trim $host }} {{ $is_regexp := hasPrefix $host }} {{ $upstream_name := when $is_regexp (sha1 $host) $host }} # {{ $host }} upstream {{ $upstream_name }} { {{ range $container := $containers }} {{ $addrLen := len $container.Addresses }} {{ range $knownNetwork := $CurrentContainer.Networks }} {{ range $containerNetwork := $container.Networks }} {{ if (and (ne $containerNetwork.Name ) (or (eq $knownNetwork.Name $containerNetwork.Name) (eq $knownNetwork.Name ))) }} ## Can be connected with network {{/* If only 1 port exposed, use that */}} {{ if eq $addrLen 1 }} {{ $address := index $container.Addresses 0 }} {{ template (dict $container $address $containerNetwork) }} {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}} {{ else }} {{ $port := coalesce $container.Env.VIRTUAL_PORT }} {{ $address := where $container.Addresses $port | first }} {{ template (dict $container $address $containerNetwork) }} {{ end }} {{ else }} # Cannot connect to network of this container server 127.0.0.1 down; {{ end }} {{ end }} {{ end }} {{ end }} } {{ $default_host := or ($.Env.DEFAULT_HOST) }} {{ $default_server := index (dict $host $default_host ) $host }} {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to */}} {{ $proto := trim (or (first (groupByKeys $containers )) ) }} {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to */}} {{ $network_tag := or (first (groupByKeys $containers )) }} {{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to */}} {{ $https_method := or (first (groupByKeys $containers )) }} {{/* Get the SSL_POLICY defined by containers w/ the same vhost, falling back to */}} {{ $ssl_policy := or (first (groupByKeys $containers )) }} {{/* Get the HSTS defined by containers w/ the same vhost, falling back to */}} {{ $hsts := or (first (groupByKeys $containers )) }} {{/* Get the VIRTUAL_ROOT By containers w/ use fastcgi root */}} {{ $vhost_root := or (first (groupByKeys $containers )) }} {{/* Get the first cert name defined by containers w/ the same vhost */}} {{ $certName := (first (groupByKeys $containers )) }} {{/* Get the best matching cert by name for the vhost. */}} {{ $vhostCert := (closest (dir ) (printf $host))}} {{/* vhostCert is actually a filename so remove any suffixes since they are added later */}} {{ $vhostCert := trimSuffix $vhostCert }} {{ $vhostCert := trimSuffix $vhostCert }} {{/* Use the cert specified on the container or fallback to the best vhost match */}} {{ $cert := (coalesce $certName $vhostCert) }} {{ $is_https := (and (ne $https_method ) (ne $cert ) (or (and (exists (printf $cert)) (exists (printf $cert))) (and (exists (printf $cert)) (exists (printf $cert)))) ) }} {{ if $is_https }} {{ if eq $https_method }} server { server_name {{ $host }}; listen 80 {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:80 {{ $default_server }}; {{ end }} access_log /var/log/nginx/access.log vhost; return 301 https://$host$request_uri; } {{ end }} server { server_name {{ $host }}; listen 443 ssl http2 {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:443 ssl http2 {{ $default_server }}; {{ end }} access_log /var/log/nginx/access.log vhost; {{ if eq $network_tag }} # Only allow traffic from internal clients include /etc/nginx/network_internal.conf; {{ end }} {{ if eq $ssl_policy }} ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; {{ else if eq $ssl_policy }} ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS'; {{ else if eq $ssl_policy }} ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP'; {{ else if eq $ssl_policy }} ssl_protocols TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256'; {{ else if eq $ssl_policy }} ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; {{ else if eq $ssl_policy }} ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; {{ else if eq $ssl_policy }} ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA'; {{ else if eq $ssl_policy }} ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA'; {{ else if eq $ssl_policy }} ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA'; {{ end }} ssl_prefer_server_ciphers on; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; {{ if (and (exists (printf $cert)) (exists (printf $cert))) }} ssl_certificate /etc/nginx/certs/letsencrypt/live/{{ (printf $cert) }}; ssl_certificate_key /etc/nginx/certs/letsencrypt/live/{{ (printf $cert) }}; {{ else if (and (exists (printf $cert)) (exists (printf $cert))) }} ssl_certificate /etc/nginx/certs/{{ (printf $cert) }}; ssl_certificate_key /etc/nginx/certs/{{ (printf $cert) }}; {{ end }} {{ if (exists (printf $cert)) }} ssl_dhparam {{ printf $cert }}; {{ end }} {{ if (exists (printf $cert)) }} ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate {{ printf $cert }}; {{ end }} {{ if (and (ne $https_method ) (ne $hsts )) }} add_header Strict-Transport-Security always; {{ end }} {{ if (exists (printf $host)) }} include {{ printf $host }}; {{ else if (exists ) }} include /etc/nginx/vhost.d/default; {{ end }} location / { {{ if eq $proto }} include uwsgi_params; uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ else if eq $proto }} root {{ trim $vhost_root }}; include fastcgi.conf; fastcgi_pass {{ trim $upstream_name }}; {{ else }} proxy_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ end }} {{ if (exists (printf $host)) }} auth_basic ; auth_basic_user_file {{ (printf $host) }}; {{ end }} {{ if (exists (printf $host)) }} include {{ printf $host}}; {{ else if (exists ) }} include /etc/nginx/vhost.d/default_location; {{ end }} } } {{ end }} {{ if or (not $is_https) (eq $https_method ) }} server { server_name {{ $host }}; listen 80 {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:80 {{ $default_server }}; {{ end }} access_log /var/log/nginx/access.log vhost; {{ if eq $network_tag }} # Only allow traffic from internal clients include /etc/nginx/network_internal.conf; {{ end }} {{ if (exists (printf $host)) }} include {{ printf $host }}; {{ else if (exists ) }} include /etc/nginx/vhost.d/default; {{ end }} location / { {{ if eq $proto }} include uwsgi_params; uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ else if eq $proto }} root {{ trim $vhost_root }}; include fastcgi.conf; fastcgi_pass {{ trim $upstream_name }}; {{ else }} proxy_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ end }} {{ if (exists (printf $host)) }} auth_basic ; auth_basic_user_file {{ (printf $host) }}; {{ end }} {{ if (exists (printf $host)) }} include {{ printf $host}}; {{ else if (exists ) }} include /etc/nginx/vhost.d/default_location; {{ end }} } } {{ if (and (not $is_https) (exists ) (exists )) }} server { server_name {{ $host }}; listen 443 ssl http2 {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:443 ssl http2 {{ $default_server }}; {{ end }} access_log /var/log/nginx/access.log vhost; return 500; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key; } {{ end }} {{ end }} {{ end }}
, nginx /etc/nginx/certs/%s.crt
/etc/nginx/certs/%s.pem
, %s — ( — , ).
/etc/nginx/certs/letsencrypt/live/%s/{fullchain.pem, privkey.pem}
, :
{{ $is_https := (and (ne $https_method "nohttps") (ne $cert "") (or (and (exists (printf "/etc/nginx/certs/letsencrypt/live/%s/fullchain.pem" $cert)) (exists (printf "/etc/nginx/certs/letsencrypt/live/%s/privkey.pem" $cert)) ) (and (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert)) ) ) ) }}
, domains.conf
.
/tank0/docker/services/nginx-proxy/certs/letsencrypt/domains.conf *.NAS.cloudns.cc NAS.cloudns.cc
. , , , client_max_body_size
20, .
/tank0/docker/services/nginx-proxy/local-config/max_upload_size.conf client_max_body_size 20G;
, :
docker-compose up
( ), Ctrl+C :
docker-compose up -d
— nginx, . , , .
, NAS.
.
docker-compose :
/tank0/docker/services/test_nginx/docker-compose.yml version: '2' networks: docker0: external: name: docker0 services: nginx-local: restart: always image: nginx:alpine expose: - 80 - 443 environment: - "VIRTUAL_HOST=test.NAS.cloudns.cc" - "VIRTUAL_PROTO=http" - "VIRTUAL_PORT=80" - CERT_NAME=NAS.cloudns.cc networks: - docker0
:
docker0
— . .expose
— , . , 80 HTTP 443 HTTPS.VIRTUAL_HOST=test.NAS.cloudns.cc
— , nginx-reverse-proxy .VIRTUAL_PROTO=http
— nginx-reverse-proxy . , HTTP.VIRTUAL_PORT=80
— nginx-reverse-proxy.CERT_NAME=NAS.cloudns.cc
— . , , . NAS — DNS .networks
— , nginx-reverse-proxy docker0
.
, . docker-compose up
, test.NAS.cloudns.cc
.
:
$ docker-compose up Creating testnginx_nginx-local_1 Attaching to testnginx_nginx-local_1 nginx-local_1 | 172.22.0.5 - - [29/Jul/2018:15:32:02 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537 (KHTML, like Gecko) Chrome/67.0 Safari/537" "192.168.2.3" nginx-local_1 | 2018/07/29 15:32:02 [error] 8
:

, , , , : .
, Ctrl+C, docker-compose down
.
local-rpoxy
, nginx-default , nas, omv 10080 10443 .
.
/tank0/docker/services/nginx-local/docker-compose.yml version: '2' networks: docker0: external: name: docker0 services: nginx-local: restart: always image: nginx:alpine expose: - 80 - 443 environment: - "VIRTUAL_HOST=NAS.cloudns.cc,nas,nas.*,www.*,omv.*,nas-controller.nas" - "VIRTUAL_PROTO=http" - "VIRTUAL_PORT=80" - CERT_NAME=NAS.cloudns.cc volumes: - ./local-config:/etc/nginx/conf.d networks: - docker0
docker-compose , .
, , , NAS.cloudns.cc
. , NAS DNS , .
/tank0/docker/services/nginx-local/local-config/default.conf # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the # scheme used to connect to this server map $http_x_forwarded_proto $proxy_x_forwarded_proto { default $http_x_forwarded_proto; '' $scheme; } # If we receive X-Forwarded-Port, pass it through; otherwise, pass along the # server port the client connected to map $http_x_forwarded_port $proxy_x_forwarded_port { default $http_x_forwarded_port; '' $server_port; } # Set appropriate X-Forwarded-Ssl header map $scheme $proxy_x_forwarded_ssl { default off; https on; } access_log on; error_log on; # HTTP 1.1 support proxy_http_version 1.1; proxy_buffering off; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; server { server_name _; # This is just an invalid value which will never trigger on a real hostname. listen 80; return 503; } server { server_name www.* nas.* omv.* ""; listen 80; location / { proxy_pass https:
172.21.0.1
— . 443, OMV HTTPS. .https://nas-controller/
— -, IPMI, nas, nas-controller.nas, nas-controller. .
LDAP
LDAP-
LDAP- — .
Docker . , , .
LDIF- .
/tank0/docker/services/ldap/docker-compose.yml version: "2" networks: ldap: docker0: external: name: docker0 services: open-ldap: image: "osixia/openldap:1.2.0" hostname: "open-ldap" restart: always environment: - "LDAP_ORGANISATION=NAS" - "LDAP_DOMAIN=nas.nas" - "LDAP_ADMIN_PASSWORD=ADMIN_PASSWORD" - "LDAP_CONFIG_PASSWORD=CONFIG_PASSWORD" - "LDAP_TLS=true" - "LDAP_TLS_ENFORCE=false" - "LDAP_TLS_CRT_FILENAME=ldap_server.crt" - "LDAP_TLS_KEY_FILENAME=ldap_server.key" - "LDAP_TLS_CA_CRT_FILENAME=ldap_server.crt" volumes: - ./certs:/container/service/slapd/assets/certs - ./ldap_data/var/lib:/var/lib/ldap - ./ldap_data/etc/ldap/slapd.d:/etc/ldap/slapd.d networks: - ldap ports: - 172.21.0.1:389:389 - 172.21.0.1::636:636 phpldapadmin: image: "osixia/phpldapadmin:0.7.1" hostname: "nas.nas" restart: always networks: - ldap - docker0 expose: - 443 links: - open-ldap:open-ldap-server volumes: - ./certs:/container/service/phpldapadmin/assets/apache2/certs environment: - VIRTUAL_HOST=ldap.* - VIRTUAL_PORT=443 - VIRTUAL_PROTO=https - CERT_NAME=NAS.cloudns.cc - "PHPLDAPADMIN_LDAP_HOSTS=open-ldap-server" #- "PHPLDAPADMIN_HTTPS=false" - "PHPLDAPADMIN_HTTPS_CRT_FILENAME=certs/ldap_server.crt" - "PHPLDAPADMIN_HTTPS_KEY_FILENAME=private/ldap_server.key" - "PHPLDAPADMIN_HTTPS_CA_CRT_FILENAME=certs/ldap_server.crt" - "PHPLDAPADMIN_LDAP_CLIENT_TLS_REQCERT=allow" ldap-ssp: image: openfrontier/ldap-ssp:https volumes: #- ./ssp/mods-enabled/ssl.conf:/etc/apache2/mods-enabled/ssl.conf - /etc/ssl/certs/ssl-cert-snakeoil.pem:/etc/ssl/certs/ssl-cert-snakeoil.pem - /etc/ssl/private/ssl-cert-snakeoil.key:/etc/ssl/private/ssl-cert-snakeoil.key restart: always networks: - ldap - docker0 expose: - 80 links: - open-ldap:open-ldap-server environment: - VIRTUAL_HOST=ssp.* - VIRTUAL_PORT=80 - VIRTUAL_PROTO=http - CERT_NAME=NAS.cloudns.cc - "LDAP_URL=ldap://open-ldap-server:389" - "LDAP_BINDDN=cn=admin,dc=nas,dc=nas" - "LDAP_BINDPW=ADMIN_PASSWORD" - "LDAP_BASE=ou=users,dc=nas,dc=nas" - "MAIL_FROM=admin@nas.nas" - "PWD_MIN_LENGTH=8" - "PWD_MIN_LOWER=3" - "PWD_MIN_DIGIT=2" - "SMTP_HOST=" - "SMTP_USER=" - "SMTP_PASS="
:
LDAP- , :
LDAP_ORGANISATION=NAS
— . .LDAP_DOMAIN=nas.nas
— . . , .LDAP_ADMIN_PASSWORD=ADMIN_PASSWORD
— .LDAP_CONFIG_PASSWORD=CONFIG_PASSWORD
— .
-, " ", .
:
/container/service/slapd/assets/certs
certs
— . ../ldap_data/
— , . LDAP .
ldap
, 389 ( LDAP) 636 (LDAP SSL, ) .
PhpLdapAdmin : LDAP ldap
443 docker0
, , nginx-reverse-proxy.
:
VIRTUAL_HOST=ldap.*
— , nginx-reverse-proxy .VIRTUAL_PORT=443
— nginx-reverse-proxy.VIRTUAL_PROTO=https
— nginx-reverse-proxy.CERT_NAME=NAS.cloudns.cc
— , .
SSL .
SSP HTTP .
, , .
— LDAP.
LDAP_URL=ldap://open-ldap-server:389
— LDAP (. links
).LDAP_BINDDN=cn=admin,dc=nas,dc=nas
— .LDAP_BINDPW=ADMIN_PASSWORD
— , , open-ldap.LDAP_BASE=ou=users,dc=nas,dc=nas
— , .
LDAP LDAP :
apt-get install ldap-utils ldapadd -x -H ldap://172.21.0.1 -D "cn=admin,dc=nas,dc=nas" -W -f ldifs/inititialize_ldap.ldif ldapadd -x -H ldap://172.21.0.1 -D "cn=admin,dc=nas,dc=nas" -W -f ldifs/base.ldif ldapadd -x -H ldap://172.21.0.1 -D "cn=admin,cn=config" -W -f ldifs/gitlab_attr.ldif
gitlab_attr.ldif
, Gitlab ( ) .
.
LDAP $ ldapsearch -x -H ldap://172.21.0.1 -b dc=nas,dc=nas -D "cn=admin,dc=nas,dc=nas" -W Enter LDAP Password:
LDAP . WEB-.
OMV LDAP
LDAP , OMV : , , , , — .
LDAP .
:

, , NAS USB.
.
NUT GUI OMV.
"->" , , , , "eaton".
" " :
driver = usbhid-ups port = auto desc = "Eaton 9130 700 VA" vendorid = 0463 pollinterval = 10
driver = usbhid-ups
— USB, USB HID.vendorid
— , lsusb
.pollinterval
— c.
.
lsusb
, :
" " " ".
, :

. , .
.
Fazit
. , , , , .
— .
-, OMV .
WEB-, , :

Docker WEB-:

, OMV .
:

:

CPU:

Das ist alles
!
