Networking Basics
Introduction
Servers live on the network: SSH for admin, HTTP for apps, DNS for hostnames. This chapter teaches how to read your IP, test connectivity, inspect listening ports, open firewall holes safely, and copy deploy artifacts with scp and rsync.
Prerequisites
- Processes and systemd
- SSH access to a Linux host (local VM or cloud)
IP Addresses and Hostnames
# Show addresses on all interfaces
ip addr show
# Short list of IPs (GNU hostname)
hostname -ITypical layout:
| Address | Meaning |
|---|---|
127.0.0.1 | Loopback—only this machine |
10.x / 192.168.x | Private LAN or VPC |
| Public IP | Shown in cloud console; may not appear on eth0 if behind NAT |
Set hostname (optional):
hostname
sudo hostnamectl set-hostname myapp-prod-01Connectivity Tests
# ICMP reachability (may be blocked by some clouds)
ping -c 4 8.8.8.8
# HTTP headers from a URL
curl -I https://example.com
# Download body to stdout
curl -s https://example.com | head
# Verbose TLS handshake debug
curl -v https://example.com 2>&1 | head -30curl is the Swiss Army knife for APIs and health checks—used in deploy scripts and monitoring.
DNS
# Resolver config (often managed by systemd-resolved)
cat /etc/resolv.conf
# Simple lookup
nslookup example.com
# Detailed query (install bind9-dnsutils on Ubuntu)
dig example.com +shortIf DNS fails, ping google.com errors but ping 8.8.8.8 works—fix nameservers or VPC DNS settings.
Listening Ports
Prefer ss on modern systems:
# TCP listeners with process names (needs root for all PIDs)
sudo ss -tlnp
# Filter port 22 (SSH)
sudo ss -tlnp | grep :22
# Filter port 8080 (common Spring Boot)
sudo ss -tlnp | grep :8080Legacy netstat -tlnp may still exist but ss is faster.
Before starting Nginx or your app, confirm the port is free—no duplicate bind errors.
Firewall: UFW on Ubuntu
Warning
SSH Lockout
Never enable a firewall without allowing SSH (22) if that is how you connect remotely.
Firewall: firewalld on RHEL Family
# Status
sudo firewall-cmd --state
# Open HTTP permanently
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# Custom port
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload| Ubuntu | RHEL |
|---|---|
ufw allow 80/tcp | firewall-cmd --add-service=http |
Cloud security groups are a second layer—inbound rules on AWS/Aliyun must match OS firewall.
SSH Config for Multiple Servers
Edit ~/.ssh/config:
Host prod
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519
Host staging
HostName 198.51.100.20
User deploy
IdentityFile ~/.ssh/id_ed25519Connect with alias:
ssh prodKeys and first login: Linux learning environment.
scp: Copy Files Over SSH
# Upload tarball to server
scp myapp-1.0.tar.gz deploy@203.0.113.10:/opt/myapp/
# Download log file
scp deploy@203.0.113.10:/var/log/nginx/access.log ./
# With config alias
scp myapp-1.0.tar.gz prod:/opt/myapp/Recursive copy for directories:
scp -r ./dist/ prod:/var/www/myapp/rsync: Efficient Sync
# Archive mode, compress, show progress
rsync -avz --progress ./build/ deploy@203.0.113.10:/opt/myapp/build/
# Exclude node_modules
rsync -avz --exclude node_modules ./ project/ prod:/srv/project/rsync only transfers changed blocks—ideal for repeated deploys of static frontends or large trees.
Mini Example: Health Check from Laptop
# Is the app listening on the server?
ssh prod 'sudo ss -tlnp | grep :8080'
# HTTP check through SSH tunnel alternative: direct if port open
curl -sf http://203.0.113.10:8080/actuator/health && echo OKFAQ
Connection refused vs timeout?
Refused: host reachable, nothing listening or firewall REJECT. Timeout: routing, wrong IP, or security group blocking.
Cannot bind to 0.0.0.0 without root?
Ports below 1024 need root—or run behind Nginx on 80 proxying to 8080.
ping works but curl fails?
Different protocols—check HTTP firewall, app down, or wrong URL/path.
IPv6?
ip -6 addr; curl -6 for v6-only tests. Many VPS still use IPv4 primarily.