Networking in Linux
Learn how to configure, monitor, and troubleshoot networks on Linux systems.
Networking is a fundamental aspect of modern computing, and Linux provides powerful tools for network configuration, monitoring, and troubleshooting. Whether you're setting up a home server, configuring a web server in the cloud, or just trying to diagnose connectivity issues, understanding Linux networking is essential.
In this part, we'll explore networking concepts and tools in Linux, from basic configuration to advanced monitoring and security.
Network Basics in Linux
Understanding Network Interfaces
Every network connection in Linux is made through a network interface. These can be physical (like Ethernet cards) or virtual (like VPN tunnels).
List network interfaces:
ip link show
Or using the older command:
ifconfig
Common naming conventions for interfaces:
eth0
,eth1
: Traditional names for Ethernet interfacesenp3s0
,ens33
: Predictable interface names in newer distributionswlan0
,wlp3s0
: Wireless interfaceslo
: Loopback interface (always present)
Viewing Network Configuration
Check IP address configuration:
ip addr show
View routing table:
ip route show
Check DNS servers:
cat /etc/resolv.conf
Display network connections:
ss -tuln
The options mean:
t
: TCP connectionsu
: UDP connectionsl
: Show only listening socketsn
: Don't resolve service names
Network Configuration
Temporary Configuration
Set an IP address temporarily:
sudo ip addr add 192.168.1.100/24 dev eth0
Bring an interface up or down:
sudo ip link set eth0 up
sudo ip link set eth0 down
Add a static route:
sudo ip route add 10.0.0.0/24 via 192.168.1.1
These changes won't persist after a reboot.
Permanent Configuration
Network configuration files differ by distribution:
Debian/Ubuntu
For simple setups, edit /etc/network/interfaces
:
sudo nano /etc/network/interfaces
Example static IP configuration:
auto eth0
iface eth0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8 8.8.4.4
For DHCP:
auto eth0
iface eth0 inet dhcp
Apply changes:
sudo systemctl restart networking
Newer Debian/Ubuntu with Netplan
Ubuntu 18.04 and newer use Netplan. Configuration files are in /etc/netplan/
:
sudo nano /etc/netplan/01-netcfg.yaml
Example configuration:
network:
version: 2
renderer: networkd
ethernets:
ens33:
dhcp4: no
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
Apply changes:
sudo netplan apply
RHEL/CentOS/Fedora
Edit files in /etc/sysconfig/network-scripts/
:
sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0
Example static IP configuration:
TYPE=Ethernet
BOOTPROTO=static
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4
DEFROUTE=yes
NAME=eth0
DEVICE=eth0
ONBOOT=yes
For DHCP:
TYPE=Ethernet
BOOTPROTO=dhcp
NAME=eth0
DEVICE=eth0
ONBOOT=yes
Apply changes:
sudo systemctl restart network
NetworkManager (Most Desktop Distributions)
NetworkManager provides both GUI and command-line tools for network configuration:
# Show connections
nmcli connection show
# Show device status
nmcli device status
# Connect to a network
nmcli connection up "Connection Name"
# Create a new connection
nmcli connection add con-name "Home Network" type ethernet ifname eth0 \
ipv4.method manual ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 \
ipv4.dns "8.8.8.8 8.8.4.4"
Configuring Wireless Networks
Connect to a WiFi network:
# Scan for available networks
sudo iwlist wlan0 scan | grep ESSID
# Connect using NetworkManager
nmcli device wifi list
nmcli device wifi connect "SSID" password "your_password"
Using wpa_supplicant
directly:
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
Add the following:
network={
ssid="Your_SSID"
psk="Your_Password"
}
Connect:
sudo wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
sudo dhclient wlan0
Network Troubleshooting Tools
Checking Connectivity
Test basic connectivity with ping
:
ping google.com
ping -c 4 192.168.1.1
Trace the route packets take:
traceroute google.com
An alternative that works through firewalls:
mtr google.com
DNS Troubleshooting
Look up DNS records:
dig google.com
dig google.com MX
dig -x 8.8.8.8
Query a specific DNS server:
dig @8.8.8.8 google.com
Check the system's hostname resolution:
getent hosts google.com
Socket and Port Analysis
Check listening ports and connections:
ss -tuln
View programs using network connections:
sudo ss -tulnp
Check which process is using a specific port:
sudo lsof -i :80
Network Traffic Analysis
Capture network traffic with tcpdump
:
sudo tcpdump -i eth0 -n
Filter traffic by host or port:
sudo tcpdump -i eth0 host 192.168.1.100
sudo tcpdump -i eth0 port 80
For a more user-friendly interface, use Wireshark:
sudo apt install wireshark # Debian/Ubuntu
sudo dnf install wireshark # Fedora/RHEL/CentOS
# Run wireshark (GUI)
sudo wireshark
Bandwidth Monitoring
Monitor bandwidth usage:
sudo apt install iftop # Debian/Ubuntu
sudo dnf install iftop # Fedora/RHEL/CentOS
sudo iftop -i eth0
For a simpler view:
sudo apt install nload # Debian/Ubuntu
sudo dnf install nload # Fedora/RHEL/CentOS
sudo nload eth0
Network Services
SSH (Secure Shell)
SSH is essential for remote administration of Linux systems.
Connect to a remote server:
ssh username@server_ip
Using a different port:
ssh -p 2222 username@server_ip
Using key authentication:
ssh -i /path/to/private_key username@server_ip
Copy files securely with scp
:
# Copy local file to remote server
scp /path/to/local/file username@server_ip:/path/to/remote/directory
# Copy remote file to local system
scp username@server_ip:/path/to/remote/file /path/to/local/directory
# Copy entire directory recursively
scp -r /path/to/local/directory username@server_ip:/path/to/remote/directory
Tunnel traffic through SSH (port forwarding):
# Local port forwarding (access remote service locally)
ssh -L 8080:localhost:80 username@server_ip
# Remote port forwarding (make local service available remotely)
ssh -R 8080:localhost:80 username@server_ip
# Dynamic port forwarding (SOCKS proxy)
ssh -D 9090 username@server_ip
SSH Server Configuration
Configure the SSH server by editing /etc/ssh/sshd_config
:
sudo nano /etc/ssh/sshd_config
Important settings:
# Change default port
Port 2222
# Disable root login
PermitRootLogin no
# Allow only specific users
AllowUsers user1 user2
# Disable password authentication (use keys only)
PasswordAuthentication no
# Allow only key-based authentication
PubkeyAuthentication yes
After changes, restart the SSH service:
sudo systemctl restart sshd
HTTP/Web Servers
Install and configure Apache:
sudo apt install apache2 # Debian/Ubuntu
sudo dnf install httpd # Fedora/RHEL/CentOS
# Start and enable the service
sudo systemctl start apache2 # Debian/Ubuntu
sudo systemctl enable apache2
sudo systemctl start httpd # Fedora/RHEL/CentOS
sudo systemctl enable httpd
Install Nginx:
sudo apt install nginx # Debian/Ubuntu
sudo dnf install nginx # Fedora/RHEL/CentOS
# Start and enable the service
sudo systemctl start nginx
sudo systemctl enable nginx
Basic Nginx configuration (/etc/nginx/sites-available/default
or /etc/nginx/conf.d/default.conf
):
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
DNS Servers
Install and configure BIND:
sudo apt install bind9 # Debian/Ubuntu
sudo dnf install bind # Fedora/RHEL/CentOS
# Configure BIND
sudo nano /etc/bind/named.conf.local
Basic zone configuration:
zone "example.com" {
type master;
file "/etc/bind/zones/example.com.zone";
};
Create the zone file:
sudo mkdir -p /etc/bind/zones
sudo nano /etc/bind/zones/example.com.zone
Zone file content:
$TTL 86400
@ IN SOA ns1.example.com. admin.example.com. (
2025051401 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
86400 ; Minimum TTL
)
@ IN NS ns1.example.com.
@ IN A 192.168.1.100
www IN A 192.168.1.100
ns1 IN A 192.168.1.100
Restart BIND:
sudo systemctl restart bind9 # Debian/Ubuntu
sudo systemctl restart named # Fedora/RHEL/CentOS
Network Security
Firewalls
UFW (Uncomplicated Firewall)
UFW is a user-friendly front-end for iptables (Debian/Ubuntu):
# Install UFW
sudo apt install ufw
# Check status
sudo ufw status
# Enable UFW
sudo ufw enable
# Basic rules
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
# Allow specific port
sudo ufw allow 8080/tcp
# Allow from specific IP
sudo ufw allow from 192.168.1.100
# Deny a service
sudo ufw deny telnet
# Delete a rule (by number)
sudo ufw status numbered
sudo ufw delete 2
firewalld
Firewalld is the default firewall on Fedora/RHEL/CentOS:
# Check status
sudo firewall-cmd --state
# List allowed services
sudo firewall-cmd --list-services
# Allow a service
sudo firewall-cmd --add-service=http --permanent
# Allow a port
sudo firewall-cmd --add-port=8080/tcp --permanent
# Apply changes
sudo firewall-cmd --reload
iptables
Direct iptables commands (low-level):
# Allow SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow HTTP
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Drop all other incoming traffic
sudo iptables -A INPUT -j DROP
# Save rules
sudo iptables-save | sudo tee /etc/iptables.rules
Secure Network Services
Restricting SSH access:
# Allow SSH only from specific IP ranges
sudo ufw allow from 192.168.1.0/24 to any port 22
Add firewall rules to limit connection attempts:
# Using iptables to limit SSH connection attempts
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
Network Encryption
Set up WireGuard VPN (modern, fast, secure VPN):
# Install WireGuard
sudo apt install wireguard # Debian/Ubuntu
sudo dnf install wireguard-tools # Fedora/RHEL/CentOS
# Generate keys
wg genkey | tee privatekey | wg pubkey > publickey
# Create configuration
sudo nano /etc/wireguard/wg0.conf
Basic WireGuard configuration:
[Interface]
PrivateKey = your_private_key_here
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
PublicKey = peer_public_key_here
AllowedIPs = 10.0.0.2/32
Start WireGuard:
sudo wg-quick up wg0
Enable at boot:
sudo systemctl enable wg-quick@wg0
Advanced Networking Topics
Network Namespaces
Network namespaces isolate network resources, similar to how containers work:
# Create a new network namespace
sudo ip netns add test_ns
# List namespaces
ip netns list
# Execute command in namespace
sudo ip netns exec test_ns ip addr
# Create a virtual Ethernet pair
sudo ip link add veth0 type veth peer name veth1
# Move one end to the namespace
sudo ip link set veth1 netns test_ns
# Configure the interfaces
sudo ip addr add 192.168.100.1/24 dev veth0
sudo ip netns exec test_ns ip addr add 192.168.100.2/24 dev veth1
# Bring up the interfaces
sudo ip link set veth0 up
sudo ip netns exec test_ns ip link set veth1 up
sudo ip netns exec test_ns ip link set lo up
Network Bridging
Create a bridge for connecting VMs or containers:
# Install bridge utilities
sudo apt install bridge-utils # Debian/Ubuntu
sudo dnf install bridge-utils # Fedora/RHEL/CentOS
# Create a bridge
sudo ip link add name br0 type bridge
sudo ip link set dev br0 up
# Add interfaces to the bridge
sudo ip link set dev eth0 master br0
sudo ip link set dev eth1 master br0
# Configure the bridge with an IP
sudo ip addr add 192.168.1.100/24 dev br0
Bonding Network Interfaces
Combine multiple network interfaces for redundancy or increased bandwidth:
# Load the bonding module
sudo modprobe bonding
# Create a bond interface
sudo ip link add bond0 type bond
sudo ip link set bond0 up
# Set the bonding mode
echo "active-backup" | sudo tee /sys/class/net/bond0/bonding/mode
# Add interfaces to the bond
sudo ip link set eth0 down
sudo ip link set eth1 down
sudo ip link set eth0 master bond0
sudo ip link set eth1 master bond0
sudo ip link set eth0 up
sudo ip link set eth1 up
# Configure the bond with an IP
sudo ip addr add 192.168.1.100/24 dev bond0
Traffic Control
Limit bandwidth with tc
(Traffic Control):
# Limit outgoing bandwidth to 1Mbps
sudo tc qdisc add dev eth0 root tbf rate 1mbit burst 32kbit latency 400ms
# Remove the limitation
sudo tc qdisc del dev eth0 root
Network Configuration for Cloud Environments
When running Linux in the cloud, network configuration is often handled differently.
Example: DigitalOcean Droplet
When you create a Droplet on DigitalOcean (use this link to receive $200 in credits), networking is pre-configured, but you may need to make changes:
Configure Private Networking:
- Private networking is enabled by default on new Droplets
- Access your Droplet through its private IP for data transfer between Droplets in the same region
Configure Floating IP:
- Assign a Floating IP to your Droplet for a static public IP that can be easily moved between Droplets
Configure Firewall:
- Use DigitalOcean's Cloud Firewall or configure UFW/iptables on your Droplet
- Basic UFW setup for a web server:
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
Practical Networking Examples
Let's apply what we've learned with some practical examples:
Setting Up a Simple Web Server
# Install Nginx
sudo apt update
sudo apt install nginx
# Check that it's running
sudo systemctl status nginx
# Configure firewall to allow HTTP traffic
sudo ufw allow 'Nginx HTTP'
sudo ufw status
# Get your public IP
curl ifconfig.me
# Now you can access your web server at http://your_ip_address
Creating a Secure SSH Configuration
# Create backup of original configuration
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Edit SSH config
sudo nano /etc/ssh/sshd_config
Make these changes:
# Use a non-standard port
Port 2222
# Disable root login
PermitRootLogin no
# Disable password authentication
PasswordAuthentication no
# Limit user access
AllowUsers yourusername
# Automatic logout of idle sessions
ClientAliveInterval 300
ClientAliveCountMax 2
Apply changes:
# Check config for errors
sudo sshd -t
# Restart SSH service if no errors
sudo systemctl restart sshd
Test before logging out:
# Open a new terminal and try to connect
ssh -p 2222 yourusername@your_server_ip
Setting Up Network Address Translation (NAT)
Configure a Linux machine to share its internet connection:
# Enable IP forwarding
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
# Make it permanent
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# Configure NAT with iptables
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
# Save iptables rules
sudo iptables-save | sudo tee /etc/iptables.rules
Setting Up DNS Caching
Improve network performance with DNS caching:
# Install dnsmasq
sudo apt install dnsmasq
# Configure dnsmasq
sudo nano /etc/dnsmasq.conf
Add these lines:
# Listen on localhost
listen-address=127.0.0.1
# Use Google DNS as upstream
server=8.8.8.8
server=8.8.4.4
# Cache size
cache-size=1000
Configure system to use the local DNS server:
sudo nano /etc/resolv.conf
Change to:
nameserver 127.0.0.1
To make it permanent:
# For systems using NetworkManager
sudo nano /etc/NetworkManager/NetworkManager.conf
Add:
[main]
dns=dnsmasq
Restart services:
sudo systemctl restart dnsmasq
sudo systemctl restart NetworkManager
Moving Forward
You now have a solid understanding of Linux networking concepts and tools. These skills will help you configure, monitor, and troubleshoot networks on any Linux system.
In the next part, we'll explore shell scripting basics, allowing you to automate tasks and build powerful tools using the Linux command line.
Linux networking capabilities range from simple configuration to advanced network services and security. Whether you're managing a single system or an entire infrastructure, these networking skills form a crucial part of your Linux toolkit.
Found an issue?