Files
tilde.club/docs/ssh.md
T

7.2 KiB

SSH access and MFA

Member keys

Use an SSH client already supplied with Linux, macOS, or Windows OpenSSH. On Windows, PowerShell can run the same ssh and ssh-keygen commands. PuTTY is also fine if the user prefers it; submit the OpenSSH-format public-key line, not a .ppk private key.

On your own computer, generate a separate key if you do not already have one you want to use. Choose a new filename rather than overwriting an existing key:

ssh-keygen -t ed25519 -a 64 -f ~/.ssh/tilde_ed25519

Use a passphrase. Send only tilde_ed25519.pub to the operator or signup form. The file without .pub is private and stays on your computer. A hardware-backed key can also be used when both the client and host support it.

Connect with:

ssh -i ~/.ssh/tilde_ed25519 member@tilde.example.net

A local ~/.ssh/config entry saves typing:

Host mytilde
    HostName tilde.example.net
    User member
    IdentityFile ~/.ssh/tilde_ed25519
    IdentitiesOnly yes
    ForwardAgent no

Verify a new host's fingerprint through a separate trusted channel. If it changes later, ask why before replacing the saved host key. Agent forwarding is normally unnecessary for using the host; enable it only for a specific reason you understand.

What the collected host does

The main daemon reads /etc/ssh/sshd_config. It has public-key support, PasswordAuthentication no, keyboard-interactive authentication enabled, and UsePAM yes. AuthenticationMethods is not set to require a combination; the observed effective value is any.

Its SSH PAM authentication stack requires pam_unix and pam_google_authenticator, except for a special help account. That means the PAM route asks for the Unix password and a TOTP code. It does not mean public-key login must also complete that route: the collected SSH configuration accepts a valid public key on its own. Existing account-specific exceptions and a separate restricted help command must be reviewed locally rather than copied into a new installation.

setup-2fa is a small wrapper around /usr/bin/google-authenticator. check_google_authenticator.sh is not referenced by the collected SSH PAM file; its printed output is not an enforced authentication policy.

The main config collected from this host does not contain an Include for sshd_config.d. The presence of files in that directory does not make them active. Check the actual service command and configuration before assuming a drop-in changes anything.

Key-only baseline for a new host

Use the example drop-in only after admin key login and sudo have been tested. Put it in a directory that the actual main config includes at global scope. Fedora's default layout normally provides /etc/ssh/sshd_config.d/*.conf; existing customized configs may not.

OpenSSH generally uses the first value it obtains for a setting. A file placed later in the include order will not necessarily override an earlier value. Keep Match sections at the end and finish a conditional section with Match all before adding unrelated global settings.

Before applying anything, keep a backup of the main file, its includes, the SSH PAM file, and any unit overrides. Keep a working connection and the provider console available. Validate the effective settings as well as syntax:

sshd -t
sshd -T -C user=member,host=client.example.net,addr=192.0.2.20
systemctl reload sshd

Run connection tests from a second terminal on your own computer. Test the admin and member separately. Match rules based on source address or local port also need representative addr, laddr, and lport values in the test context. A successful syntax check alone does not establish that the intended method will be accepted.

Require MFA after enrollment

For a new host, keep the key-only baseline working while enrolling people. The following is an example policy, not a report of the production host's current enforcement:

  1. Install google-authenticator and ensure time synchronization is healthy.
  2. Create a group named mfa-ready.
  3. Have the test member run google-authenticator interactively in their own account. Use time-based tokens, save the recovery codes somewhere private off the host, and complete a code check. Keep .google_authenticator private.
  4. Keep the Fedora SSH PAM account/session stack. Add auth required pam_google_authenticator.so to /etc/pam.d/sshd after its normal authentication rules. Do not use nullok for an account that must provide a second factor. Do not edit authselect-generated shared files to make this SSH-only change.
  5. Add the following conditional block at the end of the effective SSH config, after the baseline global settings:
Match Group mfa-ready
    KbdInteractiveAuthentication yes
    AuthenticationMethods publickey,keyboard-interactive:pam
Match all

With Fedora's password authentication PAM substack retained, this asks for a key, the Unix password, and the authenticator code. If you want a key plus TOTP without the Unix password, design and test that SSH-specific PAM stack instead of removing password checks from the shared system authentication configuration.

Validate the config, then add only the enrolled test account to the group:

groupadd -f mfa-ready
usermod --append --groups mfa-ready member
sshd -t
sshd -T -C user=member,host=client.example.net,addr=192.0.2.20
systemctl reload sshd

From the client, test correct and incorrect codes and confirm that key-only batch authentication fails for the enrolled account:

ssh -o BatchMode=yes -o PreferredAuthentications=publickey \
    -i ~/.ssh/tilde_ed25519 member@tilde.example.net

That last command is a negative test and should fail under the enforced policy. Also verify normal interactive login, SFTP if offered, recovery codes, and admin recovery. Scripts using SSH need a separately documented policy; silently exempting all automation defeats a blanket MFA claim.

Only enroll more members after the full test passes. A user-editable startup file or .new_user marker is onboarding state, not an access-control boundary.

Legacy SSH

The existing host has a second daemon on TCP 2222. Its service reads /etc/ssh/sshd_config_legacy, disables root and password login, restricts its allowed user, and deliberately enables old RSA/SHA-1 and group1 algorithms. This is a compatibility exception, not a general access method.

A new tilde does not need this service. If you have a specific legacy client requirement, isolate it in a separate daemon and source/identity policy, verify its effective settings with sshd -T -f PATH, and record who needs it and when it can be retired. Do not weaken the normal daemon or the host-wide crypto policy for every member.

Recovery

Verify the person's identity before replacing a key or resetting MFA. Remove lost factors, invalidate unused recovery codes when re-enrolling, and check whether other services share the same account password. Test that the revoked key or factor no longer works. Do not ask someone to send a private SSH key or their TOTP secret in an ordinary support message.

References: OpenSSH server configuration and Google Authenticator PAM.