一直使用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:
接下來,又將服務器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
檢查各種配置文件,各種文件訪問權限,數次折騰無果。心中郁悶,因為這台機器軟硬件環境都和其它機器一樣,而且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相關知識。