Goal

Learn to harden the Linux kernel using sysctl parameters and implement AppArmor profiles to confine applications. These are the core technical controls that limit what attackers can do even after gaining code execution.

Prerequisites: Week 11b (MAC Systems & Security Auditing)

This is Part 3 of 4 - Covers kernel hardening and AppArmor implementation.


1. Kernel Hardening with sysctl

What is Kernel Hardening?

The Linux kernel has hundreds of tuneable parameters that affect security. Kernel hardening means configuring these parameters to:

  • Enable security features (ASLR, stack canaries)
  • Disable unnecessary protocols
  • Restrict access to sensitive kernel interfaces
  • Harden network stack against attacks

Why it matters:

  • Kernel vulnerabilities can lead to full system compromise
  • Many security features are disabled by default for compatibility
  • Network stack is often the first attack surface

View Current Kernel Parameters

# List all kernel parameters
sysctl -a | less

# Check specific parameter
sysctl net.ipv4.ip_forward

# Check if ASLR is enabled
sysctl kernel.randomize_va_space

Essential Kernel Hardening Parameters

Create hardening configuration:

sudo nano /etc/sysctl.d/99-hardening.conf

Add the following hardening rules:

# === Memory Protection ===
# Enable Address Space Layout Randomization (ASLR)
kernel.randomize_va_space = 2

# Restrict kernel pointer visibility (prevents info leaks)
kernel.kptr_restrict = 2

# Restrict dmesg access to root only
kernel.dmesg_restrict = 1

# Restrict perf events to root
kernel.perf_event_paranoid = 3

# === Filesystem Protections ===
# Prevent creating hard links to files you don't own
fs.protected_hardlinks = 1

# Prevent creating symlinks to files you don't own
fs.protected_symlinks = 1

# Protect against SUID core dumps
fs.suid_dumpable = 0

# === Network Hardening ===
# Ignore ICMP redirects (prevents MITM attacks)
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

# Enable SYN cookies (protects against SYN flood attacks)
net.ipv4.tcp_syncookies = 1

# Disable IP source routing (prevents spoofing)
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# Enable reverse path filtering (anti-spoofing)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Log suspicious packets (Martians)
net.ipv4.conf.all.log_martians = 1

# Disable IPv6 router advertisements
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0

# === Process Isolation ===
# Increase PID range (makes PID guessing harder)
kernel.pid_max = 4194304

# Restrict access to kernel logs
kernel.printk = 3 3 3 3

Apply and Verify Kernel Hardening

Apply immediately:

sudo sysctl -p /etc/sysctl.d/99-hardening.conf

Verify settings applied:

sysctl kernel.randomize_va_space  # Should be 2
sysctl net.ipv4.tcp_syncookies    # Should be 1

Test that nothing broke:

ping -c 3 1.1.1.1      # Should still work
curl -I https://google.com  # Should still work

Disable Uncommon Kernel Modules

Blacklist rarely-used protocols:

sudo nano /etc/modprobe.d/blacklist-uncommon.conf
# Disable uncommon network protocols (reduces attack surface)
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true

# Disable uncommon filesystems
install cramfs /bin/true
install freevxfs /bin/true
install jffs2 /bin/true
install hfs /bin/true
install hfsplus /bin/true
install udf /bin/true

# Disable FireWire and Thunderbolt (DMA attacks)
install firewire-core /bin/true
install thunderbolt /bin/true

Apply blacklist:

sudo update-initramfs -u
sudo reboot  # Required for module blacklist to take effect

2. AppArmor Profiles

Install and Check AppArmor

# Install AppArmor utilities
sudo apt install apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra

# Check AppArmor status
sudo aa-status

AppArmor Modes

1. Enforce Mode - Policy is enforced, violations are blocked

sudo aa-enforce /etc/apparmor.d/usr.bin.firefox

2. Complain Mode - Policy violations logged but allowed (learning mode)

sudo aa-complain /etc/apparmor.d/usr.bin.firefox

3. Disabled - Profile exists but not loaded

sudo aa-disable /etc/apparmor.d/usr.bin.firefox

Applying Existing Profiles

Ubuntu comes with profiles for common applications:

# List available profiles
ls /etc/apparmor.d/

# Enforce profiles for common apps
sudo aa-enforce /etc/apparmor.d/usr.bin.firefox
sudo aa-enforce /etc/apparmor.d/usr.bin.evince      # PDF viewer
sudo aa-enforce /etc/apparmor.d/usr.sbin.tcpdump    # Network sniffer

# Check what's now enforced
sudo aa-status | grep enforce

Creating Custom AppArmor Profiles

Step 1: Generate initial profile

sudo aa-genprof /usr/local/bin/backup.sh

This opens an interactive workflow:

  1. AppArmor asks you to run the application
  2. Run your script in another terminal
  3. AppArmor captures all file/network access
  4. You approve or deny each access request
  5. Profile is saved

Step 2: Enforce the profile

sudo aa-enforce /etc/apparmor.d/usr.local.bin.backup.sh

Example: Firefox AppArmor Profile

Key restrictions (simplified):

/usr/bin/firefox {
  # Allow reading Firefox files
  /usr/lib/firefox/** r,
  /usr/share/firefox/** r,

  # Allow Firefox profile directory
  owner @{HOME}/.mozilla/** rw,

  # DENY access to sensitive directories
  deny @{HOME}/.ssh/** rw,
  deny @{HOME}/.gnupg/** rw,
  deny @{HOME}/.config/Signal/** rw,

  # Allow downloading files
  owner @{HOME}/Downloads/** rw,

  # Allow network access
  network inet stream,
  network inet6 stream,
}

This means exploited Firefox:

  • Can read/write ~/.mozilla/ (its own data)
  • Can save to ~/Downloads/
  • Cannot read ~/.ssh/ or ~/.gnupg/
  • Cannot write to system directories

Debugging AppArmor Denials

When AppArmor blocks something:

# View recent denials
sudo aa-logprof

# Or manually check syslog
sudo grep DENIED /var/log/syslog | tail -20

Fix denied access:

  1. Decide if access should be allowed
  2. If yes: Run sudo aa-logprof and approve
  3. If no: Leave denied (security working!)

Reload profile after editing:

sudo apparmor_parser -r /etc/apparmor.d/usr.bin.firefox

Lab: Create Custom AppArmor Profile

Objective: Confine a script with AppArmor

Estimated time: 30 minutes

Steps:

# Create test script
cat > /tmp/backup-test.sh << 'EOF'
#!/bin/bash
ls ~/backups/ && echo "Allowed access to backups"
ls ~/.ssh/ && echo "Should NOT access .ssh"
EOF
chmod +x /tmp/backup-test.sh

# Generate profile
sudo aa-genprof /tmp/backup-test.sh

# In another terminal, run the script
/tmp/backup-test.sh

# Back in aa-genprof: approve ~/backups/, deny ~/.ssh/
# Save and enforce
sudo aa-enforce /etc/apparmor.d/tmp.backup-test.sh

# Test: Script should now fail to access ~/.ssh/
/tmp/backup-test.sh

Deliverable: Working AppArmor profile that allows only specified directories


Lab: Kernel Hardening Implementation

Objective: Apply kernel security parameters

Estimated time: 30 minutes

Steps:

# Backup current settings
sysctl -a > ~/sysctl-backup.txt

# Create hardening config
sudo nano /etc/sysctl.d/99-hardening.conf
# (Paste configuration from Section 1)

# Apply temporarily
sudo sysctl -p /etc/sysctl.d/99-hardening.conf

# Verify key settings
sysctl kernel.randomize_va_space  # Should be 2
sysctl net.ipv4.tcp_syncookies    # Should be 1

# Test functionality
ping -c 3 1.1.1.1
curl -I google.com

# Reboot and verify persistence
sudo reboot
sysctl kernel.randomize_va_space

Deliverable: Hardened kernel settings persisting across reboot


Up Next

Week 11d covers Firejail sandboxing and the remaining hands-on labs.


Key Takeaways

  • sysctl parameters harden the kernel against common attacks
  • ASLR, SYN cookies, and source routing controls are essential network hardening
  • Module blacklisting reduces attack surface from unused kernel code
  • AppArmor profiles confine applications to specific filesystem and network access
  • Use complain mode to learn what an app needs before enforcing
  • aa-genprof automates profile creation through interactive learning