# ===========================================================================
# 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

# 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.
AuthorizedKeysFile /home/%u/.ssh/authorized_keys
AuthorizedKeysCommand /usr/local/bin/bastion-list-keys
AuthorizedKeysCommandUser agent

# 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
