{"id":28391252,"url":"https://github.com/threatpatrols/docker-sshjumphost","last_synced_at":"2026-03-18T01:33:35.695Z","repository":{"id":143026093,"uuid":"538362601","full_name":"threatpatrols/docker-sshjumphost","owner":"threatpatrols","description":"A fancy sshjumphost (bastion host) for accessing backend networks","archived":false,"fork":false,"pushed_at":"2024-10-15T12:18:34.000Z","size":145,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-31T19:03:20.481Z","etag":null,"topics":["bastion-host","docker","jumphost","ssh"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/threatpatrols/sshjumphost","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/threatpatrols.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-19T06:27:08.000Z","updated_at":"2025-04-12T08:31:36.000Z","dependencies_parsed_at":"2024-01-31T16:37:20.855Z","dependency_job_id":"3193037a-9c8b-4845-a2b1-3d8cae12268a","html_url":"https://github.com/threatpatrols/docker-sshjumphost","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threatpatrols%2Fdocker-sshjumphost","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threatpatrols%2Fdocker-sshjumphost/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threatpatrols%2Fdocker-sshjumphost/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threatpatrols%2Fdocker-sshjumphost/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/threatpatrols","download_url":"https://codeload.github.com/threatpatrols/docker-sshjumphost/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threatpatrols%2Fdocker-sshjumphost/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258539926,"owners_count":22717311,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bastion-host","docker","jumphost","ssh"],"created_at":"2025-05-31T08:39:58.089Z","updated_at":"2026-03-18T01:33:30.668Z","avatar_url":"https://github.com/threatpatrols.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sshjumphost\nAn awesome sshjumphost (bastion host) for easily accessing container backend networks and other ssh gateway games.\n\nThe `sshjumphost` makes easy work of setting up containerized ssh-key based or \nuser-ca-key based authentication ssh jumphosts.\n\nBy default, sshjumphost does not provide any login-shell since the intent is \nto __jump__ from the sshjumphost to another.  All TCP port forwarding and `-J` \nstyle ssh jumphost functionality is possible without a shell.  You can still\nget a shell setting the `SSH_SHELL` environment variable.\n\nExample: establish a SOCKS proxy inside your backend network\n```commandline\nuser@computer ~/$ ssh -D 1080 username@awesome.company.net\n#\n# sshjumphost\n# version: 3.0.0 (a0dbd7a7)\n# documentation: https://github.com/threatpatrols/docker-sshjumphost\n#\n# NB: set the SSH_SHELL environment variable to enable a login-shell at the sshjumphost.\n#\n```\n\n## Docker\n```commandline\ndocker pull threatpatrols/sshjumphost\n```\n* https://hub.docker.com/r/threatpatrols/sshjumphost\n\n---\n\n## Docker-compose example\n\n```dockerfile\nservices:\n\n  externalhost01:\n    # Description :\n    #  - username adjusted to \"awesome\" rather than the default \"sshjumphost\"\n    #  - ssh key(s) supplied via environment variable in this example externalhost01\n    #  - mount /data/hostkeys to store the hostkeys so these remain persistent on restart\n    #  - this host is attached to the \"awesome_network\" that the \"internalhost01\" is also attached to below\n\n    image: threatpatrols/sshjumphost:latest\n    restart: unless-stopped\n    ports:\n      - 22222:22/tcp\n    volumes:\n      - \"hostkeys_externalhost01:/data/hostkeys\"\n    networks:\n      - awesome_network\n    environment:\n      SSH_USERNAME: \"awesome\"  # NB: default = sshjumphost\n      SSH_AUTHORIZED_KEYS: \"sk-ecdsa-sha2-nistp256@openssh.com xxxxxxxxxxxxxxxxxxxxxxxxx\"  # NB: use your ssh key(s) here\n\n  internalhost01:\n    # Description :\n    #  - username here is also adjusted to \"awesome\" rather than the default \"sshjumphost\"\n    #  - ssh key(s) supplied via volume mount in this example internalhost01, alternative would be to simply\n    #    mount \"/data/userkeys/authorized_keys\" and not set SSH_AUTHORIZED_KEYS\n    #  - mount /data/hostkeys to store the hostkeys so these remain persistent on restart\n    #  - this host is also attached to the \"awesome_network\" which makes it reachable from the above externalhost01 host\n    #  - this host has SSH_SHELL defined which hence provides the user with a shell for the sake of the example\n\n    image: threatpatrols/sshjumphost:latest\n    restart: unless-stopped\n    volumes:\n      - \"hostkeys_internalhost01:/data/hostkeys\"\n      - \"/home/awesome/.ssh/authorized_keys:/data/userkeys/awesome_authorized_keys:ro\"\n    networks:\n      - awesome_network\n    environment:\n      SSH_USERNAME: \"awesome\"\n      SSH_SHELL: \"/bin/bash\"\n      SSH_AUTHORIZED_KEYS: \"/data/userkeys/awesome_authorized_keys\"  # NB: name of mount above\n\nnetworks:\n  awesome_network:\n\nvolumes:\n  hostkeys_externalhost01:\n  hostkeys_internalhost01:\n\n```\n\nStarting this docker-compose creates 2x docker-containers, where `externalhost01`\nis reachable via localhost on tcp-22222 and `internalhost01` that is only reachable\nvia connectivity to the `awesome_network`\n\nIt is now possible to reach `internalhost01` by using the `-J` switch to jump \nthrough `externalhost01` located at 127.0.0.1:22222\n\nNote in the example provided the `SSH_SHELL` has been set on the `internalhost01` \nwhich provides the shell prompt as shown below.\n```commandline\nuser@computer ~/$ ssh -J 127.0.0.1:22222 internalhost01\nThe authenticity of host 'internalhost01 (\u003cno hostip for proxy command\u003e)' can't be established.\nED25519 key fingerprint is SHA256:eoCSPJQMzNcmTZcaE0ge3EL4XbmTW8Y0bGqTZZ0Byk8.\nThis key is not known by any other names\nAre you sure you want to continue connecting (yes/no/[fingerprint])? yes\nWarning: Permanently added 'internalhost01' (ED25519) to the list of known hosts.\n#\n# sshjumphost: refer to documentation\n# https://hub.docker.com/r/threatpatrols/sshjumphost\n#\n# NB: set the SSH_SHELL environment variable to enable a login-shell at the sshjumphost.\n#\n0bf40e5b195f:~$\n```\n\nThe sshjumphost container also provides good visibility to STDOUT making it easy to\nmonitor via your container-environment logging etc.\n```\ndev-host01-1  | ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519\ndev-host01-1  | hostname: 0bf40e5b195f\ndev-host01-1  | ip addr: inet 192.168.112.2/20 brd 192.168.127.255 scope global eth0\ndev-host01-1  | username: awesome\ndev-host01-1  | sshkey-fingerprints:\ndev-host01-1  | 4096 SHA256:BjNltbmmfjBAF6/liSr+7NANEWzbyDvLJ6w7eTA928c (RSA)\ndev-host01-1  | hostkey-fingerprints:\ndev-host01-1  | 1024 SHA256:eXQcmDnDi2ydn+DAtLW0hGu9uXU5HTDKjNnrptyunFo root@0bf40e5b195f (DSA)\ndev-host01-1  | 256 SHA256:8tIwmrhrK8+ZLw34B+OtVvOQe976d9mRByNpgnRR2FM root@0bf40e5b195f (ECDSA)\ndev-host01-1  | 256 SHA256:eoCSPJQMzNcmTZcaE0ge3EL4XbmTW8Y0bGqTZZ0Byk8 root@0bf40e5b195f (ED25519)\ndev-host01-1  | 3072 SHA256:cOue3Ig4hFIYWaHW1Xm3jv923+tkDAUeICw6Kk/R7gs root@0bf40e5b195f (RSA)\ndev-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\ndev-host01-1  | Server listening on 0.0.0.0 port 22.\n```\n\n---\n\n## Configuration ENV variables\n\n### `SSH_USERNAME [\u003cusername\u003e]`\n* Default: `sshjumphost`\n\nChange the username to suit your purposes.\n\n### `SSH_AUTHORIZED_KEYS [\u003csshkey-value\u003e | \u003cfilepath\u003e]`\n* Default: `/data/userkeys/authorized_keys`\n\nCan be either the __actual__ ssh-key string-value -or- set as the pathname\nto the volume-mounted public-key(s) if you mount the keys at a location other\nthan the default.\n\nRecall that it is possible to set this value with more than one ssh-public \nkey, using one key per line.\n\n### `SSH_SHELL [\u003cfilename\u003e]`\n* Default: `/bin/dd`\n\nBy default, the sshjumphost user shell is set to `/bin/dd` that establishes a\nsession that does not terminate unless user-interrupted (eg CONTROL-C).  This hence\ncreates a sshjumphost cannot be repurposed for other usage beyond the intended \n__jumphost__ capability.\n\nBy setting the `SSH_SHELL` environment variable to `/bin/ash` it is possible to\ngain a login-shell on the sshjumphost if required for some reason. \n\n### `SSHD_TRUSTED_USER_CA_KEYS [\u003ccakey-value\u003e | \u003cfilepath\u003e]`\n* Default: `/data/cakeys/trusted_keys`\n\nCan be either the __actual__ ca-key string-value -or- set as the pathname\nto the volume-mounted ca-key if you mount the key at a location other than\nthe default.\n\nThe associated `AuthorizedPrincipalsFile` is read from `/data/cakeys/authorized_principals` and\nif this file does not already exist (eg via a volume-mount) then it is populated\nwith a single entry for the `SSH_USERNAME`\n\nUsing this mechanism it is possible to operate the sshjumphost in a way that \naccommodates multiple usernames authenticated through their individual user-keys \nthat have been signed by the certificate authority.\n\n### `SSHD_GATEWAY_PORTS [yes | no]`\n* Default: `no`\n\nSpecifies whether remote hosts are allowed to connect to ports forwarded for the \nclient (ie reverse tunneling)\n* https://man.openbsd.org/sshd_config#GatewayPorts\n\n### `SSHD_PERMIT_TUNNEL [yes | no]`\n* Default: `no`\n\nSpecifies whether tun(4) device forwarding is allowed - NB: this is typically __not__ what you \nwant if you are just looking for TCP port-forwarding.\n* https://man.openbsd.org/sshd_config#PermitTunnel\n\n### `SSHD_X11_FORWARDING [yes | no]`\n* Default: `no`\n\nSpecifies whether X11 forwarding is permitted.\n* https://man.openbsd.org/sshd_config#X11Forwarding\n\n### `SSHD_ALLOW_TCP_FORWARDING [yes | no]`\n* Default: `yes`\n\nSpecifies whether TCP forwarding is permitted.\n* https://man.openbsd.org/sshd_config#AllowTcpForwarding\n\n### `SSHD_ALLOW_AGENT_FORWARDING [yes | no]`\n* Default: `yes`\n\nSpecifies whether ssh-agent forwarding is permitted.\n* https://man.openbsd.org/sshd_config#AllowAgentForwarding\n\n### `SSHD_PERMIT_ROOT_LOGIN [yes | no]`\n* Default: `no`\n\nSpecifies whether a root user login is permitted.\n* https://man.openbsd.org/sshd_config#PermitRootLogin\n\n### `SSHD_LISTEN_ADDRESS [\u003cipv4-address\u003e]`\n* Default: `0.0.0.0`\n\nSpecifies the local addresses sshd(8) should listen on.\n* https://man.openbsd.org/sshd_config#ListenAddress\n\n### `SSHD_LISTEN_PORT [\u003cport-number\u003e]`\n* Default: `22`\n\nSpecifies the TCP port number that sshd(8) listens on.\n* https://man.openbsd.org/sshd_config#Port\n\n### `SSHD_LOGLEVEL [\u003clog-level\u003e]`\n* Default: `INFO`\n\nGives the verbosity level that is used when logging messages from sshd(8).\n* https://man.openbsd.org/sshd_config#LogLevel\n\n---\n\n## Noteable Changes\n* v2.x to v3.x - moved from Alpine based images to Debian images \n\n## Source\n* https://github.com/threatpatrols/docker-sshjumphost\n\n## Copyright\n* Copyright (c) 2022-2024 Nicholas de Jong \u003cndejong@threatpatrols.com\u003e\n\n## Thanks\nThis project originally forked from [binlab/docker-bastion](https://github.com/binlab/docker-bastion) and\nmostly re-written top to bottom - thanks Mark for the initial base to work from.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthreatpatrols%2Fdocker-sshjumphost","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthreatpatrols%2Fdocker-sshjumphost","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthreatpatrols%2Fdocker-sshjumphost/lists"}