一次由SELinux引起的ssh公鑰認證失敗問題


一直使用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[1517]: debug1: trying public key file /home/sw/.ssh/authorized_keys
Mar  6 16:42:14 data sshd[1517]: debug1: restore_uid: 0/0
Mar  6 16:42:14 data sshd[1517]: debug1: temporarily_use_uid: 500/500 (e=0/0)
Mar  6 16:42:14 data sshd[1517]: debug1: trying public key file /home/sw/.ssh/authorized_keys
Mar  6 16:42:14 data sshd[1517]: debug1: restore_uid: 0/0
Mar  6 16:42:14 data sshd[1517]: Failed publickey for sw from xxx.xxx.xxx.xxx port 27816 ssh2
Mar  6 16:42:14 data sshd[1517]: 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相關知識。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM