Unix Networking and Security Basics
Most of this stuff I learned by breaking things. SSH config in particular has a way of locking you out of a remote box at the worst possible time. These are the commands and concepts I actually use, with the caveats that took me a while to figure out.
Checking What's Listening
Before anything else — know what's running on your machine:
$ ss -tlnp # TCP, listening, numeric, show process $ ss -ulnp # UDP version $ netstat -tlnp # older alternative, same idea $ lsof -i :22 # what's using a specific port
ss is the modern replacement for netstat. On current Linux systems they're both available but ss is faster and more complete.
Network Interface Management
The modern way to manage interfaces is with the ip command. ifconfig still works on most systems but it's been deprecated for years.
$ ip addr show # all interfaces and their addresses $ ip addr show eth0 # specific interface $ ip link set eth0 up # bring interface up $ ip link set eth0 down # bring it down # Add/remove an address temporarily (lost on reboot) $ ip addr add 192.168.1.100/24 dev eth0 $ ip addr del 192.168.1.100/24 dev eth0
Routing
$ ip route show # routing table $ ip route add default via 192.168.1.1 # set default gateway $ ip route add 10.0.0.0/8 via 10.0.0.1 # add a static route
SSH — The Right Way
The default SSH config leaves a lot on the table. A few things worth setting up properly:
Key-Based Auth
# Generate a key (ed25519 is better than the old rsa default) $ ssh-keygen -t ed25519 -C "jason@mymachine" # Copy public key to remote server $ ssh-copy-id user@remote_host # Or manually: $ cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Locking Down sshd_config
Edit /etc/ssh/sshd_config — make your changes, test with a second session still open before restarting, and don't close that session until you've confirmed you can still log in:
PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys AllowUsers jason # whitelist specific users MaxAuthTries 3
# Test the config before reloading $ sshd -t # Reload (not restart — keeps existing sessions alive) $ systemctl reload sshd
Lock yourself out of a remote server doing this once and you'll always test with a second session after that.
SSH Config File (~/.ssh/config)
This one saves a lot of typing:
Host myserver
HostName 203.0.113.10
User jason
IdentityFile ~/.ssh/id_ed25519
Port 2222
Host *.internal
User admin
ProxyJump bastion.example.com
After this, ssh myserver just works.
Firewalls
ufw (Ubuntu/Debian)
The friendliest firewall interface on Linux:
$ ufw status verbose $ ufw allow 22/tcp $ ufw allow 80/tcp $ ufw allow from 192.168.1.0/24 to any port 5432 # postgres from local net only $ ufw deny 23/tcp $ ufw enable $ ufw reload
iptables
Lower level, more control. Most people use ufw or firewalld instead, but iptables rules are what's actually running underneath:
$ iptables -L -n -v # list all rules with packet counts $ iptables -A INPUT -p tcp --dport 22 -j ACCEPT $ iptables -A INPUT -p tcp --dport 80 -j ACCEPT $ iptables -A INPUT -j DROP # default deny (put this last)
iptables rules don't persist across reboots by default. Use iptables-save and iptables-restore, or just use ufw.
Diagnostic Tools
$ ping -c 4 8.8.8.8 # basic reachability check $ traceroute 8.8.8.8 # where packets are going $ mtr 8.8.8.8 # traceroute that updates live (better) $ dig google.com # DNS lookup $ dig @8.8.8.8 google.com # DNS lookup using a specific server $ curl -I https://example.com # check HTTP headers $ tcpdump -i eth0 port 80 # capture HTTP traffic (needs root) $ tcpdump -i eth0 -w dump.pcap # save for later analysis in Wireshark
Fail2ban
If your SSH port is exposed to the internet, you will get brute-force attempts constantly. Fail2ban watches your logs and bans IPs that fail too many times:
$ apt install fail2ban $ cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
In /etc/fail2ban/jail.local:
[sshd] enabled = true port = ssh maxretry = 5 bantime = 3600 findtime = 600
$ systemctl enable fail2ban $ systemctl start fail2ban $ fail2ban-client status sshd # see current bans $ fail2ban-client set sshd unbanip 1.2.3.4 # unban an IP
dispelled