Sign inSign up

ricariel/bastion

By ricariel

•Updated 4 days ago

Small ssh image for bastion host usage.

Image
0

50K+

ricariel/bastion repository overview

⁠docker-ssh-bastion

An SSH jump host in a container. Clients connect through it to SSH servers they cannot reach directly — the usual situation when firewalls, routing or private addressing keep the target hosts off the network the client is on.

The image deliberately offers nothing but forwarding: the single user has no shell, no TTY and no password.

⁠Building

The image is not usable as-is — it needs your public keys at build time:

docker build --build-arg AUTHORIZED_KEYS=./authorized_keys -t ssh-bastion .

AUTHORIZED_KEYS points at a file inside the build context containing one public key per line. It is installed as /home/bastion/.ssh/authorized_keys.

Host keys are generated during the build (ssh-keygen -A), so every build produces a distinct host identity. Rebuilding therefore changes the host key and clients will warn about it — keep a built image around rather than rebuilding casually, or mount persistent host keys over /etc/ssh/.

⁠Running

docker run -d --name bastion -p 2200:22 ssh-bastion

Connect through it to a host behind the bastion:

ssh -J [email protected]:2200 user@internal-host

-J (ProxyJump) is the modern form. The older equivalent:

ssh -o ProxyCommand='ssh -W %h:%p -p 2200 [email protected]' user@internal-host
⁠Client Configuration

Configuring the jump once in ~/.ssh/config avoids repeating it. A pattern can cover a whole set of hosts:

Host bastion
    HostName bastion.example.com
    Port 2200
    User bastion

Host internal-*
    ProxyJump bastion
    User me

ssh internal-web then transparently jumps through the bastion.

⁠What the Image Contains

ComponentPurpose
openssh-serverThe SSH daemon
dumb-initPID 1, so signals and zombie processes are handled correctly
avahi-daemon, libnss-mdnsmDNS name resolution for .local targets

The bastion user is created with /sbin/nologin as its shell and a disabled password, so key authentication is the only way in.

⁠Configuration

There is nothing to configure at runtime. Access is defined entirely by the keys baked in at build time; to change who has access, rebuild with a different AUTHORIZED_KEYS file.

The container exposes port 22 and runs sshd -D -e, which keeps it in the foreground and logs to stderr, so docker logs shows connection attempts.

⁠Known Issues

Two things in this repository do not do what they look like:

  • sshd_config is not applied. The file in the repository root describes the intended hardening (ForceCommand /sbin/nologin, PermitTTY no, AllowUsers bastion, PermitTunnel no, no password auth). The Dockerfile never copies it, so the image runs with the distribution's default configuration. Password authentication is still effectively blocked because the bastion account has no password and no other account is usable, but the explicit restrictions — no TTY, no tunnelling, forced nologin — are not in effect. Copy the file into /etc/ssh/sshd_config in a derived image, or add the COPY here, to get the documented behaviour.
  • The SUID-stripping step is a no-op. find / -perm +6000 is not valid GNU find syntax; the command fails and is swallowed by || true. The correct form is -perm /6000.

⁠Notes

  • Only SSH forwarding is supported. This is not a general-purpose shell host.
  • Only public key authentication is usable.
  • A single user account, bastion, is shared by all clients. Distinguish users by which key authenticated, visible in the container log.

⁠License

MIT — see LICENSE⁠.

Tag summary

Content type

Image

Digest

sha256:fa7c4579d…

Size

40.1 MB

Last updated

4 days ago

docker pull ricariel/bastion