Override ssh.socket alt portem odřízne SSH (recovery jen přes rescue)
import { Aside } from ‘@astrojs/starlight/components’;
Symptom
Sekce “Symptom”Při pokusu otevřít alt SSH port pro obejití GeoIP whitelist na portu 22 (typicky pro user na non-CZ IP přes Starlink/cestovní VPN/mobilní hotspot):
- Admin vytvoří systemd override
/etc/systemd/system/ssh.socket.d/listen.confsListenStream=2222. - Spustí
systemctl restart ssh.socket. - Socket failuje při startu → i port 22 přestane listen → server úplně nedostupný přes SSH.
- HTTPS port 443 dál funguje (Caddy/nginx běží), ale management je odříznutý.
nc -zv <server-ip> 22 hlásí Connection refused z libovolné IP, nejen z původně blokovaných.
Root cause
Sekce “Root cause”Moderní Debian/Ubuntu (22.04+) používají socket-activated SSH přes ssh.socket systemd unit, ne klasickou sshd.service. Socket-activated unit má vlastní Accept= semantiku a striktní kontrolu ListenStream direktiv.
Klasický systemd override pattern přes drop-in soubor *.d/*.conf s další ListenStream= u socket-activated unitu nepřidá další port, ale rozbije celý socket, protože systemd interpretuje override v rozporu s typem unitu. Při startu se socket dostane do failed stavu a žádný z portů (původní 22 ani nový 2222) nelistenuje.
Protože v ten okamžik už nelze do serveru přes SSH ani z whitelist IP, jedinou cestou je hardware recovery.
Fix
Sekce “Fix”Recovery (akutní — server už je odříznutý)
Sekce “Recovery (akutní — server už je odříznutý)”- Admin panel hostingu (Hetzner Robot / Cloud / OVH atd.) → aktivuj rescue Linux.
- Zkopíruj jednorázové heslo z UI.
- Pošli Reset / Ctrl+Alt+Del → server boot do rescue.
- Sleduj
nc -zv <ip> 22v loop, počkej ~3 min. ssh root@<ip>s rescue heslem (key auth v rescue nefunguje).lsblk→ identifikuj root FS (typicky/dev/mapper/vgX-rootnebo/dev/mdY).-
Terminál mkdir /mnt && mount <root-device> /mntrm -rf /mnt/etc/systemd/system/ssh.socket.d/umount /mnt - Admin panel → Reset zpět do normálního boot (rescue je jednorázový).
- Počkej až
nc -z <ip> 22projde, paksshjako obvykle.
Downtime typicky ~10 minut (2 reboots + diagnostika).
Správný způsob přidání alt portu (prevence)
Sekce “Správný způsob přidání alt portu (prevence)”Místo override vytvoř samostatný unit /etc/systemd/system/ssh-extra.socket:
[Unit]Description=Extra SSH listener (alt port)[Socket]ListenStream=2222Accept=no[Install]WantedBy=sockets.targetsystemctl daemon-reloadsystemctl enable --now ssh-extra.socketss -tlnp | grep 2222 # ověř že listenujeVlastní socket = bez konfliktu s existujícím ssh.socket. Oba porty paralelně.
Jak se tomu vyvarovat v jiných systémech
Sekce “Jak se tomu vyvarovat v jiných systémech”-
Detection:
grep -r ListenStream= /etc/systemd/system/ssh.socket.d/ 2>/dev/null— pokud něco najde, je to riziko.- Test plán pro sshd změny: před úpravou otevři druhý SSH session do serveru. Pokud něco selže, máš stále otevřené spojení a opravíš to z něj. Session přežije
systemctl restart, jen ne reboot. - Třetí terminál: po každé sshd změně otestuj z čistého terminálu, že nový SSH funguje. Teprve pak zavři druhý.
-
Anti-pattern:
- Override existujícího socket-activated unitu jen pro přidání portu.
systemctl restart ssh.socketbez předchozíhosystemd-analyze verifyconfigu.iptables -Fneboiptables -P INPUT DROPvzdáleně bezat-naplánovaného reset příkazu jako pojistka.MaxAuthTries 0neboPasswordAuthentication nobez ověření, že root má aspoň jeden funkční key vauthorized_keys.
-
Lepší přístup:
- Pro alt port = vlastní unit, ne override.
- Před každou destruktivní sshd/firewall změnou si aktivuj rescue režim preventivně — neaktivuje se sám (server boot z disku dokud sám nezavoláš reset), ale jednorázové heslo je v UI hned k dispozici.
- GeoIP whitelist drž v
ipsets persistencí přes systemd unit, který restoruje set před UFW/firewallem (Before=network-pre.target ufw.service). Pak nepřijdeš o pravidla po rebootu. - UFW pravidla pro custom porty patří do
/etc/ufw/before.rules(před default rules), neiptables -A— ten se ztratí přiufw reload/ reboot.
-
Sítová triáž když SSH na produkčním serveru odmítá:
ping <ip> # ICMP — server živý?nc -zv <ip> 443 # HTTPS — web layer běží?nc -zv <ip> 22 # SSH — listenuje?nc -zv <ip> 2222 # alt port (pokud nastaven)- ping OK + HTTPS OK + SSH timeout → firewall/GeoIP DROP (network-layer). Přepni síť (mobile/VPN) nebo přidej IP do whitelist z jiné session.
- ping OK + HTTPS OK + SSH refused → sshd nebeží / socket failed. Musíš do rescue.
- ping fail → server reboot nebo network down. Hostingový reset.
-
Nepleť si “VNC” a remote console: u dedicated serverů Hetzner je “Activate VNC installation” instalační wizard pro reinstalaci OS (přepíše disk → ztrátu dat), ne remote display. Pro management je správná cesta rescue Linux.
Sister bugs / související
Sekce “Sister bugs / související”deploy/git-clean-wipes-untracked-uploads— jiný „shoot-in-foot” pattern s podobně nákladnou recovery.