You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Edit (correction): an earlier version of this issue claimed the current plugin fails to
connect to stock modern-OpenSSH agents. Hands-on testing disproves that for the latest release
— rsa-sha2 already works end-to-end on 4.3.17.1. The body below is corrected and the scope is
narrowed accordingly. Details + evidence in the "Verification" section.
Summary
Historically the plugin's SSH agent launcher negotiated only ssh-rsa (RSA + SHA-1), which breaks
against OpenSSH 8.8+ (where ssh-rsa is disabled by default). That gap is already closed for rsa-sha2 in current releases — the bundled trilead-api negotiates rsa-sha2-256/512 for both
host-key verification and client public-key auth. The remaining, genuinely-missing capability is Ed25519 (and modern key types) for the plugin's auto-generated client key, plus making the key
type configurable. This issue proposes adding that, and would value maintainer input on scope before
a PR.
What already works (verified, latest release)
rsa-sha2 requires no new code on a current plugin. The SSH client (trilead-api, currently build-217-jenkins-371 on develop; build-217-jenkins-247 in release 4.3.17.1) registers rsa-sha2-256/rsa-sha2-512 ahead of ssh-rsa and AuthenticationManager selects from that list,
so the existing RSA-2048 key authenticates with a SHA-2 signature.
The capability first shipped in 4.3.5 (trilead-api 1.0.13). Releases 4.3.0–4.3.4 (trilead-api
1.0.3) are ssh-rsa-only.
What's actually missing
Ed25519 client keys.ssh/SshKeysHelper.generate() hardcodes JSch KeyPair.RSA, 2048 and an "ssh-rsa " public-key prefix. There is no way to provision an ssh-ed25519 (or ECDSA) auto-key.
The bundled mwiede JSch can already generate these; trilead can authenticate Ed25519 (it bundles ED25519KeyAlgorithm, with eddsa present transitively via trilead-api).
No key-type configurability.SshConfiguration only exposes customPrivateKeyCredentialsId;
there's no selector for the generated key type.
(To confirm) host-key guest-attribute naming.ComputeEngineComputerLauncher.verifyServerHostKey()
looks up the GCE guest attribute hostkeys/<name> by serverHostKeyAlgorithm.toLowerCase(). With rsa-sha2-* negotiated, the lookup for that name won't match the ssh-rsa-named attribute. This
path is currently fail-open (returns true on miss), so it does not break connections, but it
silently skips host-key verification — worth tightening alongside this work.
Verification
Isolated reproduction of the plugin's SSH bring-up (connectToSsh() → Connection.connect() then authenticateWithPublicKey(user, key, "")), using the plugin's exact bundled trilead jars and an
RSA-2048 client key, against a real sshd:
Plugin (trilead)
Server
Host-key
Client auth
Result
4.3.0 / jenkins-16 (ssh-rsa only)
stock Debian 12 (OpenSSH 9.2), no override
ssh-ed25519
rejected (signs ssh-rsa)
FAIL
4.3.0 / jenkins-16
Debian 12 + PubkeyAcceptedAlgorithms +ssh-rsa
ssh-ed25519
ssh-rsa accepted
PASS
4.3.17.1 / jenkins-247 (latest)
stock Debian 12 (OpenSSH 9.2), no override
ssh-ed25519
rsa-sha2
PASS
4.3.17.1 / jenkins-247
stock Debian 13 (OpenSSH 10.0), no override
ssh-ed25519
rsa-sha2
PASS
4.3.17.1 / jenkins-247
ssh-rsa force-disabled both legs, RSA-only host key
rsa-sha2-256
rsa-sha2
PASS
Takeaways: on the latest release, rsa-sha2 host-key + client-auth already work against stock Debian
12/13 with ssh-rsa disabled; the only legacy-ssh-rsa failures are on pre-4.3.5 plugins, on the client-auth leg.
Proposed scope
Add Ed25519 (and optionally ECDSA) as a selectable type for the auto-generated client key, default
unchanged (RSA):
Thread a key-type param through GoogleKeyPair.generate() / SshKeysHelper.generate() (use JSch KeyPairEd25519; emit the correct ssh-ed25519 public-key prefix).
Add a key-type selector to SshConfiguration (config.jelly + help-*.html + doCheck), default
RSA. Migration follows the preemptible → provisioningType precedent (readResolve() +
JCasC-compat setter); old serialized configs keep producing RSA.
Preserve the SECURITY-2045 invariant (private key stays hudson.util.Secret).
Tighten verifyServerHostKey so rsa-sha2-* maps to the ssh-rsa guest-attribute name (stop the
silent fail-open for RSA host keys).
A separate, optional hardening: a regression IT that provisions a stock Ubuntu 22.04 / Debian 12 agent
(no sshd_config overrides) and asserts the handshake succeeds — to lock in the rsa-sha2 behavior
that already works.
Backward compatibility
Default behavior unchanged: RSA auto-key, existing negotiation. The new key-type field is opt-in and
defaults to RSA, with serialized-config migration.
Testing plan
Unit: extend SshKeysHelper/GoogleKeyPairTest (keep the SECURITY-2045 plaintext-never-persisted
assertion); update InstanceConfigurationTest#testConfigRoundtrip and ConfigAsCodeTest round-trip
fixture YAML for the new field.
Integration: a *IT.java provisioning a real GCE VM that authenticates with an Ed25519 auto-key;
plus the stock-image rsa-sha2 regression IT above.
Open questions for maintainers
Is "Ed25519 client key + key-type selector" the scope you'd want, with RSA staying the default?
Worth adding the stock-image rsa-sha2 regression IT even though no production code changes for it?
Should verifyServerHostKey's rsa-sha2-* → ssh-rsa naming fix land in this issue or separately?
Summary
Historically the plugin's SSH agent launcher negotiated only
ssh-rsa(RSA + SHA-1), which breaksagainst OpenSSH 8.8+ (where
ssh-rsais disabled by default). That gap is already closed forrsa-sha2in current releases — the bundledtrilead-apinegotiatesrsa-sha2-256/512for bothhost-key verification and client public-key auth. The remaining, genuinely-missing capability is
Ed25519 (and modern key types) for the plugin's auto-generated client key, plus making the key
type configurable. This issue proposes adding that, and would value maintainer input on scope before
a PR.
What already works (verified, latest release)
rsa-sha2requires no new code on a current plugin. The SSH client (trilead-api, currentlybuild-217-jenkins-371ondevelop;build-217-jenkins-247in release 4.3.17.1) registersrsa-sha2-256/rsa-sha2-512ahead ofssh-rsaandAuthenticationManagerselects from that list,so the existing RSA-2048 key authenticates with a SHA-2 signature.
The capability first shipped in 4.3.5 (trilead-api 1.0.13). Releases 4.3.0–4.3.4 (trilead-api
1.0.3) are
ssh-rsa-only.What's actually missing
ssh/SshKeysHelper.generate()hardcodes JSchKeyPair.RSA, 2048and an"ssh-rsa "public-key prefix. There is no way to provision anssh-ed25519(or ECDSA) auto-key.The bundled mwiede JSch can already generate these; trilead can authenticate Ed25519 (it bundles
ED25519KeyAlgorithm, witheddsapresent transitively viatrilead-api).SshConfigurationonly exposescustomPrivateKeyCredentialsId;there's no selector for the generated key type.
ComputeEngineComputerLauncher.verifyServerHostKey()looks up the GCE guest attribute
hostkeys/<name>byserverHostKeyAlgorithm.toLowerCase(). Withrsa-sha2-*negotiated, the lookup for that name won't match thessh-rsa-named attribute. Thispath is currently fail-open (returns
trueon miss), so it does not break connections, but itsilently skips host-key verification — worth tightening alongside this work.
Verification
Isolated reproduction of the plugin's SSH bring-up (
connectToSsh()→Connection.connect()thenauthenticateWithPublicKey(user, key, "")), using the plugin's exact bundled trilead jars and anRSA-2048 client key, against a real
sshd:PubkeyAcceptedAlgorithms +ssh-rsaTakeaways: on the latest release,
rsa-sha2host-key + client-auth already work against stock Debian12/13 with
ssh-rsadisabled; the only legacy-ssh-rsafailures are on pre-4.3.5 plugins, on theclient-auth leg.
Proposed scope
Add Ed25519 (and optionally ECDSA) as a selectable type for the auto-generated client key, default
unchanged (RSA):
GoogleKeyPair.generate()/SshKeysHelper.generate()(use JSchKeyPairEd25519; emit the correctssh-ed25519public-key prefix).SshConfiguration(config.jelly+help-*.html+doCheck), defaultRSA. Migration follows the
preemptible→provisioningTypeprecedent (readResolve()+JCasC-compat setter); old serialized configs keep producing RSA.
hudson.util.Secret).verifyServerHostKeysorsa-sha2-*maps to thessh-rsaguest-attribute name (stop thesilent fail-open for RSA host keys).
A separate, optional hardening: a regression IT that provisions a stock Ubuntu 22.04 / Debian 12 agent
(no
sshd_configoverrides) and asserts the handshake succeeds — to lock in thersa-sha2behaviorthat already works.
Backward compatibility
Default behavior unchanged: RSA auto-key, existing negotiation. The new key-type field is opt-in and
defaults to RSA, with serialized-config migration.
Testing plan
SshKeysHelper/GoogleKeyPairTest(keep the SECURITY-2045 plaintext-never-persistedassertion); update
InstanceConfigurationTest#testConfigRoundtripandConfigAsCodeTestround-trip*IT.javaprovisioning a real GCE VM that authenticates with an Ed25519 auto-key;plus the stock-image
rsa-sha2regression IT above.Open questions for maintainers
rsa-sha2regression IT even though no production code changes for it?verifyServerHostKey'srsa-sha2-*→ssh-rsanaming fix land in this issue or separately?eddsaviatrilead-apifor Ed25519?Happy to implement whichever scope you prefer — would appreciate a steer before I open the PR.