Files
oam/knowledge base/ssh.md
2023-03-25 20:33:56 +01:00

10 KiB

SSH

  1. TL;DR
  2. Server installation on Windows
  3. Key Management
  4. Client configuration
    1. Append domains to a hostname before attempting to check if they exist
    2. Optimize connection handling
  5. Server configuration
    1. Change port
    2. Disable password authentication
    3. Permit root login
    4. Conditional blocks
  6. SSHFS
    1. Installation
  7. Troubleshooting
    1. No matching host key type found
  8. Further readings
  9. Sources

TL;DR

# Load keys from '${HOME}/.ssh' and add them to the agent.
eval $(ssh-agent) && ssh-add

# Create new keys.
ssh-keygen -t 'rsa' -b '4096'
ssh-keygen -t 'dsa'
ssh-keygen -t 'ecdsa' -b '521'
ssh-keygen -t 'ed25519' -f "${HOME}/.ssh/keys/id_ed25519" -C 'test@winzoz'
ssh-keygen -f "${HOME}/.ssh/id_rsa" -N '' -C 'batch-generated key with no password'

# Remove elements from the known hosts list.
ssh-keygen -R 'pi4.lan'
ssh-keygen -R '192.168.1.237' -f '.ssh/known_hosts'
ssh-keygen -R 'pi.lan' -f "${HOME}/.ssh/known_hosts"

# Change the password of a key.
ssh-keygen -f "${HOME}/.ssh/id_rsa" -p

# Mount a remote folder.
sshfs 'nas.lan:/mnt/data' 'Data' \
  -o 'auto_cache,reconnect,defer_permissions,noappledouble,volname=Data'

# List keys added to the agent by fingerprint.
ssh-add -l
ssh-add -L   # full key in OpenSSH format

# Authorize keys for passwordless access.
ssh-copy-id -i "${HOME}/.ssh/id_rsa.pub" user@nas.lan

# Connect to an unreachable host tunnelling the session through a bastion.
ssh -t 'bastion-host' ssh 'unreachable-host'

Server installation on Windows

Needs Administrator privileges.
Tested on Window 11 22H2.

Via PowerShell:

  1. Install the server component:

    Add-WindowsCapability -Online -Name OpenSSH.Server
    
  2. Start and enable the service:

    Start-Service sshd
    Set-Service -Name sshd -StartupType 'Automatic'
    
  3. Verify the firewall rule has been created automatically during the installation:

    if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) {
      Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
      New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
    } else {
      Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists."
    }
    

Via GUI:

  1. Open Settings > Apps, then select Optional features

  2. Scan the list to see if the OpenSSH server is not already installed

  3. At the top of the page, select View features in the Add an optional feature field

  4. Find OpenSSH Server and select Install

  5. Once the setup completes, return to Apps > Optional features and confirm OpenSSH is now listed

  6. Open the Services desktop app:

    1. Select Start
    2. Type services.msc in the search box
    3. Select the Services app or just press ENTER
  7. In the details panel, double-click OpenSSH SSH Server to enter its properties

  8. On the General tab, from the Startup type drop-down menu, select Automatic to enable the service

  9. In the same tab, select Start to start the service

Key Management

Create a new key:

ssh-keygen -t 'rsa' -b '4096'
ssh-keygen -t 'dsa'
ssh-keygen -t 'ecdsa' -b '521'
ssh-keygen -t 'ed25519' -f '.ssh/id_ed25519' -C 'test@winzoz'
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\test/.ssh/id_ed25519.
Your public key has been saved in C:\Users\test/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:lFrpPyqTy0d30TfnN0QRY678LnyCzmvMDbl1Qj2/U/w test@winzoz
The key's randomart image is:
+--[ED25519 256]--+
|           +o.o++|
|             ==*O|
|            . .X*|
|         o .   +=|
|        S S +..==|
|         . .+..*E|
|           + ...o|
|         .+ .o = |
|          =+ .o .|
+----[SHA256]-----+

Remove a host from the list of known hosts:

ssh-keygen -R 'pi4.lan'
ssh-keygen -R '192.168.1.237' -f '.ssh/known_hosts'
ssh-keygen -R 'raspberrypi.lan' -f '.ssh/known_hosts'
Host pi4.lan found: line 5
/home/user/.ssh/known_hosts updated.
Original contents retained as /home/user/.ssh/known_hosts.old

Change password of a key file

ssh-keygen -f "${HOME}/.ssh/id_rsa" -p

Client configuration

When connecting to a host, the SSH client will use settings:

  1. from the command line,
  2. from the user's ~/.ssh/config file,
  3. from the /etc/ssh/ssh_config file

Settings are loaded in a first-come-first-served way. They should hence appear from the most specific to the most generic, both by file and by position in those files:

Host targaryen
    HostName targaryen.example.com
    User john
    Port 2322
    IdentityFile ~/.ssh/targaryen.key
    LogLevel INFO
    Compression yes

Host *ell
    user oberyn
    sendenv BE_SASSY
    StrictHostKeyChecking no

Host * !martell
    LogLevel INFO
    StrictHostKeyChecking accept-new
    UserKnownHostsFile /dev/null

Host *
    User root
    Compression yes
    SendEnv -LC_* -LANG*
    SetEnv MYENV=itsvalue

Append domains to a hostname before attempting to check if they exist

CanonicalizeHostname yes
CanonicalDomains xxx.auckland.ac.nz yyy.auckland.ac.nz

Host  *.xxx.auckland.ac.nz
    User user_xxx
Host  *.yyy.auckland.ac.nz
    User user_yyy

Optimize connection handling

# Keep a connection open for 30s and reuse it when possible.
# Save the above pipe in a safe directory, and use a hash of different data to
# identify it.
# source: https://www.cyberciti.biz/faq/linux-unix-reuse-openssh-connection/
ControlMaster auto
ControlPath ~/.ssh/control-%C
ControlPersist 30s

Server configuration

Config file defaults to /etc/ssh/sshd_config.
Restart the server upon config file change.

Change port

Port 2222

Disable password authentication

PasswordAuthentication no
ChallengeResponseAuthentication no

Permit root login

PermitRootLogin yes

Conditional blocks

Only a subset of keywords may be used in a Match block. Check the SSHD_CONFIG(5) man page.

Match Address 192.168.111.0/24
    PasswordAuthentication no
    PermitRootLogin no

SSHFS

Notable options:

  • auto_cache enables caching based on modification times;
  • reconnect reconnects to the server;
  • defer_permissions works around the issue where certain shares may mount properly, but cause permissions denied errors when accessed (caused by how Mac OS X's Finder translates and interprets permissions;
  • noappledouble prevents Mac OS X to write .DS_Store files on the remote file system;
  • volname defines the name to use for the volume.

Usage:

sshfs \
  -o 'auto_cache,reconnect,defer_permissions,noappledouble,volname=Data'
  'user@nas.lan:/path/to/remote/dir' \
  '/path/to/local/dir'

Installation

# Mac OS X requires `macports`, since `brew` does not offer 'sshfs' anymore
sudo port install 'sshfs'

Troubleshooting

No matching host key type found

Error message example:

Unable to negotiate with XXX port 22: no matching host key type found. Their offer: ssh-rsa.

Cause: the server only supports the kind of RSA with SHA-1, which is considered weak and deprecated in newer SSH versions.

Workaround: explicitly set your client to use the specified key type adding

HostkeyAlgorithms        +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa

to your ~/.ssh/config like so:

Host  azure-devops
    IdentityFile              ~/.ssh/id_rsa
    IdentitiesOnly            yes
+   HostkeyAlgorithms         +ssh-rsa
+   PubkeyAcceptedAlgorithms  +ssh-rsa

Solution: update the SSH server.

Further readings

Sources