Skip to content

Replace Ganymed SSH with sshj in the JSystem automation harness - #95

Merged
Bonartze merged 1 commit into
mainfrom
ptt-ganymed-el9/replace-ganymed-ssh
Oct 19, 2026
Merged

Bonartze merged 1 commit into
mainfrom
ptt-ganymed-el9/replace-ganymed-ssh

Conversation

@Bonartze

@Bonartze Bonartze commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Why

The L2 (JSystem) automation suite cannot run on el9. The harness opened every system-object shell through JSystem's systemobject.terminal.SSH and our SshRsa subclass, both backed by Ganymed SSH2 (ch.ethz.ssh2), a 2006-era client whose handshake crypto stops at diffie-hellman-group1/group14-sha1 KEX and CBC ciphers. OpenSSH 9.x builds drop those algorithms at compile time, and sshd's +algo modifier can only re-enable what was built in, so Ganymed and an el9 sshd share no usable KEX/cipher and localhost:22 is unreachable for the harness. The packaging smoke works around it with an el8-only gate (IS_PXF_EL8), which leaves el9 with no JSystem signal.

What

  • SshRsa now extends JSystem's Terminal directly and drives the shell with sshj 0.41.2 (Java 8 compatible): connect, authenticate, allocate a dumb PTY (same as Ganymed's requestDumbPTY(), so terminal-aware commands do not colour their output), start the shell, hand the channel streams to the Terminal. Password (password + keyboard-interactive) when the SUT gives one, otherwise the SUT's privateKey; sshj reads OpenSSH-format, PEM and PuTTY keys, so the OpenSSH→PEM conversion Ganymed needed goes away. Host keys are not verified (Ganymed's trust model).
  • PxfCliConnectionImpl uses SshRsa for both the ssh and ssh-rsa protocols; nothing in the tree references JSystem's Ganymed-backed SSH any more.
  • pom.xml: ganymed-ssh2 dropped as a direct dependency and excluded from org.jsystemtest.systemobjects:cli (its only remaining path); sshj added. Two knock-on effects of sshj's own dependencies pinned back:
    • slf4j-api held on 1.7.36 (sshj declares 2.0.17, which would ignore the only binding on the classpath, hadoop-common's slf4j-reload4j 1.7.36, and silence every Hadoop/HBase client log line);
    • the Bouncy Castle 1.68 jdk15on jars that hive-shims pulls via yarn web-proxy excluded, so the classpath carries one BC (sshj's jdk18on 1.84) instead of two copies of the same classes.
  • automation/README.md: the SSH Setup section no longer asks for legacy KexAlgorithms/HostKeyAlgorithms in sshd_config or a PEM-format RSA key.

git grep -nE 'ch\.ethz\.ssh2|ganymed' automation/ now only hits the pom exclusion that removes it.

Verification

  • mvn compile (Java 8) is green; mvn dependency:tree shows no ch.ethz.ganymed artifact.
  • SshRsa driven the way PxfCliConnectionImpl does (connect → env PS1='#' bash --norc → command → prompt match → getResult() → disconnect) against two sshd containers, Rocky Linux 9 (openssh-server-9.9p1-12.el9_8) and Fedora 42 (openssh-server-9.9p1-14.fc42), each with an OpenSSH-format RSA key (-----BEGIN OPENSSH PRIVATE KEY-----, the format Ganymed could not read), an ed25519 key and a password: all six connect, the shell starts on the dumb PTY and the command output comes back through the Terminal. A wrong password fails with UserAuthException: Exhausted available authentication methods, as it should.
  • com.aqua.sysobj.conn.CliConnectionImpl (which still references JSystem's SSH class) and PxfCliConnectionImpl load and link with ganymed-ssh2 off the classpath.

The automation harness opened every system-object shell through
systemobject.terminal.SSH / our SshRsa subclass, both backed by Ganymed
SSH2 (ch.ethz.ssh2), a 2006-era client whose handshake crypto stops at
diffie-hellman-group1/group14-sha1 KEX and CBC ciphers. OpenSSH 9.x builds
drop those algorithms at compile time, and sshd's "+algo" modifier can only
re-enable what was built in, so on el9 Ganymed shares no usable KEX or
cipher with sshd and the L2 suite cannot connect to localhost:22. That is
why the packaging smoke gates L2 (and its singlecluster umbrella) to el8.

SshRsa now extends JSystem's Terminal directly and drives the shell with
sshj 0.41.2 (Java 8 compatible): connect, authenticate, allocate a "dumb"
PTY (same as Ganymed's requestDumbPTY(), so terminal-aware commands do not
colour their output), start the shell, hand the channel streams to the
Terminal. Password (password + keyboard-interactive) is tried when the SUT
gives one, otherwise the SUT's privateKey file; sshj reads OpenSSH-format,
PEM and PuTTY keys, so the OpenSSH-to-PEM conversion Ganymed needed goes
away too. Host keys are not verified, the trust model Ganymed had.
PxfCliConnectionImpl uses SshRsa for both the ssh and ssh-rsa protocols, so
nothing in the tree references JSystem's Ganymed-backed SSH any more.

pom: ganymed-ssh2 is dropped as a direct dependency and excluded from
org.jsystemtest.systemobjects:cli (its only remaining path); sshj 0.41.2
is added. Two side effects of sshj's own dependencies are pinned back:
slf4j-api stays on 1.7.36 (sshj declares 2.0.17, which would ignore the
only binding on the classpath, hadoop-common's slf4j-reload4j 1.7.36, and
silence every Hadoop/HBase client log line), and the Bouncy Castle 1.68
jdk15on jars that hive-shims pulls through yarn web-proxy are excluded so
the classpath carries a single BC (sshj's jdk18on 1.84) rather than two
copies of the same classes.

automation/README.md: the "SSH Setup" section no longer tells people to
append legacy KexAlgorithms/HostKeyAlgorithms to sshd_config or to make a
PEM-format RSA key; any unencrypted OpenSSH key works.

Verified locally (Java 8, the module compiles with `mvn compile`;
`git grep ch.ethz.ssh2|ganymed automation/` only hits the exclusion) by
driving SshRsa the way PxfCliConnectionImpl does against two sshd
containers: Rocky Linux 9 (OpenSSH 8.7p1) and Fedora 42 (OpenSSH 9.9p1,
the algorithm set el9 is moving to), each with an OpenSSH-format RSA key,
an ed25519 key and a password; the shell starts with `env PS1='#' bash
--norc`, the prompt matches and the command output comes back through the
Terminal. CliConnectionImpl, which still references JSystem's SSH class,
links fine with ganymed-ssh2 off the classpath.

Companion change: EnterpriseDB/whpg-extensions-packaging drops the
IS_PXF_EL8 gate so L2 runs on el9.
@Bonartze
Bonartze requested review from a team and 24nishant October 17, 2026 19:35
@Bonartze
Bonartze merged commit 62e2d7f into main Oct 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants