在 Linux 上使用 Apache 裝載 ASP.NET CoreHost ASP.NET Core on Linux with Apache

作者:Shayne BoyerBy Shayne Boyer

使用本指南來了解如何在 CentOS 7 上將 Apache 設定為反向 Proxy 伺服器,以將 HTTP 流量重新導向至在 Kestrel 伺服器上執行的 ASP.NET Core Web 應用程式。Using this guide, learn how to set up Apache as a reverse proxy server on CentOS 7 to redirect HTTP traffic to an ASP.NET Core web app running on Kestrel server. mod_proxy 延伸模組和相關的模組會建立伺服器的反向 Proxy。The mod_proxy extension and related modules create the server's reverse proxy.

必要條件Prerequisites

  • 執行 CentOS 7 的伺服器搭配具有 sudo 權限的標準使用者帳戶。Server running CentOS 7 with a standard user account with sudo privilege.
  • 在伺服器上安裝 .NET Core 執行階段。Install the .NET Core runtime on the server.
    1. 請前往 .NET Core 的 All Downloads (下載區) 頁面。Visit the .NET Core All Downloads page.
    2. 在 [執行階段] 下的清單中選取最新的非預覽執行階段。Select the latest non-preview runtime from the list under Runtime.
    3. 選取並遵循 CentOS/Oracle 的指示。Select and follow the instructions for CentOS/Oracle.
  • 現有的 ASP.NET Core 應用程式。An existing ASP.NET Core app.

跨應用程式發佈與複製Publish and copy over the app

架構相依部署設定應用程式。Configure the app for a framework-dependent deployment.

如果應用程式在本機執行且未設定為進行安全連線 (HTTPS),請採用下列任一方法:If the app is run locally and isn't configured to make secure connections (HTTPS), adopt either of the following approaches:

  • 設定應用程式以處理安全的本機連線。Configure the app to handle secure local connections. 如需詳細資訊,請參閱 HTTPS 組態一節。For more information, see the HTTPS configuration section.
  • Properties/launchSettings.json 檔案中的 applicationUrl 屬性移除 https://localhost:5001 (如果有的話)。Remove https://localhost:5001 (if present) from the applicationUrl property in the Properties/launchSettings.json file.

從開發環境執行 dotnet publish 將應用程式封裝到可在伺服器上執行的目錄 (例如,bin/Release/<target_framework_moniker>/publish):Run dotnet publish from the development environment to package an app into a directory (for example, bin/Release/<target_framework_moniker>/publish) that can run on the server:

dotnet publish --configuration Release

如果您不想在伺服器上維護 .NET Core 執行階段,應用程式也可以發佈為獨立式部署The app can also be published as a self-contained deployment if you prefer not to maintain the .NET Core runtime on the server.

使用整合至組織工作流程的工具 (SCP、SFTP 等等) 將 ASP.NET Core 應用程式複製到伺服器。Copy the ASP.NET Core app to the server using a tool that integrates into the organization's workflow (for example, SCP, SFTP). Web 應用程式通常可在 var 目錄下找到 (例如 var/www/helloapp)。It's common to locate web apps under the var directory (for example, var/www/helloapp).

注意

在生產環境部署案例中,持續整合工作流程會執行發佈應用程式並將資產複製到伺服器的工作。Under a production deployment scenario, a continuous integration workflow does the work of publishing the app and copying the assets to the server.

設定 Proxy 伺服器Configure a proxy server

反向 Proxy 是為動態 Web 應用程式提供服務的常見設定。A reverse proxy is a common setup for serving dynamic web apps. 反向 Proxy 會終止 HTTP 要求,並將它轉送至 ASP.NET 應用程式。The reverse proxy terminates the HTTP request and forwards it to the ASP.NET app.

Proxy 伺服器則是會將用戶端要求轉送至另一部伺服器,而不是自己完成這些要求。A proxy server is one which forwards client requests to another server instead of fulfilling requests itself. 反向 Proxy 會轉送至固定目的地,通常代表任意的用戶端。A reverse proxy forwards to a fixed destination, typically on behalf of arbitrary clients. 在本指南中,是將 Apache 設定成反向 Proxy,且執行所在的伺服器與 Kestrel 為 ASP.NET Core 應用程式提供服務的伺服器相同。In this guide, Apache is configured as the reverse proxy running on the same server that Kestrel is serving the ASP.NET Core app.

由於反向 Proxy 會轉送要求,因此請使用來自 Microsoft.AspNetCore.HttpOverrides 套件的轉送的標頭中介軟體Because requests are forwarded by reverse proxy, use the Forwarded Headers Middleware from the Microsoft.AspNetCore.HttpOverrides package. 此中介軟體會使用 X-Forwarded-Proto 標頭來更新 Request.Scheme,以便讓重新導向 URI 及其他安全性原則正確運作。The middleware updates the Request.Scheme, using the X-Forwarded-Proto header, so that redirect URIs and other security policies work correctly.

任何依賴配置的元件,例如驗證、連結產生、重新導向和地理位置,都必須在叫用轉送的標頭中介軟體後放置。Any component that depends on the scheme, such as authentication, link generation, redirects, and geolocation, must be placed after invoking the Forwarded Headers Middleware. 轉送的標頭中介軟體是一般規則,應該先於診斷和錯誤處理中介軟體以外的其他中介軟體執行。As a general rule, Forwarded Headers Middleware should run before other middleware except diagnostics and error handling middleware. 這種排序可確保依賴轉送標頭資訊的中介軟體可以耗用用於處理的標頭值。This ordering ensures that the middleware relying on forwarded headers information can consume the header values for processing.

請先在 Startup.Configure 中叫用 UseForwardedHeaders 方法,再呼叫 UseAuthentication 或類似的驗證配置中介軟體。Invoke the UseForwardedHeaders method in Startup.Configure before calling UseAuthentication or similar authentication scheme middleware. 請設定中介軟體來轉送 X-Forwarded-ForX-Forwarded-Proto 標頭:Configure the middleware to forward the X-Forwarded-For and X-Forwarded-Proto headers:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

如果未將任何 ForwardedHeadersOptions 指定給中介軟體,則要轉送的預設標頭會是 NoneIf no ForwardedHeadersOptions are specified to the middleware, the default headers to forward are None.

在預設情況下,在回送位址 (127.0.0.0/8, [::1]) 上執行的 Proxy (包括標準的本機位址 (127.0.0.1)) 是受信任的。Proxies running on loopback addresses (127.0.0.0/8, [::1]), including the standard localhost address (127.0.0.1), are trusted by default. 如果組織內有其他受信任的 Proxy 或網路處理網際網路與網頁伺服器之間的要求,請使用 ForwardedHeadersOptions,將其新增至 KnownProxiesKnownNetworks 清單。If other trusted proxies or networks within the organization handle requests between the Internet and the web server, add them to the list of KnownProxies or KnownNetworks with ForwardedHeadersOptions. 下列範例會將 IP 位址 10.0.0.100 的受信任 Proxy 伺服器新增至 Startup.ConfigureServices 中「轉送的標頭中介軟體」的 KnownProxiesThe following example adds a trusted proxy server at IP address 10.0.0.100 to the Forwarded Headers Middleware KnownProxies in Startup.ConfigureServices:

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

如需詳細資訊,請參閱 設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作For more information, see 設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作.

安裝 ApacheInstall Apache

將 CentOS 套件更新至其最新穩定版本:Update CentOS packages to their latest stable versions:

sudo yum update -y

使用單一 yum 命令在 CentOS 上安裝 Apache 網頁伺服器:Install the Apache web server on CentOS with a single yum command:

sudo yum -y install httpd mod_ssl

執行命令之後的範例輸出:Sample output after running the command:

Downloading packages:
httpd-2.4.6-40.el7.centos.4.x86_64.rpm               | 2.7 MB  00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : httpd-2.4.6-40.el7.centos.4.x86_64      1/1 
Verifying  : httpd-2.4.6-40.el7.centos.4.x86_64      1/1 

Installed:
httpd.x86_64 0:2.4.6-40.el7.centos.4

Complete!

注意

在此範例中,輸出會反映 httpd.86_64,因為 CentOS 第 7 版是 64 位元。In this example, the output reflects httpd.86_64 since the CentOS 7 version is 64 bit. 若要確認 Apache 的安裝位置,請從命令提示字元執行 whereis httpdTo verify where Apache is installed, run whereis httpd from a command prompt.

設定 ApacheConfigure Apache

Apache 的組態檔是位於 /etc/httpd/conf.d/ 目錄內。Configuration files for Apache are located within the /etc/httpd/conf.d/ directory. 除了 /etc/httpd/conf.modules.d/ (包含載入模組所需的所有設定檔) 中的模組設定檔之外,任何副檔名為 .conf 的檔案也會依字母順序處理。Any file with the .conf extension is processed in alphabetical order in addition to the module configuration files in /etc/httpd/conf.modules.d/, which contains any configuration files necessary to load modules.

為應用程式建立名為 helloapp.conf 的設定檔:Create a configuration file, named helloapp.conf, for the app:

<VirtualHost *:*>
    RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
    ServerName www.example.com
    ServerAlias *.example.com
    ErrorLog ${APACHE_LOG_DIR}helloapp-error.log
    CustomLog ${APACHE_LOG_DIR}helloapp-access.log common
</VirtualHost>

VirtualHost 區塊可以在伺服器上的一或多個檔案中出現多次。The VirtualHost block can appear multiple times, in one or more files on a server. 在上述設定檔中,Apache 會在連接埠 80 接受公用流量。In the preceding configuration file, Apache accepts public traffic on port 80. 所服務的網域是 www.example.com,而 *.example.com 別名則會解析成同一個網站。The domain www.example.com is being served, and the *.example.com alias resolves to the same website. 如需詳細資訊,請參閱名稱型虛擬主機支援 (英文)。See Name-based virtual host support for more information. 要求會在根目錄透過 Proxy 傳送至位於 127.0.0.1 之伺服器的連接埠 5000。Requests are proxied at the root to port 5000 of the server at 127.0.0.1. 如需進行雙向通訊,則必須要有 ProxyPassProxyPassReverseFor bi-directional communication, ProxyPass and ProxyPassReverse are required. 若要變更 Kestrel 的 IP/連接埠,請參閱 Kestrel:端點組態To change Kestrel's IP/port, see Kestrel: Endpoint configuration.

警告

如果無法在 VirtualHost 區塊中指定適當的 ServerName 指示詞,就會讓應用程式暴露在安全性弱點的風險下。Failure to specify a proper ServerName directive in the VirtualHost block exposes your app to security vulnerabilities. 若您擁有整個父網域 (相對於易受攻擊的 *.com) 的控制權,子網域萬用字元繫結 (例如 *.example.com) 就沒有此安全性風險。Subdomain wildcard binding (for example, *.example.com) doesn't pose this security risk if you control the entire parent domain (as opposed to *.com, which is vulnerable). 如需詳細資訊,請參閱 rfc7230 5.4 節See rfc7230 section-5.4 for more information.

您可以使用 ErrorLogCustomLog 指示詞來依 VirtualHost 設定記錄功能。Logging can be configured per VirtualHost using ErrorLog and CustomLog directives. ErrorLog 是伺服器記錄錯誤的位置,而 CustomLog 則會設定記錄檔的檔案名稱和格式。ErrorLog is the location where the server logs errors, and CustomLog sets the filename and format of log file. 在此案例中,這就是記錄要求資訊的位置。In this case, this is where request information is logged. 每個要求都會有一行。There's one line for each request.

請儲存檔案並測試設定。Save the file and test the configuration. 如果所有項目都通過,回應應該是 Syntax [OK]If everything passes, the response should be Syntax [OK].

sudo service httpd configtest

重新啟動 Apache:Restart Apache:

sudo systemctl restart httpd
sudo systemctl enable httpd

監視應用程式Monitor the app

Apache 現在已設定完成,可將對 http://localhost:80 發出的要求轉送給在位於 http://127.0.0.1:5000 的 Kestrel 上執行的 ASP.NET Core 應用程式。Apache is now setup to forward requests made to http://localhost:80 to the ASP.NET Core app running on Kestrel at http://127.0.0.1:5000. 不過,並未設定 Apache 來管理 Kestrel 處理序。However, Apache isn't set up to manage the Kestrel process. 請使用 systemd 並建立服務檔案,以啟動並監視基礎 Web 應用程式。Use systemd and create a service file to start and monitor the underlying web app. systemd 是 init 系統,提供許多強大的啟動、停止和管理處理程序功能。systemd is an init system that provides many powerful features for starting, stopping, and managing processes.

建立服務檔Create the service file

建立服務定義檔:Create the service definition file:

sudo nano /etc/systemd/system/kestrel-helloapp.service

應用程式的範例服務檔:An example service file for the app:

[Unit]
Description=Example .NET Web API App running on CentOS 7

[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/local/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=apache
Environment=ASPNETCORE_ENVIRONMENT=Production 

[Install]
WantedBy=multi-user.target

如果設定不是使用 apache 這個使用者,就必須先建立使用者並授與適當的檔案擁有權。If the user apache isn't used by the configuration, the user must be created first and given proper ownership of files.

使用 TimeoutStopSec 可設定應用程式收到初始中斷訊號之後等待關閉的時間。Use TimeoutStopSec to configure the duration of time to wait for the app to shut down after it receives the initial interrupt signal. 如果應用程式在此期間後未關閉,則會發出 SIGKILL 來終止應用程式。If the app doesn't shut down in this period, SIGKILL is issued to terminate the app. 提供不具單位的秒值 (例如 150)、時間範圍值 (例如 2min 30s) 或 infinity (表示停用逾時)。Provide the value as unitless seconds (for example, 150), a time span value (for example, 2min 30s), or infinity to disable the timeout. TimeoutStopSec 在管理員設定檔 (systemd-system.confsystem.conf.dsystemd-user.confuser.conf.d) 的預設值為 DefaultTimeoutStopSecTimeoutStopSec defaults to the value of DefaultTimeoutStopSec in the manager configuration file (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). 大多數發行版本的預設逾時為 90 秒。The default timeout for most distributions is 90 seconds.

# The default value is 90 seconds for most distributions.
TimeoutStopSec=90

有些值 (例如 SQL 連接字串) 必須以逸出方式處理,設定提供者才能讀取環境變數。Some values (for example, SQL connection strings) must be escaped for the configuration providers to read the environment variables. 請使用下列命令來產生要在設定檔中使用並已適當逸出的值:Use the following command to generate a properly escaped value for use in the configuration file:

systemd-escape "<value-to-escape>"

環境變數名稱不支援冒號 (:) 分隔符號。Colon (:) separators aren't supported in environment variable names. 請使用雙底線 (__) 來取代冒號。Use a double underscore (__) in place of a colon. 環境變數組態提供者會在將環境變數讀入組態時,將雙底線轉換為冒號。The Environment Variables configuration provider converts double-underscores into colons when environment variables are read into configuration. 在下列範例中,連接字串索引鍵 ConnectionStrings:DefaultConnection 會設定為服務定義檔中的 ConnectionStrings__DefaultConnectionIn the following example, the connection string key ConnectionStrings:DefaultConnection is set into the service definition file as ConnectionStrings__DefaultConnection:

Environment=ConnectionStrings__DefaultConnection={Connection String}

儲存檔案並啟用服務:Save the file and enable the service:

sudo systemctl enable kestrel-helloapp.service

啟動服務並確認它正在執行:Start the service and verify that it's running:

sudo systemctl start kestrel-helloapp.service
sudo systemctl status kestrel-helloapp.service

● kestrel-helloapp.service - Example .NET Web API App running on CentOS 7
    Loaded: loaded (/etc/systemd/system/kestrel-helloapp.service; enabled)
    Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
    CGroup: /system.slice/kestrel-helloapp.service
            └─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll

設定好反向 Proxy 並透過 systemd 管理 Kestrel 之後,Web 應用程式便已完全設定妥當,而從本機電腦瀏覽器透過 http://localhost 即可存取它。With the reverse proxy configured and Kestrel managed through systemd, the web app is fully configured and can be accessed from a browser on the local machine at http://localhost. 檢查回應標頭時,Server 標頭會指出是由 Kestrel 為 ASP.NET Core 應用程式提供服務:Inspecting the response headers, the Server header indicates that the ASP.NET Core app is served by Kestrel:

HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked

檢視記錄View logs

由於是使用 systemd 來管理使用 Kestrel 的 Web 應用程式,因此會將事件和處理序都記錄在集中式日誌中。Since the web app using Kestrel is managed using systemd, events and processes are logged to a centralized journal. 不過,此日誌包含 systemd 所管理全部服務和處理序的項目。However, this journal includes entries for all of the services and processes managed by systemd. 若要檢視 kestrel-helloapp.service 的特定項目,請使用下列命令:To view the kestrel-helloapp.service-specific items, use the following command:

sudo journalctl -fu kestrel-helloapp.service

如需進行時間篩選,請搭配命令指定時間選項。For time filtering, specify time options with the command. 例如,使用 --since today 來針對今天進行篩選,或使用 --until 1 hour ago 來查看前一個小時的項目。For example, use --since today to filter for the current day or --until 1 hour ago to see the previous hour's entries. 如需詳細資訊,請參閱 journalctl 的手冊頁面 (英文)。For more information, see the man page for journalctl.

sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"

資料保護Data protection

ASP.NET Core 資料保護堆疊由數個 ASP.NET Core 中介軟體使用,包括驗證中介軟體 (例如,cookie 中介軟體) 與跨網站偽造要求 (CSRF) 保護。The ASP.NET Core Data Protection stack is used by several ASP.NET Core middlewares, including authentication middleware (for example, cookie middleware) and cross-site request forgery (CSRF) protections. 即使資料保護 API 並非由使用者程式碼呼叫,仍應設定資料保護,以建立持續密碼編譯金鑰存放區Even if Data Protection APIs aren't called by user code, data protection should be configured to create a persistent cryptographic key store. 如不設定資料保護,金鑰會保留在記憶體中,並於應用程式重新啟動時捨棄。If data protection isn't configured, the keys are held in memory and discarded when the app restarts.

如果 Keyring 儲存在記憶體中,則當應用程式重新啟動時:If the key ring is stored in memory when the app restarts:

  • 所有以 Cookie 為基礎的驗證權杖都會失效。All cookie-based authentication tokens are invalidated.
  • 當使用者提出下一個要求時,需要再次登入。Users are required to sign in again on their next request.
  • 所有以 Keyring 保護的資料都無法再解密。Any data protected with the key ring can no longer be decrypted. 這可能會包含 CSRF 權杖ASP.NET Core MVC TempData cookieThis may include CSRF tokens and ASP.NET Core MVC TempData cookies.

若要設定資料保護來保存及加密金鑰環,請參閱:To configure data protection to persist and encrypt the key ring, see:

保護應用程式Secure the app

設定防火牆Configure firewall

Firewalld 是一個可管理防火牆並支援網路區域的動態精靈。Firewalld is a dynamic daemon to manage the firewall with support for network zones. 您仍然可以使用 iptables 來管理連接埠和封包篩選。Ports and packet filtering can still be managed by iptables. 預設應該安裝 FirewalldFirewalld should be installed by default. 您可以使用 yum 來安裝套件或確認是否已安裝套件。yum can be used to install the package or verify it's installed.

sudo yum install firewalld -y

請使用 firewalld 來僅開啟應用程式所需的連接埠。Use firewalld to open only the ports needed for the app. 在此情況下,將使用連接埠 80 和 443。In this case, port 80 and 443 are used. 下列命令會將連接埠 80 和 443 永久設定為開啟:The following commands permanently set ports 80 and 443 to open:

sudo firewall-cmd --add-port=80/tcp --permanent
sudo firewall-cmd --add-port=443/tcp --permanent

重新載入防火牆設定。Reload the firewall settings. 檢查預設區域中可用的服務和連接埠。Check the available services and ports in the default zone. 您可以檢查 firewall-cmd -h 來取得選項。Options are available by inspecting firewall-cmd -h.

sudo firewall-cmd --reload
sudo firewall-cmd --list-all
public (default, active)
interfaces: eth0
sources: 
services: dhcpv6-client
ports: 443/tcp 80/tcp
masquerade: no
forward-ports: 
icmp-blocks: 
rich rules: 

HTTPS 設定HTTPS configuration

設定應用程式以進行安全的本機連線 (HTTPS)Configure the app for secure (HTTPS) local connections

dotnet run 命令使用應用程式的 Properties/launchSettings.json 檔案,其設定應用程式在 applicationUrl 屬性所提供的 URL 上接聽 (例如 https://localhost:5001; http://localhost:5000)。The dotnet run command uses the app's Properties/launchSettings.json file, which configures the app to listen on the URLs provided by the applicationUrl property (for example, https://localhost:5001;http://localhost:5000).

使用下列其中一種方法,設定應用程式將憑證用在針對 dotnet run 命令的開發,或用在開發環境 (F5,若在 Visual Studio Code 中則為 Ctrl+F5):Configure the app to use a certificate in development for the dotnet run command or development environment (F5 or Ctrl+F5 in Visual Studio Code) using one of the following approaches:

設定反向 Prooxy 以進行安全的用戶端連線 (HTTPS)Configure the reverse proxy for secure (HTTPS) client connections

為了設定適用於 HTTPS 的 Apache,會使用 mod_ssl 模組。To configure Apache for HTTPS, the mod_ssl module is used. 安裝 httpd 模組時,已一併安裝 mod_ssl 模組。When the httpd module was installed, the mod_ssl module was also installed. 如果未安裝該模組,請使用 yum 將它新增到設定中。If it wasn't installed, use yum to add it to the configuration.

sudo yum install mod_ssl

若要強制執行 HTTPS,請安裝 mod_rewrite 模組來啟用 URL 重寫:To enforce HTTPS, install the mod_rewrite module to enable URL rewriting:

sudo yum install mod_rewrite

修改 helloapp.conf 檔案以啟用 URL 重寫並保護連接埠 443 上的通訊:Modify the helloapp.conf file to enable URL rewriting and secure communication on port 443:

<VirtualHost *:*>
    RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>

<VirtualHost *:80>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
</VirtualHost>

<VirtualHost *:443>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
    ErrorLog /var/log/httpd/helloapp-error.log
    CustomLog /var/log/httpd/helloapp-access.log common
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
</VirtualHost>

注意

此範例使用本機產生的憑證。This example is using a locally-generated certificate. SSLCertificateFile 應該是網域名稱的主要憑證檔案。SSLCertificateFile should be the primary certificate file for the domain name. SSLCertificateKeyFile 應該是建立 CSR 時產生的金鑰檔。SSLCertificateKeyFile should be the key file generated when CSR is created. SSLCertificateChainFile 應該是憑證授權單位所提供的中繼憑證檔案 (如果有的話)。SSLCertificateChainFile should be the intermediate certificate file (if any) that was supplied by the certificate authority.

儲存檔案並測試設定:Save the file and test the configuration:

sudo service httpd configtest

重新啟動 Apache:Restart Apache:

sudo systemctl restart httpd

Apache 的其他建議Additional Apache suggestions

其他標頭Additional headers

為了防範惡意攻擊,應該要修改或新增一些標頭。In order to secure against malicious attacks, there are a few headers that should either be modified or added. 請確認已安裝 mod_headers 模組:Ensure that the mod_headers module is installed:

sudo yum install mod_headers

保護 Apache 免於點閱綁架攻擊Secure Apache from clickjacking attacks

點閱綁架(也稱為「UI 偽裝攻擊」 ) 是一種惡意攻擊,會誘騙網站訪客點選與其目前所瀏覽頁面不同的頁面上連結或按鈕。Clickjacking, also known as a UI redress attack, is a malicious attack where a website visitor is tricked into clicking a link or button on a different page than they're currently visiting. 請使用 X-FRAME-OPTIONS 來保護網站安全。Use X-FRAME-OPTIONS to secure the site.

減輕點擊劫持攻擊:To mitigate clickjacking attacks:

  1. 編輯 httpd.conf 檔案:Edit the httpd.conf file:

    sudo nano /etc/httpd/conf/httpd.conf
    

    新增 Header append X-FRAME-OPTIONS "SAMEORIGIN" 行。Add the line Header append X-FRAME-OPTIONS "SAMEORIGIN".

  2. 儲存檔案。Save the file.

  3. 重新啟動 Apache。Restart Apache.

MIME 類型探查MIME-type sniffing

X-Content-Type-Options 標頭可防止 Internet Explorer 執行「MIME 探查」 (從檔案的內容判斷檔案的 Content-Type)。The X-Content-Type-Options header prevents Internet Explorer from MIME-sniffing (determining a file's Content-Type from the file's content). 如果伺服器將 Content-Type 標頭設定為 text/html 並搭配設定 nosniff 選項,則不論檔案內容為何,Internet Explorer 都會將該內容轉譯為 text/htmlIf the server sets the Content-Type header to text/html with the nosniff option set, Internet Explorer renders the content as text/html regardless of the file's content.

編輯 httpd.conf 檔案:Edit the httpd.conf file:

sudo nano /etc/httpd/conf/httpd.conf

新增 Header set X-Content-Type-Options "nosniff" 行。Add the line Header set X-Content-Type-Options "nosniff". 儲存檔案。Save the file. 重新啟動 Apache。Restart Apache.

負載平衡Load Balancing

這個範例示範如何在 CentOS 7 上安裝和設定 Apache,以及如何在相同的執行個體電腦上安裝和設定 Kestrel。This example shows how to setup and configure Apache on CentOS 7 and Kestrel on the same instance machine. 為了避免產生單一失敗點的情況,使用 mod_proxy_balancer 並修改 VirtualHost將可允許管理位於 Apache Proxy 伺服器後方的多個 Web 應用程式執行個體。In order to not have a single point of failure; using mod_proxy_balancer and modifying the VirtualHost would allow for managing multiple instances of the web apps behind the Apache proxy server.

sudo yum install mod_proxy_balancer

在以下所示的設定檔中,已將一個額外的 helloapp 執行個體設定在連接埠 5001 上執行。In the configuration file shown below, an additional instance of the helloapp is set up to run on port 5001. Proxy 區段中設定了平衡器設定,其中有兩個成員為 byrequests 進行負載平衡。The Proxy section is set with a balancer configuration with two members to load balance byrequests.

<VirtualHost *:*>
    RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>

<VirtualHost *:80>
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
</VirtualHost>

<VirtualHost *:443>
    ProxyPass / balancer://mycluster/ 

    ProxyPassReverse / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5001/

    <Proxy balancer://mycluster>
        BalancerMember http://127.0.0.1:5000
        BalancerMember http://127.0.0.1:5001 
        ProxySet lbmethod=byrequests
    </Proxy>

    <Location />
        SetHandler balancer
    </Location>
    ErrorLog /var/log/httpd/helloapp-error.log
    CustomLog /var/log/httpd/helloapp-access.log common
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
</VirtualHost>

速率限制Rate Limits

使用 mod_ratelimit (包含在 httpd 模組中) 時,可以限制用戶端的頻寬:Using mod_ratelimit, which is included in the httpd module, the bandwidth of clients can be limited:

sudo nano /etc/httpd/conf.d/ratelimit.conf

此範例檔案將根目錄位置下的頻寬限制為 600 KB/秒:The example file limits bandwidth as 600 KB/sec under the root location:

<IfModule mod_ratelimit.c>
    <Location />
        SetOutputFilter RATE_LIMIT
        SetEnv rate-limit 600
    </Location>
</IfModule>

要求標頭欄位太長Long request header fields

如果應用程式所需的要求標頭欄位長度超過 Proxy 伺服器的預設設定 (通常為 8,190 個位元組),請調整 LimitRequestFieldSize 指示詞的值。If the app requires request header fields longer than permitted by the proxy server's default setting (typically 8,190 bytes), adjust the value of the LimitRequestFieldSize directive. 要套用的值會因案例而異。The value to apply is scenario-dependent. 如需詳細資訊,請參閱您的伺服器文件。For more information, see your server's documentation.

警告

除非必要,否則請勿增加 LimitRequestFieldSize 的預設值。Don't increase the default value of LimitRequestFieldSize unless necessary. 增加此值會提高緩衝區溢位及惡意使用者發動拒絕服務 (DoS) 攻擊的風險。Increasing the value increases the risk of buffer overrun (overflow) and Denial of Service (DoS) attacks by malicious users.

其他資源Additional resources