Beruflich Dokumente
Kultur Dokumente
Unsere Server mieten wir für gewöhnlich bei Netcup und nutzten Debian als Betriebssystem. Basics
Sys-Admins
SSH-Config
Firewall
Basics Docker
Traefik und Portainer
Hier einpaar grundlegende Dinge die die Nutzung und Verwaltung des Server erleichtern. installieren (single node)
Als root auf den Server per SSH einloggen. Traefik eigene Zertifikate
Traefik und Portainer
installieren (multi node)
nano setup.sh
Cluster initialisieren
# Inhalt aus dem Code-Block weiter unten einfügen
NFS einrichten
chmod +x setup.sh
NFS peer
./setup.sh hinzufügen
Traefik einrichten
setup.sh Failover IP configurieren
Impressum und robots.txt
#!/bin/bash Gitlab-Runner
Mail-Server
apt-get update Backup
apt-get upgrade
apt-get dist-upgrade
apt-get install -y sudo qemu-guest-agent htop iotop jnettop nano rsync ufw
apt-get autoremove
apt-get autoclean
fallocate -l 5G /root/bigfile
fallocate -l 5G /root/bigfile2
mkdir /home/kklockgether/.ssh
touch /home/kklockgether/.ssh/authorized_keys
chown -R kklockgether:kklockgether /home/kklockgether/.ssh/
chmod -R 700 /home/kklockgether/.ssh/
mkdir /home/thofer/.ssh
touch /home/thofer/.ssh/authorized_keys
chown -R thofer:thofer /home/thofer/.ssh/
chmod -R 700 /home/thofer/.ssh/
mkdir /home/devops28/.ssh
touch /home/devops28/.ssh/authorized_keys
chown -R devops28:devops28 /home/devops28/.ssh/
chmod -R 700 /home/devops28/.ssh/
setup.sh
# User-Passwörter vergeben
passwd kklockgether
passwd thofer
passwd devops28
# Hostnamen ändern
hostnamectl set-hostname 28backup
# Neuen hostnamen eintragen
nano /etc/hosts
# hinzufügen: 127.0.1.1 28backup
# Falls 127.0.1.1 bereits existiert, einfach den Servernamen hinten dran hängen
# Für Server mit vielen Services; Limit der geöffneten Dateien erhöhen
mkdir /etc/systemd/system.conf.d/
nano /etc/systemd/system.conf.d/limits.conf
# server neu starten um limits zu übernehmen
/etc/systemd/system.conf.d/limits.conf
# https://unix.stackexchange.com/a/443467/470542
# 1048576 ist der maximal mögliche Wert für Linux. https://stackoverflow.com/a/
[Manager]
DefaultLimitNOFILE=1048576:2097152
#DefaultLimitNPROC=262144:524288
Sys-Admins
kklockgether
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDaJV/UIorYEq9mZEjPNTm19R8ylWb
thofer
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQClP5DAm8fl+q1i2YbYPR0wtUS5FIR
SSH-Config
Wichtige Anmerkung: Während der Einrichtung sollte man sich, ohne den Zugang zu testen NIEMALS
ausloggen. Ein zweites Terminal-Fenster sollte zum testen genutzt werden.
Soll der Server Software hosten und deployen, wird dies mit dem Benutzer devops28 Verwaltet.
Jeder Sys-Admin der Firma soll einen eigenen Benutzer haben. Der Zugriff wird ausschließlich per SSH-Key
erlaubt. Passwörter müssen für den sudo-Zugriff dennoch stark gewählt werden (Passwortgenerator verwenden).
# Port ändern in eine zufällige Zahl >= 1024 und <= 65353
# SSH-Einstellungen erneuern
systemctl reload ssh
# Beispielhaft:
#Host devops28deploy2
# HOSTNAME 193.30.121.212
# PORT 61122 (Den Port der auf dem Server eingetragen worden ist hier eintrage
# USER devops28
# Zugriff testen
ssh servername
Firewall
Als Firewall nutzten wir ufw Uncomplicated Firewall.
Die Firewall niemals aktivieren ohne den korrekten SSH-Port zu erlauben!
# Adminzugriff
sudo -i
# Firewall installieren
apt-get install ufw
# Für Webservices
ufw allow http
ufw allow https
# Firewall aktivieren (Sich wirklich sicher sein, dass der korrekte SSH-Port er
ufw enable
Docker
DNS-Eintrag setzten <servername>.28apps-software.de auf die IP vom Server zeigen
Docker installieren
Devops User anlegen und zur Docker-Gruppe hinzufügen
# Devops User anlegen und zur Docker-Gruppe hinzufügen (falls nicht bereits erf
adduser devops28
usermod -aG docker devops28
usermod -aG docker kklockgether
usermod -aG docker thofer
# SSH-Zugriff
mkdir /home/devops28/.ssh
nano /home/devops28/.ssh/authorized_keys
chown -R devops28:devops28 /home/devops28/.ssh
chmod -R 700 /home/devops28/.ssh/
su devops28
conf.yml
tls:
options:
default:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_AES_128_GCM_SHA256
services.portainer.deploy.labels
traefik.http.routers.portainer.rule Url anpassen
compose.yml
version: '3.8'
services:
traefik:
image: traefik
command:
- --api=true
- --api.dashboard=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik-public
- --providers.file.filename=/conf.yml
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls.options=default@file
- --certificatesresolvers.letsencryptresolver.acme.httpchallenge=true
- --certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoi
- --certificatesresolvers.letsencryptresolver.acme.email=srvadmin@28apps.
- --certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/a
# - --log.level=DEBUG
ports:
- 80:80
- 443:443
volumes:
- ./certs:/letsencrypt
- ./conf.yml:/conf.yml
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- traefik-public
deploy:
placement:
constraints:
- node.role == manager
labels:
- traefik.enable=true
- traefik.http.routers.traefik.rule=Host(`traefik.dev.28apps-software.d
- traefik.http.routers.traefik.service=api@internal
- traefik.http.routers.traefik.entrypoints=websecure
- traefik.http.routers.traefik.tls.certresolver=letsencryptresolver
- traefik.http.services.traefik.loadbalancer.server.port=1337
# basic auth
- traefik.http.routers.traefik.middlewares=traefik-auth
- traefik.http.middlewares.traefik-auth.basicauth.users=28apps:$$apr1$$
# Redirect http to https
- traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)
- traefik.http.routers.http-catchall.priority=10
- traefik.http.routers.http-catchall.entrypoints=web
- traefik.http.routers.http-catchall.middlewares=redirect-to-https@dock
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=http
portainer-agent:
image: portainer/agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
networks:
- agent_network
deploy:
mode: global
placement:
constraints: [node.platform.os == linux]
portainer:
image: portainer/portainer-ce
command: -H tcp://tasks.portainer-agent:9001 --tlsskipverify
volumes:
- portainer_data:/data
networks:
- traefik-public
- agent_network
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role == manager]
labels:
- traefik.enable=true
- traefik.http.routers.portainer.rule=Host(`portainer.dev.28apps-softwa
- traefik.http.routers.portainer.entrypoints=websecure
- traefik.http.routers.portainer.tls.certresolver=letsencryptresolver
- traefik.http.services.portainer.loadbalancer.server.port=9000
volumes:
portainer_data:
networks:
traefik-public:
external: true
agent_network:
Deploy-Script hinzufügen
cd /home/devops28/docker/traefik
echo "docker stack deploy --prune -c compose.yml traefik" > deploy.sh
chmod +x deploy.sh
./deploy.sh
services:
traefik:
image: traefik
command:
- --api=true
- --api.dashboard=true
- --providers.docker
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik-public
- --providers.file.directory=/etc/traefik/dynamic
- --entrypoints.websecure.address=:443
# - --log.level=DEBUG
ports:
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./certs-traefik.yml:/etc/traefik/dynamic/certs-traefik.yaml:ro
- /etc/apache2/ssl/wildcard-dallmann-bau.de-mit-chain.crt:/certs/server.c
- /etc/apache2/ssl/wildcard-dallmann-bau.de.key:/certs/server.key:ro
networks:
- traefik-public
deploy:
placement:
constraints:
- node.role == manager
labels:
- traefik.enable=true
- traefik.http.routers.traefik.rule=Host(`traefik.dallmann-bau.de`)
- traefik.http.routers.traefik.service=api@internal
- traefik.http.routers.traefik.entrypoints=websecure
- traefik.http.routers.traefik.tls=true
# Basic Auth
- traefik.http.routers.traefik.middlewares=auth
- traefik.http.middlewares.auth.basicauth.users=28apps:$$2y$$05$$flzEg2
certs-traefik.yml
tls:
certificates:
- certFile: /certs/server.crt
keyFile: /certs/server.key
Cluster initialisieren
#manager
docker swarm init
sudo ufw allow from <ips aller server im cluster>
# Traefik Netzwerk erstellen
docker network create --driver overlay --subnet=10.10.0.0/16 --ingress --opt en
#alle
sudo ufw allow from <ips aller server im cluster>
#worker
docker swarm join --token <token> <ip>:2377
#manager
docker node promote <worker>
docker node ls
NFS einrichten
# all
nano /etc/hosts
# ips und hostsnames von allen servern im cluster hinzufügen
mkdir -p /gluster/traefik
mkdir -p /gluster/gitlab-runner
# manager
gluster volume create traefik replica 3 peaked1:/gluster/traefik peaked2:/glust
gluster volume start traefik
gluster volume create gitlab-runner replica 3 peaked1:/gluster/gitlab-runner pe
gluster volume start gitlab-runner
# all
# /etc/fstab ergänzen
localhost:/traefik /mnt/traefik glusterfs defaults,_netdev,noauto,x-systemd
localhost:/portainer /mnt/portainer glusterfs defaults,_netdev,noauto,x-sy
systemctl daemon-reload
systemctl restart remote-fs.target
# neuer node
apt-get install glusterfs-server glusterfs-client
systemctl start glusterd
systemctl enable glusterd
ssh-keygen
# alle nodes
# /etc/hosts ergänzen
# firewall ergänzen
# bestehender node
gluster peer probe <neuer node>
gluster pool list
gluster volume add-brick traefik replica 3 peaked3:/gluster/traefik force
# neuer node
mkdir -p /gluster/traefik
chown -R root:docker /mnt
chmod -R 775 /mnt
chmod g+s /mnt
mkdir -p /mnt/traefik/
# /etc/fstab ergänzen
localhost:/traefik /mnt/traefik glusterfs defaults,_n
localhost:/gitlab-runner /mnt/gitlab-runner glusterfs defaults,_n
systemctl daemon-reload
systemctl restart remote-fs.target
Traefik einrichten
manager
su devops28
./deploy.sh
crontab -e
# einfügen
# 0 10 * * 1 /home/devops28/docker/traefik/renew-certs.sh
/home/devops28/docker/traefik/deploy.sh
/home/devops28/docker/traefik/compose.yml
version: '3.8'
networks:
traefik-public:
external: true
portainer-agent:
services:
traefik:
image: traefik:2.6
command:
- --api=true
- --api.dashboard=true
- --providers.docker
- --providers.docker.swarmMode=true
- --providers.docker.watch=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik-public
- --providers.file.directory=/conf
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# - --log.level=DEBUG
deploy:
mode: global
restart_policy:
condition: on-failure
labels:
- traefik.enable=true
- traefik.http.routers.traefik.rule=Host(`traefik.peaked.me`)
- traefik.http.routers.traefik.service=api@internal
- traefik.http.routers.traefik.entrypoints=websecure
- traefik.http.routers.traefik.tls=true
- traefik.http.services.traefik.loadbalancer.server.port=80
# Basic Auth
- traefik.http.routers.traefik.middlewares=auth
- traefik.http.middlewares.auth.basicauth.users=28apps:$$apr1$$6rr5scst
# Redirect http to https
- traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)
- traefik.http.routers.http-catchall.entrypoints=web
- traefik.http.routers.http-catchall.middlewares=traefik-ratelimit,redi
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=http
# low priority to be able to be overwriten
- traefik.http.routers.http-catchall.priority=10
# rate limits
- traefik.http.middlewares.traefik-ratelimit.ratelimit.average=100
- traefik.http.middlewares.traefik-ratelimit.ratelimit.burst=50
ports:
- 80:80
- 443:443
volumes:
- /mnt/traefik/conf:/conf:ro
- /mnt/traefik/certbot:/certs:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- traefik-public
portainer-agent:
image: portainer/agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- portainer-agent
deploy:
mode: global
restart_policy:
condition: on-failure
portainer:
image: portainer/portainer-ce
command: -H tcp://tasks.portainer-agent:9001 --tlsskipverify
volumes:
- /mnt/traefik/portainer:/data
networks:
- traefik-public
- portainer-agent
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
- traefik.enable=true
- traefik.http.routers.portainer.rule=Host(`portainer.peaked.me`)
- traefik.http.routers.portainer.entrypoints=websecure
- traefik.http.routers.portainer.tls=true
- traefik.http.services.portainer.loadbalancer.server.port=9000
/home/devops28/docker/traefik/renew-certs.sh
# *.peaked.me
containerCertbot=$(docker ps -f name=traefik_certbot --format {{.ID}})
docker exec $containerCertbot /etc/letsencrypt/renew.sh
/mnt/traefik/conf/traefik.yml
1
2 tls:
3 options:
4 default:
5 minVersion: VersionTLS13
6 tls12:
7 minVersion: VersionTLS12
8 cipherSuites:
9 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
10 - TLS_AES_256_GCM_SHA384
11 - TLS_CHACHA20_POLY1305_SHA256
12 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
13 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
14 - TLS_AES_128_GCM_SHA256
15 stores:
16 default:
17 defaultCertificate:
18 certFile: /certs/live/peaked.me/fullchain.pem
19 keyFile: /certs/live/peaked.me/privkey.pem
20 certificates:
21 - certFile: /certs/live/peaked.me/fullchain.pem
keyFile: /certs/live/peaked.me/privkey.pem
/mnt/traefik/certbot/renew.sh
1
2 #!/bin/sh
3
4 # abort script on error
5 set -e
6 set -o pipefail
7
8 certbot certonly -n --agree-tos --standalone \
9 --max-log-backups 0 \
10 --email srvadmin@28apps.de \
11 --cert-name peaked.me \
12 -d peaked.me \
13 -d portainer.peaked.me \
14 -d traefik.peaked.me \
15 -d api.peaked.me \
-d office.peaked.me
Failover IP configurieren
compose.yml
1
2 version: '3.8'
3
4 services:
5 nginx:
6 image: nginx:1-alpine
7 volumes:
8 - /home/devops28/docker/imprint/html:/usr/share/nginx/html:ro
9 networks:
10 - traefik-public
11 deploy:
12 mode: replicated
13 replicas: 1
14 labels:
15 - traefik.enable=true
16 - traefik.http.services.imprint-nginx.loadbalancer.server.port=80
17
18 - traefik.http.routers.imprint.rule=Host(`dev2.28apps-software.de
19 - traefik.http.routers.imprint.priority=1
20 - traefik.http.routers.imprint.entrypoints=websecure
21 - traefik.http.routers.imprint.tls.certresolver=letsencryptresolv
22
23 - traefik.http.routers.imprint-robots.rule=Path(`/robots.txt`) &&
24 - traefik.http.routers.imprint-robots.priority=10000
25 - traefik.http.routers.imprint-robots.entrypoints=websecure
26 - traefik.http.routers.imprint-robots.tls.certresolver=letsencryp
27
28 networks:
29 traefik-public:
external: true
deploy.sh
html/index.html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name='robots' content='noindex,follow' />
<title>28dev2 Impressum</title>
<style>
body {
font-family: Arial;
}
</style>
</head>
<body>
<p>Vertretungsberechtigte Geschäftsführer:</p>
<p>Emrah Gencer, Thomas Stehr</p>
</body>
</html>
html/robots.txt
User-agent: *
Disallow: /
Gitlab-Runner
https://gitlab.28apps-software.de/28apps-docker/gitlab-runner
Mail-Server
Hier gibt es eine umfassende Anleitung für einen Mail-Server in Docker verpackt: https://gitlab.28apps-
software.de/28server/mail-server
Backup
Wie man das Backup einrichtet ist im eigenem Abschnitt dokumentiert: 28backup