Repository navigation
refactor(ssh-proxy): fix the proxy-to-session target, gate the keygen, default to port 22 - #4675
Merged
SalimKayal merged 6 commits intoOct 8, 2026
Conversation
Collaborator
|
You can access the deployment of this PR at https://ci-renku-4675.dev.renku.ch |
SalimKayal
force-pushed
the
salimkayal/refactor/ssh-proxy-cleanup
branch
from
October 7, 2026 15:20
af3ffc5 to
7db6f0a
Compare
SalimKayal
changed the base branch from
build/renku-ssh-proxy
to
lorenzo/expose-ssh-enabled-ui
October 7, 2026 15:20
SalimKayal
marked this pull request as draft
October 7, 2026 15:38
SalimKayal
marked this pull request as ready for review
October 7, 2026 15:49
sgaist
reviewed
Oct 8, 2026
sgaist
approved these changes
Oct 8, 2026
Base automatically changed from
lorenzo/expose-ssh-enabled-ui
to
build/renku-ssh-proxy
October 8, 2026 09:27
Collaborator
|
Tearing down the temporary RenkuLab deployment for this PR. |
olevski
pushed a commit
that referenced
this pull request
Oct 14, 2026
…, default to port 22 (#4675) ## Summary Cleanup of the SSH proxy: the proxy-to-session target is now fixed rather than configurable, the hop-2 keygen is gated behind `sshProxy.enabled`, the proxy runs two hardened replicas, and the public entry defaults to port **22** so `ssh <session>@ssh.<host>` works with no `-p`. Stacked on #4586. ## Motivation and context - The hop-2 target is fixed by the amalthea contract. The session Service port is `80` and the login user is `renku`. Exposing `sshProxy.targetPort`/`targetUser` in values invites an operator to change a value that silently breaks every session; the proxy's own fallback was also stale at `2222`. - The `platform-init` hook generated the two hop-2 Secrets unconditionally, even when the proxy is disabled. - A single replica with no PodDisruptionBudget is not HA for an internet-facing entry point. - The entry defaulted to `2222`, so the copy-paste command needed a non-standard port. data-services already omits `:22` from the `ssh://` URL, so defaulting to 22 makes the plain command correct. ## Behavior - `ssh <session>@ssh.<host>` connects on the default port 22; `sshProxy.service.port` remains operator-overridable. - With `sshProxy.enabled=false`, the hop-2 key Secrets are no longer generated. - Two proxy replicas are spread across nodes and a PDB keeps one available during node drains. - The external ingress NetworkPolicy admits only the proxy's pod port (2222) instead of all ports. ## Changes - `renku-ssh-proxy/src/config.rs`: hop-2 default target port `2222 → 80`. - `helm-chart/renku/templates/ssh-proxy/deployment.yaml`: drop the `RENKU_SSH_PROXY_TARGET_PORT`/`_TARGET_USER` env; default to preferred hostname pod anti-affinity (overridable via `sshProxy.affinity`). - `helm-chart/renku/templates/ssh-proxy/pdb.yaml` (new): `policy/v1` PDB, `maxUnavailable: 50%`, created only when enabled and `replicaCount > 1`. - `helm-chart/renku/values.yaml`: remove `targetPort`/`targetUser`; `replicaCount: 1 → 2`; `service.port: 2222 → 22`. - `helm-chart/renku/templates/network-policies.yaml`: pin `allow-external-to-ssh-proxy` to pod port `2222`. - `helm-chart/renku/templates/setup-job-platform-init.yaml` + `scripts/platform-init/platform-init.py`: pass `SSH_PROXY_ENABLED` into the hook and guard `ensure_ssh_proxy_session_keys` on it. ## Notes - The NetworkPolicy pins the **pod** port `2222`, which assumes the CNI evaluates ingress policy post-DNAT (Calico/Cilium do). Verify on the first cluster that enables the proxy; a pre-DNAT CNI would need the Service port as well.
SalimKayal
added a commit
that referenced
this pull request
Oct 24, 2026
* docs: clean outdated app references (#4635) * Deleted old references to apps * resolved broken links and how to configure frontends * Run Prettier * resolve links * resolve broken link * resolve first link * resolve broken links * chore: add renku cli docs (#4630) * chore: add renku cli docs * address comments * Initial implementation of renku-ssh-proxy - allow to connect to a fixed target host - include nix testing vm - authenticate with fixed public key - Add dockerfile and workflow for build/publish - Add building ssh-proxy image to chartpress * Authorize ssh access using data services (#4613) * Enable local port-forwarding * Do not allow forwarding outside the session host * Don't break the session if port-forwarding fails * Don't drop connection when data-service connection fails * feat: ssh proxy session keygen (#4626) * chore(helm): drop unused internal-authn mount from ssh-proxy * fix(helm): generate ssh-proxy host key when unset * feat(ssh-proxy-session): add ssh-proxy-session-keys generator image * feat(ssh-proxy-session): generate static proxy-to-session keys via hook job * refactor(ssh-proxy-session): generate proxy-to-session keys in platform-init * feat: ssh proxy session authn (#4627) * feat(ssh-proxy-session): add ssh-proxy-session-keys generator image * feat(ssh-proxy-session): generate static proxy-to-session keys via hook job * refactor(ssh-proxy-session): generate proxy-to-session keys in platform-init * feat(ssh-proxy-session): load session host/auth keys from config * feat(ssh-proxy-session): pin session host key and use publickey auth * feat(ssh-proxy-session): mount session host/auth keys in ssh-proxy * chore(ssh-proxy-session): devshell and dev VM support for session keys * feat(ssh-proxy-session): pass session key secret names to data-services * refactor(ssh-proxy): remove b64 decode fallback from load_private_key_from_file * squashme: Update helm-chart/renku/templates/data-service/session-env-secret.yaml --------- Co-authored-by: Tasko Olevski <16360283+olevski@users.noreply.github.com> * feat: ssh proxy hardening (#4628) * feat(ssh-proxy-session): add ssh-proxy-session-keys generator image * feat(ssh-proxy-session): generate static proxy-to-session keys via hook job * refactor(ssh-proxy-session): generate proxy-to-session keys in platform-init * feat(ssh-proxy-session): load session host/auth keys from config * refactor(ssh-proxy): remove b64 decode fallback from load_private_key_from_file * feat(ssh-proxy): set explicit SSH auth and keepalive limits * feat(ssh-proxy): harden proxy pod security context * feat(ssh-proxy): restrict proxy egress to required peers * fix(ssh-proxy): disable unused ServiceAccount token projection * squashme: Apply batched suggestions from code review Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch> * Update helm-chart/renku/values.yaml --------- Co-authored-by: Tasko Olevski <16360283+olevski@users.noreply.github.com> Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch> * feat(ssh-proxy): dependencies audit in CI (#4629) * feat(ssh-proxy-session): add ssh-proxy-session-keys generator image * feat(ssh-proxy-session): generate static proxy-to-session keys via hook job * refactor(ssh-proxy-session): generate proxy-to-session keys in platform-init * feat(ssh-proxy-session): load session host/auth keys from config * refactor(ssh-proxy): remove b64 decode fallback from load_private_key_from_file * ci(ssh-proxy): audit Cargo.lock for known vulnerabilities * ci(ssh-proxy): track cargo dependencies with dependabot * docs(ssh-proxy): document the dependency audit cadence * refactor(ssh-proxy): use secret service for authz (#4643) * Add ssh subdomain annotation * Fix whitespace in ssh-proxy deployment.yaml * Fix release label in ssh-proxy pod * Add feature flag for ssh-proxy deployment - also pass some information into the data service * Move ssh session keys into default data-service environment * Update build pack images to 0.11.0 * chore: expose SSH_ENABLED variable the the UI pod (#4673) * refactor(ssh-proxy): fix the proxy-to-session target, gate the keygen, default to port 22 (#4675) ## Summary Cleanup of the SSH proxy: the proxy-to-session target is now fixed rather than configurable, the hop-2 keygen is gated behind `sshProxy.enabled`, the proxy runs two hardened replicas, and the public entry defaults to port **22** so `ssh <session>@ssh.<host>` works with no `-p`. Stacked on #4586. ## Motivation and context - The hop-2 target is fixed by the amalthea contract. The session Service port is `80` and the login user is `renku`. Exposing `sshProxy.targetPort`/`targetUser` in values invites an operator to change a value that silently breaks every session; the proxy's own fallback was also stale at `2222`. - The `platform-init` hook generated the two hop-2 Secrets unconditionally, even when the proxy is disabled. - A single replica with no PodDisruptionBudget is not HA for an internet-facing entry point. - The entry defaulted to `2222`, so the copy-paste command needed a non-standard port. data-services already omits `:22` from the `ssh://` URL, so defaulting to 22 makes the plain command correct. ## Behavior - `ssh <session>@ssh.<host>` connects on the default port 22; `sshProxy.service.port` remains operator-overridable. - With `sshProxy.enabled=false`, the hop-2 key Secrets are no longer generated. - Two proxy replicas are spread across nodes and a PDB keeps one available during node drains. - The external ingress NetworkPolicy admits only the proxy's pod port (2222) instead of all ports. ## Changes - `renku-ssh-proxy/src/config.rs`: hop-2 default target port `2222 → 80`. - `helm-chart/renku/templates/ssh-proxy/deployment.yaml`: drop the `RENKU_SSH_PROXY_TARGET_PORT`/`_TARGET_USER` env; default to preferred hostname pod anti-affinity (overridable via `sshProxy.affinity`). - `helm-chart/renku/templates/ssh-proxy/pdb.yaml` (new): `policy/v1` PDB, `maxUnavailable: 50%`, created only when enabled and `replicaCount > 1`. - `helm-chart/renku/values.yaml`: remove `targetPort`/`targetUser`; `replicaCount: 1 → 2`; `service.port: 2222 → 22`. - `helm-chart/renku/templates/network-policies.yaml`: pin `allow-external-to-ssh-proxy` to pod port `2222`. - `helm-chart/renku/templates/setup-job-platform-init.yaml` + `scripts/platform-init/platform-init.py`: pass `SSH_PROXY_ENABLED` into the hook and guard `ensure_ssh_proxy_session_keys` on it. ## Notes - The NetworkPolicy pins the **pod** port `2222`, which assumes the CNI evaluates ingress policy post-DNAT (Calico/Cilium do). Verify on the first cluster that enables the proxy; a pre-DNAT CNI would need the Service port as well. * feat(helm-chart): add label for networkpolicy selector * chore: bump renku-ui to 4.34.0 (#4677) * chore: address rust comments (#4688) * chore: helm chart cleanup (#4680) * feat: update data services to 0.88.0 * chore: update rust dependencies * Remove directories dependency, since it has no usages It's usage was removed in commit #b744c099 * Implement ci checks and adopt github workflow (#4700) When running `nix flake check` all checks in `nix/check.nix` are run: - the crate is compiled - cargo audit - cargo fmt --check - cargo clippy - cargo deny --------- Co-authored-by: bethcg <127967525+bethcg@users.noreply.github.com> Co-authored-by: Ralf Grubenmann <ralf.grubenmann@sdsc.ethz.ch> Co-authored-by: Salim Kayal <salim.kayal@gmail.com> Co-authored-by: Tasko Olevski <16360283+olevski@users.noreply.github.com> Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch> Co-authored-by: Lorenzo Cavazzi <43481553+lorenzo-cavazzi@users.noreply.github.com> Co-authored-by: Salim Kayal <salim.kayal@idiap.ch>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cleanup of the SSH proxy: the proxy-to-session target is now fixed rather than configurable, the hop-2 keygen is gated behind
sshProxy.enabled, the proxy runs two hardened replicas, and the public entry defaults to port 22 sossh <session>@ssh.<host>works with no-p. Stacked on #4586.Motivation and context
80and the login user isrenku. ExposingsshProxy.targetPort/targetUserin values invites an operator to change a value that silently breaks every session; the proxy's own fallback was also stale at2222.platform-inithook generated the two hop-2 Secrets unconditionally, even when the proxy is disabled.2222, so the copy-paste command needed a non-standard port. data-services already omits:22from thessh://URL, so defaulting to 22 makes the plain command correct.Behavior
ssh <session>@ssh.<host>connects on the default port 22;sshProxy.service.portremains operator-overridable.sshProxy.enabled=false, the hop-2 key Secrets are no longer generated.Changes
renku-ssh-proxy/src/config.rs: hop-2 default target port2222 → 80.helm-chart/renku/templates/ssh-proxy/deployment.yaml: drop theRENKU_SSH_PROXY_TARGET_PORT/_TARGET_USERenv; default to preferred hostname pod anti-affinity (overridable viasshProxy.affinity).helm-chart/renku/templates/ssh-proxy/pdb.yaml(new):policy/v1PDB,maxUnavailable: 50%, created only when enabled andreplicaCount > 1.helm-chart/renku/values.yaml: removetargetPort/targetUser;replicaCount: 1 → 2;service.port: 2222 → 22.helm-chart/renku/templates/network-policies.yaml: pinallow-external-to-ssh-proxyto pod port2222.helm-chart/renku/templates/setup-job-platform-init.yaml+scripts/platform-init/platform-init.py: passSSH_PROXY_ENABLEDinto the hook and guardensure_ssh_proxy_session_keyson it.Notes
2222, which assumes the CNI evaluates ingress policy post-DNAT (Calico/Cilium do). Verify on the first cluster that enables the proxy; a pre-DNAT CNI would need the Service port as well./deploy #notest extra-values=sshProxy.enabled=true,dataService.imageBuilders.enabled=true,dataService.imageBuilders.strategyName=renku-buildpacks-v3,dataService.imageBuilders.outputImagePrefix=harbor.dev.renku.ch/renku-build/,dataService.imageBuilders.nodeSelector.renku.io/node-purpose=user,dataService.imageBuilders.tolerations[0].effect=NoSchedule,dataService.imageBuilders.tolerations[0].key=renku.io/dedicated,dataService.imageBuilders.tolerations[0].operator=Equal,dataService.imageBuilders.tolerations[0].value=user renku-data-services=salimkayal/feat/ssh-keys renku-ui=lorenzo/ssh-keys-allow-disabled