一直使用CentOS作为服务器系统,平时装完系统以后都是建立publickey认证机制,然后关闭密码认证。原本是一件轻车熟路毫无压力的事情,不想前日新装一台机器按照正常配置以后居然使用publickey方式认证不成功,但是使用密码认证是可以的。

 
具体现象表现为使用SecureCRT登陆时,出现如下出错提示:
Public-key authentication with the server for user sw failed. Please verify username and public/private key pair.

查看服务器日志,找不到有用的相关记录。

 
之后直接在另一台机器上使用ssh连接,打开verbose模式(ssh -vvv),如下:
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug2: key: /home/sw/.ssh/identity (0xXXXXXXXXX)
debug2: key: /home/sw/.ssh/id_rsa ((nil))
debug2: key: /home/sw/.ssh/id_dsa ((nil))
debug3: Wrote 64 bytes for a total of 1109
debug1: Authentications that can continue: publickey,password
debug3: start over, passed a different list publickey,password
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering public key: /home/sw/.ssh/identity
debug3: send_pubkey_test
debug2: we sent a publickey packet, wait for reply
debug3: Wrote 512 bytes for a total of 1621
debug1: Authentications that can continue: publickey,password
debug1: Trying private key: /home/sw/.ssh/id_rsa
debug3: no such identity: /home/sw/.ssh/id_rsa
debug1: Trying private key: /home/sw/.ssh/id_dsa
debug3: no such identity: /home/sw/.ssh/id_dsa
debug2: we did not send a packet, disable method
debug3: authmethod_lookup password
debug3: remaining preferred: ,password
debug3: authmethod_is_enabled password
debug1: Next authentication method: password
sw@xxx.xxx.xxx.xxx's password:

可以看到,ssh先尝试了使用publickey进行认证,但是失败了,日志也没有显示相关原因,然后降级到使用密码认证。

 
接下来,又将服务器sshd的日志级别设置为DEBUG3(修改/etc/ssh/sshd_config中的LogLevel),期望得到有用的信息。修改以后重启sshd,然后再尝试连接,查看/var/log/secure,得到如下日志信息:
Mar  6 16:42:14 data sshd[]: debug1: trying public key file /home/sw/.ssh/authorized_keys
Mar 6 16:42:14 data sshd[]: debug1: restore_uid: 0/0
Mar 6 16:42:14 data sshd[]: debug1: temporarily_use_uid: 500/500 (e=0/0)
Mar 6 16:42:14 data sshd[]: debug1: trying public key file /home/sw/.ssh/authorized_keys
Mar 6 16:42:14 data sshd[]: debug1: restore_uid: 0/0
Mar 6 16:42:14 data sshd[]: Failed publickey for sw from xxx.xxx.xxx.xxx port 27816 ssh2
Mar 6 16:42:14 data sshd[]: debug3: mm_answer_keyallowed: key 0xXXXXXXXX is not allowed

日志信息只提到Failed publickey,并没有明确说明出错原因。

 
检查各种配置文件,各种文件访问权限,数次折腾无果。心中郁闷,因为这台机器软硬件环境都和其它机器一样,而且SSH的publickey认证也是配置过无数次的了。最后求助万能的Google,发现serverfault上有一个案例的现象和出错信息与我遇到几乎一样,提问者怀疑是SELinux导致的。下面的回复证实了确实是SELinux的问题,并且给出了解决方案:
Yes, SELinux is likely the cause. The .ssh dir is probably mislabeled. Look at /var/log/audit/audit.log. It should be labeled ssh_home_t. Check with ls -laZ. Run restorecon -r -vv /root/.ssh if need be.

Yep, SELinux was the cause: type=AVC msg=audit(1318597097.413:5447): avc: denied { read } for pid=19849 comm="sshd" name="authorized_keys" dev=dm-0 ino=262398 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file It works after running "restorecon -r -vv /root/.ssh". Thanks a lot.
我如获救命稻草,马上用ls -laZ检查了一下我的.ssh目录,果然不是ssh_home_t,心中窃喜,立刻使用restorecon对.ssh目录的context进行了恢复。
 
再次尝试进行连接,结果还是不行,现象和出错信息与之前一样。于是我查看了其它机器上的.ssh目录的context,都没有标为ssh_home_t,但是那些机器上的SSH服务都是正常的。我又仔细看了一下网上那个案例的描述和错误信息,我还是怀疑是SELinux导致的。于是我想把SELinux暂时关了试试,使用setenforce 0把SELinux关闭,重新尝试连接,publickey认证正常了。
 
确认了是SELinux引发的问题,接下来我查看了/var/log/audit/audit.log,发现有如下日志:
type=AVC msg=audit(1362560807.992:320): avc:  denied  { search } for  pid=1595 comm="sshd" name="/" dev=sda3 ino=2 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:file_t:s0 tclass=dir
这条日志与网上案例唯一不同的地方在于案例中是sshd对分区dm-0中的authorized_keys文件没有read权限,而我的机器上是sshd对分区sda3的根没有search权限。
 
确认了问题所在,我仔细回忆了系统的安装过程与其它机器有什么不同之处。日志中提到的sda3是系统的/home分区,当时装系统的时候由于操作失误/home分区只有200M,装完系统以后发现了这个问题,于是我把sda3分区删除重建,然后挂载到/home。这么一折腾,/home目录上的context就不对了。
 
之后我对/home目录的context进行恢复:
[root@data ~]# restorecon -r -vv /home/
restorecon reset /home context system_u:object_r:file_t:s0->system_u:object_r:home_root_t:s0
restorecon reset /home/lost+found context system_u:object_r:file_t:s0->system_u:object_r:lost_found_t:s0
restorecon reset /home/sw/.pki context unconfined_u:object_r:user_home_t:s0->unconfined_u:object_r:home_cert_t:s0
restorecon reset /home/sw/.pki/nssdb context unconfined_u:object_r:user_home_t:s0->unconfined_u:object_r:home_cert_t:s0
然后setenforce 1打开SELinux,重新连接SSH,认证成功,问题解决。
 
SELinux是Linux是的MAC(强制访问控制)系统实现,我还不太了解,接下来准备系统地学习一下SELinux相关知识。
 

一次由SELinux引起的ssh公钥认证失败问题的更多相关文章

  1. SSH公钥认证+优化

    一 ssh公钥认证流程: sshclinet机器:产生公私钥(公钥相当于一把锁) sshclient:将公钥发给sshserver(抛出锁子) sshclinet去连sshserver不需要密钥   ...

  2. Linux配置SSH公钥认证与Jenkins远程登录进行自动发布

    公钥认证,是使用一对加密字符串,一个称为公钥(public key), 任何人都可以看到其内容,用于加密:另一个称为密钥(private key),只有拥有者才能看到,用于解密. 在使用jenkins ...

  3. ssh公钥认证原理及设置root外的其他用户登录ssh

    1)创建其他用户 useradd [-d 登录目录] [-G ssh][用户名]  一定要将用户添加到ssh组不然无法没有权限登录ssh 2)设置ssh不允许root登录 vi /etc/ssh/ss ...

  4. [svc][op]SSH公钥认证+优化

    一 ssh公钥认证流程: sshclinet机器:产生公私钥(公钥相当于一把锁) sshclient:将公钥发给sshserver(抛出锁子) sshclinet去连sshserver不需要密钥 二 ...

  5. 转: SSH 公钥认证

    转: http://blog.knownsec.com/2012/05/ssh-%E5%85%AC%E9%92%A5%E8%AE%A4%E8%AF%81/ SSH 公钥认证 2012-05-15 简介 ...

  6. SSH公钥认证(码云)

    开发者向码云版本库写入最常用到的协议是 SSH 协议,因为 SSH 协议使用公钥认证,可以实现无口令访问,而若使用 HTTPS 协议每次身份认证时都需要提供口令.使用 SSH 公钥认证,就涉及到公钥的 ...

  7. SSH公钥认证登录

    概述: SSH登录的认证方式分为两种,一种是使用用户名密码的方式,另一种就是通过公钥认证的方式进行访问, 用户名密码登录的方式没什么好说的,本文主要介绍通过公钥认证的方式进行登录. 思路: 在客户端生 ...

  8. 使用SecureCRT设置linux系统登录的ssh公钥认证

    1.修改ssh配置文件/etc/ssh/sshd_configRSAAuthentication yes                             //使用RSA加密算法PubkeyAu ...

  9. linux配置ssh公钥认证,打通root用户的免密码输入的scp通道

    1.ssh-keygen ssh-keygen是unix-like系统的一个用来生成.管理ssh公钥和私钥的工具. 2.用法 常用的重要的选项有: -b num   指定生成多少比特长度的key,单位 ...

随机推荐

  1. 【JAVASCRIPT】React学习-JSX 语法

    摘要 react 学习包括几个部分: 文本渲染 JSX 语法 组件化思想 数据流 JSX 语法 1. 定义 JSX 是javascript + xml 的合集,我们可以将javascript 与 ht ...

  2. 18. leetcode 387. First Unique Character in a String

    Given a string, find the first non-repeating character in it and return it's index. If it doesn't ex ...

  3. macOS下配置scapy环境

    测试需求需要用到scapy库,遂在本机配置scapy环境,但最后一直提示权限问题,可能和sip有关系. 最后在同事介绍下使用虚拟环境(virtualenv)搞定. virtualenv: Virtua ...

  4. animate.css的使用

    前面的话 animate.css是一个使用CSS3的animation制作的动画效果的CSS集合,里面预设了很多种常用的动画,且使用非常简单.本文将详细介绍animate.css的使用 引入 anim ...

  5. 51NOD 1258 序列求和 V4 [任意模数fft 多项式求逆元 伯努利数]

    1258 序列求和 V4 题意:求\(S_m(n) = \sum_{i=1}^n i^m \mod 10^9+7\),多组数据,\(T \le 500, n \le 10^{18}, k \le 50 ...

  6. MT过安全狗增加用户

    记一次入侵时发现可以增加用户,但是由于狗的存在,无法赋予管理员权限 此时就进行类似使用注册表的复制超级管理员的操作 使用MT的克隆功能, net user test test /add mt -clo ...

  7. 为什么C++中声明和定义要分开写

    现在开始写项目了,你会发现我们一般都要写一个cpp,对应的还得有一个h文件,那么为什么在C++中我们要这么做? .h就是声明,.cpp就是实现,而所谓分离式实现就是指"声明"和&q ...

  8. mysql为什么范围查询(>,<,between,%like,like%)之后的索引无效

    因为使用了范围索引,所以会使用满足范围的所有的值,也就是说存储引擎在这个时候会提取出满足之后条件的所有值,并遍历获取满足之后条件的值. http://www.itpub.net/thread-1901 ...

  9. jaspersoft studio 的初级入门(一)

    前言 最近的工作涉及到企业的报表生成功能,于是就想用此篇博客来记录我的学习历程.进入Jasperreport项目的官网发现有一个软件叫Jaspersoft studio的,它的版本也是6.3.1跟Ja ...

  10. 关于 Node.js 的认证方面的教程(很可能)是有误的

    原文地址:Your Node.js authentication tutorial is (probably) wrong 我搜索了大量关于 Node.js/Express.js 认证的教程.所有这些 ...