68 lines
2.4 KiB
Plaintext
68 lines
2.4 KiB
Plaintext
|
|
#!/bin/sh
|
||
|
|
# ===========================================================================
|
||
|
|
# Broker-only sshd entrypoint for the OSM taxiway bastion.
|
||
|
|
# ===========================================================================
|
||
|
|
# Minimal, security-focused: key-only SSH for one non-root user whose every
|
||
|
|
# session is forced through bastion-broker (client command validated whole-line
|
||
|
|
# against the allowlist, then exec'd shell-free). No shell, no forwarding, no
|
||
|
|
# root login. Host keys persist under the mounted /etc/ssh/keys.
|
||
|
|
# ===========================================================================
|
||
|
|
set -eu
|
||
|
|
|
||
|
|
SSH_USER=agent
|
||
|
|
KEYS_DIR=/etc/ssh/keys
|
||
|
|
USERS_D=/etc/bastion/users.d
|
||
|
|
ALLOW=/etc/bastion/allowed-commands.list
|
||
|
|
|
||
|
|
# 1) Persistent host identity (bind-mounted dir → survives rebuilds).
|
||
|
|
mkdir -p "$KEYS_DIR"
|
||
|
|
for t in rsa ecdsa ed25519; do
|
||
|
|
f="$KEYS_DIR/ssh_host_${t}_key"
|
||
|
|
[ -f "$f" ] || ssh-keygen -t "$t" -f "$f" -N "" -q
|
||
|
|
done
|
||
|
|
chmod 600 "$KEYS_DIR"/ssh_host_* 2>/dev/null || true
|
||
|
|
|
||
|
|
# 2) authorized_keys from the mounted users.d/*.pub (one client identity per file).
|
||
|
|
home=$(getent passwd "$SSH_USER" | cut -d: -f6)
|
||
|
|
mkdir -p "$home/.ssh"
|
||
|
|
: > "$home/.ssh/authorized_keys"
|
||
|
|
if [ -d "$USERS_D" ]; then
|
||
|
|
cat "$USERS_D"/*.pub >> "$home/.ssh/authorized_keys" 2>/dev/null || true
|
||
|
|
fi
|
||
|
|
chown -R "$SSH_USER:$SSH_USER" "$home/.ssh"
|
||
|
|
chmod 700 "$home/.ssh"
|
||
|
|
chmod 600 "$home/.ssh/authorized_keys"
|
||
|
|
|
||
|
|
# The broker reads this live every request; make sure it exists (empty ⇒ deny all).
|
||
|
|
[ -f "$ALLOW" ] || { mkdir -p /etc/bastion; : > "$ALLOW"; }
|
||
|
|
|
||
|
|
# 3) ForceCommand wrapper → hand the client's requested command to the broker.
|
||
|
|
cat > /usr/local/bin/force-command <<'EOF'
|
||
|
|
#!/bin/sh
|
||
|
|
exec /usr/local/bin/bastion-broker "${SSH_ORIGINAL_COMMAND:-}"
|
||
|
|
EOF
|
||
|
|
chmod 0755 /usr/local/bin/force-command
|
||
|
|
|
||
|
|
# 4) sshd config — key-only, single user, forced through the broker, no forwarding.
|
||
|
|
cat > /etc/ssh/sshd_config <<EOF
|
||
|
|
Port 22
|
||
|
|
HostKey $KEYS_DIR/ssh_host_rsa_key
|
||
|
|
HostKey $KEYS_DIR/ssh_host_ecdsa_key
|
||
|
|
HostKey $KEYS_DIR/ssh_host_ed25519_key
|
||
|
|
PermitRootLogin no
|
||
|
|
PasswordAuthentication no
|
||
|
|
KbdInteractiveAuthentication no
|
||
|
|
PubkeyAuthentication yes
|
||
|
|
AllowUsers $SSH_USER
|
||
|
|
ForceCommand /usr/local/bin/force-command
|
||
|
|
AllowTcpForwarding no
|
||
|
|
AllowAgentForwarding no
|
||
|
|
X11Forwarding no
|
||
|
|
PermitTunnel no
|
||
|
|
PermitUserEnvironment no
|
||
|
|
LogLevel VERBOSE
|
||
|
|
EOF
|
||
|
|
|
||
|
|
echo "[osm-taxiways-bastion] sshd starting (broker mode, user=$SSH_USER)"
|
||
|
|
exec /usr/sbin/sshd -D -e
|