Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== Verschlüsselter Docker-Server thinc ====== Siehe [[computer:debian:hp-thinclient:ritter.local]] Hardware: HP t520 thin client mit 120GB SSD OS: debian-bookworm * Minimum-Installation * Alle Updates apt update && apt upgrade apt install \ vim \ openssh-server \ dropbear-initramfs \ apache2-utils \ mc \ rcs \ rsync \ swaks \ ufw \ inetutils-tools \ net-tools \ fuse \ at \ samba \ nullmailer \ mailutils \ hdparm \ sudo \ golang \ ethtool \ hwinfo \ hdparm \ pv \ gdu \ iw wpasupplicant wireless-tools ====== springm zur Gruppe sudoers hinzufügen ====== su - usermod -aG sudo springm Achtung: wird erst nach ausloggen wirksam Netzwerk: *.zalmoxis.aberdoch.de registriert Boot-Disk verschlüsseln ====== ssh passwordless login ====== ssh-copy-id -i .ssh/id_ecdsa.pub 192.168.2.251 ssh zalmoxis sudo cp ~/.ssh/authorized_keys /root/.ssh ====== dropbear-initramfs ====== Entsprechend c't-Artikel {{ :computer:luks_verschluesselte_linux-systeme_ueber_ssh_entsperren_c_t_magazin.pdf |}} Die ssh-public-keys der Benutzer, die das System per ssh entsperren sollen können, liegen in ''/etc/dropbear/initramfs/authorized_keys'' (kopieren von hermes...). Minimum-Inhalt für die Konfigurationsdatei: <file /etc/dropbear/initramfs/dropbear.conf bash> # # Command line options to pass to dropbear(8) # DROPBEAR_OPTIONS="-p 20022 -c cryptroot-unlock" </file> Die ''.ssh/authorized_keys'' von springm nach ''/root/.ssh'' kopieren sudo cp ~springm/.ssh/authorized_keys /root/.ssh Nach Änderung muss das initramfs aktualisiert werden: update-initramfs -u Entsperren mit ''ssh -v -p 20022 <rechnername lt. Fritzbox>'' Das ganze mit Wifi: * https://www.marcfargas.com/2017/12/enable-wireless-networks-in-debian-initramfs/ * https://www.dwarmstrong.org/remote-unlock-dropbear/ ===== Wifi in initramfs einschalten ===== Wird gebraucht um später die Platte nach dem Booten über WLAN entschlüsseln zu können. Rezept von https://www.marcfargas.com/2017/12/enable-wireless-networks-in-debian-initramfs/ ( {{ :computer:hp-thinclient:enable_wireless_networks_in_debian_initramfs_marcfargas.com.pdf |}} ) wlan0 beim Boot bekanntmachen: <file bash /etc/default/grub> ... GRUB_CMDLINE_LINUX="net.ifnames=0 ip=:::::wlan0:dhcp" ... </file> Benötigte Module für das initramfs <file bash /etc/initramfs-tools/modules> rtlwifi rtl8xxxu mac80211 usbcore rtl8192eu_nic.bin </file> <file bash /etc/initramfs-tools/scripts/init-premount/a_enable_wireless> #!/bin/sh PREREQ="" prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac . /scripts/functions AUTH_LIMIT=30 INTERFACE="wlan0" alias WPACLI="/sbin/wpa_cli -p /tmp/wpa_supplicant -i $INTERFACE " log_begin_msg "Starting WLAN connection" ### mws rmmod rtl8xxxu modprobe rtl8xxxu sleep 2 ### end mws /sbin/wpa_supplicant -i $INTERFACE -c /etc/wpa_supplicant.conf -P /run/initram-wpa_supplicant.pid -B -f /tmp/wpa_supplicant.log # Wait for AUTH_LIMIT seconds, then check the status limit=${AUTH_LIMIT} echo -n "Waiting for connection (max ${AUTH_LIMIT} seconds)" while [ $limit -ge 0 -a `WPACLI status | grep wpa_state` != "wpa_state=COMPLETED" ] do sleep 1 echo -n "." limit=`expr $limit - 1` done echo "" if [ `WPACLI status | grep wpa_state` != "wpa_state=COMPLETED" ]; then ONLINE=0 log_failure_msg "WLAN offline after timeout" panic else ONLINE=1 log_success_msg "WLAN online" fi configure_networking </file> <file bash /etc/initramfs-tools/scripts/local-bottom/kill_wireless> #!/bin/sh PREREQ="" prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac echo "Killing wpa_supplicant so the system takes over later." kill `cat /run/initram-wpa_supplicant.pid` </file> Eintrag in /etc/network/interfaces <file bash /etc/network/interfaces> ... auto wlan0 iface wlan0 inet dhcp wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf ... </file> Passwort in /etc/wpa_supplicant/wpa_supplicant.conf <file bash /etc/wpa_supplicant/wpa_supplicant.conf> ctrl_interface=/run/wpa_supplicant update_config=1 network={ ssid="Your ESSID" psk=langundverschlüsselt } </file> Die wpa_supplicant.conf findet sich identisch an 3 verschiedenen Stellen :( * /etc/wpa_supplicant.conf * /etc/wpa_supplicant/wpa_supplicant.conf * /etc/initramfs-tools/wpa_supplicant.conf ==== ESSID und/oder Wifi-Passwort ändern ==== wpa_passphrase "Eleven Ways" wifipassword >> /etc/wpa_supplicant.conf /etc/wpa_supplicant.conf editieren und alte Konfiguration auskommentieren rm /etc/wpa_supplicant/wpa_supplicant.conf cp -l /etc/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf rm /etc/initramfs-tools/wpa_supplicant.conf cp -l /etc/wpa_supplicant.conf /etc/initramfs-tools/wpa_supplicant.conf Kontrollieren auf Gleichheit mit sum $(find / -name wpa_supplicant.conf -not -path "/backupdisk") Dann initramfs neu erstellen update-initramfs -u -k all ==== Wlan als Dienst starten ==== Nach dem Entsperren wird das Wlan über einen Dienst gestartet ( https://www.skerit.com/en/configure-wifi-on-minimal-debian-11-server ) {{ :computer:hp-thinclient:configure_wifi_on_a_minimal_debian_11_server_skeritcom.pdf |}} <file bash /etc/systemd/system/dhclient.service> [Unit] Description=DHCP Client Before=network.target After=wpa_supplicant.service [Service] Type=forking ExecStart=/sbin/dhclient wlan0 -v ExecStop=/sbin/dhclient wlan0 -r Restart=always [Install] WantedBy=multi-user.target </file> Starten mit systemctl enable dhclient systemctl restart wpa_supplicant systemctl restart networking Kontrollieren mit ip a ===== ufw ===== ufw allow proto tcp from any to any port 22,80,139,443,445 ufw allow proto udp from any to any port 137,138 ufw enable ===== email senden ===== Emails sollen für Statusmails versendet werden können. Nullmailer ist einfach, 3 Konfigurationsdateien stehen in ''/etc/nullmailer'' Links * https://wiki.debian.org/nullmailer * https://dan.langille.org/2013/10/16/using-nullmailer-instead-of-a-full-blown-mail-server/ ===== debian packages sichern (und später wiederherstellen) ===== von https://unix.stackexchange.com/questions/79125/reinstalling-all-debian-packages dpkg --get-selections | grep -v deinstall | awk '{print $1}' | awk '$1=$1' ORS=' ' > /etc/installed_debs.txt kommt in die /etc/crontab. Restore erfolgt dann mit apt-get clean && apt-get update && apt-get install --reinstall $(/etc/installed_debs.txt) ===== docker ===== from https://computingforgeeks.com/how-to-install-docker-on-debian-12-bookworm/ sudo apt install -y \ lsb-release \ gnupg2 \ apt-transport-https \ ca-certificates \ curl \ software-properties-common curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/debian.gpg add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/debian $(lsb_release -cs) stable" apt update apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin usermod -aG docker springm newgrp docker systemctl status docker docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabl> Active: active (running) since Mon 2023-08-28 15:07:09 CEST; 27s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 9365 (dockerd) Tasks: 9 Memory: 29.0M CPU: 1.391s CGroup: /system.slice/docker.service └─9365 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/cont> Aug 28 15:07:04 debian-thinc systemd[1]: Starting docker.service - Docker Appli> Aug 28 15:07:04 debian-thinc dockerd[9365]: time="2023-08-28T15:07:04.749035874> Aug 28 15:07:06 debian-thinc dockerd[9365]: time="2023-08-28T15:07:06.254635497> Aug 28 15:07:08 debian-thinc dockerd[9365]: time="2023-08-28T15:07:08.360733123> Aug 28 15:07:08 debian-thinc dockerd[9365]: time="2023-08-28T15:07:08.565571357> Aug 28 15:07:08 debian-thinc dockerd[9365]: time="2023-08-28T15:07:08.566231451> Aug 28 15:07:09 debian-thinc dockerd[9365]: time="2023-08-28T15:07:09.476426543> Aug 28 15:07:09 debian-thinc systemd[1]: Started docker.service - Docker Applic> docker version Client: Docker Engine - Community Version: 24.0.5 API version: 1.43 Go version: go1.20.6 Git commit: ced0996 Built: Fri Jul 21 20:35:35 2023 OS/Arch: linux/amd64 Context: default Server: Docker Engine - Community Engine: Version: 24.0.5 API version: 1.43 (minimum version 1.12) Go version: go1.20.6 Git commit: a61e2b4 Built: Fri Jul 21 20:35:35 2023 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.22 GitCommit: 8165feabfdfe38c65b599c4993d227328c231fca runc: Version: 1.1.8 GitCommit: v1.1.8-0-g82f18fe docker-init: Version: 0.19.0 GitCommit: de40ad0 ==== lazydocker ==== https://github.com/jesseduffield/lazydocker go install github.com/jesseduffield/lazydocker@latest mv /root/go /usr/local ln -s /usr/local/go/bin/lazydocker /usr/local/bin ==== Docker-Dienste ==== === Traefik === === pihole === === restic-restserver === === resticinfo === === mailserver === === calibre === ===== Wake-on-Lan ===== * https://wiki.debian.org/WakeOnLan * https://www.thomas-krenn.com/de/wiki/Wake_on_LAN_unter_Linux Datei ''/etc/network/interfaces.d/enp1s0'' erzeugen: auto enp1s0 iface enp1s0 inet dhcp ethernet-wol g booten um die Änderung wirksam zu machen. ===== Zeitgesteuert schlafen/aufwachen ===== von https://www.baeldung.com/linux/auto-suspend-wake Achtung: Mit Verschlüsselung funktioniert nur suspend-to-memory ===== Traefik ===== Traefik ist der router für die Docker-Container. Da alle Dienste nur im LAN zur Verfügung stehen, müssen dafür *keine* Zertifikate zur Verfügung gestellt werden. ===== pihole ===== <code yaml docker-compose.yml> # from https://codecaptured.com/blog/self-hosting-pi-hole-with-docker-and-traefik/ # adapted for usage of .env file version: "3" services: pihole: image: pihole/pihole:latest container_name: pihole restart: always ports: - "53:53/tcp" - "53:53/udp" dns: - 127.0.0.1 - 9.9.9.9 environment: TZ: 'Europe/Berlin' WEBPASSWORD: ${WEBPASSWORD} PIHOLE_DNS_: 9.9.9.9;149.112.112.112;1.1.1.1 DNSSEC: 'true' ServerIP: ${SERVERIP} VIRTUAL_HOST: ${VIRTUAL_HOST} DNSMASQ_LISTENING: all DHCP_ACTIVE: ${DHCP_ACTIVE} DHCP_START: ${DHCP_START} DHCP_END: ${DHCP_END} DHCP_ROUTER: ${DHCP_ROUTER} DHCP_LEASETIME: ${DHCP_LEASETIME} WEBTHEME: default-dark PIHOLE_DOMAIN: ${PIHOLE_DOMAIN} volumes: - './services/pihole:/etc/pihole/' - './services/dnsmasq.d:/etc/dnsmasq.d/' cap_add: - NET_ADMIN restart: unless-stopped networks: lan: {} backend: ipv4_address: ${BACKEND_IPV4_ADDRESS} labels: - "traefik.enable=true" - "traefik.http.routers.pihole.rule=Host(`${VIRTUAL_HOST}`)" - "traefik.http.services.pihole.loadbalancer.server.port=80" - "traefik.http.routers.pihole.entrypoints=web" depends_on: - dhcphelper dhcphelper: image: noamokman/dhcp-helper container_name: dhcp-helper restart: unless-stopped network_mode: "host" command: -s ${BACKEND_IPV4_ADDRESS} cap_add: - NET_ADMIN networks: backend: ipam: config: - subnet: ${BACKEND_SUBNET} lan: external: true </code> <code bash [enable_line_numbers="false"] .env> PIHOLE_DOMAIN= WEBPASSWORD= # Actual server IP. Matches DHCP conf file IP SERVERIP= # Same as port traefik config VIRTUAL_HOST= DHCP_ACTIVE= DHCP_START= DHCP_END= DHCP_ROUTER= DHCP_LEASETIME= BACKEND_IPV4_ADDRESS= BACKEND_SUBNET= </code> * https://codecaptured.com/blog/self-hosting-pi-hole-with-docker-and-traefik/ * https://github.com/mirdaki/computer-config/blob/blog-pihole/services/local/README.md * https://jurian.slui.mn/posts/pi-hole-web-interface-behind-traefik/ ==== dnscrypt-proxy ==== Vorher die Versionsnummer von https://github.com/DNSCrypt/dnscrypt-proxy/releases holen cd /opt/ && \ wget https://github.com/DNSCrypt/dnscrypt-proxy/releases/download/2.1.5/dnscrypt-proxy-linux_x86_64-2.1.5.tar.gz && \ tar xvzf dnscrypt-proxy-linux_x86_64-2.1.5.tar.gz cd linux-x86_64/ cp ~springm/dnscrypt-proxy/dnscrypt-proxy.toml . sudo ./dnscrypt-proxy -service install sudo ./dnscrypt-proxy -service start ===== Backup ===== Das Backup passiert mit Restic: https://restic.net Das binary liegt in ''/usr/local/bin'' Backups erfolgen in das Verzeichnis ''/backupdisk/restic-repo'' Das restic-Passwort für das Restic-Repository wird in ''/root/resticpw'' gespeichert. ==== Eigenes Backup ==== <code bash /usr/local/sbin/restic_backup.sh> #!/bin/bash export RESTIC_REPOSITORY=/backupdisk/restic-repo export RESTIC_PASSWORD_FILE=/root/resticpw export RESTIC_EXCLUDE_FILE=/root/restic_exclude export HOME=/root /usr/local/bin/restic backup /root /etc /usr/local/bin /usr/local/sbin /home/springm/docker </code> Zu starten via cron, ebenso ''restic forget'' ==== Restic-Server ==== Der restic-Server läuft in einem docker-Container unter der URL ''http://resticserver.ritter.local'' ==== Restic-Info ==== Läuft in einem Docker-Containern. Liest die JSON-Datei aus ''/var/lib/restic/snapshots.json'' ''/var/lib/restic/snapshots.json'' wird per inotify bei Änderungen im Verzeichnis ''/backupdisk/restic-repo/snapshots'' erzeugt. Die Informationen stehen unter der URL http://resticinfo.ritter.local zur Verfügung. === Erzeugen der /var/lib/restic/snapshots.json === Ein inotify-Eintrag auf das snapshots-Verzeichnis im Restic-Repository triggert das Schreiben einer JSON-Zustandsdatei mit dem Befehl restic snapshots -c --json > /var/lib/restic/snapshots.json Dieser Befehl ist zusammen mit dem Restic-Passwort und dem Repository in ''/usr/local/sbin/restic_snapshots_json.sh'' niedergelegt: <code bash /usr/local/sbin/restic_snapshots_json.sh> #!/bin/bash /usr/bin/date >> /tmp/restic_monitoring.log export RESTIC_REPOSITORY=/backupdisk/restic-repo export RESTIC_PASSWORD_FILE=/root/resticpw export HOME=/root #/usr/local/bin/restic snapshots -c --json /usr/local/bin/restic snapshots -c --json > /var/lib/restic/snapshots.json 2>>/tmp/restic_monitoring.log </code> Die Automatisierung erfolgt über einen systemd-Service (vgl. https://www.putorius.net/systemd-path-units.html) <file bash /etc/systemd/system/restic-snapshots-mon.path> [Unit] Description="Monitor restic snapshots for changes" [Path] PathModified=/backupdisk/restic-repo/snapshots/ Unit=restic-snapshots-mon.service [Install] WantedBy=multi-user.target </file> <file bash /etc/systemd/system/restic-snapshots-mon.service> [Unit] Description="Recreate /var/lib/restic/snapshots.json when snapshots have changed" [Service] ExecStart=/usr/local/sbin/restic_snapshots_json.sh </file> <file bash /usr/local/sbin/restic-json.sh> #!/bin/bash /usr/bin/date >> /tmp/restic_monitoring.log export RESTIC_REPOSITORY=/backupdisk/restic-repo export RESTIC_PASSWORD_FILE=/root/resticpw export HOME=/root /usr/local/bin/restic snapshots -c --json > /var/lib/restic/snapshots.json 2>>/tmp/restic_monitoring.log </file> Analysieren mit ''systemd-analyze verify /etc/systemd/system/restic-snapshots-mon*'' Starten mit ''systemctl start restic-snapshots-mon.path'' Beim Systemstart hochfahren mit ''systemctl enable restic-snapshots-mon.path'' Status überprüfen mit ''systemctl status restic-snapshots-mon.path'' Log-Einträge ansehen mit ''journalctl -u restic-snapshots-mon.path'' Erzeugen der ''/var/lib/restic/snapshots.json'' beim booten durch einen cron-eintrag @reboot root /usr/local/sbin/restic_snapshots_json.sh ==== Backuptree für Kontrolle und Restore ==== Backups werden readonly im Verzeichnis ''/restic_restore'' zur Verfügung gestellt. Der restic-mount-Prozess wird täglich zu einer festgesetzten Zeit gekillt und neu gestartet, damit die neuesten Änderungen sichtbar werden. /etc/crontab ruft regelmäßig folgendes Script auf: <code bash /usr/local/sbin/mount_restic_restore.sh> #!/bin/bash #chmod 755 /restic-restore /usr/bin/umount /restic-restore sleep 3 /usr/local/bin/restic -r /backupdisk/restic-repo/ \ -p /root/resticpw \ mount \ --allow-other \ --no-default-permissions \ --no-lock \ /restic-restore </code> Links: * https://wiki.debian.org/Samba/ServerSimple * https://www.thomas-krenn.com/en/wiki/Simple_Samba_Shares_in_Debian * https://superuser.com/questions/1069044/how-to-set-up-anonymous-read-only-samba-shares computer/debian/hp-thinclient/versuch-2-debian-thinc.txt Last modified: 2025/12/27 14:23by spring