Home Blog Certs Knowledge Base About

LPIC-2 212.3 โ€” Secure Shell (OpenSSH)

Exam topic 212.3 โ€” Secure shell (OpenSSH) (weight: 4). Covers SSH client and server configuration, key management, port forwarding, and X11 forwarding.


OpenSSH Components

BinaryRole
sshClient โ€” connect to remote hosts
sshdServer daemon โ€” accepts incoming connections
ssh-keygenGenerate and manage key pairs
ssh-agentAuthentication agent (caches private keys)
ssh-addAdd keys to ssh-agent
ssh-copy-idCopy public key to remote authorized_keys
scpSecure copy (SSH-based file transfer)
sftpSecure FTP subsystem over SSH
ssh-keyscanCollect public keys from servers

Default port: 22


Server Configuration โ€” sshd_config

Main server config: /etc/ssh/sshd_config

systemctl restart sshd     # apply changes
systemctl reload sshd      # reload config without dropping connections
sshd -t                    # test config syntax

Key Parameters

Port 22                          # listening port (can specify multiple Port lines)
ListenAddress 0.0.0.0            # listen on all IPv4 interfaces
ListenAddress ::                 # listen on all IPv6 interfaces

PermitRootLogin no               # disable root login (recommended)
# PermitRootLogin prohibit-password  # allow root only with key auth
# PermitRootLogin yes            # allow root with password (insecure)

PasswordAuthentication yes       # allow password auth (set no to force keys)
PubkeyAuthentication yes         # allow key-based auth
AuthorizedKeysFile .ssh/authorized_keys  # location of authorized keys

PermitEmptyPasswords no          # deny accounts with empty passwords
MaxAuthTries 3                   # max login attempts before disconnect
MaxSessions 10                   # max sessions per connection

UsePAM yes                       # use PAM for authentication

X11Forwarding yes                # allow X11 forwarding
AllowTcpForwarding yes           # allow port forwarding

# Restrict access to specific users/groups
AllowUsers alice bob             # only these users may log in
AllowGroups ssh-users            # only members of this group
DenyUsers mallory                # deny specific users
DenyGroups badgroup

# Idle timeout
ClientAliveInterval 300          # send keepalive every 300 seconds
ClientAliveCountMax 2            # disconnect after 2 missed keepalives

Banner /etc/issue.net            # show file contents before login

Subsystem sftp /usr/lib/openssh/sftp-server   # enable SFTP subsystem

Exam fact: Changes to sshd_config require systemctl reload sshd (or sshd -t first to check syntax).

PermitRootLogin values

ValueBehavior
yesRoot can log in with password or key
noRoot cannot log in at all
prohibit-passwordRoot can log in with key only (no password)
forced-commands-onlyRoot can log in with key only if a forced command is specified

Client Configuration

Per-user config: ~/.ssh/config
System-wide config: /etc/ssh/ssh_config

# ~/.ssh/config
Host webserver
    HostName 192.168.1.100
    User deploy
    Port 2222
    IdentityFile ~/.ssh/deploy_key

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    ForwardAgent no
ssh webserver          # uses settings from ~/.ssh/config for "webserver"

Common ssh Options

ssh -p 2222 user@host              # connect on port 2222
ssh -i ~/.ssh/mykey user@host      # use specific private key
ssh -l user host                   # specify username
ssh -v user@host                   # verbose (debug)
ssh -vv user@host                  # more verbose
ssh -o StrictHostKeyChecking=no    # skip host key check (unsafe, use with care)

Key-Based Authentication

Generate Key Pair

ssh-keygen -t ed25519 -C "alice@example.com"    # Ed25519 (modern, recommended)
ssh-keygen -t rsa -b 4096 -C "alice@example.com"    # RSA 4096-bit
ssh-keygen -t ecdsa -b 521                           # ECDSA
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/alice/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase): ****

Generated files:

  • ~/.ssh/id_ed25519 โ€” private key (permissions must be 0600)
  • ~/.ssh/id_ed25519.pub โ€” public key

Key types: RSA is the traditional choice. Ed25519 is modern, shorter, and faster. DSA is obsolete and disabled in OpenSSH 7.0+.

Copy Public Key to Server

ssh-copy-id user@server                              # copy default key
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server    # copy specific key

This appends the public key to ~/.ssh/authorized_keys on the server.

Manual equivalent:

cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

authorized_keys

~/.ssh/authorized_keys โ€” one public key per line. Permissions must be:

  • ~/.ssh/ directory: 0700
  • ~/.ssh/authorized_keys: 0600
  • owned by the user
# ~/.ssh/authorized_keys
ssh-ed25519 AAAAC3Nza... alice@laptop
# Restrict a key to one command only:
command="backup.sh",no-port-forwarding,no-x11-forwarding ssh-ed25519 AAAAC3Nza... backup@server

Key options (before the key type):

  • command="cmd" โ€” force a specific command when this key is used
  • no-port-forwarding โ€” disable port forwarding for this key
  • no-x11-forwarding โ€” disable X11 forwarding
  • no-agent-forwarding โ€” disable agent forwarding
  • from="192.168.1.*" โ€” allow this key only from matching IPs

known_hosts

When connecting to a server for the first time, ssh saves its host key:

  • ~/.ssh/known_hosts โ€” per-user
  • /etc/ssh/ssh_known_hosts โ€” system-wide
ssh-keyscan -H hostname >> ~/.ssh/known_hosts    # pre-populate
ssh-keygen -R hostname                           # remove host key (after server rebuild)

ssh-agent

ssh-agent caches decrypted private keys so you don’t need to enter the passphrase repeatedly.

eval "$(ssh-agent)"         # start agent and set env variables
ssh-add ~/.ssh/id_ed25519   # add key (prompts for passphrase once)
ssh-add -l                  # list cached keys
ssh-add -d ~/.ssh/id_ed25519  # remove key
ssh-add -D                  # remove all keys

Agent Forwarding โ€” passes the agent connection through SSH so you can use your local keys on intermediate servers:

ssh -A user@jumphost         # forward agent to jumphost
# ~/.ssh/config
Host jumphost
    ForwardAgent yes

Security warning: Agent forwarding is convenient but risky โ€” anyone with root on the intermediate server can use your keys while you’re connected.


Port Forwarding (Tunneling)

Local Port Forwarding (-L)

Opens a local port that forwards to a remote host/port via SSH:

ssh -L [local_addr:]local_port:remote_host:remote_port user@sshserver
# Access remote MySQL (3306) as if it were local
ssh -L 3307:localhost:3306 user@dbserver
# Now connect: mysql -h 127.0.0.1 -P 3307

# Access internal web server through SSH jump host
ssh -L 8080:internal-web:80 user@jumphost
# Now open: http://localhost:8080

Remote Port Forwarding (-R)

Opens a port on the remote server that forwards back to a local host/port:

ssh -R [remote_addr:]remote_port:local_host:local_port user@sshserver
# Make local web server (port 80) accessible on remote server's port 8080
ssh -R 8080:localhost:80 user@remoteserver
# On remoteserver: curl http://localhost:8080 โ†’ reaches local port 80

Use case: expose a local service through a firewall (reverse tunnel).

Dynamic Port Forwarding (-D)

Creates a SOCKS proxy:

ssh -D 1080 user@sshserver
# Configure browser to use SOCKS5 proxy localhost:1080

-N and -f flags

ssh -N -L 3307:localhost:3306 user@server   # -N: don't execute a remote command
ssh -f -N -L 3307:localhost:3306 user@server  # -f: go to background

X11 Forwarding

Allows running GUI applications on the remote server and displaying them locally.

Server (/etc/ssh/sshd_config):

X11Forwarding yes
X11DisplayOffset 10      # first display number to use (default: 10)

Client:

ssh -X user@server       # enable X11 forwarding
ssh -Y user@server       # trusted X11 forwarding (less secure, fewer restrictions)
# After connecting with -X:
firefox &                # opens Firefox window on your local display

-X = untrusted (safer, some apps may refuse to run)
-Y = trusted (all X11 permissions granted)


SCP โ€” Secure Copy

# Copy local file to remote
scp file.txt user@host:/remote/path/

# Copy remote file to local
scp user@host:/remote/file.txt /local/path/

# Copy directory recursively
scp -r /local/dir/ user@host:/remote/dir/

# Use different port
scp -P 2222 file.txt user@host:/path/

# Preserve timestamps and permissions
scp -p file.txt user@host:/path/

# Specify key
scp -i ~/.ssh/mykey file.txt user@host:/path/

SFTP โ€” SSH File Transfer Protocol

SFTP is an SSH subsystem, not FTP over SSH. It provides a file transfer protocol that runs over SSH.

sftp user@host
sftp> ls
sftp> cd /remote/dir
sftp> get remotefile.txt
sftp> put localfile.txt
sftp> mkdir newdir
sftp> rm file.txt
sftp> bye

Restrict a user to SFTP only (no shell) via sshd_config:

Match User ftpuser
    ForceCommand internal-sftp
    ChrootDirectory /var/sftp/%u
    AllowTcpForwarding no
    X11Forwarding no
# /var/sftp/ftpuser must be owned by root
chown root:root /var/sftp/ftpuser
chmod 755 /var/sftp/ftpuser
# Create writable upload directory inside
mkdir /var/sftp/ftpuser/upload
chown ftpuser:ftpuser /var/sftp/ftpuser/upload

Host Key Management

Server host keys are in /etc/ssh/:

/etc/ssh/ssh_host_rsa_key       (private, 0600)
/etc/ssh/ssh_host_rsa_key.pub   (public)
/etc/ssh/ssh_host_ed25519_key
/etc/ssh/ssh_host_ed25519_key.pub

Regenerate host keys (e.g., after cloning a VM):

rm /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server    # Debian
ssh-keygen -A                      # regenerate all missing host keys

Exam Cheat Sheet

Files and Paths

PathDescription
/etc/ssh/sshd_configSSH server configuration
/etc/ssh/ssh_configSSH client defaults (system-wide)
~/.ssh/configSSH client config (per-user)
~/.ssh/id_ed25519Private key (0600)
~/.ssh/id_ed25519.pubPublic key
~/.ssh/authorized_keysAllowed public keys for this user (0600)
~/.ssh/known_hostsTrusted server host keys
/etc/ssh/ssh_known_hostsSystem-wide trusted host keys
/etc/ssh/ssh_host_*_keyServer private host keys (0600)

Key Commands

ssh-keygen -t ed25519              # generate Ed25519 key pair
ssh-copy-id user@server            # install public key on server
ssh -L 3307:localhost:3306 user@db # local port forward
ssh -R 8080:localhost:80 user@srv  # remote port forward
ssh -D 1080 user@server            # SOCKS proxy
ssh -X user@server                 # X11 forwarding
scp file.txt user@host:/path/      # secure copy

Common Exam Pitfalls

PitfallRule
authorized_keys permissionsMust be 0600; ~/.ssh/ must be 0700
-L vs -R-L = local port forwards to remote; -R = remote port forwards to local
-X vs -Y-X = untrusted (safer); -Y = trusted (apps may need this)
SFTP vs FTPSFTP is an SSH subsystem, not FTP over SSH โ€” completely separate protocol
PermitRootLogin prohibit-passwordRoot can log in with key but not password
Reload vs restartreload keeps connections alive; restart drops them
Host key mismatchEdit ~/.ssh/known_hosts or run ssh-keygen -R hostname
DSA keysDisabled in OpenSSH 7.0+ โ€” do not use