Proteger su servidor sh0
Los mismos consejos esté donde esté alojado su servidor: ningún paso propio de un proveedor, solo lo que se ejecuta en la propia máquina.
Visión general
sh0 protege lo que sirve (HTTPS, secretos cifrados, roles), pero el servidor que lo aloja es suyo. La mayoría de los servidores comprometidos no lo son a través de la aplicación: se entra por SSH con una contraseña adivinada, o por un puerto que nadie quería exponer. Esta guía cierra esas puertas, en el orden que nunca le deja fuera. sh0 comprueba los mismos puntos por usted, en directo, en la página Seguridad del servidor del panel y con sudo sh0 doctor.
Antes de empezar
Mantenga abierta su sesión SSH actual hasta el final y pruebe cada cambio desde una NUEVA sesión. Desde su ordenador, compruebe que su clave abre una sesión sin contraseña:
ssh -o PasswordAuthentication=no root@SERVER_IPSi esa sesión pide una contraseña, aún no tiene ninguna clave en el servidor. Instale una y vuelva a probar:
ssh-copy-id root@SERVER_IPSSH: solo claves
Un servidor que acepta contraseñas SSH puede ser adivinado, y root es la primera cuenta que se prueba. Cuando su clave funcione, rechace las contraseñas:
cat > /etc/ssh/sshd_config.d/00-sh0-hardening.conf <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
EOFValide y luego recargue. Nunca reinicie sshd con un archivo que sshd -t rechaza; una recarga mantiene las sesiones abiertas. El servicio se llama ssh en Debian y Ubuntu, sshd en otros sistemas.
sshd -t && systemctl reload sshCompruebe el valor efectivo para root desde una dirección externa y abra una nueva sesión con su clave antes de cerrar la actual:
sshd -T -C user=root,host=check.invalid,addr=203.0.113.1 | grep -Ei '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin) 'Cortafuegos y la trampa de Docker
Permita SSH, HTTP, HTTPS y el puerto del panel, y luego active ufw. Si SSH escucha en un puerto distinto del 22, permita ese puerto primero.
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443
ufw allow 9000/tcp
ufw --force enableEl puerto 9000 sigue abierto mientras las direcciones *.sh0.app lleguen directamente a su servidor. Ciérrelo (sh0 serve --bind 127.0.0.1) solo cuando el panel se sirva en su propio dominio con 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-USERPara mantener accesible un puerto publicado, añada una excepción antes de la regla DROP en /usr/local/sbin/sh0-docker-user:
iptables -I DOCKER-USER 2 -i "$IF" -p tcp -m conntrack --ctorigdstport 5432 -j RETURNSi su proveedor ofrece un cortafuegos de red delante del servidor, sea cual sea, úselo también: permita 22, 80, 443 (y 9000 mientras dependa de *.sh0.app) y rechace el resto. Filtra antes de que el tráfico llegue a la máquina, Docker incluido.
fail2ban
Con solo claves, los intentos no son peligrosos, pero llenan los registros. fail2ban bloquea las direcciones que insisten:
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 sshdActualizaciones y reinicios
Instale las actualizaciones de seguridad y deje que el sistema las instale automáticamente:
apt-get update && apt-get upgrade
apt-get install -y unattended-upgrades && dpkg-reconfigure -plow unattended-upgradesCuando se actualiza el núcleo o una biblioteca esencial, la corrección solo se aplica tras un reinicio (existe /var/run/reboot-required). Planifíquelo en un momento de poco tráfico: sh0 se inicia de nuevo con el sistema.
El panel con HTTPS
Sin dominio propio, el panel se sirve en HTTP sin cifrar y la contraseña del propietario cruza la red sin cifrado. Apunte un registro DNS A al servidor y luego:
sh0 panel-domain set panel.example.comQue lo haga el instalador
En un servidor nuevo, el instalador aplica los pasos de SSH, cortafuegos y fail2ban anteriores cuando se le pide. Está desactivado por defecto; en una terminal, el instalador también hace la pregunta (sin respuesta en 30 segundos, es no).
curl -fsSL https://get.sh0.dev | bash -s -- --hardenComprobar el resultado
La página Seguridad del servidor del panel (propietario y administradores) muestra estas comprobaciones en directo, con la corrección debajo de cada aviso; un punto en la navegación indica un aviso activo. Desde una terminal en el servidor:
sudo sh0 doctor