Chapter 9.1 - Securing Permissions
Learning Objectives
By the end of this chapter, you will be able to:
- Apply the principle of least privilege
- Secure file permissions
- Understand the risks of broad permissions
- Audit system permissions
- Correct incorrect permissions
Principle of Least Privilege
Concept
Give only the necessary permissions, nothing more.
Advantages:
- Reduced attack surface
- Limitation of damage
- Security compliance
Secured Permissions
Normal Files
# Configuration files
chmod 644 fichier.conf # rw-r--r--
chmod 600 fichier.conf # rw------- (private)
# Executable scripts
chmod 755 script.sh # rwxr-xr-x
chmod 700 script.sh # rwx------ (private)
# Sensitive files
chmod 600 .ssh/id_rsa # Private key
chmod 644 .ssh/id_rsa.pub # Public key
chmod 700 .ssh/ # SSH directory
Directories
# Normal directories
chmod 755 repertoire/ # rwxr-xr-x
# Private directories
chmod 700 repertoire/ # rwx------
# Shared directories
chmod 775 shared/ # rwxrwxr-x
chmod 1777 /tmp # Sticky bit
Dangerous Permissions
To Avoid
# 777 - All rights (DANGEROUS!)
chmod 777 fichier # AVOID!
# Unnecessary SUID/SGID
chmod u+s script.sh # Check necessity
# World-writable directories
chmod 777 repertoire/ # AVOID!
Detect
# Files with broad permissions
find /home -type f -perm -o+w
find / -type f -perm 777 2>/dev/null
# World-writable directories
find / -type d -perm -o+w ! -path "/proc/*" 2>/dev/null
# SUID/SGID files
find / -type f -perm /4000 2>/dev/null # SUID
find / -type f -perm /2000 2>/dev/null # SGID
SSH Security
Correct Permissions
# .ssh directory
chmod 700 ~/.ssh
# Private keys
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_ed25519
# Public keys
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/authorized_keys
# Config
chmod 600 ~/.ssh/config
Verification
# Verification script
#!/bin/bash
SSH_DIR="$HOME/.ssh"
if [ -d "$SSH_DIR" ]; then
# Check directory permissions
PERMS=$(stat -c "%a" "$SSH_DIR")
if [ "$PERMS" != "700" ]; then
echo "WARNING: .ssh should be 700, currently $PERMS"
fi
# Check private keys
for key in "$SSH_DIR"/id_*; do
if [ -f "$key" ] && [[ "$key" != *.pub ]]; then
PERMS=$(stat -c "%a" "$key")
if [ "$PERMS" != "600" ]; then
echo "WARNING: $key should be 600, currently $PERMS"
fi
fi
done
fi
Cron Security
Crontab Permissions
# User crontab
chmod 600 ~/.crontab # If external file
# Check system crontab
ls -l /etc/crontab
ls -l /etc/cron.d/*
Cron Environment
# Secure crontab
PATH=/usr/bin:/bin
SHELL=/bin/bash
MAILTO=admin@example.com
# Use absolute paths
0 2 * * * /usr/local/bin/backup.sh
# Redirect output
0 2 * * * /usr/local/bin/script.sh > /var/log/script.log 2>&1
# Do not use undefined variables
Secure Cron Scripts
#!/bin/bash
# Secure cron script
# Security options
set -euo pipefail
# Absolute paths
SCRIPT_DIR="/usr/local/bin"
LOG_FILE="/var/log/my-script.log"
# Logging function
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
}
# Checks
if [ ! -f "$SCRIPT_DIR/config" ]; then
log "ERROR: Missing config file"
exit 1
fi
# Processing...
log "Start processing"
# ...
log "End processing"
Permissions Audit
Audit Script
#!/bin/bash
# Permissions audit
echo "=== World-writable files ==="
find /home -type f -perm -o+w 2>/dev/null
echo "=== World-writable directories ==="
find /home -type d -perm -o+w 2>/dev/null
echo "=== SUID files ==="
find /home -type f -perm /4000 2>/dev/null
echo "=== SGID files ==="
find /home -type f -perm /2000 2>/dev/null
echo "=== SSH Permissions ==="
if [ -d ~/.ssh ]; then
ls -la ~/.ssh
fi
Automatic Correction
#!/bin/bash
# Correct SSH permissions
SSH_DIR="$HOME/.ssh"
if [ -d "$SSH_DIR" ]; then
chmod 700 "$SSH_DIR"
# Private keys
find "$SSH_DIR" -name "id_*" ! -name "*.pub" -exec chmod 600 {} \;
# Public keys
find "$SSH_DIR" -name "*.pub" -exec chmod 644 {} \;
# authorized_keys
[ -f "$SSH_DIR/authorized_keys" ] && chmod 600 "$SSH_DIR/authorized_keys"
# config
[ -f "$SSH_DIR/config" ] && chmod 600 "$SSH_DIR/config"
echo "SSH permissions corrected"
fi
Best Practices
Files
- 644 for normal files
- 600 for sensitive files
- 755 for executable scripts
- 700 for private scripts
Directories
- 755 for normal directories
- 700 for private directories
- 775 for shared directories (with group)
- 1777 for /tmp (sticky bit)
Checks
- Regularly audit
- Automate with scripts
- Document exceptions
- Review after changes
Summary
In this chapter, you learned:
Least privilege: Minimal necessary permissions
Securing: Appropriate permissions by type
Detection: Find dangerous permissions
SSH: Correct permissions for keys and config
Cron: Secure scripts and environment
Audit: Scripts to check and correct
Next Steps
Chapter 9.2: Sudo configuration
Chapter 9.3: Firewall
Chapter created on: December 2024