Skip to content

SSH multi-factor auth (publickey,password) fails - ssh2 sends keyboard-interactive instead of password #629

@madhur

Description

@madhur

Description

When an SSH server requires multi-factor authentication with AuthenticationMethods publickey,password in sshd_config, Termix fails to complete the connection. The publickey step succeeds, but the subsequent password step fails because the ssh2 client sends keyboard-interactive instead of the password method.

Steps to Reproduce

  1. Configure sshd with:
    AuthenticationMethods publickey,password
    PasswordAuthentication yes
    KbdInteractiveAuthentication no
    
  2. In Termix, create a credential with auth type key, a private key, and a password
  3. Attempt to connect

Expected Behavior

After publickey succeeds (partial auth), ssh2 should send password as the next auth method, completing the connection.

Actual Behavior

After publickey succeeds, ssh2 sends keyboard-interactive (because tryKeyboard: true is hardcoded in the connect config). The server rejects it since KbdInteractiveAuthentication is disabled, and the connection fails. The client disconnects without ever trying the password method.

Server Logs

Partial publickey for user from x.x.x.x port 60474 ssh2: ED25519 SHA256:...
userauth_finish: failure partial=1 next methods="password"
userauth-request for user service ssh-connection method keyboard-interactive
authmethod_lookup: method keyboard-interactive not enabled
Received disconnect from x.x.x.x port 60474:11:

Root Cause

In dist/backend/backend/ssh/terminal.js, the connect config auth methods are mutually exclusive (else if branches):

  • authType === "password" → sets connectConfig.password
  • authType === "key" → sets connectConfig.privateKey

There is no code path that sets both privateKey and password on the ssh2 connect config. Additionally, tryKeyboard: true is always set, causing ssh2 to prefer keyboard-interactive over password.

Suggested Fix

When authType === "key" and a password is also available on the credential, set both connectConfig.privateKey and connectConfig.password, and set tryKeyboard: false to force ssh2 to use the password method instead of keyboard-interactive.

// In the "key" auth branch, after setting privateKey:
if (resolvedCredentials.password) {
    connectConfig.password = resolvedCredentials.password;
    connectConfig.tryKeyboard = false;
}

Alternatively, consider adding a new authType like "key+password" for explicit multi-factor support.

Environment

  • Termix: latest (ghcr.io/lukegus/termix:latest)
  • Server: OpenSSH 10.3, Arch Linux
  • ssh2 (Node.js library) used by Termix backend

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions