Apache HTTP 伺服器 - Arch Linux 中文维基

跳至內容

# Apache HTTP 伺服器

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 Apache HTTP Server，最近一次同步於 2017-12-04，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- PHP
- MySQL
- PhpMyAdmin
- Adminer
- XAMPP
- mod_perl

LAMP是指在許多web 伺服器上使用的一個軟體組合：Linux,Apache,MySQL/MariaDB以及PHP。

Apache HTTP 伺服器，簡稱 Apache，是非常流行的Web伺服器軟體。通常和腳本語言比如 PHP，資料庫 MySQL 一起工作，合稱為 LAMP 棧(Linux, Apache, MySQL, PHP). 本文介紹。本文檔描述了怎樣安裝設置 Apache 網頁伺服器。以及選擇安裝 PHP和 MySQL 併集成到Apache伺服器中。

## 安裝

安裝軟體包 apache包.

## 配置

Apache 配置文件位於 `/etc/httpd/conf`，主要的配置文件是 `/etc/httpd/conf/httpd.conf`, 此文件會引用其它文件。

用默認配置可以啟動一個簡單的服務，有用戶訪問時會提供目錄 `/srv/http` 下的內容。

啟動 `httpd.service` systemd 服務，Apache 就會啟動，從瀏覽器中訪問 http://localhost/ 會顯示一個簡單的索引頁面。

### 高級選項

請參考 Apache 完整 directives 配置選項和 directive 快速參考.

請關注一下 `/etc/httpd/conf/httpd.conf` 中的下面選項:

    User http

  出於安全原因，Apache以root用戶身份啟動(直接的或者通過啟動腳本)後將立即切換為 `/etc/httpd/conf/httpd.conf`中指定的 UID，默認配置是 http, 安裝時會自動創建此用戶。

    Listen 80

  Apache 監聽的埠，要被外網訪問，請在路由器開放此埠。
  如果是本地調試用，可以用下面命令設置為僅供本地訪問 `Listen 127.0.0.1:80`.

    ServerAdmin you@example.com

  管理員的電子郵件，在錯誤頁面會展示給用戶。

    DocumentRoot "/srv/http"

  網頁的目錄.
  如果需要可以修改這個目錄，請記得同步修改 `<Directory "/srv/http">` 和`DocumentRoot`,否則訪問新位置時可能出現 403 Error (缺少權限)問題。不要忘記修改 `Require all denied` 行到 `Require all granted`，否則會出現 403 Error. DocumentRoot 目錄及其父目錄必須有可執行權限，這樣再能被伺服器進程使用的用戶訪問到(用 `chmod o+x /path/to/DocumentRoot` 設置)，否則會出現 403 Error.

    AllowOverride None

  在 `<Directory>` 段落中的這個設置會讓 Apache 完全忽略 `.htaccess` 文件。從 Apache 2.4，這個設置以及是默認的，所以如果要使用 `.htaccess`，請允許Overide. 如果要在 `.htaccess` 中使用 `mod_rewrite` 或其它設置, 可以指定哪些目錄允許覆蓋伺服器配置。更多信息請訪問 Apache 文檔.

提示：可以用 `apachectl configtest` 檢查配置文件是否存在問題。

更多設置可以訪問 `/etc/httpd/conf/extra/httpd-default.conf`，例如

關閉伺服器簽名:

    ServerSignature Off

隱藏 Apache 和 PHP 版本等屬性:

    ServerTokens Prod

### 用戶目錄

在默認設置下，可以通過 http://localhost/~yourusername/ 訪問用戶的主目錄並顯示 `~/public_html` 中的內容 (可以通過 `/etc/httpd/conf/extra/httpd-userdir.conf` 設置). 要禁用這個訪問，請注釋掉 `/etc/httpd/conf/httpd.conf` 文件中的如下行：

    Include conf/extra/httpd-userdir.conf

本文或本章節的事實準確性存在爭議。

原因： It is not necessary to set `+x` for every users, setting it only for the webserver via ACLs suffices (see Access Control Lists#Granting execution permissions for private files to a Web Server).（在 Talk:Apache HTTP 伺服器 中討論）

請正確設置目錄的權限，使得 Apache 可以訪問到文件。主目錄和 `~/public_html` 必須是可被其它用戶執行:

    $ chmod o+x ~
    $ chmod o+x ~/public_html
    $ chmod -R o+r ~/public_html

重啟 `httpd.service` 服務以應用更改。參考 Umask#Set the mask value.

### TLS/SSL

警告：如果計劃使用 SSL/TLS，請注意某些版本和實現 依然 有安全漏洞. 訪問 https://disablessl3.com/ 和 https://weakdh.org/sysadmin.html 可以查看當前的安全漏洞和伺服器處理方式。

OpenSSL 提供了 TLS/SSL 支持，默認已經安裝在 Arch 中。

在 `/etc/httpd/conf/httpd.conf` 中，取消下面行的注釋:

    LoadModule ssl_module modules/mod_ssl.so
    LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
    Include conf/extra/httpd-ssl.conf

TLS/SSL 需要密鑰和認證，如果你有公開域名，可以使用 Let's Encrypt 免費獲取認證，如果沒有，請參考 #創建密鑰並自簽名.

獲取密鑰和認證之後，請將 `/etc/httpd/conf/extra/httpd-ssl.conf` 中的 `SSLCertificateFile` 和 `SSLCertificateKeyFile` 指向對應的文件。如果還生成了 CA 認證鏈，請將文件名設置到 `SSLCertificateChainFile`.

重啟 `httpd.service`.

提示：Mozilla 的 SSL/TLS 文章 包含了 Apache 相關 配置的指南和一個 自動生成工具，可以有助於創建更安全的配置。

#### 創建密鑰並自簽名

創建一個私鑰並自己簽名認證，對於不需要 CSR 的大部分使用來說已經足夠:

    # cd /etc/httpd/conf
    # openssl req -new -x509 -nodes -newkey rsa:4096 -keyout server.key -out server.crt -days 1095
    # chmod 400 server.key

注意：-days 參數是可選的，RSA 密鑰大小最低是 2048 (default).

如果需要創建 CSR，用下面的密鑰創建方:

    # openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out server.key
    # chmod 400 server.key
    # openssl req -new -sha256 -key server.key -out server.csr
    # openssl x509 -req -days 1095 -in server.csr -signkey server.key -out server.crt

注意：openssl 手冊 和 opnssl 文檔 包含了更多信息。

### Virtual Hosts

注意：You will need to add a separate <VirtualHost *:443> section for virtual host SSL support. See #管理多個主機 for an example file.

如果需要不止一個主機，取消 `/etc/httpd/conf/httpd.conf`行的注釋:

    Include conf/extra/httpd-vhosts.conf

在 `/etc/httpd/conf/extra/httpd-vhosts.conf` 中設置虛擬主機，默認文件包含了一個示例。

要在本地機器測試虛擬主機，將虛擬名稱加入 `/etc/hosts` 文件:

    127.0.0.1 domainname1.dom
    127.0.0.1 domainname2.dom

重啟 `httpd.service` 服務。

#### 管理多個主機

如果要管理的主機非常多，希望更方便的維護，建議為每一個虛擬主機創建一個配置文件並文件存儲到一個文件夾中 `/etc/httpd/conf/vhosts`。

創建目錄：

    # mkdir /etc/httpd/conf/vhosts

編寫單獨的配置文件:

    # nano /etc/httpd/conf/vhosts/domainname1.dom
    # nano /etc/httpd/conf/vhosts/domainname2.dom
    ...

在 `/etc/httpd/conf/httpd.conf` 中 `Include` 單獨的配置文件:

    #Enabled Vhosts:
    Include conf/vhosts/domainname1.dom
    Include conf/vhosts/domainname2.dom

通過注釋或取消注釋可以單獨啟用或禁用一個虛擬主機。

基本的 vhost 文件：

    /etc/httpd/conf/vhosts/domainname1.dom

    <VirtualHost *:80>
        ServerAdmin webmaster@domainname1.dom
        DocumentRoot "/home/user/http/domainname1.dom"
        ServerName domainname1.dom
        ServerAlias domainname1.dom
        ErrorLog "/var/log/httpd/domainname1.dom-error_log"
        CustomLog "/var/log/httpd/domainname1.dom-access_log" common

        <Directory "/home/user/http/domainname1.dom">
            Require all granted
        </Directory>
    </VirtualHost>

    <VirtualHost *:443>
        ServerAdmin webmaster@domainname1.dom
        DocumentRoot "/home/user/http/domainname1.dom"
        ServerName domainname1.dom:443
        ServerAlias domainname1.dom:443
        SSLEngine on
        SSLCertificateFile "/etc/httpd/conf/apache.crt"
        SSLCertificateKeyFile "/etc/httpd/conf/apache.key"
        ErrorLog "/var/log/httpd/domainname1.dom-error_log"
        CustomLog "/var/log/httpd/domainname1.dom-access_log" common

        <Directory "/home/user/http/domainname1.dom">
            Require all granted
        </Directory>
    </VirtualHost>

## 擴展

### PHP

首先，參考 PHP 頁面，完成 PHP 的安裝。

有多種方式可以在 Apache 下使用 PHP，#使用 libphp 最簡單，但是擴展性最差，libphp 還需要修改 mpm 模塊，可能影響其它擴展，比如和 #HTTP2 不兼容。

#### 使用 libphp

安裝軟體包 php-apache包。

php-apache包 中包含的 `libphp7.so` 不支持 `mod_mpm_event`，僅支持 `mod_mpm_prefork`(FS#39218)。需要在 `/etc/httpd/conf/httpd.conf` 中注釋掉:

    #LoadModule mpm_event_module modules/mod_mpm_event.so

取消下面行的注釋:

    LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

不然將發生下面的錯誤:

    Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe.  You need to recompile PHP.
    AH00013: Pre-configuration failed
    httpd.service: control process exited, code=exited status=1

另外在本小節的下方還有兩種處理高並發的方案供選擇． 　 ( 使用php-fpm管理進程和使用mod_fcgid管理進程)

要啟用 PHP，在 `/etc/httpd/conf/httpd.conf` 中添加如下行：

- 將這一行放在`LoadModule` 的末尾：

     LoadModule php_module modules/libphp.so
     AddHandler php-script php

- 將這一行放到`Include`列表的末尾：

     Include conf/extra/php_module.conf

重啟 `httpd.service`。

#### 使用 php-fpm 和 mod_proxy_fcgi

這種方式是使用php-fpm來管理進程的，進程不是由apache啟動和管理的．

注意：與使用ProxyPass的廣泛設置不同，使用SetHandler的代理配置遵守Apache指令，例如DirectoryIndex。 這是為了確保與為libphp7、mod_fastcgi和mod_fcgid而設計的軟體有更好的兼容性。 如果您仍然想嘗試使用ProxyPass，請嘗試使用如下所示的行：

    ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/srv/http/$1

安裝官方軟體包 php-fpm包 .

啟用代理模塊:

    /etc/httpd/conf/httpd.conf

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

創建文件： `/etc/httpd/conf/extra/php-fpm.conf` 寫入以下內容:

    /etc/httpd/conf/extra/php-fpm.conf

    DirectoryIndex index.php index.html
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
    </FilesMatch>

把以下這句添加到配置文件 `/etc/httpd/conf/httpd.conf` 中 include 部份的最後

    Include conf/extra/php-fpm.conf

注意：在 `sock` 和 `fcgi` 中間的管道符兩邊不要有空格! `localhost` 可以替換成任何的字符串. 詳細請見 here

你可以自行配置 PHP-FPM 通過這個編輯這個配置文件 `/etc/php/php-fpm.d/www.conf`, 但是默認的配置已經工作的很好了.

重啟 `httpd.service` 和 `php-fpm.service`這兩個服務.

注意：如果之前在 `httpd.conf` 加入了下面內容，請刪除它們，已經不再需要：

    LoadModule php7_module modules/libphp7.so
    Include conf/extra/php7_module.conf

#### 使用 apache2-mpm-worker 和 mod_fcgid

這種方式和上一種方式(php-fpm)的區別：

       php-fgi进程是由apache模块启动并管理，而不需要配置和使用php-fpm来管理进程。
       在php-cgi进程以apache用户身份运行，php程序写的文件，其权限为apache用户（而不像php-fpm下写文件为php-fpm用户所有，默认是nobody），这样在目录权限管理方面一致性高些。

安裝軟體包 mod_fcgidAUR(詳情)和 php-cgi包。

創建需要的目錄並建立軟連結:

    # mkdir /srv/http/fcgid-bin
    # ln -s /usr/bin/php-cgi /srv/http/fcgid-bin/php-fcgid-wrapper

創建 `/etc/httpd/conf/extra/php-fcgid.conf`，內容是:

    /etc/httpd/conf/extra/php-fcgid.conf

    # Required modules: fcgid_module

    <IfModule fcgid_module>
        AddHandler php-fcgid .php
        AddType application/x-httpd-php .php
        Action php-fcgid /fcgid-bin/php-fcgid-wrapper
        ScriptAlias /fcgid-bin/ /srv/http/fcgid-bin/
        SocketPath /var/run/httpd/fcgidsock
        SharememPath /var/run/httpd/fcgid_shm
            # If you don't allow bigger requests many applications may fail (such as WordPress login)
            FcgidMaxRequestLen 536870912
            # Path to php.ini – defaults to /etc/phpX/cgi
            DefaultInitEnv PHPRC=/etc/php/
            # Number of PHP childs that will be launched. Leave undefined to let PHP decide.
            #DefaultInitEnv PHP_FCGI_CHILDREN 3
            # Maximum requests before a process is stopped and a new one is launched
            #DefaultInitEnv PHP_FCGI_MAX_REQUESTS 5000
        <Location /fcgid-bin/>
            SetHandler fcgid-script
            Options +ExecCGI
        </Location>
    </IfModule>

編輯 `/etc/httpd/conf/httpd.conf`，啟用 actions 模塊：

    LoadModule actions_module modules/mod_actions.so

並添加如下配置:

    LoadModule fcgid_module modules/mod_fcgid.so
    Include conf/extra/httpd-mpm.conf
    Include conf/extra/php-fcgid.conf

Restart `httpd.service`.

#### 測試 PHP

在 apache 文檔根目錄（即`/srv/http/`或`~public_html`）中創建test.php文件，在其中寫入：

    <?php phpinfo(); ?>

然後訪問： http://localhost/test.php 或者 http://localhost/~myname/test.php

高級的配置和擴展，請設置 PHP.

### HTTP2

要啟用 http2，安裝 libnghttp2包 軟體包(屬於core倉庫,一般默認已經安裝)。然後取消 `httpd.conf` 中下面行前的注釋:

    LoadModule http2_module modules/mod_http2.so

並加入:

    Protocols h2 http/1.1

更多信息請參考 mod_http2 文檔。

## 問題處理

### Apache 的狀態和日誌

狀態信息可以用 systemctl 查詢。

Apache 默認的系統日誌位於 `/var/log/httpd/`。

### 啟動後出現 Error: PID file /run/httpd/httpd.pid not readable

在 `httpd.conf` 中注釋掉 `unique_id_module` 行：

    #LoadModule unique_id_module modules/mod_unique_id.so

### AH00534: httpd: Configuration error: No MPM loaded.

最近的升級需要修改 `httpd.conf` 配置文件，取消下面行前的注釋：

    /etc/httpd/conf/httpd.conf

    LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

### AH00072: make_sock: could not bind to address

多種都可能導致此問題，最常見的問題是已經有程序監聽了設置的埠，通過下面命令確認：

    # netstat -lnp | grep -e :80 -e :443

如該能查到結果，關閉占用埠的程序，然後重試。

還有一個原因是 Apache 沒有以 root 執行，運行下面命令看看問題是否依然發生：

    # httpd -k start

最後，可能配置有問題，導致程序同時監聽了埠兩次，例如下面的配置就有這個問題：

    Listen 0.0.0.0:80
    Listen [::]:80

### php.ini 中的 max_execution_time 設置無效

`php.ini` 中的 `max_execution_time` 設置為大於 30 (秒), 還會受到 `503 Service Unavailable` 的話，還需要添加 `ProxyTimeout` 到 `<FilesMatch \.php$>` 段落之前:

    /etc/httpd/conf/httpd.conf

    ProxyTimeout 300

重啟 `httpd.service`.

## 參閱

- Apache 官方網站
- Apache wiki
- 生成ssh_test_certificate的教程
- Apache故障排除Wiki

分類：​

- 網絡伺服器

隱藏分類：​

- 使用「模板:準確性」標記的頁面或章節

Apache HTTP 伺服器
新增話題