1.3K
A lightweight Debian-based bastion container that:
authorized_keysauthorized_keys via volume| Port | Purpose |
|---|---|
| 22 | SSH server (always exposed) |
| 8080 | Web admin UI (expose temporarily) |
Example during admin tasks:
-p 22:22
-p 8080:8080
Then disable/close port 8080 when done.
| Volume mount path | Purpose |
|---|---|
/etc/ssh | Persistent SSH host keys |
/tmp | Writable temp on read-only rootfs |
/authorized_keys | Persistent authorized keys file |
Example volume setup:
docker volume create bastion_ssh
docker volume create bastion_tmp
docker volume create bastion_auth
| Variable | Default | Description |
|---|---|---|
AUTHORIZED_KEYS | (empty) | Initial SSH keys (newline-separated). |
AUTHORIZED_KEYS_PATH | /authorized_keys/authorized_keys | Path to the managed key file. |
BASTION_USER | bastion | SSH login user. |
SSH_PORT | 22 | SSH port inside container. |
APP_PORT | 8080 | Web UI port. |
ADMIN_USERNAME | admin | Web UI login. |
ADMIN_PASSWORD_BCRYPT | bcrypt hash of ChangeMe! | Override in production! |
SESSION_SECRET | auto-created if missing | Needed for CSRF + sessions. |
python3 - <<'PY'
import bcrypt
print(bcrypt.hashpw(b"MyStrongAdminPassword!", bcrypt.gensalt()).decode())
PY
OpenSSH refuses loose permissions.
entrypoint.sh enforces:
/authorized_keys ā 0700 bastion:bastion
/authorized_keys/authorized_keys ā 0600 bastion:bastion
This prevents:
Authentication refused: bad ownership or modes for directory /authorized_keys
docker build -t nexaa/bastion-key-manager:latest .
docker run -d --name bastion \
-p 22:22 \
-p 8080:8080 \
-v bastion_ssh:/etc/ssh \
-v bastion_tmp:/tmp \
-v bastion_auth:/authorized_keys \
-e AUTHORIZED_KEYS="$(cat ~/.ssh/id_ed25519.pub)" \
nexaa/bastion-key-manager:latest
SSH:
ssh bastion@localhost
Web UI:
http://localhost:8080
Default credentials:
admin / ChangeMe!
ā ļø Override this in production!
ADMIN_HASH=$(python3 - <<'PY'
import bcrypt
print(bcrypt.hashpw(b"MyStrongAdminPassword123!", bcrypt.gensalt()).decode())
PY)
docker run -d --name bastion \
-p 22:22 \
-p 8080:8080 \
-v bastion_ssh:/etc/ssh \
-v bastion_tmp:/tmp \
-v bastion_auth:/authorized_keys \
-e AUTHORIZED_KEYS="$(cat ~/.ssh/id_ed25519.pub)" \
-e ADMIN_USERNAME=admin \
-e ADMIN_PASSWORD_BCRYPT="$ADMIN_HASH" \
-e SESSION_SECRET="$(python3 - <<'PY'
import secrets; print(secrets.token_hex(32))
PY
)" \
--read-only \
--cap-drop ALL --cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges \
--restart=always \
nexaa/bastion-key-manager:latest
Tunnel through the bastion:
ssh -L 3307:db.internal:3306 bastion@<host>
Connect locally:
mysql -h 127.0.0.1 -P 3307 -u user -p
Keys can be modified through the web UI without restarting the container.
[audit] user=erwin action=add key_suffix='...'
Place your banner at /etc/motd.
Example:
Welcome to the Nexaa Bastion Host!
SSH access is managed via the Web UI.
Avoid double MOTD by setting in sshd_config:
PrintMotd no
UsePAM yes
Content type
Image
Digest
sha256:b830218faā¦
Size
63.3 MB
Last updated
10 months ago
docker pull erwinmaastilaa/simple-bastion