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

IP Addresses and Hostnames

bash
# Show addresses on all interfaces
ip addr show
 
# Short list of IPs (GNU hostname)
hostname -I

Typical layout:

AddressMeaning
127.0.0.1Loopback—only this machine
10.x / 192.168.xPrivate LAN or VPC
Public IPShown in cloud console; may not appear on eth0 if behind NAT

Set hostname (optional):

bash
hostname
sudo hostnamectl set-hostname myapp-prod-01

Connectivity Tests

bash
# 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 -30

curl is the Swiss Army knife for APIs and health checks—used in deploy scripts and monitoring.

DNS

bash
# 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 +short

If 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:

bash
# 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 :8080

Legacy 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

bash
# 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
UbuntuRHEL
ufw allow 80/tcpfirewall-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:

plaintext
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_ed25519

Connect with alias:

bash
ssh prod

Keys and first login: Linux learning environment.

scp: Copy Files Over SSH

bash
# 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:

bash
scp -r ./dist/ prod:/var/www/myapp/

rsync: Efficient Sync

bash
# 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

bash
# 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 OK

FAQ

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.

What comes next?

Shell scripting basics.