Sécuriser son serveur sh0
Les mêmes conseils où que votre serveur soit hébergé : aucune étape propre à un fournisseur, seulement ce qui tourne sur la machine elle-même.
Vue d’ensemble
sh0 sécurise ce qu’il sert (HTTPS, secrets chiffrés, rôles), mais le serveur qui le porte est le vôtre. La plupart des serveurs compromis ne le sont pas par l’application : on y entre en SSH avec un mot de passe deviné, ou par un port que personne ne voulait exposer. Ce guide ferme ces portes, dans l’ordre qui ne vous enferme jamais dehors. sh0 vérifie les mêmes points pour vous, en direct, sur la page Sécurité du serveur du tableau de bord et avec sudo sh0 doctor.
Avant de commencer
Gardez votre session SSH actuelle ouverte jusqu’au bout, et testez chaque changement depuis une NOUVELLE session. Depuis votre ordinateur, vérifiez que votre clé ouvre une session sans mot de passe :
ssh -o PasswordAuthentication=no root@SERVER_IPSi cette session demande un mot de passe, vous n’avez pas encore de clé sur le serveur. Installez-en une, puis testez à nouveau :
ssh-copy-id root@SERVER_IPSSH : clés seulement
Un serveur qui accepte les mots de passe SSH peut être deviné, et root est le premier compte essayé. Une fois votre clé vérifiée, refusez les mots de passe :
cat > /etc/ssh/sshd_config.d/00-sh0-hardening.conf <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
EOFValidez, puis rechargez. Ne redémarrez jamais sshd sur un fichier que sshd -t refuse ; un rechargement garde les sessions ouvertes. Le service s’appelle ssh sur Debian et Ubuntu, sshd ailleurs.
sshd -t && systemctl reload sshVérifiez la valeur effective pour root depuis une adresse extérieure, puis ouvrez une nouvelle session avec votre clé avant de fermer la session actuelle :
sshd -T -C user=root,host=check.invalid,addr=203.0.113.1 | grep -Ei '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin) 'Pare-feu, et le piège Docker
Autorisez SSH, HTTP, HTTPS et le port du panneau, puis activez ufw. Si SSH écoute sur un autre port que 22, autorisez ce port d’abord.
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443
ufw allow 9000/tcp
ufw --force enableLe port 9000 reste ouvert tant que les adresses *.sh0.app atteignent votre serveur directement. Ne le fermez (sh0 serve --bind 127.0.0.1) qu’une fois le panneau servi sur son propre domaine en HTTPS.
cat > /usr/local/sbin/sh0-docker-user <<'EOF'
#!/bin/sh
# Docker-published ports: from the public interface, only replies get through.
IF=$(ip -o route get 1.1.1.1 | sed -n 's/.* dev \([^ ]*\).*/\1/p')
[ -n "$IF" ] || exit 1
iptables -C DOCKER-USER -i "$IF" -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN 2>/dev/null ||
iptables -I DOCKER-USER 1 -i "$IF" -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN
iptables -C DOCKER-USER -i "$IF" -j DROP 2>/dev/null ||
iptables -I DOCKER-USER 2 -i "$IF" -j DROP
EOF
chmod 755 /usr/local/sbin/sh0-docker-user
cat > /etc/systemd/system/sh0-docker-user.service <<'EOF'
[Unit]
Description=sh0: filter Docker-published ports (DOCKER-USER)
After=docker.service
Requires=docker.service
PartOf=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/sh0-docker-user
[Install]
WantedBy=docker.service
EOF
systemctl daemon-reload
systemctl enable --now sh0-docker-user
iptables -S DOCKER-USERPour garder un port publié joignable, ajoutez une exception avant la règle DROP dans /usr/local/sbin/sh0-docker-user :
iptables -I DOCKER-USER 2 -i "$IF" -p tcp -m conntrack --ctorigdstport 5432 -j RETURNSi votre fournisseur propose un pare-feu réseau devant le serveur, quel qu’il soit, utilisez-le aussi : autorisez 22, 80, 443 (et 9000 tant que vous dépendez de *.sh0.app), refusez le reste. Il filtre avant que le trafic n’atteigne la machine, Docker compris.
fail2ban
Avec des clés seulement, les tentatives sont sans danger, mais elles remplissent les journaux. fail2ban bannit les adresses qui insistent :
apt-get install -y fail2ban python3-systemd
cat > /etc/fail2ban/jail.d/sh0-sshd.local <<'EOF'
[sshd]
enabled = true
backend = systemd
journalmatch = _COMM=sshd + _COMM=sshd-session
maxretry = 5
findtime = 10m
bantime = 1h
EOF
systemctl enable fail2ban
systemctl restart fail2ban
fail2ban-client status sshdCorrectifs et redémarrages
Installez les correctifs de sécurité, puis laissez le système les installer automatiquement :
apt-get update && apt-get upgrade
apt-get install -y unattended-upgrades && dpkg-reconfigure -plow unattended-upgradesQuand le noyau ou une bibliothèque essentielle est mis à jour, le correctif ne s’applique qu’après un redémarrage (/var/run/reboot-required existe). Prévoyez-le à une heure creuse : sh0 redémarre avec le système.
Le panneau en HTTPS
Sans domaine propre, le panneau est servi en HTTP clair et le mot de passe du propriétaire traverse le réseau sans chiffrement. Faites pointer un enregistrement DNS A sur le serveur, puis :
sh0 panel-domain set panel.example.comLaisser l’installeur le faire
Sur un serveur neuf, l’installeur applique les étapes SSH, pare-feu et fail2ban ci-dessus quand on le lui demande. C’est désactivé par défaut ; dans un terminal, l’installeur pose aussi la question (sans réponse sous 30 secondes, c’est non).
curl -fsSL https://get.sh0.dev | bash -s -- --hardenVérifier le résultat
La page Sécurité du serveur du tableau de bord (propriétaire et administrateurs) affiche ces vérifications en direct, avec la correction sous chaque avertissement ; un point dans la navigation signale un avertissement actif. Depuis un terminal sur le serveur :
sudo sh0 doctor