Introduction to Securing Gentoo Servers
Gentoo Linux is a source-based distribution renowned for its flexibility and performance. Because every package is compiled from source with user-defined USE flags, Gentoo offers a uniquely small attack surface compared to binary distributions. However, this power comes with responsibility: a misconfigured Gentoo server can be just as vulnerable as any other system. This tutorial provides a practical, end-to-end checklist for hardening a Gentoo server from initial installation through ongoing maintenance.
Why Gentoo Security Matters
Security on Gentoo matters for several reasons. First, because you control the build process, you can strip out unnecessary features that introduce vulnerabilities. Second, Gentoo's rolling nature means updates arrive quickly, but only if you actively apply them — there is no automatic patching by default. Third, many Gentoo deployments run on edge cases, embedded systems, or custom infrastructure where a compromise can have outsized impact. A hardened Gentoo server leverages the distribution's strengths while mitigating its manual-update weaknesses.
Phase 1: Installation Hardening
Security begins at install time. The choices you make during the initial Gentoo setup reverberate throughout the server's lifetime.
Choosing the Right Profile and Stage
Select a hardened profile if your workload supports it. Hardened profiles enable PIE (Position Independent Executables), stack smashing protection, and other compiler-level mitigations by default.
# List available profiles
eselect profile list
# Select a hardened profile
eselect profile set 1
# Verify the selection
eselect profile show
Configuring USE Flags for Minimal Attack Surface
Review your make.conf and remove any USE flags you do not need. Fewer enabled features mean fewer potential vulnerabilities.
# /etc/portage/make.conf
USE="-doc -test -examples -X -alsa -opengl -wayland"
USE="${USE} ssl crypt pam systemd"
MAKEOPTS="-j4"
FEATURES="buildpkg collision-protect"
The collision-protect feature prevents packages from overwriting files owned by other packages, which can mask malicious or accidental file replacements.
Compiler Hardening Flags
Add explicit hardening flags to your make.conf to ensure consistent protection across all builds:
# /etc/portage/make.conf
CFLAGS="-O2 -pipe -fstack-protector-strong -D_FORTIFY_SOURCE=2"
CXXFLAGS="${CFLAGS}"
LDFLAGS="-Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack"
-fstack-protector-strong: Inserts stack canaries to detect buffer overflows.-D_FORTIFY_SOURCE=2: Adds runtime checks to common libc functions.-Wl,-z,relroand-Wl,-z,now: Enable full RELRO, protecting GOT entries.-Wl,-z,noexecstack: Marks the stack as non-executable.
Phase 2: Kernel Hardening
The kernel is the foundation of system security. A poorly configured kernel undermines every other hardening measure.
Essential Kernel Options
When configuring your kernel with make menuconfig, enable the following options:
# Disable loading modules at runtime
CONFIG_MODULES=n
# Or, if modules are required, restrict them
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
# Enable SELinux or AppArmor
CONFIG_SECURITY_SELINUX=y
# or
CONFIG_SECURITY_APPARMOR=y
# Restrict kernel pointer access
CONFIG_RANDOMIZE_BASE=y
CONFIG_RANDOMIZE_MEMORY=y
# Restrict dmesg access
CONFIG_SECURITY_DMESG_RESTRICT=y
# Disable legacy /dev/mem access
CONFIG_STRICT_DEVMEM=y
CONFIG_IO_STRICT_DEVMEM=y
# Enable BPF hardening
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
Applying sysctl Tunables
Create a sysctl configuration file to enforce runtime kernel protections:
# /etc/sysctl.d/99-hardening.conf
# Network hardening
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_source_route = 0
# Disable IP forwarding (unless this is a router)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
# Memory protection
kernel.randomize_va_space = 2
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
kernel.perf_event_paranoid = 3
kernel.yama.ptrace_scope = 2
# Filesystem hardening
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.protected_fifos = 2
fs.protected_regular = 2
fs.suid_dumpable = 0
Apply the changes immediately:
sysctl --system
Phase 3: User and Access Management
Securing SSH Access
SSH is the primary entry point for most servers. Lock it down aggressively.
# /etc/ssh/sshd_config
# Disable root login
PermitRootLogin no
# Disable password authentication
PasswordAuthentication no
PubkeyAuthentication yes
# Limit to specific users
AllowUsers deploy admin
# Reduce login grace period
LoginGraceTime 30
# Limit authentication attempts
MaxAuthTries 3
# Disable X11 forwarding if not needed
X11Forwarding no
# Use strong ciphers and MACs
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512
# Idle timeout
ClientAliveInterval 300
ClientAliveCountMax 0
Restart the SSH daemon after changes:
systemctl restart sshd
Configuring Sudo and Privilege Escalation
Avoid giving users full root access. Use sudo with granular rules:
# /etc/sudoers.d/deploy
deploy ALL=(root) /usr/bin/emerge --sync, /usr/bin/emerge --update *
deploy ALL=(root) /usr/bin/systemctl restart nginx
deploy ALL=(root) /usr/bin/journalctl -u nginx
Always edit sudoers files with visudo to validate syntax before saving:
visudo -f /etc/sudoers.d/deploy
Enforcing Password Policies
Configure PAM to enforce strong passwords and account lockout:
# /etc/security/passwdqc.conf
min=disabled,disabled,12,8,7
max=72
passphrase=4
match=4
similar=deny
enforce=everyone
# /etc/pam.d/system-auth - add to password section
password required pam_pwquality.so retry=3 minlen=12 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1
password required pam_pwhistory.so use_authtok remember=12
Phase 4: Package and Update Management
Regular Security Updates
Gentoo does not auto-update. Establish a routine for syncing and applying security patches:
# Sync the portage tree
emaint sync -a
# Check for security vulnerabilities
glsa-check --list
# Apply all GLSA-flagged packages
glsa-check --fix all
# Full system update
emerge --ask --update --deep --newuse @world
emerge --ask --depclean
emerge --ask @preserved-rebuild
Automate GLSA checks with a cron job or systemd timer:
# /etc/cron.daily/glsa-check
#!/bin/bash
glsa-check --list 2>&1 | mail -s "Gentoo GLSA Report $(hostname)" admin@example.com
chmod +x /etc/cron.daily/glsa-check
Using glsa-check Effectively
The glsa-check tool is Gentoo's primary vulnerability scanner. It cross-references installed packages against published Gentoo Linux Security Advisories.
# List all applicable GLSAs
glsa-check --list
# Show details of a specific GLSA
glsa-check --dump 202312-01
# Test without applying
glsa-check --test 202312-01
# Apply a specific fix
glsa-check --fix 202312-01
Verifying Package Integrity
Ensure your repositories use signed manifests and verify them:
# /etc/portage/repos.conf/gentoo.conf
[gentoo]
location = /var/db/repos/gentoo
sync-type = rsync
sync-uri = rsync://rsync.gentoo.org/gentoo-portage
sync-openpgp-key-path = /usr/share/openpgp-keys/gentoo-release.asc
sync-openpgp-key-refresh = no
sync-openpgp-keyserver = hkps://keys.gentoo.org
Phase 5: Firewall and Network Security
Configuring nftables
Gentoo supports both iptables and nftables. For new deployments, nftables is recommended due to its cleaner syntax and better performance.
# /etc/nftables.conf
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow loopback
iif "lo" accept
# Allow established connections
ct state established,related accept
# Allow SSH with rate limiting
tcp dport 22 ct state new limit rate 3/minute burst 5 packets accept
# Allow HTTP/HTTPS
tcp dport { 80, 443 } accept
# Drop invalid packets
ct state invalid drop
# Allow ICMP (rate limited)
icmp type echo-request limit rate 1/second accept
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 1/second accept
# Log and drop everything else
limit rate 5/minute log prefix "nftables-drop: " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Enable and start the service:
systemctl enable nftables
systemctl start nftables
nft list ruleset
Port Knocking for Sensitive Services
For administrative services that should not be publicly accessible, consider port knocking with knockd:
# /etc/knockd.conf
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 10
start_command = nft add rule inet filter input tcp dport 22 accept
stop_command = nft delete rule inet filter input tcp dport 22 accept
cmd_timeout = 600
Phase 6: Filesystem and Data Protection
Securing Temporary Directories
Mount /tmp, /var/tmp, and /dev/shm with noexec, nosuid, and nodev options:
# /etc/fstab
tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev,size=2G 0 0
tmpfs /var/tmp tmpfs defaults,noexec,nosuid,nodev,size=2G 0 0
tmpfs /dev/shm tmpfs defaults,noexec,nosuid,nodev,size=1G 0 0
File Integrity Monitoring with AIDE
Install and configure AIDE to detect unauthorized file changes:
emerge --ask app-forensics/aide
# Initialize the AIDE database
aide --init
# Move the database to the active location
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Run a check
aide --check
Schedule regular integrity checks:
# /etc/cron.daily/aide-check
#!/bin/bash
aide --check 2>&1 | mail -s "AIDE Report $(hostname)" admin@example.com
Securing Sensitive Files
Review and tighten permissions on critical system files:
# Restrict cron access
chmod 700 /etc/cron.d
chmod 600 /etc/crontab
# Restrict SSH host keys
chmod 600 /etc/ssh/ssh_host_*_key
chmod 644 /etc/ssh/ssh_host_*_key.pub
# Restrict bootloader config
chmod 600 /boot/grub/grub.cfg
# Protect sudoers
chmod 440 /etc/sudoers
chmod 440 /etc/sudoers.d/*
Phase 7: Logging and Auditing
Centralized Logging
Configure journald to persist logs and forward critical events to a remote log server:
# /etc/systemd/journald.conf
[Journal]
Storage=persistent
Compress=yes
SystemMaxUse=2G
SystemMaxFileSize=100M
MaxRetentionSec=6month
ForwardToSyslog=yes
# /etc/rsyslog.d/remote.conf - forward to central log server
*.* action(type="omfwd" target="logserver.internal" port="6514" protocol="tcp"
action.resumeRetryCount="-1"
queue.type="LinkedList"
queue.size="10000")
Enabling Process Auditing
Install and configure the Linux audit daemon for detailed process tracking:
emerge --ask sys-process/audit
systemctl enable auditd
systemctl start auditd
# /etc/audit/rules.d/audit.rules
# Monitor login events
-w /var/log/tallylog -p wa -k logins
-w /var/log/lastlog -p wa -k logins
# Monitor sudo usage
-w /etc/sudoers -p wa -k sudo
-w /etc/sudoers.d/ -p wa -k sudo
# Monitor SSH configuration changes
-w /etc/ssh/sshd_config -p wa -k ssh_config
# Monitor user/group modifications
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
# Monitor cron changes
-w /etc/crontab -p wa -k cron
-w /etc/cron.d/ -p wa -k cron
# Watch for system time changes
-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change
# Reload audit rules
augenrules --load
# View audit logs
ausearch -k ssh_config
aureport --summary
Phase 8: Service Isolation and Sandboxing
Systemd Service Hardening
For every custom systemd service, apply sandboxing directives. Create drop-in overrides rather than editing the original unit file:
# /etc/systemd/system/myservice.service.d/hardening.conf
[Service]
# Filesystem isolation
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
# Network isolation (if service doesn't need network)
# RestrictAddressFamilies=AF_UNIX
# User namespace isolation
PrivateUsers=true
# Kernel protection
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
ProtectClock=true
ProtectHostname=true
ProtectProc=invisible
# Capability restrictions
CapabilityBoundingSet=
AmbientCapabilities=
# Resource limits
LimitNOFILE=1024
LimitNPROC=256
# Memory protection
MemoryDenyWriteExecute=true
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
RemoveIPC=true
# System call filtering
SystemCallFilter=@system-service
SystemCallFilter=~@privileged @resources
SystemCallArchitectures=native
# No new privileges
NoNewPrivileges=true
systemctl daemon-reload
systemctl restart myservice
AppArmor or SELinux MAC
Mandatory Access Control adds a layer of policy enforcement beyond traditional file permissions. AppArmor is generally easier to configure on Gentoo:
# Enable AppArmor in kernel and bootloader
# Add to kernel command line: apparmor=1 security=apparmor
# Install AppArmor userspace
emerge --ask sys-libs/libapparmor sys-apps/apparmor-utils
# Enable and start the service
systemctl enable apparmor
systemctl start apparmor
# Check status
aa-status
Create profiles for custom services:
# Generate a profile template
aa-genprof /usr/local/bin/myservice
# Put a profile into complain mode (logging only)
aa-complain /usr/local/bin/myservice
# Switch to enforce mode
aa-enforce /usr/local/bin/myservice
Phase 9: Monitoring and Intrusion Detection
Installing Fail2ban
Fail2ban monitors log files and automatically bans IPs showing malicious behavior:
emerge --ask net-analyzer/fail2ban
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
banaction = nftables-multiport
backend = systemd
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 86400
[nginx-http-auth]
enabled = true
port = http,https
maxretry = 5
bantime = 3600
systemctl enable fail2ban
systemctl start fail2ban
fail2ban-client status
fail2ban-client status sshd
Rootkit Detection
Install rkhunter for periodic rootkit scans:
emerge --ask app-forensics/rkhunter
# Update the database
rkhunter --update
rkhunter --propupd
# Run a scan
rkhunter --check --sk
# /etc/cron.weekly/rkhunter
#!/bin/bash
rkhunter --check --sk --report-warnings-only 2>&1 | \
mail -s "rkhunter Report $(hostname)" admin@example.com
Best Practices Summary
- Minimize installed packages: Every package is a potential attack vector. Use precise USE flags and avoid installing unnecessary software.
- Automate updates safely: Use GLSA checks on a schedule, but review changes before applying full system updates in production.
- Layer your defenses: Combine kernel hardening, firewall rules, MAC policies, and application-level controls. No single measure is sufficient.
- Monitor continuously: Logs are useless if nobody reads them. Set up alerting for critical events and review audit reports regularly.
- Test your backups: A hardened server is meaningless if you cannot recover from a compromise. Verify restore procedures quarterly.
- Document your configuration: Maintain a record of all hardening changes so you can reproduce or audit them later.
- Review periodically: Security is not a one-time task. Revisit this checklist after major updates, new service deployments, or architecture changes.
- Use separate accounts: Never share credentials. Each administrator should have an individual account with appropriate sudo permissions.
- Disable unused services: Run
systemctl list-unit-files --state=enabledregularly and disable anything unnecessary. - Keep firmware updated: Server firmware, BMC, and NIC firmware can contain vulnerabilities. Check manufacturer advisories regularly.
Conclusion
Securing a Gentoo server is an ongoing process that takes advantage of the distribution's unique source-based architecture. By carefully selecting USE flags, applying compiler hardening, configuring a minimal kernel, enforcing strict access controls, maintaining regular update routines, and layering monitoring tools, you can build a server that is significantly more resistant to attack than a default installation. The checklist above is not exhaustive — every environment has its own threat model — but it provides a strong baseline that addresses the most common attack vectors. Remember that security is a spectrum, not a binary state: the goal is to raise the cost of compromise high enough that attackers move on to easier targets, while ensuring you can detect and respond quickly when something does go wrong. Revisit and refine these measures regularly as your infrastructure evolves and new threats emerge.