An awesome sshjumphost (bastion host) for easily accessing container backend networks
4.9K
An awesome sshjumphost (bastion host) for easily accessing container backend networks and other ssh gateway games.
The sshjumphost makes easy work of setting up containerized ssh-key based or
user-ca-key based authentication ssh jumphosts.
By default, sshjumphost does not provide any login-shell since the intent is
to jump from the sshjumphost to another. All TCP port forwarding and -J
style ssh jumphost functionality is possible without a shell. You can still
get a shell setting the SSH_SHELL environment variable.
Example: establish a SOCKS proxy inside your backend network
user@computer ~/$ ssh -D 1080 [email protected]
#
# sshjumphost
# version: 3.0.0 (a0dbd7a7)
# documentation: https://github.com/threatpatrols/docker-sshjumphost
#
# NB: set the SSH_SHELL environment variable to enable a login-shell at the sshjumphost.
#
docker pull threatpatrols/sshjumphost
services:
externalhost01:
# Description :
# - username adjusted to "awesome" rather than the default "sshjumphost"
# - ssh key(s) supplied via environment variable in this example externalhost01
# - mount /data/hostkeys to store the hostkeys so these remain persistent on restart
# - this host is attached to the "awesome_network" that the "internalhost01" is also attached to below
image: threatpatrols/sshjumphost:latest
restart: unless-stopped
ports:
- 22222:22/tcp
volumes:
- "hostkeys_externalhost01:/data/hostkeys"
networks:
- awesome_network
environment:
SSH_USERNAME: "awesome" # NB: default = sshjumphost
SSH_AUTHORIZED_KEYS: "[email protected] xxxxxxxxxxxxxxxxxxxxxxxxx" # NB: use your ssh key(s) here
internalhost01:
# Description :
# - username here is also adjusted to "awesome" rather than the default "sshjumphost"
# - ssh key(s) supplied via volume mount in this example internalhost01, alternative would be to simply
# mount "/data/userkeys/authorized_keys" and not set SSH_AUTHORIZED_KEYS
# - mount /data/hostkeys to store the hostkeys so these remain persistent on restart
# - this host is also attached to the "awesome_network" which makes it reachable from the above externalhost01 host
# - this host has SSH_SHELL defined which hence provides the user with a shell for the sake of the example
image: threatpatrols/sshjumphost:latest
restart: unless-stopped
volumes:
- "hostkeys_internalhost01:/data/hostkeys"
- "/home/awesome/.ssh/authorized_keys:/data/userkeys/awesome_authorized_keys:ro"
networks:
- awesome_network
environment:
SSH_USERNAME: "awesome"
SSH_SHELL: "/bin/bash"
SSH_AUTHORIZED_KEYS: "/data/userkeys/awesome_authorized_keys" # NB: name of mount above
networks:
awesome_network:
volumes:
hostkeys_externalhost01:
hostkeys_internalhost01:
Starting this docker-compose creates 2x docker-containers, where externalhost01
is reachable via localhost on tcp-22222 and internalhost01 that is only reachable
via connectivity to the awesome_network
It is now possible to reach internalhost01 by using the -J switch to jump
through externalhost01 located at 127.0.0.1:22222
Note in the example provided the SSH_SHELL has been set on the internalhost01
which provides the shell prompt as shown below.
user@computer ~/$ ssh -J 127.0.0.1:22222 internalhost01
The authenticity of host 'internalhost01 (<no hostip for proxy command>)' can't be established.
ED25519 key fingerprint is SHA256:eoCSPJQMzNcmTZcaE0ge3EL4XbmTW8Y0bGqTZZ0Byk8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'internalhost01' (ED25519) to the list of known hosts.
#
# sshjumphost: refer to documentation
# https://hub.docker.com/r/threatpatrols/sshjumphost
#
# NB: set the SSH_SHELL environment variable to enable a login-shell at the sshjumphost.
#
0bf40e5b195f:~$
The sshjumphost container also provides good visibility to STDOUT making it easy to monitor via your container-environment logging etc.
dev-host01-1 | ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519
dev-host01-1 | hostname: 0bf40e5b195f
dev-host01-1 | ip addr: inet 192.168.112.2/20 brd 192.168.127.255 scope global eth0
dev-host01-1 | username: awesome
dev-host01-1 | sshkey-fingerprints:
dev-host01-1 | 4096 SHA256:BjNltbmmfjBAF6/liSr+7NANEWzbyDvLJ6w7eTA928c (RSA)
dev-host01-1 | hostkey-fingerprints:
dev-host01-1 | 1024 SHA256:eXQcmDnDi2ydn+DAtLW0hGu9uXU5HTDKjNnrptyunFo root@0bf40e5b195f (DSA)
dev-host01-1 | 256 SHA256:8tIwmrhrK8+ZLw34B+OtVvOQe976d9mRByNpgnRR2FM root@0bf40e5b195f (ECDSA)
dev-host01-1 | 256 SHA256:eoCSPJQMzNcmTZcaE0ge3EL4XbmTW8Y0bGqTZZ0Byk8 root@0bf40e5b195f (ED25519)
dev-host01-1 | 3072 SHA256:cOue3Ig4hFIYWaHW1Xm3jv923+tkDAUeICw6Kk/R7gs root@0bf40e5b195f (RSA)
dev-host01-1 | sshd_command: /usr/sbin/sshd -D -e -4 -o PasswordAuthentication=no -o PermitEmptyPasswords=no -o PermitRootLogin=no -o AuthorizedKeysFile=/data/home/.ssh/authorized_keys -o HostKey=/data/hostkeys/ssh_host_dsa_key -o HostKey=/data/hostkeys/ssh_host_ecdsa_key -o HostKey=/data/hostkeys/ssh_host_ed25519_key -o HostKey=/data/hostkeys/ssh_host_rsa_key -o PubkeyAuthentication=yes -o GatewayPorts=no -o PermitTunnel=no -o X11Forwarding=no -o AllowTcpForwarding=yes -o AllowAgentForwarding=yes -o ListenAddress=0.0.0.0 -o Port=22 -o LogLevel=INFO
dev-host01-1 | Server listening on 0.0.0.0 port 22.
SSH_USERNAME [<username>]sshjumphostChange the username to suit your purposes.
SSH_AUTHORIZED_KEYS [<sshkey-value> | <filepath>]/data/userkeys/authorized_keysCan be either the actual ssh-key string-value -or- set as the pathname to the volume-mounted public-key(s) if you mount the keys at a location other than the default.
Recall that it is possible to set this value with more than one ssh-public key, using one key per line.
SSH_SHELL [<filename>]/bin/ddBy default, the sshjumphost user shell is set to /bin/dd that establishes a
session that does not terminate unless user-interrupted (eg CONTROL-C). This hence
creates a sshjumphost cannot be repurposed for other usage beyond the intended
jumphost capability.
By setting the SSH_SHELL environment variable to /bin/ash it is possible to
gain a login-shell on the sshjumphost if required for some reason.
SSHD_TRUSTED_USER_CA_KEYS [<cakey-value> | <filepath>]/data/cakeys/trusted_keysCan be either the actual ca-key string-value -or- set as the pathname to the volume-mounted ca-key if you mount the key at a location other than the default.
The associated AuthorizedPrincipalsFile is read from /data/cakeys/authorized_principals and
if this file does not already exist (eg via a volume-mount) then it is populated
with a single entry for the SSH_USERNAME
Using this mechanism it is possible to operate the sshjumphost in a way that accommodates multiple usernames authenticated through their individual user-keys that have been signed by the certificate authority.
SSHD_GATEWAY_PORTS [yes | no]noSpecifies whether remote hosts are allowed to connect to ports forwarded for the client (ie reverse tunneling)
SSHD_PERMIT_TUNNEL [yes | no]noSpecifies whether tun(4) device forwarding is allowed - NB: this is typically not what you want if you are just looking for TCP port-forwarding.
SSHD_X11_FORWARDING [yes | no]noSpecifies whether X11 forwarding is permitted.
SSHD_ALLOW_TCP_FORWARDING [yes | no]yesSpecifies whether TCP forwarding is permitted.
SSHD_ALLOW_AGENT_FORWARDING [yes | no]yesSpecifies whether ssh-agent forwarding is permitted.
SSHD_PERMIT_ROOT_LOGIN [yes | no]noSpecifies whether a root user login is permitted.
SSHD_LISTEN_ADDRESS [<ipv4-address>]0.0.0.0Specifies the local addresses sshd(8) should listen on.
SSHD_LISTEN_PORT [<port-number>]22Specifies the TCP port number that sshd(8) listens on.
SSHD_LOGLEVEL [<log-level>]INFOGives the verbosity level that is used when logging messages from sshd(8).
This project originally forked from binlab/docker-bastion and mostly re-written top to bottom - thanks Mark for the initial base to work from.
Content type
Image
Digest
sha256:de9238489…
Size
44 MB
Last updated
almost 2 years ago
docker pull threatpatrols/sshjumphost