commit 1f8106cb44f97346ce1d033578d4c6e9d3f96eb4 Author: Joerg Lehmann Date: Sat Dec 3 17:06:53 2022 +0000 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a5ba92 --- /dev/null +++ b/README.md @@ -0,0 +1,247 @@ +# onyx - Container Server of nbit Informatik GmbH + +In this directory (/home/containers/onyx_pods), you will find all configuration files to run the containers (with Podman and Kubernetes YAML files) + +Persistent data is stored in /data + +Specs: +- Rocky Linux 9 +- Hetzner Cloud Server CX 31 + - 2 vCPUs + - 8 GB RAM + - 80 GB Disk + +## Create Server + +Name: onyx.nbit.ch + +Set Root-Password (by hand) + +` +# dnf update +# groupadd containers +# useradd -m -g containers containers +# passwd containers +# hostnamectl set-hostname onyx.nbit.ch +` + +enable EPEL Repo: +` +# dnf install epel-release +` + +## Firewall + +```bash +# dnf install firewalld +# firewall-cmd --add-service={http,https} --permanent +# TODO +``` + +## fail2ban on Host for ssh + +```bash +# dnf install fail2ban +# cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local +edit /etc/fail2ban/jail.local: +enabled = true => below [sshd] + +# systemctl restart fail2ban + +command to check who is banned: +# fail2ban-client status sshd +``` + + +## Install Software + +```bash +# dnf install git +# dnf install podman +# dnf install jq +``` + +## Backup Server + +TODO + +```bash +Backup MySQL-DBs: + +/usr/local/bin/backup-mysql-dbs.sh (sinngemaess, eine Zeile pro Container): +root@moby:/usr/local/bin# more backup-mysql-dbs.sh +#!/bin/bash +# Backup der MySQL DBs (Docker) +# +for container_name in $(docker ps --format "{{.Image}} {{.Names}}" |grep mysql |awk '{print $2}'); do + if [ -f /usr/local/bin/${container_name}.pwd ]; then + # im pwd-File muss "PWD=XXXX" (root) gesetzt werden + . /usr/local/bin/${container_name}.pwd + docker exec ${container_name} /usr/bin/mysqldump -u root --password=${PWD} --all-databases > /backup/mysql-databases-${container_name}-$(date +%Y%m%W).sql 2>/dev/null + else + >&2 echo "Password must be set as PWD=XXXX in /usr/local/bin/${container_name}.pwd" + fi +done + +# Cleanup Old Backups +find /backup -type f -mtime +30 -exec rm {} \; + +/etc/cron.d/backup-mysql-dbs: +# Backup MySQL DBs +# +45 5 * * * root /usr/local/bin/backup-mysql-dbs.sh >/dev/null + + +Restore: just in case: +cat backup.sql | docker exec -i CONTAINER /usr/bin/mysql -u root --password=root DATABASE + + +# dnf install restic +# mkdir /backup +# mkdir /backup-restic +# restic init --repo /backup-restic/restic-repo-$(hostname --short) # Passwort in Keepass + +SSH Keypaar fuer User root erstellen und auf Hetzner Storagebox hinterlegen: + +# ssh-keygen + + + +Restic Script: + +/usr/local/bin/backup-to-disk.sh +#!/bin/bash +# Backup der wichtigsten Verzeichnisse nach einem Verzeichnis +# +# Es wird restic verwendet. +# +PATH=$PATH:/usr/local/bin +export RESTIC_PASSWORD="$(hostname --short)7355" +restic backup --quiet --repo /backup-restic/restic-repo-$(hostname --short) /home /etc /var /opt /var/lib/docker/volumes /usr/local/bin /backup --exclude=/var/log --exclude=/var/lib/docker/overlay2 + +if [ $? -eq 0 ]; then + restic forget --quiet --repo /backup-restic/restic-repo-$(hostname --short) --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 20 --prune +else + >&2 echo "Problem with restic Backup $(hostname --short)" +fi + +/etc/cron.d/backup-to-disk: +# +# Backup important Files to Disk +# +55 6 * * * root /usr/local/bin/backup-to-disk.sh >/dev/null + +Backup auf Storag Box: + +# cat > /etc/cron.d/rsync-backup-to-other-host </dev/null +HERE +``` + + +## Wordpress behind Traefik + +following needs to be inserted in wp-config.php (on top of PHP Code): + +```bash +if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) + $_SERVER['HTTPS']='on'; +``` + + +### DNS Server Tests + +TODO => REVIEW + +```bash +# cat /etc/cron.d/checkdnsserver +# +# Check DNS Server +# +*/15 * * * * root /usr/local/bin/checkdnsserver.sh >/dev/null + + +# cat /usr/local/bin/checkdnsserver.sh +#!/bin/bash +# +# Check my DNS servers and report to CloudRadar +# +# Joerg Lehmann, 17.8.2021 +# + +for dnsserver in ns1.nbit.ch ns2.nbit.ch ; do + dig +short ${dnsserver} @${dnsserver} >/dev/null 2>&1 + if [ $? -eq 0 ]; then + csender -t 6tZlIPoM7OQb \ + -u https://hub.cloudradar.io/cct/ \ + -n checkdnsserver \ + -s 1 + else + csender -t 6tZlIPoM7OQb \ + -u https://hub.cloudradar.io/cct/ \ + -n checkdnsserver \ + -s 0 \ + -a "DNS Test @${dnsserver} failed" + fi + sleep 10 +done +``` + +### Setup Traefik + +see https://gerov.eu/posts/traefik-for-podman/ + +```bash +# echo 'net.ipv4.ip_unprivileged_port_start=80' >> /etc/sysctl.d/containers.conf +# loginctl enable-linger containers +# The following fixes "Failed to connect to bus: No medium found" +export XDG_RUNTIME_DIR=/run/user/$(id -u) +containers$ systemctl --user enable --now podman.socket +containers$ podman network create web +containers$ touch acme.json +containers$ chmod 0600 acme.json + +containers$ podman run --name=traefik -d \ + --security-opt label=type:container_runtime_t \ + -v /run/user/1000/podman/podman.sock:/var/run/docker.sock:z \ + -v ./acme.json:/acme.json:z \ + -v ./configuration/:/configuration/:z \ + --net web \ + -p 80:80 \ + -p 443:443 \ + --restart always \ + docker.io/library/traefik:latest \ + --entrypoints.web.address=":80" \ + --entrypoints.web.http.redirections.entryPoint.to=websecure \ + --entrypoints.web.http.redirections.entryPoint.scheme=https \ + --entrypoints.websecure.address=":443" \ + --providers.docker=true \ + --certificatesresolvers.myresolver.acme.email=postmaster@nbit.ch \ + --certificatesresolvers.myresolver.acme.storage=/acme.json \ + --certificatesresolvers.myresolver.acme.tlschallenge=true \ + --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory \ + --certificatesresolvers.myresolver.acme.httpChallenge.entrypoint=web \ + --providers.file.directory=/configuration/ \ + --providers.file.watch=true \ + --accesslog=true \ + --log.level=DEBUG + + +containers$ mkdir -p ~/.config/systemd/user/ +containers$ cd ~/.config/systemd/user/ +containers$ podman generate systemd -f -n traefik +containers$ systemctl --user enable container-traefik.service + +containers$ podman stop traefik +containers$ systemctl --user start container-traefik.service + +# mkdir /data +# chown containers:containers /data + +containers$ escaped=$(systemd-escape ~/onyx_pods/traefik/traefik.yaml) +containers$ systemctl --user start podman-kube@$escaped.service +containers$ systemctl --user enable podman-kube@$escaped.service +``` diff --git a/traefik/configuration/tls-config.yml b/traefik/configuration/tls-config.yml new file mode 100644 index 0000000..aad2ff5 --- /dev/null +++ b/traefik/configuration/tls-config.yml @@ -0,0 +1,20 @@ +tls: + options: + default: + sniStrict: true + minVersion: VersionTLS12 + cipherSuites: + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + tlsv13only: + minVersion: VersionTLS13 + stores: + default: + defaultGeneratedCert: + resolver: myresolver + domain: + main: onyx.nbit.ch diff --git a/traefik/traefik.yaml b/traefik/traefik.yaml new file mode 100644 index 0000000..a6649f9 --- /dev/null +++ b/traefik/traefik.yaml @@ -0,0 +1,64 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + bind-mount-options:/data/traefik/acme.json: z + bind-mount-options:/home/containers/onyx_pods/traefik/configuration: z + bind-mount-options:/run/user/1000/podman/podman.sock: z + io.kubernetes.cri-o.TTY/traefik: "false" + io.podman.annotations.autoremove/traefik: "FALSE" + io.podman.annotations.init/traefik: "FALSE" + io.podman.annotations.label/traefik: type:container_runtime_t + io.podman.annotations.privileged/traefik: "FALSE" + io.podman.annotations.publish-all/traefik: "FALSE" + creationTimestamp: "2022-12-03T15:45:41Z" + labels: + app: traefik-pod + name: traefik-pod +spec: + hostNetwork: true + containers: + - args: + - --entrypoints.web.address=:80 + - --entrypoints.web.http.redirections.entryPoint.to=websecure + - --entrypoints.web.http.redirections.entryPoint.scheme=https + - --entrypoints.websecure.address=:443 + - --providers.docker=true + - --certificatesresolvers.myresolver.acme.email=postmaster@nbit.ch + - --certificatesresolvers.myresolver.acme.storage=/acme.json + - --certificatesresolvers.myresolver.acme.tlschallenge=true + - --certificatesresolvers.myresolver.acme.httpChallenge.entrypoint=web + - --providers.file.directory=/configuration/ + - --providers.file.watch=true + - --accesslog=true + image: docker.io/library/traefik:latest + name: traefik + securityContext: + capabilities: + drop: + - CAP_MKNOD + - CAP_AUDIT_WRITE + seLinuxOptions: + type: container_runtime_t + volumeMounts: + - mountPath: /configuration/ + name: home-containers-onyx_pods-traefik-configuration-host-0 + - mountPath: /var/run/docker.sock + name: run-user-1000-podman-podman.sock-host-1 + - mountPath: /acme.json + name: data-traefik-acme.json-host-2 + volumes: + - hostPath: + path: /home/containers/onyx_pods/traefik/configuration + type: Directory + name: home-containers-onyx_pods-traefik-configuration-host-0 + - hostPath: + path: /run/user/1000/podman/podman.sock + type: File + name: run-user-1000-podman-podman.sock-host-1 + - hostPath: + path: /data/traefik/acme.json + type: File + name: data-traefik-acme.json-host-2 +