如何在 Linux 上將 SSH 使用者存取限制在主目錄中?

你可以透過結合檔案系統規則與嚴格的帳號隔離機制來強化 Linux 環境的安全性。你可以設定 SSH 使用者存取策略,將使用者限制在單一主目錄內。系統管理員通常會實施 chroot 監獄,以阻止使用者橫向遍歷伺服器上的敏感目錄與系統路徑。
你還必須對父層目錄實施嚴格的 POSIX 權限控制,以防止未經授權的檔案瀏覽。要實現有效的目錄隔離,在編輯設定檔之前需要滿足三個明確前提條件:你需要擁有主機伺服器的 root 權限、系統中正在執行的 OpenSSH 守護行程,以及一個用於測試的標準帳號。這些基礎管理條件能夠幫助你安全地完成安全設定部署,避免把自己鎖在遠端系統之外。
設定 SSH Chroot Jail 環境
你可以設定 SSH 選項,將帳號隔離在安全的 chroot 監獄中。系統管理員透過將使用者限制到指定目錄,來阻止其未經授權地遍歷關鍵系統路徑。
在 sshd_config 中套用 SSH Chroot 指令
當你為目標帳號建立 chroot 監獄設定時,需要編輯 /etc/ssh/sshd_config。OpenSSH 會根據單一帳號或群組定義來評估參數。下表重點呈現不同比對條件在實際運作上的差異:
| 觀察項目 | 使用 Match User 搭配 ChrootDirectory | 額外加入 Match Group 指令 |
|---|---|---|
| 設定重新處理 | 使用者會被正常解析;除錯日誌中會顯示有效使用者名稱,例如 user test matched group list ...。 | 群組比對會在使用者名稱為空的情況下嘗試執行,因此產生 Can't match group ... because user does not exist。 |
| ChrootDirectory 行為 | ChrootDirectory 會被可靠地套用,例如套用到 C:\,而且 SFTP 工作階段會被正確限制在監獄內。 | 由於在使用者被完整重新解析之前,設定重新處理已失敗,ChrootDirectory 無法被穩定套用。 |
| 連線結果 | SFTP 工作階段成功;pwd 與目錄清單功能皆可正常運作。 | 會間歇性出現 Permission denied 或 client_loop: send disconnect: Connection reset;失敗表現可能會因嘗試次數而異。 |
你可以將以下指令追加到 /etc/ssh/sshd_config 檔案末尾,以強制實施工作階段隔離:
Subsystem sftp internal-sftp
Match Group sftpgroup
ChrootDirectory /sftp/%u
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no設定 Chroot 目錄擁有權
嚴格的擁有權規則支配著 Linux 上的每一個隔離環境。OpenSSH 會在授予存取權限之前驗證所有父層目錄:
sshd 會驗證 chroot 路徑中的每一層目錄都歸 root 所有,且不能被任何其他使用者或群組寫入。驗證完成後,它會 chroot 到該目錄,然後再切換到使用者的主目錄。
你應依照順序執行部署步驟,以安全地建立並設定 SSH 使用者存取:
- 使用
groupadd sftpgroup建立一個專用群組。 - 使用
mkdir /sftp建立 chroot 根目錄,然後透過chown root:root /sftp設定擁有者,並透過chmod 755 /sftp設定權限。 - 執行
useradd -g sftpgroup -s /sbin/nologin sftpuser建立一個沒有 shell 存取權限的帳號,然後使用passwd sftpuser設定密碼。 - 在該隔離環境中建立上傳目錄,執行
mkdir /sftp/sftpuser/upload,然後設定存取屬性:chown root:root /sftp/sftpuser與chmod 777 /sftp/sftpuser/upload。 - 使用
systemctl restart sshd.service重新啟動守護行程。
在設定過程中管理帳號時,你必須執行精確的命令順序:
- 在初始建立帳號時執行
useradd,以指派基礎屬性。 - 使用
usermod -d /sftp/sftpuser/upload sftpuser修改現有目錄路徑。 - 套用
usermod -s /sbin/nologin sftpuser來停用互動式 shell 存取。 - 執行
usermod -aG sftpgroup sftpuser將現有使用者加入該群組。 - 必須保持父層目錄歸 root 所有,否則 chroot 過程將完全失敗。
這種常見的 chroot jail 設定可以將檔案傳輸限制在監獄環境內,同時阻止檔案系統導覽越界。如果你使用金鑰驗證,請設定 AuthorizedKeysFile /home/%u/.ssh/authorized_keys,因為金鑰驗證發生在進入 chroot 環境之前。在監獄中提供一個可寫入目錄,可以在維持監獄安全的同時允許檔案上傳與傳輸。
透過 POSIX 權限限制使用者存取
預設的 Linux 設定通常會允許非 root 帳號查看共用系統路徑下的目錄名稱。非特權帳號可能在未經授權的情況下列出父層路徑中的內容。你必須調整系統設定,才能徹底限制使用者存取。限制使用者存取,是保護機密資料安全的重要手段。
系統管理員會修改 POSIX 規則,以保護主要主目錄路徑的安全。你可以透過設定嚴格的存取權限,防止使用者越權瀏覽其他使用者目錄。
強化父層 Home 目錄存取控制
標準 Linux 安裝通常允許帳號查看共用父層路徑下的目錄結構。你可以透過修改主系統層級的目錄存取控制,來保護這些位置。
管理員會使用明確的命令選項來控制目錄進入與檔案清單操作:
chmod 750 /home:授予擁有者完整控制權限,授予群組成員讀取和執行權限,而對其他帳號不授予任何權限。chmod 711 /home:為所有帳號授予執行權限,使使用者可以穿越/home進行路徑存取,但無法查看其目錄清單內容。
這些設定能夠阻止非特權帳號枚舉主機的目錄結構,同時保留合法帳號所需的正常路徑遍歷能力。
保護使用者主目錄權限
在保護主要父層目錄之後,你還必須鎖定單一使用者目錄的權限設定。對使用者主目錄設定 chmod 700,代表只給目錄擁有者授予讀取、寫入與執行權限。此模式會阻止群組成員和其他外部帳號查看私人檔案。
OpenSSH 會在實際驗證過程中檢查檔案系統安全性。如果目標帳號目錄權限過於寬鬆,遠端 SSH 服務可能會拒絕連線。
| 模式 | 擁有者 | 群組 | 其他人 | 安全意涵 |
|---|---|---|---|---|
| 700 | 讀取、寫入、執行 | 無 | 無 | 將存取權限完全鎖定給目標使用者本人。 |
| 755 | 讀取、寫入、執行 | 讀取、執行 | 讀取、執行 | 允許外部帳號讀取該主目錄中的檔案。 |
你可以透過直接對每個使用者的主目錄套用 700 模式,在整台主機上維持強而有力的帳號隔離。
實施受限 Shell 與命令控制
除了基礎系統設定之外,你還可以部署受限 shell 來進一步限制使用者。受限 shell 能鎖定執行權限,並阻止帳號離開指定位置。
設定 Restricted Bash Shell 環境
系統管理員會使用受限 shell 來阻止 SSH 工作階段中未經授權的命令執行。你首先需要確認系統中存在 rbash。如果系統缺少預設二進位檔,你可以從 /usr/bin/bash 建立一個指向 /usr/bin/rbash 的符號連結。
接下來,你可以建立一個新帳號,或更新現有使用者設定。你可在建立帳號時使用 useradd -s /usr/bin/rbash newuser 指定 rbash 作為登入 shell。你也可以使用 usermod -s /usr/bin/rbash targetuser 來修改現有目標帳號。無論何時需要更新 shell 指派,你都可以再次執行 usermod。如果你在遷移帳號,也可以呼叫 usermod 來調整設定檔。系統管理員會透過執行 usermod 來維護所有受管理帳號的 shell 邊界。
在自訂命令路徑中限制可執行檔
你需要實施路徑隔離,以防止執行未經授權的二進位檔。你可以在使用者主目錄中建立一個由 root 擁有的目錄,例如 /home/targetuser/.bin,作為安全命令的專用目錄。然後只將被核准的命令連結到該目錄中,例如 ls、su 和 clear。
在使用者設定檔 .bashrc 中,你需要定義 PATH=$HOME/.bin 並設定 umask 077。你還應將檔案擁有權改為 root:targetuser,這樣帳號本人就無法修改啟動腳本。
下表總結了受限 shell 內建強制執行的安全保護機制:
| rbash 限制 | 它所阻止的行為 | 實際表現證據 |
|---|---|---|
cd 被停用 | 變更目前工作目錄 | cd /tmp 會因 “restricted” 錯誤而失敗 |
exec、set、unset 被阻止 | 修改 shell 環境及啟動新 shell 工作階段 | exec bash 會因 “restricted” 錯誤而失敗 |
| 重新導向被停用 | 透過 >、<、>> 寫入或讀取檔案 | echo "Test" > test.txt 會被拒絕 |
包含 / 的路徑名稱被拒絕 | 透過絕對/相對路徑在 PATH 之外啟動命令 | 嘗試執行 /bin/ls 會因 “restricted” 錯誤被拒絕 |
PATH 被設定為特定使用者的 bin | 執行允許清單之外的任意命令 | 只能執行像 hello.sh 這樣的白名單腳本 |
| SSH 一次性命令 | 不受 rbash 互動模式限制的阻止 | 註解指出 ssh some_host any_command 仍然可用 |
使用受限 shell 可以阻止使用者啟動未核准程式、執行目錄切換,或修改關鍵環境變數。
驗證使用者隔離與存取限制
測試 SFTP 與 Shell 邊界控制
在更新伺服器設定後,你需要透過實際的 SFTP 測試來驗證 chroot jail 參數是否生效。這項測試能夠確認遠端帳號是否被鎖定在指定邊界位置內。你可以開啟終端機,透過 SSH 執行 sftp user@host 來測試檔案傳輸限制。伺服器會在登入後立即實施目錄限制。在 /etc/ssh/sshd_config 中設定 ForceCommand internal-sftp,可以將工作階段能力完全限制為檔案管理。你可以藉由這些嚴格規則,將使用者存取限制在指定系統範圍之內。
接下來,你還要評估互動式工作階段限制。透過執行 ssh user@host 啟動一個工作階段來測試系統安全性。受限 shell 會阻止改變工作位置的命令。像 pwd、echo 和 history 這樣的 shell 內建命令仍能成功執行,因為它們由 bash 在內部處理。然而,當你鎖定使用者主目錄路徑後,像 ls、date 或 uname 這樣的外部二進位命令將完全失敗。一個設定正確的受限 shell 會拒絕執行越界二進位檔,也會阻止使用者變更環境路徑。正確的 chroot jail 設定則能持續維持帳號隔離。
驗證 SSH 使用者存取與目錄遍歷限制
你可以透過直接測試目錄導覽控制來驗證 SSH 使用者存取限制。請按照以下步驟檢查你的 chroot jail 實作:
- 以受限使用者身分登入:
ssh jailuser@localhost。 - 在遠端 shell 中切換到表面上的根目錄:
cd /。 - 使用
ls檢視目錄;應當只能看到監獄內部內容,而不是真實檔案系統。 - 嘗試透過
cd ..向上移動;工作階段應仍停留在/,這證明目錄遍歷已被阻止。 - 在稽核日誌中驗證 chroot 是否已啟用:
sudo grep -i chroot /var/log/auth.log。
這套結構化測試流程能夠確認系統邊界是否有效限制了遠端工作階段中的使用者存取。
測試可以確保你的 chroot jail 設定真正隔離帳號,而不會出現意外的存取洩漏。
你可以透過執行實際測試命令來驗證隔離環境。執行 ssh user@host 建立新的遠端工作階段。接著執行 pwd,並嘗試使用 cd .. 進行目錄導覽。活動中的工作階段應將你的路徑鎖定在目標目錄結構內部。你必須定期對 Linux 主機上的目錄權限進行安全稽核,以防止權限回退並持續維護存取控制安全。
你還應監控系統日誌,以盡早發現未授權存取嘗試。檢查 /var/log/auth.log,或在伺服器上執行 journalctl -u ssh。這些系統日誌會顯示登入驗證詳情,並立即記錄失敗的目錄遍歷事件。持續檢查日誌,能夠長期維持伺服器環境中的帳號邊界控制效果。
常見問題
為什麼在 chroot jail 上設定錯誤權限會導致 SSH 失敗?
OpenSSH 會強制執行嚴格的安全標準。在啟動 chroot jail 之前,路徑中的每一層父目錄都必須歸 root 所有。群組寫入權限會破壞這些安全檢查。因此,你的連線會失敗,或者環境初始化會被跳過。
如何在不提供 shell 存取的情況下將帳號限制在 jail 中?
你可以將帳號的 shell 設定為 /sbin/nologin。然後在設定檔中指定 ForceCommand internal-sftp。這項設定會將遠端檔案傳輸限制在指定 jail 內部。
帳號能否在 Linux 環境中逃離其主目錄?
不能,受限 shell 會阻止像 cd 這樣的導覽內建命令。系統會拒絕路徑修改以及允許路徑之外的命令執行。使用者無法逃離其目標目錄,也不能修改系統變數。
哪些權限設定可以阻止使用者查看其他人的主目錄?
你可以對每個個人目錄套用 chmod 700。這個命令僅向目錄擁有者授予完整存取權限。此外,你還可以對 /home 設定 chmod 750,以阻止非特權帳號讀取父層路徑內容。
如何確認 chroot 已隔離 SSH 工作階段?
你可以透過 SSH 建立一個工作階段來測試邊界限制。執行 cd .. 檢查目錄遍歷是否被阻止。活動中的工作階段會將你的路徑鎖定在第二層 jail 內部,同時系統日誌會確認 chroot 已正確啟用。
