【SSH和SFTP】
■ 設置一個只允許訪問部分目錄的SFTP服務器
由於SSH和SFTP之間的緊密聯系,一個SFTP服務器必然會導致開放一定的SSH服務,而SSH的風險顯然比SFTP要大一些。自然,我們就會需要:1.禁止SSH登錄但保持SFTP服務可用;2.SFTP也不能讓外部用戶可以自由讀寫所有服務器上信息。這兩個需求可以通過用戶配置及sshd配置來配合完成。
在/etc/ssh/sshd_config中加上這些配置:
#Subsystem sftp /usr/libexec/openssh/sftp-server #這行是默認開啟的,用#把它注釋掉 #添加下面這些內容,其中ftpuser是我們要進行限制的用戶 Subsystem sftp internal-sftp Match User ftpuser ChrootDirectory /hsdata/datadir/ftpuser X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp
如果順利,那么ftpuser通過sftp協議連入之后,默認就是在/hsdata/datadir/ftpuser這個目錄下,且cd ..;或者讀寫其他目錄下的嘗試都會失敗。比如cd /tmp時會提示不存在/tmp目錄。因為此時對於這個SFTP的客戶端來說,/hsdata/datadir/ftpuser就是根目錄/。
要想順利實現,有兩個前提條件:
1. ChrootDirectory配置項的值即/hsdata/datadir/ftpuser這個目錄及其所有長輩目錄(/hsdata/datadir和/hsdata)必須都是root:root的。
2. ChrootDirecotry配置項的值的目錄及其所有長輩目錄,最大權限只能開放到755,即寫權限只能讓目錄所有者(即root)擁有。
上述sshd_config的變更成功實現了對sftp用戶進行訪問限制的功能,但是此時用戶還可以通過ssh連入,這就沒有意義了。禁止其ssh連入但是允許sftp連入的實現方式很簡單,是改變用戶的默認shell(which是/bin/bash)為/bin/false:
#在root權限下 usermod -s /bin/false ftpuser
■ 幾個概念初探
使用java的jsch包,進行SSH/SFTP連接時,經常會出現各種各樣的錯誤。比如報錯Algorithm Negotiation錯誤,比如End of IO Stream等等。首先jsch包版本本身會對連接能否成功建立有影響。比如一個實踐是當S端的openssh組件升級之后,C端無論如何連不上,但是將jsch包從45版本升級到53或者54版本就可以了。。這個比較迷,也還沒來得及深究原因。
其次要明確,SSH連接中有C端(客戶端)和S端(服務端)。如果要進行一個連接,那么C端和S端應該都裝有openssh(都是Linux的場合),如果兩者版本一致是最好了。但是往往C端和S端的openssh版本不同。版本不同會導致很多亂七八糟的事情。
在建立連接的過程中,C和S端要進行加密算法(Cipher)、密鑰交換算法(Kex Algorithm)和消息確認算法(MAC)。Kex的全稱是Key Exchange,MAC的全稱是Message Authentication Code。如果兩端無法協商成立使用統一的算法,那么連接就無法建立。通常一個特定發行版本的openssh會自帶一些默認支持的算法,對於剩余不默認支持的,可以在配置文件中加入額外配置增加支持。
當openssh升級過后客戶端發現無法連接了,那么很有可能是openssh新版本將一些默認支持的老算法(尤其是kex算法部分)列入了默認不支持范圍。可以考慮在/etc/ssh/sshd_config中增加相關配置即可。具體增加的配置可以百度一下,有很多,也就是配置了名為Ciphers,Kex Algorithms和MACs的三項。
另一方面,在手動通過字符界面的ssh客戶端發起連接時,如果想要知道客戶端和服務端究竟協商成了什么樣的算法,那么可以ssh -vvv 目標IP,加上參數-vvv之后,ssh連接過程中的所有debug日志都會被打印出來。在打印出來的日志中可以詳細查詢debug1(C端日志)和debug2(S端日志)開頭的部分。其中就有debug1后面的kex algorithm和debg2后面的algorithm,分別指出了C、S端使用的Kex算法。
在C或S任意一端上,如果想要查看默認支持的算法,還可以嘗試通過man sshd_config或者ssh -Q kex(僅限於查看kex算法,也可換成cipher或者mac)兩條命令。不過對於一些版本比價老的openssh,可能這些命令不支持需要注意。