使用 Apache 在 Linux 上托管 ASP.NET CoreHost ASP.NET Core on Linux with Apache

作者:Shayne BoyerBy Shayne Boyer

使用本指南,了解如何在 CentOS 7 上将 Apache 设置为反向代理服务器,以将 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 extension 和相关模块可创建服务器的反向代理。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“所有下载”页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). 通常可在 var 目录(例如 var/www/helloapp)下找到 Web 应用 。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.

配置代理服务器Configure a proxy server

反向代理是为动态 Web 应用提供服务的常见设置。A reverse proxy is a common setup for serving dynamic web apps. 反向代理终止 HTTP 请求,并将其转发到 ASP.NET 应用。The reverse proxy terminates the HTTP request and forwards it to the ASP.NET app.

代理服务器将客户端请求转发到另一个服务器,而不是自身实现这些请求。A proxy server is one which forwards client requests to another server instead of fulfilling requests itself. 反向代理转发到固定的目标,通常代表任意客户端。A reverse proxy forwards to a fixed destination, typically on behalf of arbitrary clients. 在本指南中,Apache 被配置为反向代理,在 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.

由于请求是通过反向代理转接的,因此使用 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.

在调用 UseAuthentication 或类似的身份验证方案中间件之前,调用 Startup.Configure 中的 UseForwardedHeaders 方法。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])(包括标准 localhost 地址 (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. 如果组织内的其他受信任代理或网络处理 Internet 与 Web 服务器之间的请求,请使用 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 的受信任代理服务器添加到 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 以使用代理服务器和负载均衡器For more information, see 配置 ASP.NET Core 以使用代理服务器和负载均衡器.

安装 ApacheInstall Apache

将 CentOS 包更新为其最新稳定版本:Update CentOS packages to their latest stable versions:

sudo yum update -y

使用单个 yum 命令在 CentOS 上安装 Apache Web 服务器: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. 请求会通过代理从根位置转到 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)中 DefaultTimeoutStopSec 的值。TimeoutStopSec 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:DefaultConnectionConnectionStrings__DefaultConnection 形式设置到服务定义文件中:In 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

在配置了反向代理并通过 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. 检查响应标头,服务器 标头表示 ASP.NET Core 应用由 Kestrel 提供服务: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

由于使用 Kestrel 的 Web 应用是通过 systemd 进行管理的,因此事件和进程将记录到集中日志。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.

如果密钥环存储于内存中,则在应用重启时: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.
  • 无法再解密使用密钥环保护的任何数据。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. 仍可以使用 iptable 管理端口和数据包筛选。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 属性(例如 https://localhost:5001;http://localhost:5000)提供的 URL 。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 命令或开发环境(Visual Studio Code 中的 F5 或 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:

配置反向代理,以便进行安全 (HTTPS) 客户端连接 Configure the reverse proxy for secure (HTTPS) client connections

若要为 Apache 配置 HTTPS,请使用 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). 如果服务器通过设置 nosniff 选项将 Content-Type 标头设置为 text/html,则不管文件内容为何,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 和 Kestrel 上设置和配置 Apache。This example shows how to setup and configure Apache on CentOS 7 and Kestrel on the same instance machine. 为了不出现单一故障点;使用 mod_proxy_balancer 并修改 VirtualHost 可实现在 Apache 代理服务器后方管理 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. “代理” 部分设置了具有两个成员的均衡器配置,以便对 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

使用 httpd 模块中包含的 mod_ratelimit ,客户端的带宽可以限制为: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

如果应用需要的请求标头字段超过代理服务器的默认设置允许的长度(通常为 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