SSH
SSH is a secure protocol and the most common way of remotely administering Linux servers and other equipment. SSH uses symmetrical encryption, which means a single key encrypts outbound messages to and inbound messages from the other participant.
The SSH session is established in two stages:
- Negotiate session key
- Authenticate the user
The symmetrical key used for the session, called the session key, is negotiated through the asymmetrical Diffie-Hellman key exchange protocol. This algorithm combines private data with public data from the other participant to produce the identical, session key, and the encryption used for the rest of the connection is called binary packet protocol.
The simplest and least secure method of authentication is password-based. Although the password is sent through the encryption, it is still considered vulnerable to brute-force attacks.
SSH key pairs, which are asymmetric, are recommended. These are what is generated by ssh-keygen, and stored in $HOME/.ssh with names that reflect the encryption algorithm, i.e. "id_rsa" and "id_rsa.pub", etc. The public key, used to encrypt data for the private key, can be freely shared. In fact, this is the purpose of ssh-copy-id, to share the public key. However the private key, which is used for decryption, must be kept secret.
The client sends an ID for the key pair it wants to authenticate with to the server. The server then checks the authorized_keys file of the requested account for the ID. A random number is generated by the server, encrypted with the public key, and sent to the client. The client then decrypts the random number and combines it with the shared session key and calculates the MD5 hash. This hash is then sent back to the server, which checks the calculation.
Note that the SSH server is named openssh-server in Ubuntu repos and the service is named ssh, as opposed to sshd on Red Hat systems.
Tasks
Port forwarding
-
Port forwarding is accomplished in one of two ways, local or remote with respect to the server not the client.
- Local (
-L
): connections to the client are forwarded through the SSH tunnel to the SSH server. This technique is used to provide functionality similar to a VPN, where remote access is made possible to content on a private network, such as file shares or web applications that are not exposed publicly. - Remote (
-R
)... - Dynamic
Here, a private web application served locally on ssh-server will be served on the client at the same port. The first "localhost" can actually be omitted, since the connection will be exposed on localhost host by default and is almost universally.
The confusing part is the second "localhost", because that is actually in reference to the ssh server itself.
It is actually possible to forward a request to another host on ssh-server's network, creating a jump box. Here a connection on the client's localhost:81 is forwarded to ssh-server, which then sends it to 192.168.1.1:80.ssh -L localhost:80:localhost:80 ssh-server
ssh -L 81:192.168.1.1:80 ssh-server
- Local (
X forwarding
- Have remote system use local computer {me.luna.edu}'s X display
ssh -Y user@host
export DISPLAY=me.luna.edu:0
fail2ban
-
<!-- On the first ban, f2b creates a new chain named f2b-name where "name" is the name of the jail, as defined in the config.
/etc/fail2ban/action.d/iptables.confactionstart = <iptables> -N f2b-<name>
This chain becomes the target of banned IPs, which are somehow added (although I don't know how). -->
Fail2ban is an intrusion prevention framework written in Python and that runs as a service. It can be installed from most distributions' repos.
The jail is a key concept in f2b that couples filters and actions definitions.
Fail2ban is configured through .ini-format configs found in /etc/fail2ban. It is recommended not to edit the default configs ending in .config but rather to create a custom config called jail.local which will be automatically loaded by the service.
Example jail[sshd] enabled=true port=ssh filter=sshd logpath=/var/log/auth.log maxretry=0 findtime=300 bantime=3600
Failed logins can be checked by running lastb, and connections are also logged to SystemD.
journalctl -ru sshd
# Display banned IPs fail2ban-client banned # Manually ban an IP fail2ban-client set sshd banip $IPADDRESS # Manually unban an IP fail2ban-client unban $IPADDRESS
Configuration
Server and client configuration both use the same set of keywords that can be defined inline on invocation or in config files.
Client configuration
-
Host home HostName 192.168.1.1 User root Port 50022 SetEnv BAT_THEME=OneHalfLight # (1) LocalForward 8080 localhost:8080 # (2)
- SetEnv allows environment variables to be set in a remote session.
However, these same environment variables must be explicitly specified in AcceptEnv key of the server configuration.
This entry will set a specific syntax highlighting theme for use on the bat CLI utility.
AcceptEnv BAT_THEME
- The use of LocalForward here is equivalent to the use of the -L option at the command-line:
ssh -L 8080:localhost:8080 $SERVER
- SetEnv allows environment variables to be set in a remote session.
However, these same environment variables must be explicitly specified in AcceptEnv key of the server configuration.
This entry will set a specific syntax highlighting theme for use on the bat CLI utility.
SSH to a transient server
-
To prevent recording a transient server to the client's known hosts file, for example when SSHing to many hosts from a single client, say while managing a corporate environment.
UserKnownHostsFile /dev/null # (1) StrictHostKeyChecking no # (2)
Canonical hostname
-
In corporate environments with verbose domain names, canonical hostnames can be configured to automatically append repetitive domain names ("canonicalize") to destination hosts.
In this example, any connection made to a hostname beginning with "server" will append "example.com".
Host server* CanonicalDomains example.com # (1) CanonicalizeHostname always # (2)
Server configuration
-
/etc/ssh/sshd_config is the configuration for the SSH server daemon.
Disable cleartext passwords
PasswordAuthentication no
Disable root login
PermitRootLogin no
Commands
endlessh
-
Log verbosity
# Silent endlessh # Normal endlessh -v # Debug endlessh -vv
Log verbosityLogLevel 0 # silent LogLevel 1 # normal LogLevel 2 # debug
ssh-add
-
ssh-add adds private key identities to the OpenSSH authentication agent, ssh-agent. Notably, ssh-add requires the SSH_AUTH_SOCK environment variable set by ssh-agent.
When run without arguments, it adds the private keys found in ~/.ssh, i.e.
- id_rsa
- id_dsa
- id_ecdsa
- id_ecdsa_sk
- id_ed25519
- id_ed25519_sk
eval $(ssh-agent); ssh-add <(cat "$(keyFile.secureFilePath)")
ssh-agent
-
ssh-agent is a helper program that keeps track of identity keys and passphrases, allowing them to be used without further interaction, similar to SSO. Running it produces output that is meant to be used with the eval command in order to set the environment variables SSH_AGENT_PID and SSH_AUTH_SOCK, which are needed by ssh-add.
eval $(ssh-agent); ssh-add <(cat "$(keyFile.secureFilePath)")
If only a single process is running, the -k option will kill it (although it is possible to fork multiple ssh-agent processes).
ssh-agent -k # (1)
- Equivalent to
kill $SSH_AGENT_PID
- Equivalent to
ssh-copy-id
-
This command copies the SSH public key to a specified account's ~/.ssh/authorized_keys file.
In Windows, this command is not available, so a workaround is to simply pipe the public key over SSH itself.
type $env:USERPROFILE\.ssh\id_rsa.pub | ssh {IP-ADDRESS-OR-FQDN} "cat >> .ssh/authorized_keys"
ssh-keygen
- Generate host keys
sudo ssh-keygen -A