本專欄文章持續更新,新增內容使用藍色表示。
往期相關內容
【Linux】權限管理詳解(三):SELinux安全性管理 | Redhat-CSDN博客
【Linux】網絡安全管理:Netfilter、nftables 與 Firewalld | Redhat_linux netfilter-CSDN博客
補充內容
SELinux 策略通過標記網絡端口嚴格過濾網絡流量,例如, 22/TCP 端口具有 ssh_port_t 標簽;HTTP 端口 80/TCP 和 443/TCP 具有 http_port_t 標簽。當某個進程希望偵聽端口時,SELinux 將檢查進程標簽和端口標簽是否對應。
補充:標準端口和非標準端口。標準端口是Linux內部定義好的,比如 TCP 22,SSH 82,HTTP 80,HTTP 443,MySQL 3306等等。但是生產上一般不適用標準端口,所以需要添加非標準端口。
?端口標簽管理
操作 | 命令格式 |
---|---|
添加端口標簽 | semanage port -a -t <類型> -p <協議> <端口號> |
修改端口標簽 | semanage port -m -t <類型> -p <協議> <端口號> |
刪除端口標簽 | semanage port -d -p <協議> <端口號> |
查詢所有端口 | semanage port -l |
查詢特定端口 | semanage port -l | grep <端口號> |
查看自定義修改 | semanage [對象類型] -l -C |
參數解釋:
-
-a?:?Add,添加
-
-m?:?Modify,修改
-
-d?:?Delete,刪除
-
-l?:?List,列出
-
-t ?:?Type,指定 SELinux?類型?(如?http_port_t,?ssh_port_t)
-
-p?:?Protocol,指定協議?(tcp?或?udp)
示例:
# 允許 Apache(httpd) 監聽 TCP 8080 端口
semanage port -a -t http_port_t -p tcp 8080# 將 TCP 2222 端口改為?ssh?服務類型
semanage port -m -t ssh_port_t -p tcp 2222# 刪除 TCP 8080 端口的 SELinux 標簽
semanage port -d -p tcp 8080# 列出所有端口標簽,并可配合 grep 過濾
semanage port -l | grep http# 查詢指定端口被標記為何種類型
semanage port -l | grep 8080# 列出用戶自定義的端口策略修改
semanage port -l -C
【實驗】Web 服務器非標準配置訪問
1. 環境準備
操作系統:RHEL 8 或 9,或者社區分支 CentOS Stream / Rocky Linux / AlmaLinux。
軟件:Apache HTTP Server (httpd)、firewalld、policycoreutils-python-utils(提供 semanage 命令)。
預設狀態:SELinux 處于 Enforcing 模式,防火墻開啟。
2. 實驗場景與任務
你作為系統管理員,需要部署一個新的靜態網站。出于安全和管理考慮,你決定:
將網站文件放在非默認目錄 /srv/webapp/ 下,而不是默認的 /var/www/html/。
注:推薦使用目錄 /home/用戶名/webapp 完成實驗,后續步驟中的 /srv/webapp/ 都替換為 /home/用戶名/webapp 即可,原因在【解決 SELinux 端口問題】處有解釋。
讓 Apache 監聽在非標準端口 8088?上,而不是默認的 80 端口。
任務是完成配置,并確保外部用戶可以通過瀏覽器訪問 http://<服務器IP>:8088。
3. 實驗步驟
3.1 基礎準備與環境搭建
注意:以下命令均以 root 用戶身份運行。
3.1.1 安裝 Apache Web 服務器
dnf install httpd -y
3.1.2 創建非默認網站目錄和測試頁面
mkdir /srv/webapp/
# 使用 echo 或 vim 創建簡單測試頁面
echo "Hello from My WebApp on Port 8080!" > /srv/webapp/index.html
此時嘗試本機訪問訪問會失敗(連接被拒絕)。
curl http://localhost:8088
3.2 配置 Apache
3.2.1 編輯 Apache 主配置文件
vim /etc/httpd/conf/httpd.conf
1)找到 Listen 將后面的端口從默認的 80,改為 8088。
Listen 8088
2)找到 DocumentRoot "/var/www/html"? 和與之對應的 <Directory "/var/www/html"> 塊,改為目標目錄。
DocumentRoot "/srv/webapp"<Directory "/srv/webapp">...
</Directory>
3.2.2 啟動并啟用 Apache 服務
此時檢查 httpd 狀態,發現未啟用,嘗試啟動并啟用 Apache 服務。
systemctl status httpd
systemctl enable httpdsystemctl start httpd # 會失敗
此時 start 不能成功:
根據提示使用命令 journalctl -xeu httpd.service 查看日志信息,從錯誤提示中可以發現?Apache(httpd 進程)沒有被 SELinux 允許綁定到 8088 端口,所以未能成功開啟,所以等到解決完SELinux的端口問題之后,再嘗試啟動。
3.3 解決防火墻問題
3.3.1 檢查防火墻放行規則
firewall-cmd --list-all
發現不存在 8088?端口。
3.3.2 放行 TCP 8088端口
firewall-cmd --permanent --add-port=8088/tcp
firewall-cmd --reload
# 驗證端口是否已添加
firewall-cmd --list-all
3.4 解決 SELinux 問題
3.4.1 檢查 SELinux 端口策略
semanage port -l | grep http
發現沒有 8080 端口。
3.4.2 添加端口 8080 到 HTTP 端口列表中
semanage port -a -t http_port_t -p tcp 8088
# 再次驗證
semanage port -l | grep http
再次嘗試啟動?httpd,可以成功。
systemctl start httpd
systemctl status httpd
再次在本機上嘗試,雖然有內容("Test Page for the HTTP Server on ......"),但是不是設置的文件內容("Hello from My WebApp on Port 8080!")。
curl http://localhost:8088
這是因為被默認測試頁攔截了,禁用一下即可:
# 重命名該文件使其失效
mv /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.bak# 然后重啟 Apache
systemctl restart httpd
再次訪問,結果為設置的測試頁面,只不過狀態碼是 403 禁止訪問,權限不足。
3.4.3 檢查目錄的 SELinux 上下文
比較默認目錄和目標目錄上下文區別。
ls -ldZ /var/www/html/
ls -ldZ /srv/webapp/
發現 /var/www/html/ 的上下文包含 httpd_sys_content_t,而 /srv/mywebapp/ 的上下文是var_t。
3.4.4 修正網站目錄的 SELinux 上下文
打標簽正常是使用以下方式:
semanage fcontext -a -t httpd_sys_content_t " /home/用戶名/webapp/(/.*)?"
但是由于根 (/) 目錄下的某些路徑有其默認的、受保護的 SELinux 上下文策略,所以此種方式有時會失敗或無效。
此處采用?semanage fcontext 的 -e (equal) 選項,讓 /srv/mywebapp 及其所有子文件和子目錄,都使用與 /var/www 完全相同的 SELinux 上下文類型規則。
# 給 /srv/mywebapp 目錄及其內容打上正確標簽
semanage fcontext -a -e /var/www /srv/webapp# 應用這條策略規則
restorecon -Rv /srv/webapp/# 驗證上下文是否已更改
ls -ldZ /srv/webapp/
?再次在本機上嘗試,結果成功。
curl http://localhost:8088
另一臺主機通過瀏覽器訪問 http://<IP>:8080,也同樣成功。
實驗結束。
如有問題或建議,歡迎在評論區中留言~