When setting up a cloud server running Ubuntu 10.04 with Ruby, Passenger, and Apache, I encountered an interesting security dilemma. The default location for SSH authorized_keys files (~/.ssh/authorized_keys
) creates potential vulnerabilities, especially for service accounts like www-data
.
In my case, www-data
's authorized_keys file resided in /var/www/.ssh/
- right in Apache's document root. This raised immediate concerns:
/var/www/
├── .htaccess
├── .ssh/
│ └── authorized_keys # Potentially exposed!
└── public_html/
After researching, I implemented a centralized approach by modifying /etc/ssh/sshd_config
:
# Original:
# AuthorizedKeysFile .ssh/authorized_keys
# Modified:
AuthorizedKeysFile /etc/ssh/authorized_keys/%u
This change offers two main benefits:
- Eliminates exposure risk from misconfigured web servers
- Provides a single, managed location for all keys
Here's how to properly set up the centralized system:
# Create the directory structure
sudo mkdir -p /etc/ssh/authorized_keys
sudo chmod 755 /etc/ssh/authorized_keys
# Set proper permissions for each user's key file
sudo touch /etc/ssh/authorized_keys/root
sudo touch /etc/ssh/authorized_keys/www-data
sudo chmod 644 /etc/ssh/authorized_keys/*
While this solution solves the exposure problem, it introduces new considerations:
- Access Control: The centralized location makes all users' keys visible to administrators
- Permission Management: Requires strict control over who can modify these files
- User Enumeration: The existence of key files reveals which accounts are enabled for SSH access
To mitigate these risks, I recommend:
# Restrict access to the authorized_keys directory
sudo chown root:root /etc/ssh/authorized_keys
sudo chmod 700 /etc/ssh/authorized_keys
# Use ACLs for finer control (if needed)
sudo setfacl -Rm u:adminuser:r-x /etc/ssh/authorized_keys
For those who prefer not to centralize all keys, consider these alternatives:
# Option 1: Custom directory outside web root
AuthorizedKeysFile /etc/ssh/keys/%u
# Option 2: Combine centralized and per-user locations
AuthorizedKeysFile /etc/ssh/authorized_keys/%u .ssh/authorized_keys
Each approach has trade-offs between security and convenience that should be evaluated based on your specific environment.
When configuring SSH authentication on Ubuntu servers, many administrators encounter the same dilemma: the default ~/.ssh/authorized_keys
location presents potential security risks for system users like www-data
. The standard Apache configuration places web content in /var/www
, which coincidentally becomes the home directory for the www-data
user.
Consider this vulnerable scenario:
# Default www-data directory structure
/var/www/
├── .ssh/
│ └── authorized_keys
└── public_html/
If Apache's directory listing is accidentally enabled or there's a misconfiguration, the .ssh
directory could become exposed through web requests.
The AuthorizedKeysFile
directive in /etc/ssh/sshd_config
offers a solution by allowing key storage outside user home directories. Here's how to implement it:
# Edit sshd_config
sudo nano /etc/ssh/sshd_config
# Add or modify this line
AuthorizedKeysFile /etc/ssh/authorized_keys/%u
Then create the directory structure:
sudo mkdir -p /etc/ssh/authorized_keys
sudo chmod 755 /etc/ssh/authorized_keys
For our specific case with root
and www-data
:
# Migrate existing keys
sudo mv /root/.ssh/authorized_keys /etc/ssh/authorized_keys/root
sudo mv /var/www/.ssh/authorized_keys /etc/ssh/authorized_keys/www-data
# Set proper permissions
sudo chmod 644 /etc/ssh/authorized_keys/*
sudo chown root:root /etc/ssh/authorized_keys/*
Benefits:
- Isolates SSH keys from web-accessible directories
- Simplifies key management and auditing
- Reduces risk from misconfigured web server permissions
Potential Drawbacks:
- Centralization means a single point of failure for key storage
- Requires additional monitoring of the central directory
- May complicate automated user provisioning tools
For more granular security, consider combining centralized keys with a restricted shell environment:
# In sshd_config
Match User www-data
ChrootDirectory /var/www
AuthorizedKeysFile /etc/ssh/authorized_keys/www-data
AllowTcpForwarding no
X11Forwarding no
This approach gives you the benefits of centralized key management while further restricting what the web server user can access via SSH.
Regardless of which method you choose, follow these security practices:
# Recommended permissions for the auth keys directory
sudo chmod 750 /etc/ssh/authorized_keys
sudo chown root:ssh-users /etc/ssh/authorized_keys
# Create an audit script to monitor changes
#!/bin/bash
inotifywait -m -e modify,create,delete /etc/ssh/authorized_keys/ |
while read path action file; do
echo "$(date) - $file was $action" >> /var/log/auth_keys_monitor.log
done
Remember to restart the SSH service after configuration changes:
sudo service ssh restart