-
Notifications
You must be signed in to change notification settings - Fork 0
Raspberry Pi Security Hardening Guide
Transform your Raspberry Pi from default configuration to secure, production-ready system
- Initial Setup Security
- Default User Hardening
- SSH Hardening
- Network Security
- Wireless Security
- VNC Security
- Interface Security
- Firewall Configuration
- System Hardening
- Monitoring & Maintenance
Before connecting to the internet:
# 1. Change default password IMMEDIATELY
passwd
# Enter new strong password (16+ characters, mixed case, numbers, symbols)
# 2. Update system
sudo apt update
sudo apt full-upgrade -y
# 3. Enable automatic security updates
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgradesSecurity Priority: CRITICAL
Time Required: 10 minutes
Fresh Raspberry Pi OS installations have:
- Default user:
pi - Default password:
raspberry - This is public knowledge - attackers scan for it!
# Create new user with sudo privileges
sudo adduser yourname
sudo usermod -aG sudo yourname
# Log out and log in as new user
# Then delete pi user:
sudo deluser -remove-home piSecurity Priority: CRITICAL
Time Required: 5 minutes
# Lock the pi user
sudo passwd -l pi
# Disable login shell
sudo usermod -s /usr/sbin/nologin pi
# Create your own user
sudo adduser yourname
sudo usermod -aG sudo yourname# Change password to strong one
sudo passwd pi
# Use 20+ character passphrase
# Rename the user
sudo usermod -l newname pi
sudo usermod -d /home/newname -m newname
sudo groupmod -n newname pi- SSH enabled by default
- Password authentication allowed
- Root login might be permitted
# 1. Generate SSH key on your computer (NOT on the Pi)
ssh-keygen -t ed25519 -C "raspberry-pi"
# 2. Copy key to Pi
ssh-copy-id youruser@raspberrypi.local
# 3. Test key-based login
ssh youruser@raspberrypi.local
# Should log in without password
# 4. Disable password authentication
sudo nano /etc/ssh/sshd_configEdit /etc/ssh/sshd_config:
# Disable password authentication
PasswordAuthentication no
# Disable root login
PermitRootLogin no
# Disable empty passwords
PermitEmptyPasswords no
# Disable host-based authentication
HostbasedAuthentication no
IgnoreRhosts yes
# Use strong ciphers
Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,diffie-hellman-group18-sha512
# Limit login attempts
MaxAuthTries 3
LoginGraceTime 30
# Session settings
ClientAliveInterval 300
ClientAliveCountMax 2
# Only allow specific users
AllowUsers youruser
# Log level
LogLevel VERBOSE# 5. Test configuration
sudo sshd -t
# 6. Reload SSH
sudo systemctl reload sshd
# 7. Don't close current session - test new connection first!
# Open new terminal and test:
ssh youruser@raspberrypi.localSecurity Priority: CRITICAL
Time Required: 15 minutes
# Install UFW
sudo apt install ufw
# Default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH (before enabling!)
sudo ufw allow ssh
# Allow specific services as needed:
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 53 # DNS (if running Pi-hole)
# Enable firewall
sudo ufw enable
# Check status
sudo ufw status verboseSecurity Priority: CRITICAL
Time Required: 5 minutes
# Install Fail2Ban
sudo apt install fail2ban
# Create local configuration
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit configuration
sudo nano /etc/fail2ban/jail.localKey settings:
[DEFAULT]
bantime = 3600 # Ban for 1 hour
findtime = 600 # 10 minute window
maxretry = 3 # 3 failures = ban
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3# Start Fail2Ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Check status
sudo fail2ban-client status sshdSecurity Priority: HIGH
Time Required: 10 minutes
Default configuration may store plaintext passwords
# Generate WPA PSK hash
wpa_passphrase "YourSSID" "YourPassword"
# Output will show:
network={
ssid="YourSSID"
#psk="YourPassword"
psk=0123456789abcdef... # This is the hash
}
# Edit configuration
sudo nano /etc/wpa_supplicant/wpa_supplicant.confSecure configuration:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=US
network={
ssid="YourSSID"
psk=0123456789abcdef... # Use HASH, not plaintext!
proto=RSN # WPA2/WPA3
key_mgmt=WPA-PSK # Or SAE for WPA3
pairwise=CCMP
auth_alg=OPEN
}
# Restart networking
sudo systemctl restart dhcpcd
# Test connection
ping -c 4 8.8.8.8Security Priority: HIGH
Time Required: 5 minutes
# If not using Bluetooth, disable it:
sudo systemctl stop bluetooth
sudo systemctl disable bluetooth
# If using Bluetooth, make non-discoverable:
sudo hciconfig hci0 noscan
# Disable at boot (add to /boot/config.txt):
echo "dtoverlay=disable-bt" | sudo tee -a /boot/config.txtSecurity Priority: MEDIUM
Time Required: 2 minutes
VNC can be insecure by default
# Stop VNC
sudo systemctl stop vncserver-x11-serviced
sudo systemctl disable vncserver-x11-serviced
# Or use raspi-config
sudo raspi-config
# Interface Options -> VNC -> No# Use raspi-config
sudo raspi-config
# Interface Options -> VNC -> Yes
# Advanced Options -> VNC Resolution -> Set desired resolution
# Configure encryption
sudo nano /root/.vnc/config.d/vncserver-x11Add:
Encryption=AlwaysOn
Authentication=VncAuthUse SSH tunnel for VNC:
# On your computer:
ssh -L 5901:localhost:5901 pi@raspberrypi.local
# Then connect VNC to localhost:5901
# This tunnels VNC through encrypted SSHSecurity Priority: HIGH
Time Required: 10 minutes
# View enabled interfaces
cat /boot/config.txt | grep -v "^#" | grep "dtparam\|start_x"Edit /boot/config.txt:
sudo nano /boot/config.txtDisable as needed:
# Camera (if not using)
#start_x=1
start_x=0
# I2C (if not using)
#dtparam=i2c_arm=on
# SPI (if not using)
#dtparam=spi=on
# Serial/UART (important for security!)
enable_uart=0
# Disable Bluetooth
dtoverlay=disable-bt
# Disable Wi-Fi (if using ethernet)
dtoverlay=disable-wifi# Reboot to apply
sudo rebootSecurity Priority: MEDIUM
Time Required: 5 minutes
# Check GPIO group membership
getent group gpio
# Remove unnecessary users from gpio group
sudo gpasswd -d username gpio
# Only authorized users should have hardware accessWhy: Serial console provides root access without authentication
# Edit cmdline.txt
sudo nano /boot/cmdline.txt
# Remove these if present:
# console=serial0,115200
# console=ttyAMA0,115200
# Edit config.txt
sudo nano /boot/config.txt
# Ensure:
enable_uart=0
# Reboot
sudo rebootSecurity Priority: HIGH
Time Required: 3 minutes
# Edit sysctl configuration
sudo nano /etc/sysctl.confAdd:
# IP Forwarding (disable if not routing)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
# ICMP Redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Secure ICMP
net.ipv4.conf.all.secure_redirects = 0
# Log suspicious packets
net.ipv4.conf.all.log_martians = 1
# Ignore broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Enable TCP SYN Cookies
net.ipv4.tcp_syncookies = 1
# Enable ASLR
kernel.randomize_va_space = 2
# Restrict dmesg
kernel.dmesg_restrict = 1
# Restrict kernel pointers
kernel.kptr_restrict = 2# Apply changes
sudo sysctl -pSecurity Priority: HIGH
Time Required: 5 minutes
# Check running services
systemctl list-units --type=service --state=running
# Common services to disable:
sudo systemctl disable avahi-daemon # mDNS (.local)
sudo systemctl disable bluetooth # Bluetooth
sudo systemctl disable triggerhappy # Input events
sudo systemctl disable hciuart # Bluetooth UART
# Stop them
sudo systemctl stop avahi-daemon
sudo systemctl stop bluetooth
sudo systemctl stop triggerhappySecurity Priority: MEDIUM
Time Required: 5 minutes
# Check if AppArmor is active
sudo aa-status
# If not installed:
sudo apt install apparmor apparmor-utils
# Enable AppArmor
sudo systemctl enable apparmor
sudo systemctl start apparmorSecurity Priority: MEDIUM
Time Required: 5 minutes
# Install unattended-upgrades
sudo apt install unattended-upgrades apt-listchanges
# Configure
sudo dpkg-reconfigure -plow unattended-upgrades
# Edit configuration
sudo nano /etc/apt/apt.conf.d/50unattended-upgradesEnable:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}:${distro_codename}-updates";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
Security Priority: HIGH
Time Required: 5 minutes
# Install logwatch
sudo apt install logwatch
# Configure
sudo nano /etc/logwatch/conf/logwatch.confSet:
Output = mail
Format = html
MailTo = your@email.com
Detail = Med# Install monitoring tools
sudo apt install vnstat htop iftop
# Monitor network
sudo iftop
# Monitor processes
htop
# Check temperature (overheating can indicate issues)
vcgencmd measure_temp
# Monitor disk usage
df -h
# Check for unauthorized users
who
last# Create security check script
sudo nano /root/security_check.shAdd:
#!/bin/bash
DATE=$(date +%Y%m%d)
# Update system
apt update && apt full-upgrade -y
# Update firmware
rpi-update
# Run security audit
/usr/local/bin/pi-security-audit \
-f csv \
-o /var/log/security/audit_$DATE.csv
# Email if critical issues
CRITICAL=$(grep "CAT I.*FAIL" /var/log/security/audit_$DATE.csv | wc -l)
if [ $CRITICAL -gt 0 ]; then
echo "ALERT: $CRITICAL critical issues found" | \
mail -s "Pi Security Alert" admin@example.com
fi# Make executable
sudo chmod +x /root/security_check.sh
# Schedule monthly
sudo crontab -eAdd:
0 3 1 * * /root/security_check.sh
Use this checklist after hardening:
- Changed default password
- Created new user or renamed pi user
- SSH hardened (key-based auth, no passwords)
- Firewall enabled (UFW)
- System updated
- Automatic security updates enabled
- Serial console disabled
- Root login disabled
- Fail2Ban configured
- VNC secured or disabled
- Wi-Fi uses encrypted PSK
- Bluetooth disabled (if not needed)
- Unused interfaces disabled
- Kernel parameters hardened
- AppArmor enabled
- Avahi disabled (if not needed)
- Default hostname changed
- GPIO permissions reviewed
- Unnecessary services disabled
- Log monitoring configured
- Regular security audits scheduled
For immediate security improvement:
# 1. User security (2 min)
passwd # Change default password
sudo adduser yourname
sudo usermod -aG sudo yourname
# 2. SSH keys (5 min)
# On your computer:
ssh-keygen -t ed25519
ssh-copy-id yourname@raspberrypi.local
# 3. SSH hardening (2 min)
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl reload sshd
# 4. Firewall (2 min)
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw allow ssh
sudo ufw enable
# 5. Updates (3 min)
sudo apt update && sudo apt full-upgrade -y
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades
# 6. Disable serial console (1 min)
sudo sed -i 's/console=serial0,[0-9]* //g' /boot/cmdline.txt
echo "enable_uart=0" | sudo tee -a /boot/config.txt
# Reboot
sudo rebootResult: Your Pi is now significantly more secure!
Last Updated: December 21, 2025