Home DNS Lookup Ping Traceroute IP Location IP Calculator MAC Lookup iPerf IPv6 Calc Port Check Port Scaner Speedtest Blog

Basic Linux Hardening Steps That Dont Break Workflows

Introduction

Security hardening should raise the bar for attackers without frustrating your team. Start with reversible, low-risk changes that reduce exposure and add visibility, then iterate.

Principles that wont break things

  • Incremental & reversible: change one thing at a time; keep rollback commands handy.
  • Stage & test: apply on a non-prod host first; monitor logs/metrics for 2448h.
  • Prefer allowlists over denylists: smaller blast radius, clearer intent.
  • Log everything you can: visibility beats guesswork when something misbehaves.

Quick wins (safe defaults)

Step Why Sample command
Disable unused services Shrinks attack surface & resource use systemctl --type=service --state=running
sudo systemctl disable --now avahi-daemon
Keep SSH but harden it Stops easy brute force; keeps remote access sudoedit /etc/ssh/sshd_config (see below), then sudo systemctl reload sshd
Apply regular updates Patches known vulns with minimal change Debian/Ubuntu: sudo apt update && sudo apt upgrade -y
RHEL/Fedora: sudo dnf upgrade -y
Firewall: default deny inbound Only expose what you intend UFW: sudo ufw default deny incoming; sudo ufw allow OpenSSH; sudo ufw enable
Tighten sudo Least privilege; better audit sudo visudo -f /etc/sudoers.d/10-team (see example)
Add fail2ban Blocks repeated auth failures sudo apt install fail2ban / sudo dnf install fail2ban
Persist system logs Keep evidence across reboots sudo sed -i 's/^#\?Storage=.*/Storage=persistent/' /etc/systemd/journald.conf && sudo systemctl restart systemd-journald

SSH hardening (safe, incremental)

Keep SSH accessible, but reduce brute force and risky defaults. Test from a second session before reloading.

# /etc/ssh/sshd_config (add or ensure these)
Protocol 2
PermitRootLogin no
PasswordAuthentication yes      # keep for now; switch to 'no' after keys are deployed
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
AllowGroups sshusers             # create & add users you trust

# Optional: migrate by subnet (dont lock yourself out)
# Match Address 10.0.0.0/8
#   PasswordAuthentication no

Then:

sudo groupadd -f sshusers
sudo usermod -aG sshusers <youruser>
sudo sshd -t && sudo systemctl reload sshd

Once keys are deployed for all admins, set PasswordAuthentication no and consider MFA (PAM) later.

Firewall examples (UFW & nftables)

UFW (easy)

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
# add services you actually serve
sudo ufw allow 80,443/tcp
sudo ufw enable
sudo ufw status verbose

nftables (minimal)

sudo tee /etc/nftables.conf >/dev/null <<'EOF'
table inet filter {
  chain input {
    type filter hook input priority 0;
    ct state established,related accept
    iif lo accept
    tcp dport {22,80,443} accept
    icmp type echo-request limit rate 5/second accept
    reject with icmpx type admin-prohibited
  }
  chain forward { type filter hook forward priority 0; drop; }
  chain output  { type filter hook output  priority 0; accept; }
}
EOF
sudo systemctl enable --now nftables

Updates without surprises

  • Schedule a weekly window for kernel & service restarts.
  • Enable unattended security updates (Debian/Ubuntu):
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
  • RHEL/Fedora: use dnf-automatic for security advisories only.

Sudo: least privilege with audit

# /etc/sudoers.d/10-team (edit with visudo)
Defaults timestamp_timeout=10
%wheel ALL=(ALL) ALL
# Example: specific admins can restart a service without full root:
%deploy ALL=(root) NOPASSWD: /bin/systemctl restart myapp.service

Add users to groups instead of granting user-by-user sudo rules:

sudo usermod -aG wheel <admin>
sudo groupadd -f deploy && sudo usermod -aG deploy <operator>

Fail2ban (default jail for SSH)

# /etc/fail2ban/jail.local
[sshd]
enabled = true
maxretry = 5
bantime = 1h
findtime = 10m
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Logging & housekeeping

  • Persist journals: set Storage=persistent (see quick wins).
  • Logrotate: ensure defaults are present; avoid filling disks.
  • Check world-writable spots (notification only):
sudo find / -xdev -type d -perm -0002 ! -path "/proc/*" 2>/dev/null

Low-risk sysctl tweaks

# /etc/sysctl.d/60-safe-hardening.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
# apply
sudo sysctl --system

Avoid aggressive kernel changes on production first; roll out after staging validation.

Impact

These steps balance security and usability: fewer exposed services, safer remote access, predictable updates, and better visibilitywithout breaking day-to-day workflows.

Quick checklist

ItemStatus
Unused services disabled?
SSH hardened & tested?
Firewall default deny inbound?
Security updates scheduled?
Sudo least privilege in place?
Fail2ban active?
Logs persistent & rotated?
Safe sysctl applied?

Conclusion

Start with these low-risk hardening steps, monitor the effect, and iterate. The goal is steady security gains with zero disruption to your teams productivity.

Tip: Keep a rollback note for every change you make (the inverse command or config), and test it once so you dont learn it under pressure.