Testing Authentication Methods

This guide explains how to configure a local OpenSSH server and a test user so that each SSH authentication method can be exercised against SSH-MITM in passthrough mode. All examples assume the test user is named sshtest and SSH-MITM listens on port 10022 while the target sshd runs on port 22.

Tip

For most development and CI testing, the built-in mock server is the simpler choice — no root access, no system configuration, no test user required:

python -m sshmitm.mockserver

It provides ready-made users for all four authentication methods. Use the OpenSSH setup below when you need to test against a real sshd, require SFTP or port-forwarding support, or want production-realistic behaviour.

Prerequisites

Create a dedicated test user that will be used across all scenarios:

$ sudo useradd -m -s /bin/bash sshtest

Start SSH-MITM in passthrough mode pointing at the local sshd:

$ ssh-mitm server --remote-host 127.0.0.1 --remote-port 22

All client commands below connect to SSH-MITM on port 10022. To verify a method against sshd directly, omit -p 10022.

none authentication

The none method authenticates a user without any credential. OpenSSH accepts it when PermitEmptyPasswords yes is set and the account has no password hash in /etc/shadow. Because PAM is invoked in the background, it also needs the nullok option so that an empty password is not rejected at the PAM layer.

sshd configuration

Create a drop-in file (adjust the path for your distribution):

$ echo "PermitEmptyPasswords yes" | sudo tee /etc/ssh/sshd_config.d/none-auth-test.conf
$ sudo systemctl reload sshd

PAM configuration

If /etc/pam.d/sshd does not exist, create it. The critical part is nullok on the pam_unix line — without it PAM rejects empty passwords even when the shadow entry is blank:

# /etc/pam.d/sshd
auth        required    pam_unix.so nullok try_first_pass
account     include     common-account
password    include     common-password
session     include     common-session

User setup

Remove the password hash so the account has no password:

$ sudo passwd -d sshtest

Verify the shadow entry — the second field must be empty:

$ sudo getent shadow sshtest
sshtest::20599:0:99999:7:::

Testing

Direct against sshd:

$ ssh -o PreferredAuthentications=none -o StrictHostKeyChecking=no \
      sshtest@127.0.0.1
Authenticated to 127.0.0.1 ([127.0.0.1]:22) using "none".

Via SSH-MITM (passthrough mode, no extra flags required):

$ ssh -o PreferredAuthentications=none -o StrictHostKeyChecking=no \
      -p 10022 sshtest@127.0.0.1
Authenticated to 127.0.0.1 ([127.0.0.1]:10022) using "none".

SSH-MITM log excerpt:

INFO  Remote auth-methods: ['none']
INFO  Remote authentication succeeded
      Remote Address: 127.0.0.1:22
      Username: sshtest
      Agent: no agent

Note

--force-none-auth makes SSH-MITM accept none on the client side regardless of whether the remote server supports it — useful when the target sshd is not under your control. For a proper end-to-end test where sshd performs the actual authentication, use the passthrough setup above.

password authentication

Password authentication is enabled by default in OpenSSH. The client sends the password in plain text inside the encrypted channel; SSH-MITM can read and log it.

sshd configuration

Ensure password authentication is active (it is on by default):

# /etc/ssh/sshd_config.d/password-auth-test.conf
PasswordAuthentication yes

User setup

Set a password for the test user:

$ sudo passwd sshtest

Testing

Direct against sshd:

$ ssh -o PreferredAuthentications=password sshtest@127.0.0.1

Via SSH-MITM:

$ ssh -o PreferredAuthentications=password -p 10022 sshtest@127.0.0.1

SSH-MITM log excerpt:

INFO  Remote authentication succeeded
      Remote Address: 127.0.0.1:22
      Username: sshtest
      Password: secret
      Agent: no agent

publickey authentication

Public key authentication relies on asymmetric cryptography. The client signs a challenge with its private key; the server verifies the signature against the stored public key. SSH-MITM intercepts the session by requesting the client’s agent and using it to authenticate against the remote server.

sshd configuration

Public key authentication is enabled by default:

# /etc/ssh/sshd_config.d/pubkey-auth-test.conf
PubkeyAuthentication yes

User setup

Generate a key pair (no passphrase for automated testing) and install the public key:

$ ssh-keygen -t ed25519 -f ~/.ssh/id_test_ed25519 -N ""
$ sudo -u sshtest mkdir -p /home/sshtest/.ssh
$ cat ~/.ssh/id_test_ed25519.pub | sudo tee /home/sshtest/.ssh/authorized_keys
$ sudo chmod 700 /home/sshtest/.ssh
$ sudo chmod 600 /home/sshtest/.ssh/authorized_keys
$ sudo chown -R sshtest:sshtest /home/sshtest/.ssh

Testing

Direct against sshd:

$ ssh -i ~/.ssh/id_test_ed25519 -o StrictHostKeyChecking=no sshtest@127.0.0.1

Via SSH-MITM — use agent forwarding so SSH-MITM can authenticate against the remote:

$ ssh-add ~/.ssh/id_test_ed25519
$ ssh -A -o StrictHostKeyChecking=no -p 10022 sshtest@127.0.0.1

SSH-MITM log excerpt:

INFO  Remote authentication succeeded
      Remote Address: 127.0.0.1:22
      Username: sshtest
      Agent: available

Without agent forwarding SSH-MITM cannot complete the remote authentication. In that case configure a honeypot fallback (see authentication).

keyboard-interactive authentication

Keyboard-interactive is a challenge–response protocol (RFC 4256). The server sends one or more prompts; the client answers each one. In the simplest case a single password prompt is used, making it functionally similar to password authentication from the user’s perspective.

sshd configuration

# /etc/ssh/sshd_config.d/kbdint-auth-test.conf
KbdInteractiveAuthentication yes

PAM configuration

Keyboard-interactive is driven by PAM. The default common-auth stack works for a single password prompt. The nullok option is only needed if the test account has no password.

User setup

Set a password (keyboard-interactive does not work with empty passwords in the typical PAM stack):

$ sudo passwd sshtest

Testing

Direct against sshd:

$ ssh -o PreferredAuthentications=keyboard-interactive sshtest@127.0.0.1

Via SSH-MITM:

$ ssh-mitm server --remote-host 127.0.0.1 --remote-port 22
$ ssh -o PreferredAuthentications=keyboard-interactive \
      -p 10022 sshtest@127.0.0.1

Note

SSH-MITM forwards keyboard-interactive challenges transparently, including multi-step challenge–response (e.g. TOTP) and multi-round iterative exchanges as defined in RFC 4256. The built-in mock server (python -m sshmitm.mockserver) provides ready-made users for both single-round and iterative keyboard-interactive authentication for testing.

Cleanup

Restore the system to its original state after testing:

$ sudo rm -f /etc/ssh/sshd_config.d/none-auth-test.conf
$ sudo rm -f /etc/ssh/sshd_config.d/password-auth-test.conf
$ sudo rm -f /etc/ssh/sshd_config.d/pubkey-auth-test.conf
$ sudo rm -f /etc/ssh/sshd_config.d/kbdint-auth-test.conf
$ sudo rm -f /etc/pam.d/sshd
$ sudo systemctl reload sshd
$ sudo userdel -r sshtest