In enterprise environments, it's common to have different authentication requirements for internal vs external SSH access. Public key authentication provides stronger security for internet-facing connections, while password authentication might be acceptable (and more convenient) for trusted internal networks.
The modern way to implement this in OpenSSH is using Match
blocks in your sshd_config
file. Here's how to structure it:
# Global settings apply to all connections Port 22 Protocol 2 LoginGraceTime 2m PermitRootLogin no MaxAuthTries 3 # Match internal network connections Match Address 192.168.1.0/24,10.0.0.0/8 PasswordAuthentication yes AuthenticationMethods publickey,password # Match everything else (external connections) Match all PasswordAuthentication no AuthenticationMethods publickey
For more complex network configurations, you can combine multiple matching criteria:
Match Address 192.168.1.0/24,10.0.0.0/8 User *,!root PasswordAuthentication yes PubkeyAuthentication yes
After making changes, always test your configuration before restarting the SSH daemon:
sudo sshd -t
If no errors are reported, apply the changes:
sudo systemctl restart ssh
If you're having problems, check these common pitfalls:
- Ensure your network ranges are correctly specified
- Verify that the Match blocks appear after global directives
- Check for typos in the configuration file
To verify the policy is working as intended, monitor your auth.log:
sudo tail -f /var/log/auth.log | grep sshd
In enterprise environments, it's common to need different authentication methods for SSH based on network origin. Public key authentication provides stronger security for external connections, while password authentication might be acceptable (or even required) for internal networks due to existing authentication systems.
The solution involves using Match Address
directives in the sshd_config
file to apply different authentication rules based on the client's IP address. Here's how to implement it:
# /etc/ssh/sshd_config # Global settings apply to all connections Port 22 Protocol 2 LoginGraceTime 60 PermitRootLogin no MaxAuthTries 3 # Default: require public key authentication for all AuthenticationMethods publickey PubkeyAuthentication yes PasswordAuthentication no # Internal network exception (192.168.1.0/24 in this example) Match Address 192.168.1.0/24 PasswordAuthentication yes AuthenticationMethods publickey,password
For more complex network setups, you can combine multiple conditions:
Match Address 192.168.1.*,10.0.0.* PasswordAuthentication yes AuthenticationMethods publickey,password PermitEmptyPasswords no
After modifying the configuration, always test and validate:
# Test configuration syntax sudo sshd -t # Reload SSH service sudo service ssh reload # Verify from internal network (should accept password) ssh -o PreferredAuthentications=password user@server # Verify from external network (should reject password) ssh -o PreferredAuthentications=password user@public-ip
When implementing this configuration:
- Ensure internal network ranges are properly specified
- Monitor authentication attempts for brute force attacks
- Consider additional protections like fail2ban for public interfaces
- Regularly rotate SSH host keys and user keys
If authentication isn't working as expected:
# Check authentication logs tail -f /var/log/auth.log # Verify PAM configuration isn't overriding SSH settings cat /etc/pam.d/sshd # Check SELinux/AppArmor permissions if applicable