之前兩篇文章利用SSH代理訪問內(nèi)網(wǎng)資源和使用SSH代理在本地開發(fā)環(huán)境調(diào)試各種回調(diào)兩篇文章锅论,介紹了ssh的各種代理姿勢药薯,SSH的功能確實強(qiáng)悍饿序。如果用過ssh代理功能熬苍,就有人要問了,我能否限制用戶只允許使用代理功能地技,而不允許用戶登錄到我的系統(tǒng)中呢蜈七?
當(dāng)然可以!否則又怎么會稱為SSH(注:SSH是Secure Shell的縮寫)呢莫矗?連權(quán)限都不能保障怎么敢叫Secure
呢飒硅?本篇文章就來詳解下SSH的花式權(quán)限,來點不一樣的干貨作谚。
NOTE: 本文提及的
SSH
三娩,主要指OpenSSH
的實現(xiàn)和功能,其他SSH
服務(wù)端和客戶端可能實現(xiàn)不完全一致妹懒,比如putty
這個客戶端使用的配置就和OpenSSH
不一樣雀监。其他SSH
服務(wù)端和客戶端請務(wù)必參考官方文檔。
SSH的功能概述
先談?wù)凷SH有哪些功能眨唬,才能談到每個功能有哪些權(quán)限会前。SSH最常見的有三大功能:
- remote shell:可以說最初的功能了,用的最多最廣的也是這個功能匾竿,也是絕大多數(shù)用戶對ssh的初步印象
- proxy:這個功能相對來說可能運維接觸的多瓦宜,也用的多。我的前兩篇文章重點介紹這個功能
- file transfer:
scp
/sftp
/rsync
等命令使用SSH協(xié)議實現(xiàn)文件遠(yuǎn)程傳輸岭妖,sshfs
通過SSH協(xié)議將遠(yuǎn)程目錄掛載到本地临庇,等等。
其次是SSH是一個典型的C/S應(yīng)用昵慌,服務(wù)端運行sshd
守護(hù)進(jìn)程苔巨,監(jiān)聽TCP/22
端口(默認(rèn)情況下),客戶端運行ssh
程序废离,遠(yuǎn)程連接sshd
應(yīng)用,使用以上三種功能礁芦。
sshd
使用/etc/ssh/sshd_config
和~/.ssh/authorized_keys
(這個文件僅用于做密鑰認(rèn)證的配置蜻韭,如果和sshd_config配置沖突則此文件配置生效悼尾。此配置文件可以實現(xiàn)細(xì)化到密鑰的權(quán)限,gitlab使用此配置實現(xiàn)用戶的ssh訪問控制)配置文件做服務(wù)配置肖方,ssh
客戶端使用/etc/ssh/ssh_config
(全局配置)和~/.ssh/config
(個性配置)兩個配置文件(windows 10的openssh使用%USERPROFILE%\.ssh\config
)闺魏。默認(rèn)配置文件幾乎不用動,ssh就幫我們做好了開箱即用的配置叁熔。本文不會講解ssh每個配置項的含義泵督,只會根據(jù)一些場景講解對應(yīng)的權(quán)限控制连舍,所有場景都是以默認(rèn)配置為基準(zhǔn),講解一些常用的配置泡仗,一些不常用的配置項就不提及了。
下面我們將詳解每個功能的權(quán)限
遠(yuǎn)程連接的權(quán)限限制
ssh user@ip
最基本的使用方式猜憎,直接遠(yuǎn)程連接到服務(wù)器的shell上娩怎,實現(xiàn)遠(yuǎn)程控制的需求。
不允許遠(yuǎn)程登錄
只要用戶滿足以下條件之一胰柑,ssh便會拒絕登錄:
- 用戶無密碼(由于默認(rèn)開啟了
PermitEmptyPasswords no
選項) - 用戶無合法shell(注意如果不指定shell截亦,則默認(rèn)為
/bin/sh
) - 明確拒絕使用各種可登錄的渠道(比如
PasswordAuthentication no
,PubkeyAuthentication no
等等) -
/etc/nologin
存在,則除root
外所有用戶均拒絕登錄柬讨,并打印/etc/nologin
文件內(nèi)容作為提示信息
所以通常創(chuàng)建一個低權(quán)限賬戶崩瓤,只負(fù)責(zé)運行本地服務(wù)的,使用的useradd命令大致如下:
useradd -r -M -s /bin/false user
新用戶無密碼踩官,并且不是一個合法的shell却桶,所以根本沒法登錄
/bin/false
,/sbin/nologin
等做shell的區(qū)別:/bin/false
只是返回1
退出碼,什么都不輸出卖鲤,所以ssh登錄的時候顯示了一下motd
信息(如果有)就直接退出了肾扰。而/sbin/nologin
會輸出一行This account is currently not available.
,然后再以1
退出碼退出蛋逾。所以用戶如果登錄除了會看到那些信息之外集晚,還會看到/sbin/nologin
的提示信息。使用/etc/nologin
配置也有類似的效果区匣。如果是其他壓根不存在的文件做shell配置偷拔,那么就會反復(fù)提示登錄失敗。
如果連motd信息都不想讓用戶看到亏钩,可以直接創(chuàng)建一個~/.hushlogin
空文件即可莲绰。如果想通過修改配置文件,那么需要同時修改/etc/sshd_config
(PrintMotd no
)和/etc/pam.d/sshd
(去掉pam_motd.so
加載)姑丑,比較麻煩蛤签。
不允許root登錄
設(shè)置PermitRootLogin
選項即可。no
表示徹底拒絕root遠(yuǎn)程登錄栅哀,想要切換成root就只能通過普通用戶的su -
或sudo -i
切換root身份了震肮。prohibit-password
和without-password
(Ubuntu 14.04以后默認(rèn))表示拒絕密碼登錄称龙,表示只能通過密鑰登錄了。forced-commands-only
選項表示只允許密鑰認(rèn)證戳晌,但是必須給定command
鲫尊,也就是非交互式執(zhí)行ssh。
限定ip白名單登錄
這個其實辦法很多沦偎,比如在防火墻控制疫向,在/etc/hosts.(deny|allow)
控制等,其實在/etc/sshd_config
也可以控制豪嚎,方法就是使用Match address
搔驼,比如:
Match Address 127.0.0.*
PubkeyAuthentication yes
用sshd配置本身做ip白名單的比較少,但是Match
配置卻是一個非常有用的配置項疙渣,它可以實現(xiàn)我們對用戶或用戶組區(qū)別對待匙奴,這個我們會在后面再細(xì)說。
代理的權(quán)限限制
有關(guān)代理的使用可以參考我之前寫的利用SSH代理訪問內(nèi)網(wǎng)資源和使用SSH代理在本地開發(fā)環(huán)境調(diào)試各種回調(diào)兩篇文章妄荔。
禁止端口轉(zhuǎn)發(fā)
AllowTcpForwarding no
禁止X11轉(zhuǎn)發(fā)
X11Forwarding no
x11轉(zhuǎn)發(fā)功能實際應(yīng)用會非常罕見泼菌,作用是將遠(yuǎn)程的圖形數(shù)據(jù)在本地的X server上展示,以實現(xiàn)本地操作遠(yuǎn)程圖形程序的功能啦租。首先是Linux服務(wù)器大多運行在無圖形環(huán)境下哗伯,本身就沒有圖形化程序跑在上面,再加上客戶機(jī)可能多數(shù)是windows篷角,又沒有X環(huán)境焊刹,更加限制了這個功能的使用。還有就是x11 forwarding性能不是很好恳蹲,實際使用會發(fā)現(xiàn)非撑翱椋卡,不適合使用那種對響應(yīng)速度要求比較靈敏的應(yīng)用程序嘉蕾,比如瀏覽器贺奠,在x11 forwarding下運行動圖會非常卡错忱。最后就是需要跑圖形化程序的服務(wù)器多數(shù)都安裝有桌面環(huán)境儡率,配置有vnc,因此就更沒有人愿意使用這個功能了以清。
限制轉(zhuǎn)發(fā)端口
如果不希望所有端口都能用于轉(zhuǎn)發(fā)請求儿普,可以配置PermitOpen
參數(shù):
PermitOpen host:port
PermitOpen IPv4_addr:port
PermitOpen [IPv6_addr]:port
如果允許多個端口用于轉(zhuǎn)發(fā),那么必須一個個配置出來掷倔,any
(默認(rèn))表示所有端口都允許用于轉(zhuǎn)發(fā)眉孩。
文件傳輸?shù)臋?quán)限限制
這個比較繁瑣,因為目前常見的通過ssh傳輸文件的有三個命令scp
,rsync
,sftp
勒葱。它們的機(jī)制不一樣勺像,其中scp
和rsync
是通過遠(yuǎn)程非交互式執(zhí)行命令實現(xiàn)的障贸,而sftp
是通過openssh的sftp server實現(xiàn)的。
對于scp
和rsync
吟宦,只需要限制非交互式命令就可以了,比如
ForceCommand /bin/bash
或在~/.ssh/authorized_keys
對應(yīng)的rsa public key 前面加上command="/bin/bash"
(參考gitlab的/var/opt/gitlab/.ssh/authorized_keys
)涩维,效果是等效的殃姓。這樣就可以實現(xiàn)允許用戶遠(yuǎn)程登錄系統(tǒng),但是scp
和rsync
命令失效瓦阐,同時由于限定死了command參數(shù)蜗侈,導(dǎo)致你的非交互式ssh命令也無法使用了,比如ssh user@ip ls /
這一類非交互式ssh不起作用了睡蟋。
但是對于sftp
的限制則要容易的多踏幻,因為sftp
權(quán)限是單獨分開的,不和ssh命令執(zhí)行權(quán)限混在一起戳杀,并且sftp也和ftp一樣该面,有自帶的一些命令實現(xiàn)(比如ls, cd, get, put等等),如果設(shè)置
ForceCommand internal-sftp
或等效的~/.ssh/authorized_keys
配置信卡,則表示只允許使用sftp隔缀,不允許shell登錄。如果配置中去掉Subsystem sftp /usr/lib/openssh/sftp-server
這一行就可以關(guān)閉sftp服務(wù)
關(guān)于Match
經(jīng)常時候我們需要混合以上各種權(quán)限使用傍菇。比如某些用戶我們開放出來猾瘸,但是限制它的功能,此時Match
配置就是我們的好朋友了丢习。
限制某個用戶只能使用TCP代理
Match User limited-user
AllowTcpForwarding yes # 這個是默認(rèn)配置牵触,如果沒改過的話可以不加
X11Forwarding no # 禁止x11 forwarding
GatewayPorts yes # 允許ssh -R參數(shù)bind所有ip,否則只允許bind 127.0.0.1
AllowAgentForwarding no
PasswordAuthentication no # 不允許密碼登錄
PermitOpen localhost:62222 # 只允許打開localhost:62222做端口轉(zhuǎn)發(fā)
ForceCommand echo 'This account can only be used for TCP proxy'
以上命令可以根據(jù)實際情況調(diào)節(jié)咐低,比如將user的shell置為
/sbin/nologin
揽思,這樣一來ForceCommand
其實可以去掉,如果用戶登錄shell就會提示This account is currently not available.
渊鞋。
由于用戶不能登錄shell绰更,不能使用密碼認(rèn)證,因此想要使用代理锡宋,必須使用類似于下面的命令:
ssh -R 62222:192.168.1.1:80 -i /path/to/id_rsa -N
使用-i
參數(shù)指定私鑰文件用于公鑰認(rèn)證儡湾,使用-N
參數(shù)表示不執(zhí)行遠(yuǎn)程命令,僅僅使用port forwarding执俩。
NOTE:
sshuttle
的原理是使用ssh command在遠(yuǎn)程執(zhí)行python命令徐钠,轉(zhuǎn)發(fā)請求,因此以上的配置由于不能執(zhí)行command役首,所以sshuttle
就不能用了尝丐。
sftp only
Match Group sftp-only
ForceCommand internal-sftp
PasswordAuthentication yes
ChrootDirectory /var/sftp
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
這里我們Match了sftp-only
這個組显拜,在這個組下面的用戶都使用下面的配置。使用了ForceCommand爹袁,因此不能登錄shell远荠,使用了ChrootDirectory
限制了用戶的根目錄,關(guān)閉了各種轉(zhuǎn)發(fā)功能失息。
root用戶不允許外網(wǎng)訪問譬淳,但是內(nèi)網(wǎng)可以
PermitRootLogin no
Match Address 192.168.1.0/24
PermitRootLogin yes
通過Match
的組合,我們可以很方便的限制一些特定用戶的權(quán)限盹兢,這樣就實現(xiàn)了ssh用戶的一些特殊化管理邻梆。
結(jié)語
這里只是按照一些可能遇到的場景講解了下sshd_config
的配置,對于等效的~/.ssh/authorized_keys
配置同樣適用绎秒。其實ssh還有很多強(qiáng)大的功能浦妄,但是用的可能比較少,這里就不詳細(xì)講解那些不太常見的參數(shù)了见芹,有興趣的讀者可以自行查閱man手冊獲取更多資料:
-
sshd(8) (關(guān)于
~/.ssh/authorized_keys
的幫助這里有詳解) - sshd_config(5)
- ssh_config(5)