安全

加固您的 Web 服务器:Nginx 与 Apache 安全指南

在 Apache 上配置 VirtualHost 或在 Nginx 上配置 Server 块时,有多项安全选项值得考虑。本文介绍配置 HTTPS、升级到 HTTP/2、隐藏服务器版本信息、设置 HTTP 安全响应头、禁用无用的 HTTP 方法,以及启用拒绝服务防护。

· 5 分钟阅读 · 难度 中级
Illustration 1 — Fortifier votre Serveur Web : Guide de Sécurité pour Nginx et Apache

在 Apache 上配置 VirtualHost 或在 Nginx 上配置 Server 块(这是两种最常用的 Web 服务器)时,有多项安全选项值得您考虑。

下面列出其中一部分,不过具体细节取决于您所使用的 Web 服务器类型以及您应用特有的安全需求。

目录

使用 Certbot 配置 HTTPS

升级到 HTTP/2 和 HTTP/3 版本

禁用发送版本信息

配置 HTTP 安全响应头

禁用无用的 HTTP 方法

启用拒绝服务防护

配置 HTTPS

这是第一步,也是最重要的一步。HTTPS 对客户端与服务器之间的流量进行加密,使其更难被拦截和读取。为此您需要一份 SSL 证书,它可以通过 Let's Encrypt 免费获取,也可以向各种提供商购买。一旦拥有证书,您就可以配置服务器来使用它。

请务必把 "exemple.com" 和 "www.exemple.com" 替换为您自己的域名。

< w/ Nginx >

下面介绍如何在基于 Debian 的 Linux 系统(如 Ubuntu)上为 Nginx 安装 Certbot 并获取 SSL 证书:

运行以下命令安装 Certbot 软件和 Nginx 插件:


sudo apt-get install certbot python3-certbot-nginx

然后,使用 Certbot 获取 SSL 证书并配置 Nginx:


sudo certbot --nginx -d exemple.com -d www.exemple.com

请按照屏幕上的说明操作。Certbot 会自动修改 Nginx 的配置以应用 SSL 证书。

< w/ Apache >

下面介绍如何在基于 Debian 的 Linux 系统(如 Ubuntu)上为 Apache 安装 Certbot 并获取 SSL 证书:

运行以下命令安装 Certbot 软件和 Apache 插件:


sudo apt-get install certbot python3-certbot-apache

然后,使用 Certbot 获取 SSL 证书并配置 Apache:


sudo certbot --apache -d exemple.com -d www.exemple.com

请按照屏幕上的说明操作。Certbot 会自动修改 Apache 的配置以使用 SSL 证书。

Certbot 还会尝试在证书过期之前自动续期。您可以使用以下命令测试自动续期流程:


sudo certbot renew --dry-run

启用 HTTP 第 2 版

HTTP/2 是 HTTP 协议的第二个主要版本,相比 HTTP/1.1 在性能方面带来了许多改进,尤其得益于请求多路复用,它允许在单条连接上并行发送多个请求。

< w/ Nginx >

要在 Nginx 中启用 HTTP/2,您只需在服务器配置的 listen 指令中添加 http2 参数即可。

打开您站点的 Nginx 配置文件。它通常位于 /etc/nginx/ 或 /etc/nginx/sites-available/ 中。

为 SSL 连接的 listen 指令添加 http2,如下所示:


server {
    listen 443 ssl http2;
    ...
}

< w/ Apache>

对于 Apache,启用 HTTP/2 需要使用 mod_http2 模块。

请确保已启用 mod_http2 模块。您可以运行以下命令来启用它:


sudo a2enmod http2

然后,打开您 Apache 站点的配置文件。它通常位于 /etc/apache2/sites-available/ 目录中。

添加 Protocols 指令以启用 HTTP/2:


<VirtualHost *:443>
    Protocols h2 http/1.1
    ...
</VirtualHost>

这将为您的网站启用 HTTP/2。请注意,HTTP/2 通常与 HTTPS 一起使用,因此请确保您的网站已用它加以保护。


禁用服务器版本信息

默认情况下,您的服务器可能会通过 HTTP 响应头在响应中包含版本信息,这可能帮助攻击者识别潜在的漏洞。虽然这在调试时可能有用,但也可能向潜在攻击者提供有价值的信息。例如,如果您的服务器使用了已知存在安全漏洞的软件版本,攻击者就可能利用这些漏洞来攻击您的服务器。

因此,最好禁用这些版本信息。方法如下:

< w/ Nginx >

在 Nginx 中,您可以修改位于 /etc/nginx/nginx.conf 的基本配置,并使用 server_tokens 指令来控制是否发送服务器版本信息。

修改默认配置文件:


sudo nano /etc/nginx/nginx.conf

然后,取消注释以下这一行(删除 #),如果它存在的话,否则就添加它。


server_tokens off;

server_tokens off; 告诉 Nginx 不要在 HTTP 响应头中包含版本信息。

如果您不希望该指令全局生效,也可以把它放在 Nginx 配置文件的某个 server 块中。

< w/ Apache >

在 Apache 的基本配置中,您需要修改主配置文件。该文件的确切名称和位置可能因您的操作系统和安装方式而异,但它通常名为 apache2.conf 或 httpd.conf,一般位于诸如 /etc/apache2/ 或 /etc/httpd/ 之类的目录中。

修改默认配置文件:


sudo nano /etc/apache2/apache2.conf

查找 ServerTokens 和 ServerSignature 指令,并按如下方式修改或添加它们:


ServerTokens Prod
ServerSignature Off

ServerTokens Prod 告诉 Apache 只返回产品名称(即 "Apache")而不带任何版本信息。ServerSignature Off 则禁止在服务器生成的错误页面中包含服务器版本信息。

这些指令可以放在配置文件根部的任何位置,只要在任何 <VirtualHost> 或 <Directory> 块之外即可。


配置 HTTP 安全响应头

有多个 HTTP 响应头可以提升您网站的安全性,例如 X-Content-Type-Options: nosniff(它阻止浏览器「猜测」内容类型)和 Content-Security-Policy(它限制内容可以从何处加载)。

< w/ Nginx >

在 Nginx 中,可以在配置文件(通常位于 /etc/nginx/nginx.conf 或 /etc/nginx/sites-available/default)的 server 或 location 块内部,使用 add_header 指令来添加安全响应头。

例如:


server {
    ...
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    add_header Content-Security-Policy "default-src 'self'";
    ...
}

< w/ Apache >

在 Apache 中,您可以使用 mod_headers 模块来添加安全响应头。您可以把它们添加到 Apache 配置文件(通常位于 /etc/apache2/sites-available/000-default.conf 或 /etc/httpd/conf/httpd.conf)的 Directory、Location 或 Files 块内部。

例如:


<Directory /var/www/html>
    ...
    Header always set X-Frame-Options "SAMEORIGIN"
    Header set X-XSS-Protection "1; mode=block"
    Header set X-Content-Type-Options "nosniff"
    Header set Content-Security-Policy "default-src 'self'"
    ...
</Directory>

添加这些指令后,别忘了重启或重新加载您的 Web 服务器,以使更改生效。

无论是 Nginx 还是 Apache,这些响应头指令的含义都相同。

说明:

  • X-Frame-Options: SAMEORIGIN:阻止您的网站被嵌入 iframe 中,这有助于防范「点击劫持」攻击。SAMEORIGIN 表示页面只能在与页面本身同源的框架中显示。
  • X-XSS-Protection: 1; mode=block:该响应头启用 Web 浏览器内置的跨站脚本(XSS)过滤器。在 block 模式下,若检测到攻击,它会阻止页面渲染。
  • X-Content-Type-Options: nosniff:阻止浏览器进行所谓的「MIME 类型嗅探」,也就是尝试猜测响应的 MIME 类型。如果 MIME 类型无效,浏览器不应尝试猜测,而应直接拒绝该数据。
  • Content-Security-Policy: default-src 'self':该响应头用于控制浏览器被允许为某个页面加载哪些资源。使用 default-src 'self' 时,您只允许来自同一域名的来源。

禁用无用的 HTTP 方法

当您使用浏览器访问网站时,它会向服务器发送所谓的 HTTP 请求。该请求可以是不同的类型,即「方法」。最常见的两种方法是 "GET"(用于请求数据,如网页)和 "POST"(用于发送数据,例如当您填写表单时)。

然而,还有其他 HTTP 方法,例如 "PUT"、"DELETE"、"OPTIONS" 等。在许多情况下,网站并不需要所有这些方法,其中一些如果未加以正确控制,可能带来安全风险。

禁用无用的 HTTP 方法,意味着告诉服务器不接受您不需要的类型的请求。这减少了攻击者可以借以造成破坏的途径。

< w/ Nginx >

在 Nginx 中,您可以使用 limit_except 指令来限制允许的方法。

例如:


location / {
    limit_except GET POST {
        deny all;
    }
}

这表示只允许 GET 和 POST 请求,所有其他方法都将被拒绝。

< w/ Apache >

在 Apache 中,您可以使用 Allow 和 Order 指令来控制允许的方法。

例如:


<Directory "/var/www/html">
    AllowOverride None
    Order allow,deny
    Allow from all
    <LimitExcept GET POST>
        Deny from all
    </LimitExcept>
</Directory>

与 Nginx 示例类似,这只允许 GET 和 POST 请求,并拒绝其他方法。

禁用您无意使用的 HTTP 方法是一种良好实践,因为这减少了潜在的攻击面。


启用拒绝服务防护

为了保护您的网站免受拒绝服务攻击,您可以限制请求速率(rate limiting)。这可以限制客户端在一定时间内能够发出的请求数量。

Web 服务器通常提供一些选项来限制并发连接数、连接时长、请求大小等,这些都有助于防范拒绝服务攻击。

以下是在 Nginx 和 Apache 中的操作方法:

< w/ Nginx >

在 Nginx 中,您可以使用 ngx_http_limit_req_module 模块来限制请求速率。

例如:


http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

    server {
        ...
        location /login.html {
            limit_req zone=one;
            ...
        }
        ...
    }
}

在此示例中,limit_req_zone 定义了一个名为 "one" 的内存区域,用于存储客户端的 IP 地址,并把请求速率限制为每秒 10 次。limit_req 把该限制应用于特定的 location,突发速率(burst rate)为 20 且没有任何延迟。

< w/ Apache >

在 Apache 中,您可以使用 mod_ratelimit 模块来限制传输速率,或使用 mod_evasive 模块来获得更全面的拒绝服务防护。

以下是一个使用 mod_ratelimit 的配置示例:


<VirtualHost *:80>
    ...
    <Location "/login.html">
        SetOutputFilter RATE_LIMIT
        SetEnv rate-limit 500
    </Location>
    ...
</VirtualHost>

在此示例中,SetOutputFilter RATE_LIMIT 为指定的 location 启用速率过滤,SetEnv rate-limit 500 把速率限制为每秒 500 字节。

要使用 mod_evasive,您需要先安装它,因为 Apache 默认不包含它。


sudo apt-get install libapache2-mod-evasive

安装后,您可以通过在配置中添加类似如下内容来启用和配置它:


<IfModule mod_evasive20.c>
    DOSHashTableSize    3097
    DOSPageCount        2
    DOSSiteCount        50
    DOSPageInterval     1
    DOSSiteInterval     1
    DOSBlockingPeriod   10
</IfModule>

这设置了若干参数,例如在一定时间间隔内每个页面和每个站点允许的请求数量,以及当客户端超过这些限制时被封锁的时长。


启用内容隔离:您可以配置服务器为每个请求使用独立的进程或线程,这样在单个请求被攻破时可以限制潜在的损害。

  1. 限制请求速率(Rate Limiting):为了防范暴力破解或 DDoS 攻击,限制客户端在一定时间内能够发出的请求数量可能会有帮助。
  2. 部署 Web 应用防火墙(WAF):这是另一层安全防护,可以帮助保护您的应用免受常见攻击,例如 SQL 代码注入。
  3. 使用身份验证:如果您的网站包含不应公开访问的部分,请务必使用某种形式的身份验证。Apache 为此提供了多个模块,例如 mod_auth_basic 或 mod_auth_digest。