Two small tools remove most daily friction on servers: an SSH client config that remembers hosts, users and keys, and tmux, which keeps your work running when your connection drops. Both are worth ten minutes of setup.
Versions in use on this date. OpenSSH 7.6 and tmux 2.6 on Ubuntu 18.04.4 LTS. ProxyJump needs OpenSSH 7.3 or later on the client; the jump host only needs a normal sshd.
How the pieces fit
flowchart TB
L[Laptop<br/>ssh-agent holds unlocked key] -->|ssh bastion| B[Bastion host<br/>public IP, locked down]
B -->|ProxyJump| W[web01 private subnet]
B -->|ProxyJump| D[db01 private subnet]
L -.->|ControlMaster reuses one connection| B
W --> T[tmux session on server<br/>survives disconnects]
~/.ssh/config
Host *
ServerAliveInterval 30
ServerAliveCountMax 3
AddKeysToAgent yes
IdentitiesOnly yes
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10m
Host bastion
HostName 203.0.113.10
User ravi
IdentityFile ~/.ssh/id_ed25519
Host web01 db01
User ravi
ProxyJump bastion
IdentityFile ~/.ssh/id_ed25519
Host web01
HostName 10.0.1.11
Host db01
HostName 10.0.2.21
LocalForward 15432 localhost:5432
chmod 600 ~/.ssh/config
ssh web01 # goes through bastion automatically
ssh -L 8080:internal-app:80 bastion # one-off local port forward
scp file.txt web01:/tmp/ # config applies to scp and rsync as well
ssh -O check bastion # is the shared connection alive
What the options do:
ServerAliveIntervalkeeps NAT and firewalls from dropping idle sessions, and ends dead ones.ControlMaster/ControlPersistreuse one TCP connection for later sessions, which makes the secondsshorscpto the same host instant.IdentitiesOnly yesoffers only the key named for that host, which avoids “Too many authentication failures”.ProxyJumpis safer than agent forwarding. AvoidForwardAgent yeson shared hosts because a root user there can use your forwarded agent while you are connected.
ssh-agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519 # asks for the passphrase once
ssh-add -l # list loaded keys
Keep a passphrase on every key; the agent removes the repeated typing.
tmux: sessions that survive
Without tmux, a closed laptop or dropped Wi-Fi kills a long-running command. tmux runs on the server, and you re-attach.
sudo apt install tmux
tmux new -s deploy # new named session
# ... run work ... Ctrl-b d # detach: it keeps running
tmux ls
tmux attach -t deploy
tmux kill-session -t deploy
The prefix is Ctrl-b, followed by:
| Keys | Action |
|---|---|
c / n / p / , |
New / next / previous window, rename window |
% / " |
Split pane vertically / horizontally |
| arrow keys | Move between panes |
z |
Zoom a pane |
[ |
Scroll and copy mode (q to leave) |
d |
Detach |
? |
Help |
A starter ~/.tmux.conf:
set -g mouse on
set -g history-limit 50000
set -g base-index 1
setw -g pane-base-index 1
set -g status-right '#H %H:%M'
bind r source-file ~/.tmux.conf \; display "reloaded"
Reload with tmux source-file ~/.tmux.conf. Because tmux 2.6 on Ubuntu 18.04 is not the newest, check options against man tmux for your version.
Good habits
- Start long jobs (upgrades, migrations, big copies) inside tmux, and name sessions after the task.
- Do not leave a root shell open in a shared tmux session; use separate sessions per person, or
tmux -Sshared sockets only on purpose. - Keep
~/.ssh/configin a private repository (without keys) so new laptops are productive immediately. - Use
ssh -v hostto debug connections, andssh -G hostto print the effective configuration for a host.