2026-05-28 08:50:06 +00:00
|
|
|
# ===========================================================================
|
|
|
|
|
# docker-bastion — hardened sshd config
|
|
|
|
|
#
|
|
|
|
|
# Every authenticated session is routed through /etc/bastion/force-command,
|
|
|
|
|
# which is generated at container start from $FORCE_COMMAND. The bastion
|
|
|
|
|
# user has /sbin/nologin as its shell so there is no fallback if the
|
|
|
|
|
# ForceCommand wrapper is missing or fails — the session simply ends.
|
|
|
|
|
# ===========================================================================
|
|
|
|
|
|
|
|
|
|
Port 22
|
|
|
|
|
AddressFamily any
|
|
|
|
|
ListenAddress 0.0.0.0
|
|
|
|
|
ListenAddress ::
|
|
|
|
|
|
|
|
|
|
# Host keys live in /etc/ssh/keys/ so they can survive image rebuilds via
|
|
|
|
|
# a named volume. start-container generates them on first boot if missing.
|
|
|
|
|
HostKey /etc/ssh/keys/ssh_host_ed25519_key
|
|
|
|
|
HostKey /etc/ssh/keys/ssh_host_rsa_key
|
|
|
|
|
|
|
|
|
|
# Privilege separation directory (Alpine default is /var/empty).
|
|
|
|
|
StrictModes yes
|
|
|
|
|
|
|
|
|
|
# Auth — public keys only, no passwords, no interactive prompts.
|
|
|
|
|
# (UsePAM is omitted: Alpine's openssh-server is built without PAM support
|
|
|
|
|
# and rejects the directive entirely. Without PAM compiled in, the no-PAM
|
|
|
|
|
# behavior is already the default — nothing to disable.)
|
|
|
|
|
PermitRootLogin no
|
|
|
|
|
PasswordAuthentication no
|
|
|
|
|
KbdInteractiveAuthentication no
|
|
|
|
|
PubkeyAuthentication yes
|
2026-05-28 10:31:51 +00:00
|
|
|
|
|
|
|
|
# Two key sources sshd consults on every auth attempt:
|
|
|
|
|
# 1. The boot-time merged file at /home/%u/.ssh/authorized_keys —
|
|
|
|
|
# populated from $AUTHORIZED_KEYS_HOST / $AUTHORIZED_KEYS_REPO file
|
|
|
|
|
# mounts. Static after container start.
|
|
|
|
|
# 2. AuthorizedKeysCommand /usr/local/bin/bastion-list-keys —
|
|
|
|
|
# enumerates *.pub files in $AUTHORIZED_KEYS_DIR (default
|
|
|
|
|
# /etc/bastion/users.d). Runs on every login, so adding or removing
|
|
|
|
|
# a pubkey file takes effect immediately without a container restart.
|
2026-05-28 08:50:06 +00:00
|
|
|
AuthorizedKeysFile /home/%u/.ssh/authorized_keys
|
2026-05-28 10:31:51 +00:00
|
|
|
AuthorizedKeysCommand /usr/local/bin/bastion-list-keys
|
|
|
|
|
AuthorizedKeysCommandUser agent
|
2026-05-28 08:50:06 +00:00
|
|
|
|
|
|
|
|
# Surface reduction — no forwarding, no tunnels, no user env / rc files.
|
|
|
|
|
AllowAgentForwarding no
|
|
|
|
|
AllowTcpForwarding no
|
|
|
|
|
X11Forwarding no
|
|
|
|
|
GatewayPorts no
|
|
|
|
|
PermitTunnel no
|
|
|
|
|
PermitUserEnvironment no
|
|
|
|
|
PermitUserRC no
|
|
|
|
|
|
|
|
|
|
# Logging.
|
|
|
|
|
LogLevel VERBOSE
|
|
|
|
|
SyslogFacility AUTH
|
|
|
|
|
|
|
|
|
|
# Belt + suspenders: applies even if per-key command="" is missing.
|
|
|
|
|
ForceCommand /etc/bastion/force-command
|