# suEXEC支持
**suEXEC**特性使得Apache可以使用與調用web服務器的用戶**不同**的用戶身份來運行**CGI**和**SSI**程序。而通常情況下,CGI或者SSI程序執行時使用和web服務器相同的用戶身份。
正確運用該特性,可以減少很多因為提供用戶執行私有CGI或者SSI程序所帶來的安全風險。但如果配置不當的話,則可能引起很多問題,使你的計算機產生更多的安全漏洞。如果你對管理 _setuid root_ 程序以及可能導致的安全問題不熟悉的話,我們強烈建議你不要使用suEXEC。
## 開始之前
在我們開始切入正題之前,你必須明白Apache開發組以及本文檔所做的假設。
首先,我們假設你正在使用類UNIX操作系統,只有這類操作系統才具有**setuid**和**setgid**命令。所有的其他命令行的例子也是如此。其他的操作系統平臺,即使也支持suEXEC,但是它的配置可能和我們所講的并不相同。
第二,我們假設你熟悉計算機的安全和管理計算機的一些基本概念。這關系到如何正確理解**setuid/setgid**操作以及對你的系統可能帶來的各種影響和不同的安全等級。
第三,我們假設你正在使用源代碼**未經修改的**suEXEC版本。所有suEXEC的代碼都經過開發者的仔細查驗并做過大量測試。在這些代碼中,人們采取了各種預防措施,使之簡單、健壯、安全。修改這些代碼可能會導致預料之外的問題和安全隱患。所以我們強烈地建議你**不要修改**代碼,除非你精通安全編程,并愿意和Apache開發組共享成果。
第四,也是最后一點,Apache開發組已經決定**默認不安裝**suEXEC。suEXEC的配置需要管理員細致關注各個細節。在仔細考察過關于suEXEC的各種設置方法后,管理員應該使用標準的安裝方法來安裝suEXEC。設置的參數應該經過仔細推敲,以保證系統的安全運行。Apache開發組希望通過限制suEXEC的安裝,僅使那些經過細致理解,并有能力運用它的管理員來使用。
你還想使用suEXEC嗎?還想?很好!那我們開始吧!
## suEXEC的安全模型
在我們開始配置和安裝suEXEC之前,我們需要先討論一下它的安全模型。這樣,你才能更好的理解suEXEC內部究竟做了些什么事情,以及哪些確保系統安全的預防措施。
**suEXEC**是基于一個setuid的"封裝"程序,該程序由"主"Apache web服務器調用。當一個HTTP請求的是管理員指定的、以不同于"主"服務器用戶身份運行的CGI或SSI程序時,該封裝程序將被調用。處理這樣的請求時,Apache將被請求的程序名及其UID和GID提供給suEXEC封裝器。
封裝器(wrapper)通過處理下面所描述的步驟,來決定封裝的成功或失敗:如果有任意一個條件為假,程序將把錯誤情況記錄到日志中,退出并返回錯誤信息。否則繼續執行。(以下所說的"程序"均指"CGI/SSI程序")
1. **用戶使用了合法的系統賬號來執行封裝程序了嗎?**
確保運行封裝器的是一個系統中確實存在的用戶。
2. **封裝器被調用時,使用的參數個數正確嗎?**
封裝器僅在使用了正確數量的參數調用時才會執行。Apache web服務器知道正確的參數格式是什么。如果封裝器沒有收到正確數量的參數,則說明要么被黑客攻擊,要么Apache二進制代碼中suEXEC的部分出了問題。
3. **這個合法的用戶被允許運行封裝器嗎?**
這個用戶是可以運行封裝器的用戶嗎?僅有一個用戶(Apache用戶)被允許運行封裝器。
4. **目標CGI/SSI程序有不安全的分級路徑索引嗎?**
目標CGI/SSI程序包含了"/"開頭或者有".."后向路徑索引嗎?這些都是不允許的;并且目標程序必須位于suEXEC的文檔根目錄下。(參見下面的:`--with-suexec-docroot=_DIR_`)
5. **目標程序的所屬用戶名合法嗎?**
目標程序的所屬用戶名存在嗎?
6. **目標程序的所屬用戶組合法嗎?**
目標程序的所屬用戶組存在嗎?
7. **目標程序的所屬用戶名不是超級用戶嗎?**
目前,suEXEC不允許root執行CGI/SSI程序。
8. **目標程序所屬用戶的UID高于最小UID值嗎?**
最小UID值是在配置中指定的。你可以指定允許執行CGI/SSI程序的最小UID值,這樣可以保證不會和系統賬號沖突。
9. **目標程序的所屬用戶組不是超級用戶組嗎?**
目前,suEXEC不允許root組用戶執行CGI/SSI程序。
10. **目標程序所屬用戶組的GID高于最小GID值嗎?**
最小GID值是在配置中指定的。你可以指定允許執行CGI/SSI程序的最小GID值,這樣可以保證不會和系統賬號沖突。
11. **封裝器能夠成功地變為目標用戶和組嗎?**
這里就是程序變為目標用戶和組的關鍵步驟了。我們是通過調用setuid和setgid來實現的。在組訪問列表中,和該用戶相關的所有組信息都將被初始化。
12. **能夠切換到程序所在的目錄嗎?**
如果不存在,將無法包含程序文件。如果不能切換一般也表示目錄不存在。
13. **這個目錄在Apache的網絡空間中嗎?**
如果是對于服務器的一般請求,那么請求的目錄是在suEXEC的根文檔目錄下嗎?如果請求的是一個用戶目錄,那么該目錄是在suEXEC配置的該用戶的根目錄下嗎?(參見:[suEXEC配置選項](#calibre_link-548))
14. **該目錄不具有其他用戶可寫的權限嗎?**
我們不想把目錄開放給其他人;只有屬主才可以改變該目錄中的內容。
15. **目標CGI/SSI程序存在嗎?**
如果不存在,當然無法繼續運行。
16. **目標CGI/SSI程序不可以被其他用戶改寫嗎?**
我們不想給其他人有修改程序的權限。
17. **目標程序尚未被setuid或者setgid ?**
我們不想要執行的程序被再次改變UID/GID。
18. **目標用戶和組與程序的用戶和組相同嗎?**
用戶是這個文件的屬主嗎?
19. **我們可以成功清除進程的環境變量并保證操作的安全性嗎?**
suEXEC通過建立一個安全的可執行路徑(在配置中定義)來清除該進程的環境變量,同時只傳送在安全環境變量列表(配置中定義)中所列出的環境變量。
20. **可以成功的變為目標程序并執行嗎?**
這里就是suEXEC結束,并開始運行目標程序的地方了。
這是suEXEC封裝器標準操作方式的安全模型。它有些嚴格,并強加了CGI/SSI設計上的限制。但它是仔細考慮過安全之后一步步發展起來的模型。
更多關于該安全模型如何根據服務器的配置來限制使用者的權限,以及恰當的suEXEC安裝步驟能夠避免的安全隱患,請參見[警告和舉例](#calibre_link-579)部分。
## 配置和安裝suEXEC
繼續我們的探險 ...
**suEXEC配置選項**
`--enable-suexec`
該選項啟用默認禁止的suEXEC功能。并同時至少提供一個 `--with-suexec-xxxxx` 選項,以使APACI使用suEXEC功能來處理請求。
`--with-suexec-bin=_PATH_`
出于安全考慮,`suexec`二進制程序的路徑必須用這個選項指定并硬編碼在服務器里。比如:`--with-suexec-bin=/usr/sbin/suexec`
`--with-suexec-caller=_UID_`
Apache運行時所用的[UID](#calibre_link-168)。這是唯一允許執行程序的用戶。
`--with-suexec-userdir=_DIR_`
定義suEXEC允許訪問的用戶宿主目錄下的子目錄。suEXEC將以用戶身份執行這個目錄下的所有可執行程序,所以這些程序必須是"安全程序"。如果使用"簡單的"`UserDir`指令(即不帶"*"),則此處應該被設置為相同的值。當`UserDir`指令所指向的目錄與"passwd"文件所指定的用戶宿主目錄不同時,suEXEC將不會正常工作,其默認值是"public_html"。如果所支持的虛擬主機對每個用戶有不同的`UserDir` ,則應該把他們集中在同一個父目錄下,而用這個參數指向這個父目錄。**如果配置不當,"~userdir"下的cgi請求將無效!**
`--with-suexec-docroot=_DIR_`
定義Apache的`DocumentRoot`。它是除`UserDir`外suEXEC唯一可以使用的目錄。其默認目錄是 `--datadir` 值所指定的帶有"/htdocs"的后綴的目錄,比如:如果配置了"`--datadir=/home/apache`",那么"/home/apache/htdocs"目錄將作為suEXEC處理器的文檔根目錄。
`--with-suexec-uidmin=_UID_`
定義了suEXEC目標用戶的最低UID。對大多數系統,一般是500或100。默認值是100
`--with-suexec-gidmin=_GID_`
定義了suEXEC目標組的最低GID。對大多數系統,是100,默認值也是100。
`--with-suexec-logfile=_FILE_`
它定義了suEXEC用于記錄所做的事情以及發生的錯誤的日志文件名(對審核和排錯很有用),默認文件名是"suexec_log",并位于標準的日志文件目錄中(`--logfiledir`)。
`--with-suexec-safepath=_PATH_`
定義傳給CGI程序的一個安全的PATH環境變量的值。默認值是"/usr/local/bin:/usr/bin:/bin"
**編譯和安裝suEXEC處理器**
若用 `--enable-suexec` 打開了suEXEC功能,那么執行`make`命令時(Apache自帶的)`suexec`二進制文件就會被自動建立。所有組件編譯完畢后執行 `make install` 命令進行安裝時,`suexec`文件將被安裝在 `--sbindir` 選項指定的目錄中,默認為"/usr/local/apache2/sbin/suexec"。
注意,安裝過程需要**root權限**。為了使suEXEC處理器可以設置UID,其所有者必須為`_root_` ,并且文件模式中的執行位必須設置為1(允許執行)。
**設置許可權限**
雖然suEXEC包裝會檢查以確保它的調用者就是`配置選項` `--with-suexec-caller` 所指定的用戶。但是總是存在這樣的可能性:一個系統或者庫在suEXEC執行用戶身份檢查之前調用它,這樣就存在一個可利用的漏洞。通常,避免這種問題的最佳辦法是,使用文件系的統權限來確保只有Apache組用戶運行的程序才能執行suEXEC。
如果你的web-server是按照如下所示進行配置的:
```
User www
Group webgroup
```
并且`suexec`被安裝在"/usr/local/apache2/sbin/suexec"目錄,你應當運行以下命令:
```
chgrp webgroup /usr/local/apache2/bin/suexec
chmod 4750 /usr/local/apache2/bin/suexec
```
這將確保只有Apache組用戶運行的程序才能執行suEXEC。
## 啟用和禁用suEXEC
Apache在啟動過程中,會在 `--sbindir` 選項指定的目錄(默認為:"/usr/local/apache/sbin/suexec")中尋找`suexec`。如果Apache找到了一個正確配置的suEXEC處理器,會在錯誤日志中記錄以下信息:
```
[notice] suEXEC mechanism enabled (wrapper: <var class="calibre40">/path/to/suexec</var>)
```
如果服務器啟動后沒有這個信息,那么很可能是服務器沒找到適當的處理器,或者是這個執行程序沒有安裝_setuid root_。
如果要在Apache服務器運行過程中打開suEXEC功能,則必須停止并重新啟動Apache。用一個簡單的HUP或USR1信號來重新啟動是不夠的。
如果要關閉suEXEC功能,應該刪除`suexec`文件,并停止和重新啟動Apache。
## 使用suEXEC
對CGI程序的請求僅在下述兩種情況下才會調用suEXEC包裝:對一個含`SuexecUserGroup`指令的虛擬主機發起請求,或者該請求由`mod_userdir`模塊處理。
**虛擬主機:**
使用suEXEC處理器的方法之一是在`VirtualHost`定義中使用`SuexecUserGroup`指令。通過設置這個指令來確定不同于主服務器的UID,所有對CGI資源的請求將以`<VirtualHost>`所定義的_User_和_Group_身份執行。如果`<VirtualHost>`中沒有這個指令,則將以主服務器的UID身份執行。
**用戶目錄:**
由`mod_userdir`處理的請求會調用suEXEC處理器以被請求的用戶目錄所屬的UID執行CGI程序。此功能的唯一要求是,此用戶必須有CGI執行權限,并且其腳本符合上述[安全檢查](#calibre_link-581)的要求。參見 `--with-suexec-userdir` [編譯選項](#calibre_link-548)。
## 調試suEXEC
如上所述,suEXEC處理器會在 `--with-suexec-logfile` 選項所指定的日志文件中記錄信息。如果你感覺配置和安裝不正常,可以查看這個日志以及服務器的錯誤日志。
## 謹防Jabberwock:警告和舉例
**注意!**這部分文檔可能還沒有完成。查看最新的修訂版本,請到Apache開發組的[在線文檔](http://httpd.apache.org/docs/2.2/suexec.html)。
以下是有關限制和服務器安裝的幾個注意事項,在提交任何關于suEXEC的"bugs"以前,請仔細閱讀。
* **suEXEC注意事項**
* 層次限制
出于安全和效率考慮,所有suEXEC請求必須被限制在虛擬主機或者用戶目錄的頂層。舉例來說,如果你配置了4個虛擬主機,你必須把所有虛擬主機的文檔根目錄都安置在同一個主Apache目錄中,這樣才能為虛擬主機啟用suEXEC。(例子以后會有的)
* suEXEC的PATH環境變量
改變這個變量的值是危險的,必須確保其中每個路徑都是**可以信任**的目錄。你不會希望誰都可以在你的服務器上安裝特洛伊木馬。
* 改變suEXEC的代碼
重申,如果你不清楚你在干什么就盡量避免,否則會帶來**大麻煩**的。
- Apache HTTP Server Version 2.2 文檔 [最后更新:2006年3月21日]
- 版本說明
- 從1.3升級到2.0
- 從2.0升級到2.2
- Apache 2.2 新特性概述
- Apache 2.0 新特性概述
- The Apache License, Version 2.0
- 參考手冊
- 編譯與安裝
- 啟動Apache
- 停止和重啟
- 配置文件
- 配置段(容器)
- 緩沖指南
- 服務器全局配置
- 日志文件
- 從URL到文件系統的映射
- 安全方面的提示
- 動態共享對象(DSO)支持
- 內容協商
- 自定義錯誤響應
- 地址和端口的綁定(Binding)
- 多路處理模塊
- Apache的環境變量
- Apache處理器的使用
- 過濾器(Filter)
- suEXEC支持
- 性能方面的提示
- URL重寫指南
- Apache虛擬主機文檔
- 基于主機名的虛擬主機
- 基于IP地址的虛擬主機
- 大批量虛擬主機的動態配置
- 虛擬主機示例
- 深入研究虛擬主機的匹配
- 文件描述符限制
- 關于DNS和Apache
- 常見問題
- 經常問到的問題
- Apache的SSL/TLS加密
- SSL/TLS高強度加密:緒論
- SSL/TLS高強度加密:兼容性
- SSL/TLS高強度加密:如何...?
- SSL/TLS Strong Encryption: FAQ
- 如何.../指南
- 認證、授權、訪問控制
- CGI動態頁面
- 服務器端包含入門
- .htaccess文件
- 用戶網站目錄
- 針對特定平臺的說明
- 在Microsoft Windows中使用Apache
- 在Microsoft Windows上編譯Apache
- Using Apache With Novell NetWare
- Running a High-Performance Web Server on HPUX
- The Apache EBCDIC Port
- 服務器和支持程序
- httpd - Apache超文本傳輸協議服務器
- ab - Apache HTTP服務器性能測試工具
- apachectl - Apache HTTP服務器控制接口
- apxs - Apache 擴展工具
- configure - 配置源代碼樹
- dbmmanage - 管理DBM格式的用戶認證文件
- htcacheclean - 清理磁盤緩沖區
- htdbm - 操作DBM密碼數據庫
- htdigest - 管理用于摘要認證的用戶文件
- httxt2dbm - 生成RewriteMap指令使用的dbm文件
- htpasswd - 管理用于基本認證的用戶文件
- logresolve - 解析Apache日志中的IP地址為主機名
- rotatelogs - 滾動Apache日志的管道日志程序
- suexec - 在執行外部程序之前切換用戶
- 其他程序
- 雜項文檔
- 與Apache相關的標準
- Apache模塊
- 描述模塊的術語
- 描述指令的術語
- Apache核心(Core)特性
- Apache MPM 公共指令
- Apache MPM beos
- Apache MPM event
- Apache MPM netware
- Apache MPM os2
- Apache MPM prefork
- Apache MPM winnt
- Apache MPM worker
- Apache模塊 mod_actions
- Apache模塊 mod_alias
- Apache模塊 mod_asis
- Apache模塊 mod_auth_basic
- Apache模塊 mod_auth_digest
- Apache模塊 mod_authn_alias
- Apache模塊 mod_authn_anon
- Apache模塊 mod_authn_dbd
- Apache模塊 mod_authn_dbm
- Apache模塊 mod_authn_default
- Apache模塊 mod_authn_file
- Apache模塊 mod_authnz_ldap
- Apache模塊 mod_authz_dbm
- Apache模塊 mod_authz_default
- Apache模塊 mod_authz_groupfile
- Apache模塊 mod_authz_host
- Apache模塊 mod_authz_owner
- Apache模塊 mod_authz_user
- Apache模塊 mod_autoindex
- Apache模塊 mod_cache
- Apache模塊 mod_cern_meta
- Apache模塊 mod_cgi
- Apache模塊 mod_cgid
- Apache模塊 mod_charset_lite
- Apache模塊 mod_dav
- Apache模塊 mod_dav_fs
- Apache模塊 mod_dav_lock
- Apache模塊 mod_dbd
- Apache模塊 mod_deflate
- Apache模塊 mod_dir
- Apache模塊 mod_disk_cache
- Apache模塊 mod_dumpio
- Apache模塊 mod_echo
- Apache模塊 mod_env
- Apache模塊 mod_example
- Apache模塊 mod_expires
- Apache模塊 mod_ext_filter
- Apache模塊 mod_file_cache
- Apache模塊 mod_filter
- Apache模塊 mod_headers
- Apache模塊 mod_ident
- Apache模塊 mod_imagemap
- Apache模塊 mod_include
- Apache模塊 mod_info
- Apache模塊 mod_isapi
- Apache模塊 mod_ldap
- Apache模塊 mod_log_config
- Apache模塊 mod_log_forensic
- Apache模塊 mod_logio
- Apache模塊 mod_mem_cache
- Apache模塊 mod_mime
- Apache模塊 mod_mime_magic
- Apache模塊 mod_negotiation
- Apache模塊 mod_nw_ssl
- Apache模塊 mod_proxy
- Apache模塊 mod_proxy_ajp
- Apache模塊 mod_proxy_balancer
- Apache模塊 mod_proxy_connect
- Apache模塊 mod_proxy_ftp
- Apache模塊 mod_proxy_http
- Apache模塊 mod_rewrite
- Apache模塊 mod_setenvif
- Apache模塊 mod_so
- Apache模塊 mod_speling
- Apache模塊 mod_ssl
- Apache模塊 mod_status
- Apache模塊 mod_suexec
- Apache模塊 mod_unique_id
- Apache模塊 mod_userdir
- Apache模塊 mod_usertrack
- Apache模塊 mod_version
- Apache模塊 mod_vhost_alias
- Developer Documentation for Apache 2.0
- Apache 1.3 API notes
- Debugging Memory Allocation in APR
- Documenting Apache 2.0
- Apache 2.0 Hook Functions
- Converting Modules from Apache 1.3 to Apache 2.0
- Request Processing in Apache 2.0
- How filters work in Apache 2.0
- Apache 2.0 Thread Safety Issues
- 詞匯和索引
- 詞匯表
- 指令索引
- 指令速查
- 模塊索引
- 站點導航