Arch Linux Hardening for Pentesters
Overview
As a pentester, your own workstation should be the last machine to get compromised. Arch Linux ships minimal by default — no firewall, no hardened kernel parameters, no intrusion detection. That's great for customization, terrible for security.
This guide walks through hardening a daily-driver Arch + Hyprland setup used for both pentesting work and everyday use. Every step is explained so you understand what you're doing and why — because understanding defenses makes you a better attacker.
OS: Arch Linux (rolling release)
WM: Hyprland (Wayland)
Setup: Windows dual boot, Bluetooth active, RustDesk remote access
Disk: NVMe, ext4 (no LUKS)
Firewall (UFW)
Arch has no firewall by default. Every open port is exposed to whatever network you're on. UFW (Uncomplicated Firewall) is the fastest fix — it wraps iptables into a simple interface.
sudo pacman -S ufw
sudo systemctl enable --now ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
deny incoming — blocks all unsolicited inbound connections. If you're not running a server, nothing should be listening.
allow outgoing — lets your traffic out normally. Web browsing, updates, VPN connections all work fine.
Verification
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
Also check what's actually listening on your system:
$ sudo ss -tlnp
State Recv-Q Send-Q Local Address:Port Process
LISTEN 0 0 127.0.0.1:631 cupsd # Printer service
LISTEN 0 0 127.0.0.1:9050 tor # Tor SOCKS proxy
Both services listen on 127.0.0.1 (localhost only) — they're not exposed to the network. If you see 0.0.0.0 or [::], that service is accessible from outside. Investigate immediately.
Bluetooth Hardening
Bluetooth is a common close-range attack vector — BlueBorne, KNOB, BIAS are all real exploits. If you use it for headphones or speakers, don't disable it — just restrict it.
[General]
DiscoverableTimeout = 30
Discoverable = false
Pairable = false
[Policy]
AutoEnable = false
sudo systemctl restart bluetooth
| Parameter | What It Does |
|---|---|
DiscoverableTimeout = 30 |
Auto-disables discovery after 30 seconds when you manually turn it on |
Discoverable = false |
Your device is invisible to nearby Bluetooth scans by default |
Pairable = false |
No one can pair without you explicitly allowing it first |
AutoEnable = false |
Bluetooth doesn't auto-start on boot — you control when it's active |
Kernel Hardening (sysctl)
These kernel parameters are your defense against network-level attacks and information leakage. Each one closes a specific attack vector that you'll encounter (and exploit) during pentests.
# --- Network Protection ---
# IP Spoofing protection (Reverse Path Filtering)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Reject ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# Don't send ICMP redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# SYN flood protection
net.ipv4.tcp_syncookies = 1
# Reject source-routed packets
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# --- Memory & Kernel Protection ---
# ASLR maximum level
kernel.randomize_va_space = 2
# Restrict core dumps from SUID programs
fs.suid_dumpable = 0
# Hide kernel pointers
kernel.kptr_restrict = 2
# Restrict dmesg access
kernel.dmesg_restrict = 1
sudo sysctl --system
Why Each Parameter Matters
| Parameter | Protects Against | How It Works |
|---|---|---|
rp_filter = 1 |
IP Spoofing, MITM | Validates incoming packet source matches the expected interface — drops packets with fake source IPs |
accept_redirects = 0 |
Traffic hijacking | Ignores ICMP "send your traffic here instead" messages that an attacker could use to reroute your traffic through their machine |
send_redirects = 0 |
Information leakage | Stops your machine from telling others to redirect traffic — you're not a router |
tcp_syncookies = 1 |
SYN flood DoS | TCP handshake: SYN → SYN-ACK → ACK. Attacker sends thousands of SYNs without completing. Syncookies use crypto verification instead of holding connections in memory |
accept_source_route = 0 |
Firewall bypass | Rejects packets that specify their own route through the network — normally routers decide the path |
randomize_va_space = 2 |
Buffer overflow | ASLR randomizes stack, heap, and mmap addresses every execution. Attackers need predictable addresses — this makes exploitation significantly harder |
suid_dumpable = 0 |
Credential theft | Prevents SUID (root-level) programs from writing memory dumps to disk — those dumps could contain passwords and tokens |
kptr_restrict = 2 |
Kernel exploitation | Hides kernel memory addresses from /proc/kallsyms — essential info for writing kernel exploits, now hidden even from root |
dmesg_restrict = 1 |
Reconnaissance | Blocks unprivileged access to kernel logs containing hardware info, driver details, and memory addresses. sudo dmesg still works |
None of these affect normal usage. sudo dmesg still works. Your apps run fine. Core dumps from regular programs still work via coredumpctl. If you need to temporarily disable something (e.g., kptr_restrict for kernel debugging), use sudo sysctl kernel.kptr_restrict=0 — it resets on reboot.
Sudo & Login Security
Sudo Timeout
By default, sudo caches your password for 5 minutes. If someone accesses your terminal during that window, they have root. Shorten it.
sudo visudo
# Find the Defaults line and change to:
Defaults env_reset, timestamp_timeout=1
Now sudo asks for your password again after just 1 minute of inactivity instead of 5.
Login Brute Force Protection
Limit failed login attempts to slow down brute force attacks on your local login.
deny = 5
unlock_time = 300
After 5 failed attempts, the account locks for 5 minutes (300 seconds). Simple but effective — it makes password brute forcing impractical for local access.
File Permission Hardening
These are critical system files. Wrong permissions here is a classic privilege escalation vector you'll see in CTFs and real pentests.
sudo chmod 600 /etc/shadow # Password hashes — root only
sudo chmod 600 /etc/gshadow # Group password hashes — root only
sudo chmod 644 /etc/passwd # User list — readable, not writable
sudo chmod 644 /etc/group # Group list — readable, not writable
/etc/shadow contains password hashes. If a regular user can read it, they can copy the hashes and crack them offline with tools like hashcat or john. This is one of the first things you check during Linux privilege escalation — and it's one of the first things to lock down on your own machine.
Service Minimization
The hardening principle is simple: if you don't need it running, turn it off. Every running service is a potential attack surface.
# Check all listening services
sudo ss -tlnp
# Disable services you only use occasionally
sudo systemctl disable tor # Start manually: sudo systemctl start tor
sudo systemctl disable bluetooth # If you rarely use it
If you see a service listening on 0.0.0.0 or [::] and you don't know why — investigate it. If you don't need it, disable it. Services on 127.0.0.1 are localhost-only and lower risk, but still worth auditing.
Kernel Update Notifications
Create a pacman hook to remind you to reboot after kernel updates:
sudo mkdir -p /etc/pacman.d/hooks
[Trigger]
Operation = Upgrade
Type = Package
Target = linux
Target = linux-headers
[Action]
Description = Kernel updated — reboot recommended
When = PostTransaction
Exec = /usr/bin/echo ">>> KERNEL UPDATED - Reboot recommended <<<"
File Integrity Monitoring (AIDE)
AIDE (Advanced Intrusion Detection Environment) takes a snapshot of your system files and their hashes. If anything changes — a rootkit modifies a binary, an attacker alters a config — AIDE flags it. This is a blue team staple, and understanding it makes you a better red teamer.
# Install
sudo pacman -S aide
# Initialize database (takes ~1 min for ~450k files)
sudo aide --init
# Activate the database
sudo cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
# Enable daily automatic checks
sudo systemctl enable --now aidecheck.timer
# Manual integrity check
sudo aide --check
# View automated check logs
sudo journalctl -abu aidecheck
# After system updates, refresh the database
sudo aide --update
sudo cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
Run aide --update after legitimate system updates (pacman -Syu), otherwise AIDE will flag every updated file as a potential intrusion. Update the database after you've verified the changes are expected.
Dual Boot Considerations
Running Windows alongside Arch introduces additional attack surface. The key concern: Windows can access your Arch partition with third-party tools, and vice versa.
- No LUKS = No disk encryption — anyone booting a live USB can read your entire Arch partition
- Windows side access — ext4 readers exist for Windows, your files aren't safe just because it's a different filesystem
- GRUB tampering — without Secure Boot, the bootloader can be modified
Mitigations
- LUKS encryption is the real fix, but requires an Arch reinstall
- GRUB password can prevent unauthorized boot option changes
- Keep BitLocker enabled on the Windows side
- Keep both OSes updated — a compromised Windows can pivot to Arch
Verification Checklist
Run these commands to verify everything is properly configured:
# Firewall active?
sudo ufw status verbose
# Kernel parameters applied?
sysctl kernel.randomize_va_space # Should return: 2
sysctl net.ipv4.conf.all.rp_filter # Should return: 1
sysctl kernel.kptr_restrict # Should return: 2
sysctl kernel.dmesg_restrict # Should return: 1
# No unexpected listeners?
sudo ss -tlnp
# AIDE database exists?
ls -la /var/lib/aide/aide.db.gz
# AIDE timer active?
systemctl status aidecheck.timer
# File permissions correct?
ls -la /etc/shadow # Should be: -rw-------
ls -la /etc/passwd # Should be: -rw-r--r--
🎯 Key Takeaways
- Arch ships insecure by default — no firewall, no hardened kernel, no IDS. You have to build your own defenses.
- Firewall first — UFW with deny incoming is the single most impactful change you can make in 30 seconds.
- sysctl hardening closes network-level attack vectors (spoofing, redirects, SYN flood) and kernel information leakage that you'll actively exploit during pentests.
- Service minimization reduces attack surface — if it's not running, it can't be exploited.
- AIDE gives you tripwire detection — understanding blue team tools makes your red team work better.
- Know your defenses to break others' — every hardening step you apply is something you'll test for (and exploit when missing) in real engagements.
What's Next
- LUKS full disk encryption — the ultimate physical access protection
- AppArmor profiles — mandatory access control for application sandboxing
- Secure Boot — prevent boot-level tampering
- USB device whitelisting — block BadUSB / Rubber Ducky attacks
- Network segmentation — isolate pentest lab traffic from personal traffic
- VPN kill switch — ensure traffic doesn't leak outside VPN during engagements