Module 8.2: Network Administration
Operations — LFCS | Complexity:
[COMPLEX]| Time: 45-55 min
Prerequisites
Section titled “Prerequisites”Before starting this module:
- Required: Module 3.1: TCP/IP Essentials for IP addressing, subnets, and routing
- Required: Module 3.4: iptables & netfilter for packet filtering fundamentals
- Helpful: Module 1.2: Processes & systemd for service management
What You’ll Be Able to Do
Section titled “What You’ll Be Able to Do”After this module, you will be able to:
- Configure network interfaces, routes, and DNS resolution using nmcli and ip commands
- Secure SSH access and manage firewall rules with firewalld
- Implement network bonding and VLAN tagging for server redundancy
- Diagnose network connectivity failures using a systematic approach (link → IP → route → DNS → firewall)
Why This Module Matters
Section titled “Why This Module Matters”TCP/IP knowledge tells you how packets flow. This module teaches you how to control that flow — who gets in, who gets out, which interfaces bond together, and how to harden your network services.
Understanding network administration helps you:
- Secure servers — Firewalls are your first and last line of defense
- Build reliable networks — Bonding and bridging prevent single points of failure
- Enable routing — NAT and masquerading let private networks reach the internet
- Pass the LFCS exam — Networking is 25% of the exam, the largest single domain
If your server is on the internet without a properly configured firewall, it’s not a question of if it gets compromised — it’s when.
Did You Know?
Section titled “Did You Know?”-
firewalld replaced iptables as the default on RHEL/CentOS 7+ and Fedora. Under the hood, firewalld uses nftables (the successor to iptables) as its backend. Ubuntu uses
ufwby default but firewalld works there too. -
Network bonding can survive cable pulls — With active-backup bonding, you can physically unplug a network cable and traffic seamlessly switches to the other interface. Data centers use this everywhere.
-
NTP matters more than you think — A time drift of just a few seconds can break Kerberos authentication, cause TLS certificate failures, and make log correlation impossible. Chrony replaced ntpd because it syncs faster and handles virtual machines better.
IPv4/IPv6 Configuration with nmcli
Section titled “IPv4/IPv6 Configuration with nmcli”NetworkManager (nmcli) is the standard tool for managing network configurations across modern Linux distributions.
IPv4 Configuration
Section titled “IPv4 Configuration”# List connectionsnmcli connection show
# Show device statusnmcli device status
# Configure static IPv4sudo nmcli connection modify "Wired connection 1" \ ipv4.addresses 192.168.1.100/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns "8.8.8.8 1.1.1.1" \ ipv4.method manual
# Switch to DHCPsudo nmcli connection modify "Wired connection 1" \ ipv4.method auto
# Apply changessudo nmcli connection up "Wired connection 1"
# Verifyip addr showip route showStop and think: If your server has an IP address but can’t reach the internet, which
nmclisetting might be missing? (Hint: Think about how packets find their way out of your local network).
IPv6 Configuration
Section titled “IPv6 Configuration”# Add static IPv6 addresssudo nmcli connection modify "Wired connection 1" \ ipv6.addresses "fd00::100/64" \ ipv6.gateway "fd00::1" \ ipv6.method manual
# Enable both IPv4 and IPv6sudo nmcli connection modify "Wired connection 1" \ ipv4.method manual \ ipv4.addresses 192.168.1.100/24 \ ipv6.method manual \ ipv6.addresses "fd00::100/64"
# Disable IPv6 (if needed)sudo nmcli connection modify "Wired connection 1" \ ipv6.method disabled
# Applysudo nmcli connection up "Wired connection 1"
# Verifyip -6 addr showip -6 route showAdding Static Routes
Section titled “Adding Static Routes”# Add a static routesudo nmcli connection modify "Wired connection 1" \ +ipv4.routes "10.10.0.0/16 192.168.1.254"
# Add route with metricsudo nmcli connection modify "Wired connection 1" \ +ipv4.routes "10.10.0.0/16 192.168.1.254 100"
# Applysudo nmcli connection up "Wired connection 1"
# Verifyip route showNetwork Bonding and Bridging
Section titled “Network Bonding and Bridging”Network Bonding (Link Aggregation)
Section titled “Network Bonding (Link Aggregation)”Bonding combines multiple network interfaces for redundancy or throughput:
graph TD App[Applications] --> Bond[bond0 Interface] Bond -->|Active| Eth1[eth1 Physical] Bond -->|Backup| Eth2[eth2 Physical] Eth1 --> Switch[Network Switch] Eth2 -.-> Switch| Mode | Name | Use Case |
|---|---|---|
| 0 | balance-rr | Round-robin, increased throughput |
| 1 | active-backup | Failover, one active at a time |
| 2 | balance-xor | Transmit based on hash |
| 4 | 802.3ad (LACP) | Dynamic link aggregation (requires switch support) |
| 6 | balance-alb | Adaptive load balancing |
Mode 1 (active-backup) is the most common in production — simple, reliable, no switch configuration needed.
# Create a bond using nmclisudo nmcli connection add type bond \ con-name bond0 \ ifname bond0 \ bond.options "mode=active-backup,miimon=100"
# Add slave interfaces to the bondsudo nmcli connection add type ethernet \ con-name bond0-slave1 \ ifname eth1 \ master bond0
sudo nmcli connection add type ethernet \ con-name bond0-slave2 \ ifname eth2 \ master bond0
# Configure IP on the bondsudo nmcli connection modify bond0 \ ipv4.addresses 192.168.1.10/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns "8.8.8.8 8.8.4.4" \ ipv4.method manual
# Bring up the bondsudo nmcli connection up bond0
# Verifycat /proc/net/bonding/bond0# Shows which slave is active, link status, etc.
# Test failover: bring down one slavesudo nmcli connection down bond0-slave1# Traffic continues on bond0-slave2Stop and think: If you unplug the cable for the active interface in an active-backup bond, what happens to existing TCP connections? Do they drop or stay alive?
Network Bridging
Section titled “Network Bridging”Bridges connect two network segments at Layer 2. In Linux, they’re essential for virtual machines and containers.
# Create a bridgesudo nmcli connection add type bridge \ con-name br0 \ ifname br0
# Add physical interface to bridgesudo nmcli connection add type ethernet \ con-name br0-port1 \ ifname eth1 \ master br0
# Configure IP on bridgesudo nmcli connection modify br0 \ ipv4.addresses 192.168.1.20/24 \ ipv4.gateway 192.168.1.1 \ ipv4.method manual
# Bring upsudo nmcli connection up br0
# Verifybridge link showip addr show br0War story: A team set up LACP bonding (mode 4) on their servers but forgot to configure the matching port-channel on the network switch. Both interfaces came up, traffic flowed… sort of. Packets were being load-balanced across two independent links, causing out-of-order delivery, TCP retransmissions, and random 50% packet loss. The monitoring showed the interfaces as “up” with good throughput, but applications were timing out. It took two days to figure out because everyone assumed “the network is fine — both links are up.” The fix was a 5-minute switch configuration. Lesson: bonding mode 4 (LACP) requires BOTH sides to be configured. Mode 1 (active-backup) is forgiving and needs no switch changes.
VLAN Tagging (802.1Q)
Section titled “VLAN Tagging (802.1Q)”Virtual LANs (VLANs) allow you to segment a single physical network into multiple logical networks. This is essential for isolating traffic (e.g., separating management traffic from public web traffic) without requiring separate physical cables and switches for every network.
# Create a VLAN interface (VLAN ID 10) on physical interface eth0sudo nmcli connection add type vlan \ con-name eth0-vlan10 \ ifname eth0.10 \ dev eth0 \ id 10 \ ipv4.addresses 10.0.10.50/24 \ ipv4.method manual
# Bring up the VLAN interfacesudo nmcli connection up eth0-vlan10
# Verifyip addr show eth0.10Stop and think: If you configure a VLAN interface on your server but cannot ping other devices on the same VLAN, what network infrastructure component might be missing the VLAN configuration?
Time Synchronization with Chrony
Section titled “Time Synchronization with Chrony”Accurate time is critical for log correlation, certificate validation, authentication (Kerberos), and distributed systems.
Why Chrony Over ntpd
Section titled “Why Chrony Over ntpd”- Faster initial sync — Chrony syncs in seconds; ntpd can take minutes
- Better for VMs — Handles clock jumps from VM suspend/resume
- Lower resource usage — Lightweight and efficient
- Default on modern distros — RHEL 8+, Ubuntu 22.04+ use chrony
Configuration
Section titled “Configuration”# Install chronysudo apt install -y chrony
# Check configurationcat /etc/chrony/chrony.confKey configuration in /etc/chrony/chrony.conf:
# NTP servers (pool is preferred — auto-selects nearby servers)pool ntp.ubuntu.com iburst maxsources 4pool 0.ubuntu.pool.ntp.org iburst maxsources 1pool 1.ubuntu.pool.ntp.org iburst maxsources 1pool 2.ubuntu.pool.ntp.org iburst maxsources 2
# Record the rate at which the system clock gains/driftsdriftfile /var/lib/chrony/chrony.drift
# Allow NTP clients from local network (if acting as NTP server)# allow 192.168.1.0/24
# Step the clock if offset is larger than 1 second (first 3 updates)makestep 1.0 3# Start and enablesudo systemctl enable --now chrony
# Check synchronization statuschronyc tracking# Reference ID : A9FEA9FE (time.cloudflare.com)# Stratum : 3# Ref time (UTC) : Sun Mar 22 14:30:00 2026# System time : 0.000000123 seconds fast of NTP time# Last offset : +0.000000045 seconds
# List NTP sourceschronyc sources -v
# Force immediate syncsudo chronyc makestep
# Check if chrony is being usedtimedatectl# Look for: NTP service: activeSetting Timezone
Section titled “Setting Timezone”# List timezonestimedatectl list-timezones | grep America
# Set timezonesudo timedatectl set-timezone UTC
# VerifytimedatectldateFirewall Management with firewalld
Section titled “Firewall Management with firewalld”Why firewalld Over Raw iptables
Section titled “Why firewalld Over Raw iptables”Raw iptables rules are powerful but fragile. One mistake can lock you out. firewalld adds:
- Zones: Group interfaces and rules by trust level
- Runtime vs permanent: Test rules before making them permanent
- Services: Pre-defined rule sets (ssh, http, https, etc.)
- Rich rules: Complex rules without raw iptables syntax
Installing and Starting firewalld
Section titled “Installing and Starting firewalld”# Install (may already be present)sudo apt install -y firewalld
# Start and enablesudo systemctl enable --now firewalld
# Check statussudo firewall-cmd --state# running
# Check active zonessudo firewall-cmd --get-active-zones# public# interfaces: eth0Zones define the trust level for network connections:
| Zone | Purpose | Default Behavior |
|---|---|---|
drop | Untrusted networks | Drop all incoming, no reply |
block | Untrusted networks | Reject incoming with ICMP |
public | Public networks (default) | Reject incoming except selected |
external | NAT/masquerading | Masquerade outbound traffic |
dmz | DMZ servers | Limited incoming allowed |
work | Work networks | Trust some services |
home | Home networks | Trust more services |
internal | Internal networks | Similar to work |
trusted | Trust everything | Allow all traffic |
# List all zonessudo firewall-cmd --get-zones
# Show default zonesudo firewall-cmd --get-default-zone# public
# Change default zonesudo firewall-cmd --set-default-zone=public
# Assign interface to a zonesudo firewall-cmd --zone=internal --change-interface=eth1 --permanentsudo firewall-cmd --reload
# Show zone detailssudo firewall-cmd --zone=public --list-allManaging Services
Section titled “Managing Services”# List available pre-defined servicessudo firewall-cmd --get-services
# List services enabled in current zonesudo firewall-cmd --list-services# dhcpv6-client ssh
# Add a service (runtime only — lost on reload)sudo firewall-cmd --add-service=httpsudo firewall-cmd --add-service=https
# Add a service permanentlysudo firewall-cmd --add-service=http --permanentsudo firewall-cmd --add-service=https --permanentsudo firewall-cmd --reload
# Remove a servicesudo firewall-cmd --remove-service=http --permanentsudo firewall-cmd --reload
# Add a custom portsudo firewall-cmd --add-port=8080/tcp --permanentsudo firewall-cmd --add-port=3000-3100/tcp --permanentsudo firewall-cmd --reloadRich Rules
Section titled “Rich Rules”Rich rules provide fine-grained control when simple service/port rules aren’t enough:
# Allow SSH only from specific subnetsudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' --permanent
# Block a specific IPsudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.50" drop' --permanent
# Rate-limit connections (prevent brute force)sudo firewall-cmd --add-rich-rule='rule family="ipv4" service name="ssh" accept limit value="3/m"' --permanent
# Log and drop traffic from a subnetsudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" log prefix="BLOCKED: " level="warning" drop' --permanent
# Apply changessudo firewall-cmd --reload
# List rich rulessudo firewall-cmd --list-rich-rulesRuntime vs Permanent
Section titled “Runtime vs Permanent”# Runtime rule (test it first)sudo firewall-cmd --add-service=http
# If it works, make it permanentsudo firewall-cmd --runtime-to-permanent
# Or start over — reload drops runtime-only rulessudo firewall-cmd --reload
# This workflow prevents lockouts:# 1. Add rule (runtime)# 2. Test access# 3. If good: --runtime-to-permanent# 4. If bad: --reload to revertPause and predict: If you add a rich rule to block an IP and reload
firewalldwithout using the--permanentflag, what will happen to your rule?
nftables (The Modern Backend)
Section titled “nftables (The Modern Backend)”nftables replaces iptables as the Linux kernel packet filtering framework. firewalld uses nftables under the hood, but you should know the basics for the LFCS.
# Check if nftables is activesudo nft list ruleset
# List tablessudo nft list tables
# Create a simple firewall from scratchsudo nft add table inet filtersudo nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'sudo nft add chain inet filter forward '{ type filter hook forward priority 0; policy drop; }'sudo nft add chain inet filter output '{ type filter hook output priority 0; policy accept; }'
# Allow established connectionssudo nft add rule inet filter input ct state established,related accept
# Allow loopbacksudo nft add rule inet filter input iifname "lo" accept
# Allow SSHsudo nft add rule inet filter input tcp dport 22 accept
# Allow ICMP (ping)sudo nft add rule inet filter input ip protocol icmp accept
# View rulessudo nft list chain inet filter input
# Save rules persistentlysudo nft list ruleset | sudo tee /etc/nftables.confsudo systemctl enable nftablesExam tip: On the LFCS exam (Ubuntu), you’ll most likely use
ufworfirewalld. But understanding that nftables is the underlying framework helps when debugging.
NAT and Masquerading
Section titled “NAT and Masquerading”NAT (Network Address Translation) lets machines on a private network access the internet through a gateway machine. Masquerading is a form of NAT where the source address is dynamically replaced with the gateway’s address.
Analogy: Think of NAT as a corporate receptionist. An office has 100 employees, each with an internal extension (Private IP). When an employee calls the outside world, the receptionist (NAT gateway) intercepts the call, replaces the internal extension with the company’s main public phone number (Masquerading), and forwards it. When the external party replies, the receptionist remembers who made the original call and routes it back to the correct internal extension.
graph LR Internal1[Internal Server 1\n192.168.1.10] --> NAT[NAT Gateway\neth1: 192.168.1.1\neth0: 203.0.113.5] Internal2[Internal Server 2\n192.168.1.11] --> NAT NAT -->|Source IP: 203.0.113.5| Internet((Internet))Enable IP Forwarding
Section titled “Enable IP Forwarding”# Check current statuscat /proc/sys/net/ipv4/ip_forward# 0 = disabled, 1 = enabled
# Enable temporarilysudo sysctl -w net.ipv4.ip_forward=1
# Enable permanentlyecho "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-ip-forward.confsudo sysctl -p /etc/sysctl.d/99-ip-forward.confMasquerading with firewalld
Section titled “Masquerading with firewalld”# Enable masquerading on external zonesudo firewall-cmd --zone=external --add-masquerade --permanent
# Assign external interface to external zonesudo firewall-cmd --zone=external --change-interface=eth0 --permanent
# Assign internal interface to internal zonesudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
# Allow forwarding from internal to externalsudo firewall-cmd --zone=internal --add-forward --permanent
sudo firewall-cmd --reload
# Verify masquerading is enabledsudo firewall-cmd --zone=external --query-masquerade# yesPort Forwarding
Section titled “Port Forwarding”# Forward port 8080 on external to internal server 192.168.1.100:80sudo firewall-cmd --zone=external --add-forward-port=port=8080:proto=tcp:toport=80:toaddr=192.168.1.100 --permanent
sudo firewall-cmd --reload
# Verifysudo firewall-cmd --zone=external --list-forward-portsSSH Hardening
Section titled “SSH Hardening”SSH is the primary remote access method for Linux servers. Default configurations are rarely secure enough for production.
Key-Based Authentication
Section titled “Key-Based Authentication”# Generate an SSH key pair (on client machine)ssh-keygen -t ed25519 -C "admin @company.com"# Ed25519 is preferred over RSA — shorter, faster, more secure
# Copy public key to serverssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# Or manually:cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# Test key loginssh -i ~/.ssh/id_ed25519 user @src/content/docs/uk/prerequisites/zero-to-terminal/module-0.8-servers-and-ssh.mdHardening sshd_config
Section titled “Hardening sshd_config”Edit /etc/ssh/sshd_config:
# Disable password authentication (key-only)PasswordAuthentication no
# Disable root loginPermitRootLogin no
# Use only SSH protocol 2Protocol 2
# Limit to specific users or groupsAllowUsers admin deploy# Or: AllowGroups sshusers
# Change default port (security through obscurity — helps with noise)Port 2222
# Disable empty passwordsPermitEmptyPasswords no
# Set idle timeout (disconnect after 5 minutes of inactivity)ClientAliveInterval 300ClientAliveCountMax 0
# Limit authentication attemptsMaxAuthTries 3
# Disable X11 forwarding (unless needed)X11Forwarding no
# Disable TCP forwarding (unless needed)AllowTcpForwarding no# Test configuration before restartingsudo sshd -t# No output = no errors
# Restart SSHsudo systemctl restart sshd
# CRITICAL: Test from another terminal BEFORE closing your current session# If config is wrong, you can still fix it from the existing sessionStop and think: If you set
PasswordAuthentication nobut haven’t successfully copied your SSH key to the server yet, what will happen when you restart the SSH service and log out?
Fail2ban for Brute Force Protection
Section titled “Fail2ban for Brute Force Protection”# Install fail2bansudo apt install -y fail2ban
# Create local config (never edit jail.conf directly)sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.localEdit /etc/fail2ban/jail.local:
[DEFAULT]bantime = 1hfindtime = 10mmaxretry = 5
[sshd]enabled = trueport = sshlogpath = %(sshd_log)sbackend = systemdmaxretry = 3bantime = 24h# Start fail2bansudo systemctl enable --now fail2ban
# Check statussudo fail2ban-client status sshd# Status for the jail: sshd# |- Filter# | |- Currently failed: 0# | `- Total failed: 12# `- Actions# |- Currently banned: 2# `- Total banned: 5
# Unban an IPsudo fail2ban-client set sshd unbanip 192.168.1.50
# View banned IPssudo fail2ban-client get sshd bannedSystematic Network Diagnosis
Section titled “Systematic Network Diagnosis”When a network connection fails, don’t guess. Follow the OSI model from the bottom up to systematically isolate the issue.
- Link (Layer 1/2): Is the cable plugged in? Is the interface up?
Terminal window ip link show eth0# Look for state UP and NO-CARRIER - IP Configuration (Layer 3): Does the interface have the correct IP and subnet mask?
Terminal window ip addr show eth0 - Routing (Layer 3): Does the system know how to reach the destination? Is there a default gateway?
Terminal window ip route showping -c 4 8.8.8.8 # Test routing to the internet - DNS (Layer 7): Can the system resolve domain names to IP addresses?
Terminal window resolvectl statusdig google.com - Firewall (Layer 4): Is a firewall blocking the traffic locally or remotely?
Terminal window sudo firewall-cmd --list-alltelnet destination_ip port # Test if the port is open
Stop and think: If
ping 8.8.8.8works, butping google.comfails, at which step of the systematic diagnosis did the failure occur?
Common Mistakes
Section titled “Common Mistakes”| Mistake | What Happens | Fix |
|---|---|---|
firewall-cmd without --permanent | Rule lost on reload/reboot | Add --permanent and --reload |
| Blocking SSH before adding allow rule | Locked out of server | Always allow SSH first, then set default deny |
| Bonding mode 4 without switch config | Packet loss, retransmissions | Use mode 1 (active-backup) or configure switch |
PasswordAuthentication no without testing key login | Locked out completely | Test key auth in separate session first |
No nofail on network mounts in fstab | Server won’t boot if NFS down | Always use nofail,_netdev for network mounts |
Forgetting sysctl ip_forward for NAT | Packets arrive but don’t get forwarded | Enable net.ipv4.ip_forward=1 |
Editing jail.conf instead of jail.local | Changes overwritten on update | Always create and edit jail.local |
Test your network administration knowledge:
Question 1: A junior admin configured a server’s network using nmcli. The server can reach other machines in the 10.0.5.0/24 subnet, but it cannot communicate with the internet or any other subnets. What configuration is missing, and how would you verify this using the ip command?
Show Answer
The default gateway is missing. You would use ip route show to check for a line starting with default via .... Without a default gateway, the system’s routing table has no instructions on where to send packets destined for outside its local subnet. Since the local switch handles traffic within the 10.0.5.0/24 subnet, that traffic succeeds, but external requests are immediately dropped by the kernel because there is no known path forward.
Question 2: You are configuring firewalld to allow a new application running on port 8443. You run sudo firewall-cmd --add-port=8443/tcp --permanent. However, external clients still cannot connect. What crucial step was forgotten, and why did the traffic fail?
Show Answer
The admin forgot to apply the changes to the running configuration using sudo firewall-cmd --reload. The --permanent flag only writes the rule to the configuration files on disk, ensuring it survives a reboot. It does not automatically inject the rule into the active, running firewall state. To make it take effect immediately, you must either reload the firewall or apply the rule twice (once without the flag for runtime, once with it for permanence).
Question 3: Your physical server connects to a managed switch that uses 802.1Q to separate guest Wi-Fi traffic (VLAN 20) from internal corporate traffic (VLAN 10). You need to attach a single physical interface (eth0) to the internal corporate network. What nmcli connection type must you use, and what ID must be specified?
Show Answer
You must use the vlan connection type and specify id 10. This instructs the Linux kernel to create a logical interface (like eth0.10) that automatically tags outgoing packets with VLAN ID 10. It also configures the interface to accept incoming packets tagged with VLAN 10 by the switch, stripping the tag before passing the payload to the operating system. Without this tagging, the managed switch would drop the server’s untagged packets or route them to a default, incorrect VLAN.
Question 4: An application team reports that their service intermittently drops connections. You suspect a failing network cable on eth1. To prevent downtime during cable replacement, you want to combine eth1 and eth2 so that if one fails, the other takes over immediately, without asking the network team to reconfigure the switch. What technology and specific mode should you deploy?
Show Answer
You should deploy Network Bonding using Mode 1 (active-backup). This mode requires no special configuration or support (like LACP) on the network switch, making it foolproof to deploy independently. Only one interface actively transmits and receives traffic at a time. If the primary physical link (eth1) drops, the bonding driver immediately shifts the MAC address and all traffic to the backup link (eth2), ensuring continuous application availability.
Question 5: A developer states they cannot SSH into a newly provisioned Linux server. You follow the systematic diagnosis approach: you verify the server is powered on, ip link shows the interface is UP, ip addr shows the correct IP (192.168.1.50), and ip route has the correct gateway. You can even ping the server successfully. What are the next two logical layers/components to check?
Show Answer
Following systematic diagnosis, since Layer 1, 2, and 3 (IP and routing) are working (proven by ping), you should next check Layer 4/7 services. First, verify the Firewall by checking if firewalld or ufw is actively dropping TCP port 22 traffic (sudo firewall-cmd --list-all). Next, verify the SSH Service itself by checking if sshd is actually running (systemctl status sshd). If the service is running and reachable, it is highly likely that SSH hardening rules (like AllowUsers or disabling password authentication before keys were copied) are actively rejecting the developer’s login attempts.
Hands-On Exercise: Secure a Server from Scratch
Section titled “Hands-On Exercise: Secure a Server from Scratch”Objective: Configure firewall rules, harden SSH, set up NTP, and configure network interfaces.
Environment: A Linux VM (Ubuntu 22.04 preferred) with at least one network interface.
Task 1: Configure firewalld
Section titled “Task 1: Configure firewalld”# Install and start firewalldsudo apt install -y firewalldsudo systemctl enable --now firewalld
# Set default zone to publicsudo firewall-cmd --set-default-zone=public
# Allow only SSH and HTTPSsudo firewall-cmd --add-service=ssh --permanentsudo firewall-cmd --add-service=https --permanent
# Add a custom port for your applicationsudo firewall-cmd --add-port=8443/tcp --permanent
# Block a test IP with rich rulesudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.99.99.99" drop' --permanent
# Reload and verifysudo firewall-cmd --reloadsudo firewall-cmd --list-allExpected output: Default zone is public with ssh, https, and port 8443 allowed, plus a rich rule blocking 10.99.99.99.
Task 2: Harden SSH
Section titled “Task 2: Harden SSH”# Backup original configsudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Generate a key pair (if you don't have one)ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
# Add your key to authorized_keysmkdir -p ~/.ssh && chmod 700 ~/.sshcat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keys
# Harden sshd_configsudo sed -i 's/#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_configsudo sed -i 's/#MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_configsudo sed -i 's/#ClientAliveInterval.*/ClientAliveInterval 300/' /etc/ssh/sshd_configsudo sed -i 's/X11Forwarding yes/X11Forwarding no/' /etc/ssh/sshd_config
# Test configsudo sshd -t
# Restartsudo systemctl restart sshdTask 3: Configure Time Synchronization
Section titled “Task 3: Configure Time Synchronization”# Install and enable chronysudo apt install -y chronysudo systemctl enable --now chrony
# Set timezone to UTCsudo timedatectl set-timezone UTC
# Force syncsudo chronyc makestep
# Verifychronyc trackingtimedatectlTask 4: Configure a Static IP with nmcli
Section titled “Task 4: Configure a Static IP with nmcli”# Show current connectionsnmcli connection show
# Create a new connection with static IP (adjust interface name)sudo nmcli connection add type ethernet \ con-name static-eth0 \ ifname eth0 \ ipv4.addresses 192.168.1.200/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns "8.8.8.8 1.1.1.1" \ ipv4.method manual
# Verify (don't activate if this is your only connection over SSH!)nmcli connection show static-eth0Success Criteria
Section titled “Success Criteria”- firewalld running with custom rules (ssh, https, 8443, rich rule)
- SSH hardened: root login disabled, max auth tries limited
- Chrony running and time synchronized
- Static IP configured via nmcli
- All changes persist across reboot (
--permanent, config files)
Cleanup
Section titled “Cleanup”# Restore SSH configsudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_configsudo systemctl restart sshd
# Remove firewalld test rulessudo firewall-cmd --remove-service=https --permanentsudo firewall-cmd --remove-port=8443/tcp --permanentsudo firewall-cmd --remove-rich-rule='rule family="ipv4" source address="10.99.99.99" drop' --permanentsudo firewall-cmd --reload
# Remove test nmcli connectionsudo nmcli connection delete static-eth0Next Module
Section titled “Next Module”You’ve now covered the key LFCS gaps in storage and networking. Return to the LFCS Learning Path to review remaining study areas, or continue strengthening your Linux fundamentals with Module 5.1: The USE Method for performance analysis.