尝试使用密钥文件进行SSH身份验证:服务器拒绝了我们的密钥。

我正在尝试使用密钥文件而不是用户名/密码来设置SSH身份验证。客户端是运行PuTTY的Windows机器,服务器是一个Ubuntu 12.04 LTS服务器。
我下载了puttygen.exe并生成了一对密钥。在/etc/ssh/sshd_config中,我有这一行:
AuthorizedKeysFile %h/.ssh/authorized_keys

在我的客户公钥文件上写着这个:
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "my@email.address.com"
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAr3Qo6T5XU06ZigGOd3eKvfBhFLhg5kWv8lz6
qJ2G9XCbexlPQGanPhh+vcPkhor6+7OmB+WSdHeNO652kTofnauTKcTCbHjsT7cJ
GNrO8WVURRh4fabknUHPmauerWQZ6TgRPGaz0aucU+2C+DUo2SKVFDir1vb+4u83
AV1pKxs=my@email.address.com
---- END SSH2 PUBLIC KEY ----

我复制了从“ssh-rsa AAA”到“my@email.address.com”的部分,并将其放入了我的服务器上的文件~/.ssh/authorized_keys(位于我的个人家目录中)。在PuTTY的连接设置中,我在 Connection > SSH > Auth 中输入了客户端生成的私钥路径,并保存了会话设置。

我使用以下命令重新启动了ssh服务器:

sudo service ssh restart

现在如果我在PuTTY中加载配置文件(我确认私钥仍在Connection > SSH > Auth中,路径也是正确的),然后运行该配置文件,它会显示

Server refused our key

我尝试将公钥放在位于目录 ./ssh/authorized_keys/ 下的文件中,但没有帮助,所以我使用了 ./ssh/authorized_keys 作为文件,把密钥粘贴进去。我还尝试在服务器上生成了一对私钥/公钥,并将公钥放在 ./ssh/authorized_files 中,在客户端的 PuTTY 中加载私钥。重启服务器也没有帮助。
我发现错误可能会通过将密钥放在用户的主文件夹之外的位置来解决,但这只在主文件夹加密时有用,而这个主文件夹没有被加密。
我还尝试生成了一个 4096 位的密钥,想着也许 1024 位太短了。
我该如何让这个工作起来?谢谢!

编辑:

好的,/var/log/auth.log 中写着:
sshd: Authentication refused: bad ownership or modes for directory /home/vorkbaard/.ssh

Google告诉我~/.ssh/应该是700,~/.ssh/authorized_keys应该是600,所以我按照这样做了。现在/var/log/auth.log显示:
sshd: error: key_read: uudecode AAAAB3N [etc etc etc until about 3/4 of my public key]

2/var/log/auth.log非常有帮助,谢谢 =) - kot-da-vinci
+1 检查 /var/log/auth.log。我有一个不相关的问题,但检查那个日志文件帮助我解决了它。 - Richard
17个回答

好的,问题已经解决了,但我看不出这与我之前尝试的有什么不同。
我做了以下操作:
- 使用puttygen.exe生成了一对密钥(长度:1024位) - 在PuTTY配置文件中加载了私钥 - 将公钥以一行的形式输入到~/.ssh/authorized_keys文件中 (ssh-rsa {your_public_key},在ssh-rsa和您的密钥之间只能有一个空格) - 执行chmod 700 ~/.ssh - 执行chmod 600 ~/.ssh/authorized_keys - 执行chown $USER:$USER ~/.ssh -R - 修改/etc/ssh/sshd_config文件,使其包含AuthorizedKeysFile %h/.ssh/authorized_keys - 执行sudo service ssh restart 如需故障排除,请执行# tail -f /var/log/auth.log
感谢您的帮助!

1嗯,那个sshd: error: key_read: uudecode AAAAB3N错误在auth.log中发生了什么? - Alaa Ali
1阿拉,我一点也不知道。也许是我在粘贴之前弄错了上一个密钥字符串。现在auth.log没有新的记录了,基于密钥的身份验证运行得非常顺畅。我的主要问题是我对需要做什么并不确定,这让如何做变得更加困难。所以我不知道为什么,但它确实有效。再次感谢你的帮助 :) - Forkbeard
太棒了!我已经纠结了两天了。这个答案真是救了我一命!! - naka
第三步是我遇到的关键。我没有将公钥放入authorized_keys文件中,只是将我的mykey.pub文件粘贴到~/.ssh文件夹中,并以为它会自动识别。实际上,我最终需要运行这个命令或者在其他可能存在的密钥下面进行编辑和粘贴:cat mykey.pub >> authorized_keys。现在看起来很简单,但经验教训是所有的公钥都必须存放在authorized_keys而不仅仅在~/.ssh/目录中。如果这种说法不正确,请有经验的人提供建议。 - timbrown
如果这些步骤没有帮助,请检查以下内容:
  1. 您是否将保存的PuTTY公钥复制到了authorized_keys文件中,而不是OpenSSH的公钥。
  2. 如果您使用PuTTYgen进行复制粘贴(这是正确的做法),可能会导致公钥被分成多行;公钥应该是单行的,请确保在复制时没有添加前导或尾随空格。
感谢r_hartman https://www.centos.org/forums/viewtopic.php?t=990
- mvladk
1我会添加 chmod go-w ~/ - CappY
这篇帖子非常有帮助,但我需要将我的公钥格式更改为以ssh-rsa XYZASDF开头才能使其正常工作。我使用了"保存公钥"按钮,但它保存成了不同的格式。 - Marcel Burkhard
在PuttyGen中,默认的密钥长度现在是2048。你提到的(长度1024)解决了我的问题。谢谢! - Danny Schoemann
我觉得你的意思是:"sudo service sshd restart",而不是ssh。 - Trevor Hickey
我遇到了一些问题...我可以使用root访问,但是当我尝试使用我的用户(nott)访问时,出现了问题...服务器拒绝我的密钥,一些调试显示"failed publickey for nott",而且我的路径与你的路径一样,在%h之前。 - Freedo
另一个发生的原因是使用加密的主目录,当进行交互式登录之前,用户的主目录仍然被加密且无法访问。 - naisanza
谢谢,这对我很有帮助。只是要注意的是,我注意到在Raspian Jessie上经常发生这种情况。由于某种原因,这一行默认被注释掉了。 - user287691
这个步骤对我起了作用:chown $USER:$USER ~/.ssh -R - Jan
我还需要添加chmod 755 ~,但我认为我特别需要非组/其他人的写入权限。 - ShoeLace
chown $USER:$USER ~/.ssh -R 这条命令的作用是将 ~/.ssh 目录及其下的所有文件和子目录的属主和属组都修改为当前用户。不需要替换实际的用户名/登录名,因为 $USER 是一个环境变量,会被替换为当前用户的用户名。 - user1700890
1在/etc/ssh/sshd_config中找到了两个主要的事情:取消注释AuthorizedKeysFile行和PubkeyAcceptedKeyTypes ssh-dss行。 - Bimal Poudel
1这是黄金清单。按照这个清单逐项检查,其中一个应该能解决问题。通常是权限问题,或者说文件夹不属于用户所有。它对权限非常挑剔。.ssh文件夹和authorized_keys文件的权限需要与清单上的匹配(700和600)。你正在连接的用户需要拥有这个文件夹。记住使用chown username:group ~/.ssh -R命令。-R选项会处理所有子文件夹,并且会覆盖下面的所有内容。 - G_Style
兄弟,我已经花了好几个小时在这上面折腾了。我知道这东西有点老了,但它还是好用!非常感谢! - Jason Waltz
将公钥添加到主机.ssh/authorized_keys文件的第二行,然后保存,对我来说有效。太棒了!谢谢你。 - Mugé
只是为了给未来的访问者添加一个有用的评论:我刚刚遇到了一个奇怪的问题,我的SSH密钥突然停止工作,完全让我措手不及。我查看了auth.log文件,发现我的HOME文件夹的用户权限出错了,而不是.ssh或auth keys文件。当我在我的~文件夹中运行"ls -al"命令时,确实发现'.'的条目已经损坏了,一旦我运行"chown myname:users ."并进行了修复,SSH就能够再次使用现有的密钥了。 - shawty

我刚遇到了这个问题。尽管在这个帖子中已经提到了正确设置配置(authorized_keys等权限),但事实证明我的公钥格式错误。它的格式是:
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "imported-openssh-key"
AAAAB3NzaC1yc2EAAAADAQABAAABAQDUoj0N3vuLpeviGvZTasGQ...
... lPmTrOfVTxI9wjax2JvKcyE0fiNMzXO7qiHJsQM9G9ZB4Lkf71kT
---- END SSH2 PUBLIC KEY ----

不起作用。但通过这种形式使其起作用:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU.....j0N3vuLpeviGvZTasGQa1rcJiPXQMW7v3uurb+n94B9MQaaWR0odsg5DJQL92TNenOda5BO1nd08y6+sdLQmHXExTz6X8FzgoVsAkEl3RscxcxHUksiKA9JfTo38vQvG/bPxIHMCuSumCQVA1laf3rO/uOrkcB7iMWhaoi1/z6AbFtPzeh7xjGfInMWwtBI0CsHSRF73VWIxT26w0P+KjafCjSn/7vDO1bT8QHujSQelU/GqaVEvbbvPl1a7POVjKgHLNekolwRKfNeVEewcnmZaoqfHgOKlPmTrOfVTxI9wjax2JvKcyE0fiNMzXO7qiHJsQM9G9ZB4Lkf71kT UserName@HOSTNAME

21你可以使用 ssh-keygen -i -f filenameofwindowsformpub.key 将公钥转换为你的 OpenSSH 服务器能够理解的格式。 - Black
是的,对我来说有效!必须在一行中。真不敢相信只是这样简单! - adelriosantiago
2嗨kuraara,我认为@Black上面的指示应该在答案中突出显示。 - ekerner
我可以在OpenSSH服务器格式中添加注释吗?对于人类来说,很难确定这个密钥代表的是哪台计算机。 - user1700890
当我按照@Black的建议操作时,字符串末尾没有UserName@HOSTNAME。我不知道这部分是否重要。 - arnoldbird
"ssh-keygen -i -f" 对我来说起作用了。 - TexasNeo

我必须更改主目录的权限

chmod 700 ~

2这对我也起作用了(尽管在AIX上)。 - stevepastelan
在CentOS上对我起作用了 - Jaywalker
在Redhat上对我起作用!组写访问似乎是具体的问题。但如果我保留组读权限,它仍然对我起作用:"chmod 740 ~"。 - Paul
如果你愿意重新开始,我觉得最简单的方法是在目标机器上运行rm ~/.ssh,然后在客户端上运行ssh-copy-id -i <ssh_key_file> <login>@<target>ssh-copy-id会在目标机器上创建一个具有正确权限的~/.ssh文件夹。 - JS.
我无法感谢你的足够,我花了一天时间在这里找到了你的答案。 - Sahin

问题是Windows使用不同的换行符(new line)与Linux不同,所以当从Windows复制密钥到Linux时,在Linux编辑器中看不到行尾的\n。
如果你在Linux中尾随/var/log/auth.log并尝试登录,错误信息会如下所示:
sshd: error: key_read: uudecode AAAAB3N[....]==\n
如果你在Windows上更改密钥,使其成为一行且末尾没有换行符,并将其复制到Linux上,应该可以解决问题(对我来说起作用了)。

这是我的问题,但我在auth.log中没有看到任何暗示这种情况的东西。真令人沮丧... - Anthony

我不得不将~/.ssh目录的权限从770更改为700,将~/.ssh/authorized_keys文件的权限从660更改为600。
出于某种原因,删除组权限对我解决了这个问题。
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

~/.ssh/authorized_keys 文件要求密钥必须在一行上。如果您像上面粘贴的那样将其分成多行添加,请尝试将这些行连接起来。

谢谢,那很有道理,现在我明白为什么它是一个文件而不是目录了。然而,它并没有帮助。 - Forkbeard
5对于可能对此感到困惑的任何人来说,他的意思是每个键本身必须在单独的一行上,但不同的键需要在不同的行上。 - Anthony

这是对我有效的方法:
在puttygen中,生成密钥后,请确保将顶部字段中的信息复制并粘贴到您的authorized_keys文件中。如果您将公钥保存到客户端机器上,然后打开它,那么与puttygen屏幕顶部的文本不同。再次确保将文本从puttygen屏幕的顶部(在生成密钥后)复制并粘贴到位于~/.ssh目录下的authorized_keys文件中。

这实际上解决了问题。我不明白为什么如果你点击保存公钥,它不会保存正确的格式。 - luky

有时候,问题可能与公钥不在同一行有关,所以这种方法似乎可以解决这个问题:
echo 'the content of the public key' >> /root/.ssh/authorized_keys

除了以上所有的答案之外,还要确保你从puttygen正确地复制和粘贴密钥!
如果你只是双击键字符串的大部分来选择它,可能无法获取整个字符串,因为文本框会在某些字符(如+)上拆分行,这样你就无法选择+字符后面的文本(因为文本框太小而看不到)。一定要手动选择整个字符串,从ssh-rsa到文本框的最末尾。

常见错误是人们在使用文本编辑器(如Vim)时,在激活“插入”模式之前粘贴已复制的文本(在Vim中按+i然后再粘贴)。