Add ldap-test-host: a real LDAP-joined downstream host for testing jump-host

New optional service (jump-host compose profile) built from the new
theta42/ldap-client submodule: a genuinely SSSD + AuthorizedKeysCommand
LDAP-joined host, not a container with a manually-dropped public key in
authorized_keys. Lets jump-host's actual key-injection -> upstream-connect
flow be exercised end-to-end against the local dev stack's own LDAP.

Verified: real SSH login through jump-host's uid_-_target grammar, live key
injection into LDAP, and ldap-test-host serving that key via
AuthorizedKeysCommand -- both via the SSH CLI and WinSCP.

config.example/ldap-test-host.vars.example documents the one field an
operator fills in (the ldapclient service account's bind password, already
generated by bootstrap.js as serviceAccountPass) -- the rest points at this
stack's own local LDAP by default.
This commit is contained in:
2026-07-30 09:47:54 -04:00
parent f2e924bf58
commit 084c8fdfb3
4 changed files with 55 additions and 0 deletions
+3
View File
@@ -8,3 +8,6 @@
path = jump-host path = jump-host
url = https://github.com/theta42/jump-host.git url = https://github.com/theta42/jump-host.git
branch = master branch = master
[submodule "ldap-client"]
path = ldap-client
url = https://github.com/theta42/ldap-client.git
@@ -0,0 +1,26 @@
# ldap-client config for the optional local jump-host test fixture
# (ldap-test-host service in docker-compose.yml, jump-host compose profile).
# Copy to ./config/ldap-test-host.vars and fill in the bind password from
# your own ./config/sso-secrets.js's `serviceAccountPass` (the
# cn=ldapclient,ou=people,<base> service account bootstrap/bootstrap.js
# creates specifically for this kind of 3rd-party/container LDAP bind).
#
# This is what lets ldap-test-host be a REAL SSSD+AuthorizedKeysCommand-joined
# downstream host, so jump-host's key-injection -> upstream-connect flow can
# be exercised end-to-end against something more than a container with a
# manually-dropped public key in authorized_keys.
export ldap_host="sso-manager"
export ldap_base_dn="dc=localtest,dc=me"
export ldap_bind_dn="cn=ldapclient,ou=People,$ldap_base_dn"
export ldap_bind_password="REPLACE_WITH_serviceAccountPass_FROM_sso-secrets.js"
# sso_url/sso_token deliberately left unset -- register the host + access
# group manually via the Directory admin API instead (index.sh's optional
# auto-registration also wants a parent site Resource to exist first).
# index.sh gates that block on `[[ -v sso_token ]]`, which is true even for
# an empty string, so leave these genuinely absent, not "".
export ldap_location="jumptest"
ldap_access_groups=( "${ldap_location}_access" "${ldap_location}_host_$(hostname)_access" )
+25
View File
@@ -189,6 +189,31 @@ services:
- jump-data:/var/lib/jump-host # generated host keys persist here - jump-data:/var/lib/jump-host # generated host keys persist here
- jump-redis-data:/data # Redis (sessions, OAuth state, API tokens) persists here - jump-redis-data:/data # Redis (sessions, OAuth state, API tokens) persists here
# A real, LDAP-joined (SSSD + AuthorizedKeysCommand) downstream host for
# testing jump-host's actual key-injection -> upstream-connect flow --
# a container with a manually-dropped public key in authorized_keys never
# exercises the LDAP-key-serving path a real production host does. Built
# from the theta42/ldap-client submodule -- see ./config/ldap-test-host.vars
# for setup notes. Same jump-host profile, so
# `docker compose --profile jump-host up` brings up jump-host and a host it
# can actually reach together.
ldap-test-host:
profiles: ["jump-host"]
build:
context: ./ldap-client
dockerfile: Dockerfile
container_name: ldap-test-host
hostname: ldap-test-host
restart: unless-stopped
networks: [theta-net]
depends_on:
sso-manager:
condition: service_healthy
privileged: false
volumes:
- ./config/ldap-test-host.vars:/config/ldap.vars:ro
- ./config/ldap-ca.crt:/config/ldap-ca.crt:ro
networks: networks:
theta-net: theta-net:
driver: bridge driver: bridge
Submodule
+1
Submodule ldap-client added at f6cf923974