What Does the "Permission denied" Error Mean
The SSH Permission denied error appears when the SSH daemon (sshd) on the target server refuses authentication. The message may look like this:
Permission denied (publickey,password).
Or, if a specific method is used:
Permission denied (publickey).
The error occurs at the authentication stage, meaning the connection is established, but the server does not allow the user in. This is not a network failure (unlike Connection refused), but a problem with credentials or security settings.
Causes
- Incorrect credentials — wrong username, password, or using the wrong private key.
- Incorrect permissions on
~/.sshfiles — on the server, the.sshfolder orauthorized_keysfile must have strict permissions (700 and 600 respectively) and belong to the target user. - Disabled authentication methods in
sshd_config— for example,PasswordAuthentication nowhen attempting to log in with a password. - User is locked or has no shell — in
/etc/passwd, the user has/usr/sbin/nologinor/bin/false. - SELinux/AppArmor — security context prevents access to
~/.ssh. - IP blocking — via
fail2ban,denyhosts, orhosts.deny. - Key mismatch — the public key on the server does not match the private key on the client.
- Restrictions in
sshd_config—AllowUsers,DenyUsers,AllowGroups,DenyGroupsexclude the user. - Host key issues — although this usually causes a different warning, it can sometimes affect authentication.
Method 1: Checking Credentials and Basic Steps
Ensure you are attempting to log in with the correct username and authentication method.
- Specify the user explicitly in the command:
ssh -l username server_ip
orssh username@server_ip - When using a key, check that the private key is loaded into
ssh-agent:ssh-add -l
If the list is empty, add the key:ssh-add ~/.ssh/id_rsa
Or specify the key directly:ssh -i ~/.ssh/id_rsa username@server_ip - When using a password, ensure the password is correct and the account has no restrictions (e.g., password expiration).
- Check if the server is reachable (network layer):
ping server_ip nc -zv server_ip 22
💡 Tip: If you are unsure which authentication method is being used, try explicitly specifying
-o PubkeyAuthentication=nofor password or-o PreferredAuthentications=publickeyfor key.
Method 2: Fixing Permissions on .ssh Files on the Server
Incorrect permissions are the most common cause. Connect to the server via console (if you have physical access) or use an alternative method (e.g., your cloud provider's web console).
- Log in to the server under the account you are trying to connect to via SSH (or as root).
- Check current permissions:
ls -la ~/.ssh
Expected output:drwx------ 2 user user 4096 Feb 16 12:00 . drwxr-xr-x 5 user user 4096 Feb 16 12:00 .. -rw------- 1 user user 400 Feb 16 12:00 authorized_keys - Fix permissions:
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chown -R $(whoami):$(whoami) ~/.ssh - For SELinux (if used):
restorecon -Rv ~/.ssh - Restart the SSH daemon:
sudo systemctl restart sshd
Method 3: Checking and Configuring sshd_config
The sshd_config configuration file can block authentication.
- Open the file:
sudo nano /etc/ssh/sshd_config
orsudo vi /etc/ssh/sshd_config - Ensure lines have correct values:
PubkeyAuthentication yes PasswordAuthentication yes # if using a password PermitRootLogin no # or prohibit-password, but not yes for security ChallengeResponseAuthentication no UsePAM yes - Check access directives:
- If
AllowUsersorAllowGroupsexists, ensure your user is listed. - If
DenyUsersorDenyGroupsexists, ensure your user is not in the list.
- If
- Reload the configuration:
sudo systemctl restart sshd
Or check syntax before reloading:sudo sshd -t - If you changed the port (via
Port), ensure you are connecting to the correct port:ssh -p 2222 username@server_ip
Method 4: Analyzing SSH Logs
Logs contain the exact reason for the denial.
- On the server, view logs in real-time while attempting a connection:
- Ubuntu/Debian:
sudo tail -f /var/log/auth.log - RHEL/CentOS/Fedora:
sudo tail -f /var/log/secure
- Ubuntu/Debian:
- Typical entries:
Failed publickey for username from client_ip port ...: key problem.Failed password for username from client_ip port ...: incorrect password or password authentication disabled.User username not allowed because not listed in AllowUsers: restriction in config.User username not allowed because shell /usr/sbin/nologin not listed in /etc/shells: shell forbidden.
- Use
grepto filter:sudo grep "sshd.*Failed" /var/log/auth.log
Method 5: Checking Blocks and SELinux/AppArmor
Checking IP Blocks
- Check
fail2ban(if installed):sudo fail2ban-client status sshd
If your IP is in the list, unban it:sudo fail2ban-client set sshd unbanip client_ip - Check
hosts.deny:cat /etc/hosts.deny
If there is a linesshd: ALLorsshd: client_ip, remove it or add an exception inhosts.allow. - Check
iptables/nftables:sudo iptables -L -n | grep 22 sudo nft list ruleset | grep 22
Checking SELinux (RHEL/CentOS/Fedora)
- Check status:
sestatus
IfEnabled, check the context of~/.ssh:ls -laZ ~/.ssh
Files should havessh_home_tand the directoryssh_home_dir_t. - Restore context:
sudo restorecon -Rv ~/.ssh - If the problem persists, temporarily disable SELinux for diagnosis:
sudo setenforce 0
Do not leave it disabled! After diagnosis, find the proper solution (correct context or policy).
Checking AppArmor (Ubuntu/Debian)
- Check the sshd profile:
sudo aa-status | grep sshd
If the profile is inenforcemode, try switching tocomplain:sudo aa-complain /etc/apparmor.d/usr.sbin.sshd
Restartsshdand test the connection. - If it works, configure the profile correctly or leave it in
complainif there is no threat.
Method 6: Checking Shell and User Status
- Ensure the user has a shell:
grep ^username: /etc/passwd
The last field should be/bin/bash,/bin/sh, or another valid shell from/etc/shells. If it is/usr/sbin/nologinor/bin/false, change it:sudo chsh -s /bin/bash username - Check if the user is locked:
sudo passwd -S username
If the status isL(locked), unlock it:sudo passwd -u username - Check if the password has expired:
sudo chage -l username
If the password has expired (Password expires), reset it:sudo passwd username
Prevention
- Use SSH keys instead of passwords — they are more reliable and convenient.
- Regularly update OpenSSH to receive vulnerability fixes:
sudo apt update && sudo apt upgrade openssh-server # Debian/Ubuntu sudo yum update openssh-server # RHEL/CentOS 7 sudo dnf update openssh-server # RHEL/CentOS 8+/Fedora - Configure
sshd_configsecurely: disablePasswordAuthenticationif using keys; restrict access viaAllowUsers. - Monitor logs (
/var/log/auth.logor/var/log/secure) for suspicious attempts. - Use a firewall (
ufw,firewalld,iptables) to restrict port 22 to only trusted IPs. - Do not use root access directly — log in as a regular user and elevate privileges with
sudo. - Regularly check permissions on
~/.sshandauthorized_keysafter system changes. - When using SELinux/AppArmor, do not disable them; configure policies correctly.
If the issue is not resolved, check network settings (NAT, cloud security groups) and PAM authentication (/etc/pam.d/sshd). As a last resort, temporarily increase the logging level in sshd_config (LogLevel VERBOSE) and restart sshd for more details.