Skip to content

fix(gluekube_ssh): use ProxyJump instead of SSH agent forwarding - #562

Open
venkatamutyala wants to merge 2 commits into
mainfrom
fix/gluekube-ssh-proxyjump
Open

fix(gluekube_ssh): use ProxyJump instead of SSH agent forwarding#562
venkatamutyala wants to merge 2 commits into
mainfrom
fix/gluekube-ssh-proxyjump

Conversation

@venkatamutyala

Copy link
Copy Markdown
Contributor

Problem

gluekube_ssh --profile <p> --cluster <fqdn> --kubectl (and the interactive SSH / kubeconfig / port-forward paths) fail with:

✗ Failed to fetch kubeconfig - aborting (existing ~/.kube/config left untouched)

Root cause is not the AutoGlue API — cluster resolution, /clusters/<id>, and /ssh/<id>?reveal=true all return correct data. The bastion's sshd has been hardened to:

allowagentforwarding no
allowtcpforwarding yes

Every bastion hop in the script used ssh -A + a nested ssh on the bastion and relied on the forwarded agent to authenticate the second hop. With agent forwarding disabled, the forwarded agent is stripped and the master rejects the connection: Permission denied (publickey).

Fix

Reach cluster nodes through the bastion with a -W ProxyCommand instead of agent forwarding. Both hops authenticate from the local ssh-agent (keys are already loaded by load_connection_keys):

  • The agent is never forwarded to the bastion → works with AllowAgentForwarding no.
  • No private key is ever written to disk → more secure than agent forwarding, and avoids key-at-rest exposure.
  • Only needs AllowTcpForwarding yes, which is enabled.

Converted call sites: headless quick-connect fetch + port-forward (kubeconfig_and_port_forward), interactive port-forward (kubectl_mode), kubeconfig copy (kubeconfig_mode), and non-bastion SSH (connect_ssh). Added a shared bastion_proxy helper + SSH_OPTS.

Because the tunnel now terminates on the master, the port-forwards bind 6443 locally only — nothing on the bastion — so the random mid-port workaround (previously needed to dodge a stale bastion-side 6443 bind) is removed.

Testing

Verified end-to-end against nonprod.jupiter.onglueops.rocks:

  • Fresh kubeconfig fetched and saved.
  • Foreground port-forward established; kubectl get --raw=/version through the tunnel returned v1.34.5.
  • bash -n syntax check passes.

🤖 Generated with Claude Code

…ent forwarding

The bastion's sshd now sets `AllowAgentForwarding no` (AllowTcpForwarding is
still yes). Every double-hop in gluekube_ssh relied on `ssh -A` + a nested
`ssh` on the bastion, so the forwarded agent was stripped and the second hop
failed with "Permission denied (publickey)" — the kubeconfig fetch, the
port-forwards, and interactive SSH to non-bastion nodes all broke.

Switch all bastion hops to a `-W` ProxyCommand and authenticate both hops from
the LOCAL ssh-agent (keys are already loaded by load_connection_keys). The
agent is never exposed to the bastion and no private key is written to disk,
so this is both functional again and more secure than agent forwarding.

Because the tunnel now terminates on the master, the port-forwards only bind
6443 locally — nothing on the bastion — so the random mid-port workaround that
existed to dodge a stale bastion-side 6443 bind is removed.

Verified end-to-end against nonprod.jupiter.onglueops.rocks: fresh kubeconfig
fetched and the forwarded API answered kubectl (v1.34.5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant