Nginx 配置教程 – wiki基地


Nginx 配置教程:从入门到精通

Nginx (发音为 “engine-x”) 是一款高性能的 HTTP 和反向代理服务器,同时也是一个通用的 TCP/UDP 代理服务器。自 2004 年首次发布以来,Nginx 因其卓越的性能、稳定性和低资源消耗而迅速流行,成为许多高流量网站和应用的基石。理解 Nginx 的配置方式是发挥其强大功能的第一步。

本文将带您深入了解 Nginx 的配置体系,从基础结构到常见的应用场景,包括静态文件服务、虚拟主机、反向代理、负载均衡以及 SSL/TLS 加密等。无论您是刚接触 Nginx 的新手,还是希望系统性地梳理 Nginx 配置的高级用户,都能从中获益。

第一章:Nginx 配置文件的基础结构

Nginx 的配置中心是一个主配置文件,通常位于 /etc/nginx/nginx.conf (对于基于 Debian/Ubuntu 的系统) 或 /etc/nginx/ 下的其他路径 (对于基于 RHEL/CentOS 的系统)。这个主文件通过 include 指令引入其他配置文件,从而实现配置的模块化和组织性。

一个典型的 nginx.conf 文件的结构如下:

“`nginx

main context (全局块)

影响 Nginx 服务器整体运行的设置

user www-data; # 指定 Nginx 工作进程的运行用户和组
worker_processes auto; # 工作进程数,auto 表示根据 CPU 核数自动设置
error_log /var/log/nginx/error.log warn; # 错误日志路径和级别
pid /var/run/nginx.pid; # Nginx 主进程的 PID 文件路径

events context (事件块)

控制 Nginx 网络连接的各种设置

events {
worker_connections 1024; # 每个工作进程可以同时处理的最大连接数
# use epoll; # Linux 下的高效事件模型,通常无需显式指定,auto 即可
# accept_mutex off; # 是否使用连接互斥锁,高并发下建议 off
}

http context (HTTP块)

配置 HTTP 服务器的大部分功能,包括 Web 服务、反向代理、负载均衡等

http {
# 基本设置
include mime.types; # 包含 MIME 类型映射文件
default_type application/octet-stream; # 默认 MIME 类型

# 日志设置
access_log /var/log/nginx/access.log combined; # 访问日志路径和格式

# 性能优化
sendfile on; # 开启高效文件传输模式
tcp_nopush on; # 在 sendfile 模式下提高文件传输效率
tcp_nodelay on; # 保持连接时,立即发送数据,提高实时性
keepalive_timeout 65; # 客户端连接保持活动的超时时间
types_hash_max_size 2048; # MIME 类型哈希表的最大容量

# Gzip 压缩设置
# gzip on;
# gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

# SSL 设置 (通常在 server 块中更常用)
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;

# 引入其他配置文件
include /etc/nginx/conf.d/*.conf; # 包含 conf.d 目录下所有 .conf 文件
# include /etc/nginx/sites-enabled/*; # 包含 sites-enabled 目录下所有文件 (Ubuntu/Debian 风格)

# server context (服务器块,即虚拟主机)
# 定义一个虚拟主机,处理特定的域名和端口的请求
server {
    listen 80; # 监听端口
    listen [::]:80; # 监听 IPv6 端口
    server_name example.com www.example.com; # 绑定域名

    root /var/www/example.com/html; # 网站根目录

    index index.html index.htm; # 默认索引文件

    # location context (位置块)
    # 定义如何处理匹配特定 URI 的请求
    location / {
        try_files $uri $uri/ =404; # 按顺序查找文件或目录,如果找不到则返回 404
    }

    # location /images/ {
    #     # 处理 /images/ 路径下的请求
    #     # alias /data/images/; # 将 /images/ 映射到文件系统中的 /data/images/
    #     autoindex on; # 允许列出目录内容
    # }

    # location ~ \.php$ {
    #     # 处理所有以 .php 结尾的请求
    #     # pass to a FastCGI process (like PHP-FPM)
    #     # include snippets/fastcgi-php.conf;
    #     # fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    # }

    # ... 可以有多个 location 块
}

# server {
#     # 定义另一个虚拟主机
#     listen 80;
#     server_name another-example.com;
#     root /var/www/another-example.com/html;
#     index index.html;

#     location / {
#         try_files $uri $uri/ =404;
#     }
# }

# upstream context (上游服务器块)
# 定义一组后端服务器,用于负载均衡或反向代理
# upstream backend {
#     server backend1.example.com weight=5; # 后端服务器 1,权重为 5
#     server 192.168.1.1:8080; # 后端服务器 2
#     server unix:/tmp/backend3; # 通过 Unix domain socket 连接后端服务器 3
#     # server backup1.example.com backup; # 备份服务器
#     # server backend4.example.com down; # 暂时禁用该服务器
#
#     # 负载均衡算法
#     # least_conn; # 最少连接数
#     # ip_hash; # 根据客户端 IP 地址散列
#     # random index; # 随机选择 (Nginx Plus)
#     # hash $request_uri consistent; # 一致性哈希 (Nginx Plus)
# }

# ... 可以有多个 upstream 块

}

mail context (邮件代理块,用于配置 POP3/IMAP/SMTP 代理)

mail {

# … mail related configurations

}

stream context (TCP/UDP 代理块)

stream {

# … tcp/udp proxy configurations

}

“`

配置块 (Context) 解释:

  1. main (全局块): 这些指令影响 Nginx 服务器的整体运行,例如工作进程数、错误日志位置、运行用户等。
  2. events (事件块): 配置 Nginx 的连接处理模型和工作进程的最大连接数。这部分设置对 Nginx 的性能至关重要。
  3. http (HTTP 块): 这是配置 HTTP 服务器功能的主要块。几乎所有的与 Web 服务相关的配置都放在这里,包括 MIME 类型、日志、Gzip 压缩、SSL 设置以及虚拟主机 (server) 和上游服务器 (upstream) 定义等。
  4. server (服务器块): 定义一个虚拟主机。一个 http 块可以包含多个 server 块,每个 server 块通常对应一个网站或应用。它通过 listen 指令指定监听的端口和地址,通过 server_name 指令绑定域名。
  5. location (位置块): 定义如何处理特定 URI (统一资源标识符) 的请求。一个 server 块可以包含多个 location 块,Nginx 会根据请求的 URI 匹配最合适的 location 块来执行相应的处理逻辑。
  6. upstream (上游服务器块): 用于定义一组后端服务器,通常用于实现反向代理和负载均衡。

组织配置文件:

为了方便管理,特别是当您有多个网站或应用时,通常会将每个 server 块或相关的配置分离到单独的文件中,然后通过 include 指令在 http 块中引入。

  • conf.d/*.conf 风格:/etc/nginx/conf.d/ 目录下创建以 .conf 结尾的文件,每个文件包含一个或多个 server 块或 upstream 块。主配置文件通过 include /etc/nginx/conf.d/*.conf; 引入它们。这种方式在 CentOS/RHEL 系统中比较常见。
  • sites-available/sites-enabled 风格:/etc/nginx/sites-available/ 目录下创建配置文件,然后在 /etc/nginx/sites-enabled/ 目录下创建指向 /etc/nginx/sites-available/ 中文件的软链接 (symbolic link)。主配置文件通过 include /etc/nginx/sites-enabled/*; 引入这些链接。这种方式在 Debian/Ubuntu 系统中比较常见。要启用一个网站,创建一个软链接;要禁用一个网站,删除软链接即可,原始配置仍然保留在 sites-available 中。

第二章:核心配置指令详解

2.1 全局块 (main)

  • user user [group];: 设置 Nginx 工作进程运行的用户和组。出于安全考虑,建议使用非特权用户 (如 www-data)。
  • worker_processes auto | number;: 设置工作进程数。auto 是推荐值,让 Nginx 根据 CPU 核数自动调整。设置为具体的数字时,通常建议与 CPU 核数相等或为其倍数。
  • error_log file [level];: 设置错误日志的路径和级别。级别从低到高依次是 debug, info, notice, warn, error, crit, alert, emerg。生产环境中常用的级别是 warnerror
  • pid file;: 设置存储 Nginx 主进程 PID 的文件路径。

2.2 事件块 (events)

  • worker_connections number;: 设置每个工作进程可以同时建立的最大连接数。Nginx 的最大连接数 = worker_processes * worker_connections。这个值取决于服务器的硬件资源和操作系统限制 (如文件描述符数量)。
  • use method;: 指定 Nginx 使用的事件驱动模型,如 epoll (Linux)、kqueue (FreeBSD, macOS)、devpoll (Solaris)、poll, select 等。通常 Nginx 会自动选择最优的模型,无需手动设置。

2.3 HTTP 块 (http)

  • include file | mask;: 引入其他配置文件。这对于组织和管理大型配置至关重要。
  • default_type mime-type;: 当 Nginx 无法确定文件的 MIME 类型时使用的默认类型。通常与 include mime.types; 一起使用。
  • access_log file [format];: 设置访问日志的路径和格式。combined 是常用的预定义格式,记录客户端 IP、请求时间、请求方法和 URI、状态码、响应大小、User Agent 等信息。
  • sendfile on | off;: 开启或关闭 sendfile 模式。开启后,Nginx 可以直接通过操作系统内核发送文件,减少 CPU 和内存的开销,显著提高静态文件传输性能。
  • tcp_nopush on | off;: 在 sendfile 开启时,将响应头和文件内容打包一次发送,而不是分开发送,提高网络效率。通常与 sendfile on; 一起使用。
  • tcp_nodelay on | off;: 在 keep-alive 连接下,禁用 Nagle 算法,使小的数据包也能立即发送,降低延迟。对于交互性应用有益。
  • keepalive_timeout timeout [header_timeout];: 设置客户端连接保持活动的超时时间。在这个时间内,同一个连接可以处理多个请求,减少连接建立的开销。
  • gzip on | off;: 开启或关闭 Gzip 压缩。对文本文件进行压缩可以显著减少传输数据量,加快网页加载速度。
  • gzip_types mime-type ...;: 指定哪些 MIME 类型的响应需要进行 Gzip 压缩。
  • gzip_comp_level level;: 设置 Gzip 压缩级别 (1-9),级别越高压缩率越高但 CPU 消耗越大。通常 5-6 是一个不错的平衡点。
  • ssl_protocols protocols;: 设置支持的 SSL/TLS 协议版本,如 TLSv1.2 TLSv1.3。出于安全考虑,应禁用旧版本 (如 SSLv3, TLSv1, TLSv1.1)。
  • ssl_ciphers ciphers;: 设置服务器端支持的加密算法列表。应使用安全强度高的算法,并遵循最新的安全建议。

2.4 服务器块 (server)

  • listen address:port | port [ssl] [http2];: 指定服务器监听的 IP 地址和端口。
    • listen 80;:监听所有网络接口的 80 端口。
    • listen 192.168.1.1:80;:只监听指定 IP 的 80 端口。
    • listen 443 ssl;:监听 443 端口并启用 SSL/TLS。
    • listen 443 ssl http2;:监听 443 端口并启用 SSL/TLS 和 HTTP/2。
    • listen [::]:80;:监听 IPv6 的 80 端口。
  • server_name name ...;: 定义服务器的域名。当 Nginx 收到请求时,会根据请求头中的 Host 字段来匹配 server_name,找到对应的 server 块。
    • server_name example.com www.example.com;:匹配 example.comwww.example.com
    • server_name *.example.com;:匹配 mail.example.com 等子域名。
    • server_name example.*;:匹配 example.com, example.org 等。
    • 如果请求没有匹配任何 server_name,Nginx 会将请求交给该端口上的第一个 server 块处理 (称为 default server)。
  • root path;: 设置网站的根目录。当处理静态文件请求时,Nginx 会将请求的 URI 附加到 root 路径后面,形成完整的文件路径。
  • index file ...;: 定义目录索引文件。当请求的 URI 是一个目录时,Nginx 会在该目录下按顺序查找这些文件作为响应。
  • error_page code ... [uri] | =response;: 定义错误页面。当出现指定的 HTTP 状态码时,Nginx 会返回指定的 URI 或内容。
    • error_page 404 /404.html;:当发生 404 错误时,内部重定向到 /404.html
    • error_page 500 502 503 504 /50x.html;:当发生 500, 502, 503, 504 错误时,内部重定向到 /50x.html
    • error_page 403 = /forbidden.html;:当发生 403 错误时,返回 /forbidden.html 的内容,但响应状态码仍然是 403。
    • error_page 404 =404 /empty;:当发生 404 错误时,内部重定向到 /empty,并强制响应状态码为 404。

2.5 位置块 (location)

location 块是 Nginx 配置中最灵活但也最复杂的部分,它决定了如何处理匹配特定 URI 的请求。location 指令有不同的匹配方式和优先级。

语法:

nginx
location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }

匹配方式和优先级 (从高到低):

  1. location = uri { ... }: 精确匹配。 只有请求的 URI 与 uri 完全相等时才匹配。如果找到精确匹配,则立即停止搜索,使用此 location 块。
  2. location ^~ uri { ... }: 前缀匹配 (优先)。 如果请求的 URI 以指定的 uri 开头,则匹配。如果找到最长的前缀匹配,且使用了 ^~ 修饰符,则停止搜索,使用此 location 块。
  3. location ~ regex { ... }: 正则匹配 (区分大小写)。 如果请求的 URI 与指定的正则表达式 regex 匹配,则匹配。
  4. location ~* regex { ... }: 正则匹配 (不区分大小写)。 如果请求的 URI 与指定的正则表达式 regex (不区分大小写) 匹配,则匹配。
    • 注意: 如果有多个正则匹配 location 块,Nginx 会使用第一个匹配成功的块。
  5. location uri { ... }location /uri/ { ... }: 前缀匹配 (普通)。 如果请求的 URI 以指定的 uri 开头,则匹配。Nginx 会找到所有普通前缀匹配中最长的一个。如果最长的前缀匹配没有使用 ^~ 修饰符,Nginx 会继续检查正则匹配;如果存在正则匹配,则使用第一个匹配成功的正则块,否则使用这个最长的普通前缀匹配块。
  6. location / { ... }: 通用匹配。 这是最广泛的匹配,任何没有被前面规则匹配到的请求都会进入这个块。它通常作为最终的 fallback 配置。

匹配过程总结:

  1. 首先尝试所有精确匹配 (=)。如果找到,立即停止并使用。
  2. 然后检查所有前缀匹配 (^~ 和普通前缀)。
    • 找到最长的普通前缀匹配块。
    • 如果最长前缀匹配块使用了 ^~ 修饰符,则立即停止并使用它。
    • 如果最长前缀匹配块没有使用 ^~ 修饰符,记住这个块,但继续下一步。
  3. 按配置文件中出现的顺序检查所有正则表达式匹配 (~~*)。如果找到第一个匹配的正则块,停止搜索并使用它 (即使前面有更长的普通前缀匹配)。
  4. 如果正则表达式匹配都没有成功,则使用之前记住的那个最长的普通前缀匹配块
  5. 如果所有前面的匹配都失败,则使用通用匹配 (location /)。

location 块中的常用指令:

  • root path;: 在 location 块中设置根目录会覆盖 server 块中的设置。Nginx 将请求 URI 附加到此路径后寻找文件。
  • alias path;: 用于改变 URI 的一部分到文件系统的另一部分。与 root 不同,alias 会替换匹配到的 URI 部分。通常用于 location 块中匹配某个特定路径。注意: 使用 alias 时,指定的路径末尾通常应该带斜杠 /,并且对应的 location 匹配也应该以斜杠结尾。
  • index file ...;: 在 location 块中设置索引文件会覆盖 server 块中的设置。
  • try_files file ... uri;: 按顺序检查文件是否存在。file 可以是文件路径或目录路径 ($uri, $uri/)。如果找到文件,则返回该文件。如果所有文件都没找到,则内部重定向到最后一个参数 uri (可以是另一个 location 块,或者一个状态码如 =404)。
  • return code [text];return code URL;: 立即停止处理请求并返回指定的 HTTP 状态码和可选的文本或重定向 URL。常用于简单的重定向或拒绝请求。
    • return 403;:返回 403 Forbidden 错误。
    • return 301 http://www.new-example.com$request_uri;:永久重定向到新域名。
  • rewrite regex replacement [flag];: 使用正则表达式捕获请求 URI 的一部分,并根据 replacement 规则重写 URI。flag 控制重写后的处理方式:
    • last: 完成当前重写规则后,重新开始查找 location 匹配 (使用新的 URI)。
    • break: 完成当前重写规则后,停止执行当前 location 块中的后续重写规则,并使用重写后的 URI 处理请求 (不再重新查找 location)。
    • redirect: 返回 302 临时重定向。
    • permanent: 返回 301 永久重定向。
    • 注意: rewrite 是一个强大的但可能复杂的工具,能用 try_filesreturn 实现的场景,通常更推荐使用后者,它们性能更高且更易理解。

2.6 上游服务器块 (upstream)

  • upstream name { ... }: 定义一个上游服务器组,name 是组的名称,可以在 proxy_pass 或其他模块中使用。
  • server address [parameters];: 在 upstream 块中定义一个后端服务器的地址。地址可以是 IP 地址、主机名或 Unix domain socket 路径。
    • weight=number: 设置服务器的权重,默认为 1。权重越高,被分配到的请求越多。
    • max_fails=number: 在指定时间内失败达到此次数,Nginx 标记服务器为不可用。默认 1。
    • fail_timeout=time: 服务器被标记为不可用后,经过此时间会再次尝试连接。默认 10 秒。
    • backup: 将服务器标记为备份服务器,只有主服务器都不可用时才会被使用。
    • down: 标记服务器为永久不可用,不会接收任何请求。
  • 负载均衡方法:
    • least_conn;: 将请求发送到连接数最少的服务器。
    • ip_hash;: 根据客户端 IP 地址的哈希值将请求分发到服务器,确保同一客户端的请求发送到同一服务器 (适用于需要会话粘滞的场景)。
    • random [method]; (Nginx Plus): 随机选择服务器。
    • hash key [consistent]; (Nginx Plus): 根据指定的 key (如 $request_uri) 进行哈希分发,可选一致性哈希。
    • 默认方法是 Round Robin (轮询),按顺序将请求分发到服务器,与权重结合使用。

第三章:常见应用场景配置实例

3.1 静态文件服务

最简单的 Nginx 用途是托管静态文件。

“`nginx
server {
listen 80;
server_name static.example.com;

root /var/www/static.example.com/html; # 设置根目录

location / {
    # try_files $uri $uri/ /index.html =404; # 查找文件、目录,如果找不到则返回 index.html,再找不到返回 404
    try_files $uri $uri/ =404; # 查找文件或目录,找不到直接返回 404
    # 开启目录列表 (如果请求 URI 是目录且找不到 index 文件)
    # autoindex on;
}

# 针对特定文件类型的优化
location ~* \.(jpg|jpeg|gif|png|css|js|ico|txt|woff2?|ttf|svg|eot)$ {
    expires 30d; # 设置浏览器缓存过期时间为 30 天
    access_log off; # 不记录静态资源的访问日志,减少磁盘 IO
}

# 拒绝访问隐藏文件
location ~ /\.ht {
    deny all;
}

}
“`

3.2 配置多个网站 (虚拟主机)

通过 server 块和 server_name 指令,可以在同一台 Nginx 服务器上托管多个域名不同的网站。

使用 sites-available/sites-enabled 风格:

  1. /etc/nginx/sites-available/ 创建 site1.conf:

    “`nginx

    /etc/nginx/sites-available/site1.conf

    server {
    listen 80;
    server_name site1.example.com;
    root /var/www/site1.example.com/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
    

    }
    “`

  2. /etc/nginx/sites-available/ 创建 site2.conf:

    “`nginx

    /etc/nginx/sites-available/site2.conf

    server {
    listen 80;
    server_name site2.example.com;
    root /var/www/site2.example.com/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
    

    }
    “`

  3. 启用网站 (创建软链接):

    bash
    sudo ln -s /etc/nginx/sites-available/site1.conf /etc/nginx/sites-enabled/
    sudo ln -s /etc/nginx/sites-available/site2.conf /etc/nginx/sites-enabled/

  4. 检查配置并重载 Nginx:

    bash
    sudo nginx -t
    sudo nginx -s reload

3.3 反向代理

Nginx 作为反向代理,将客户端请求转发到后端应用服务器 (如 Node.js, Python/Django/Flask, Java/Spring Boot 等),并将后端响应返回给客户端。这可以隐藏后端服务器的真实 IP 和端口,同时利用 Nginx 的高性能处理静态文件、SSL 加密、缓存、限流等。

“`nginx

定义后端应用服务器组 (可选,如果只有一个后端可以直接在 location 中指定)

upstream my_backend {

server 127.0.0.1:3000; # Node.js 应用可能运行在 3000 端口

# 或者 server unix:/path/to/your/app.sock; # 通过 Unix domain socket

}

server {
listen 80;
server_name api.example.com;

location / {
    # 将所有请求代理到本地 3000 端口的后端服务
    proxy_pass http://127.0.0.1:3000;
    # 或者 proxy_pass http://my_backend; # 如果使用了 upstream 块

    # 设置重要的请求头,以便后端应用能正确获取客户端信息
    proxy_set_header Host $host; # 保持客户端请求的 Host 头
    proxy_set_header X-Real-IP $remote_addr; # 客户端真实 IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 记录完整的转发链路 IP
    proxy_set_header X-Forwarded-Proto $scheme; # 记录客户端请求协议 (http 或 https)

    # 可选:设置代理连接超时
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;

    # 可选:代理缓存设置
    # proxy_cache my_cache;
    # proxy_cache_valid 200 302 10m; # 缓存 200 和 302 响应 10 分钟
    # proxy_cache_valid 404 1m;     # 缓存 404 响应 1 分钟
}

# 如果应用同时提供静态文件,可以在 Nginx 中直接处理以提高性能
location /static/ {
    alias /path/to/your/app/static_files/;
    expires 30d;
}

}
“`

3.4 负载均衡

当有多个后端服务器时,可以使用 Nginx 的负载均衡功能将流量分发到这些服务器上,提高应用的可用性和性能。

“`nginx

定义上游服务器组

upstream app_servers {
# 默认使用轮询 (Round Robin)
server 192.168.1.100:8080 weight=3; # 服务器 1,权重 3
server 192.168.1.101:8080 weight=1; # 服务器 2,权重 1 (将接收更少请求)
server 192.168.1.102:8080; # 服务器 3,权重 1 (默认)
# server 192.168.1.103:8080 backup; # 备份服务器

# 启用最少连接数算法
# least_conn;

# 启用 IP Hash 算法 (用于会话粘滞)
# ip_hash;

}

server {
listen 80;
server_name myapp.example.com;

location / {
    # 将请求代理到上面定义的 app_servers 组
    proxy_pass http://app_servers;

    # 代理请求头设置 (与反向代理类似)
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # 可选:健康检查 (Nginx Plus 功能,开源版通常需要第三方模块或外部工具)
    # health_check;
}

}
“`

3.5 配置 SSL/TLS (HTTPS)

为网站启用 HTTPS 是现代 Web 开发的基本要求。您需要一个 SSL/TLS 证书 (可以是 Let’s Encrypt 的免费证书,也可以是购买的商业证书) 和对应的私钥文件。

“`nginx
server {
# 强制 HTTP 跳转到 HTTPS (可选)
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri; # 永久重定向
}

server {
listen 443 ssl http2; # 监听 443 端口并启用 SSL 和 HTTP/2
server_name example.com www.example.com;

root /var/www/example.com/html;
index index.html;

# SSL 证书文件路径
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # 您的证书链文件
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # 您的私钥文件

# 安全的 SSL 配置
ssl_protocols TLSv1.2 TLSv1.3; # 仅使用 TLSv1.2 和 TLSv1.3
ssl_prefer_server_ciphers on; # 优先使用服务器端指定的加密算法
# 推荐的加密算法列表 (示例,应参考最新的安全建议)
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256';
ssl_session_cache shared:SSL:10m; # SSL 会话缓存大小
ssl_session_timeout 10m; # SSL 会话超时时间

# 启用 HSTS (HTTP Strict Transport Security),强制浏览器以后只通过 HTTPS 访问
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
# resolver 8.8.8.8 8.8.4.4 valid=300s; # DNS 解析器,用于 OCSP Stapling
# resolver_timeout 5s;

location / {
    try_files $uri $uri/ =404;
}

# Let's Encrypt 证书续期验证路径
location ~ /.well-known/acme-challenge/ {
    allow all;
    root /var/www/certbot; # 指定用于验证的目录,通常由 certbot 工具设置
}

}
“`

3.6 基本认证

使用用户名和密码保护某个路径下的资源。

“`nginx
server {
listen 80;
server_name secure.example.com;

location / {
    # 公开访问的区域
    root /var/www/secure.example.com/public;
    index index.html;
    try_files $uri $uri/ =404;
}

location /admin/ {
    # 需要密码访问的区域
    auth_basic "Restricted Area"; # 认证提示信息
    auth_basic_user_file /etc/nginx/.htpasswd; # 密码文件路径
    root /var/www/secure.example.com/admin;
    index index.html;
    try_files $uri $uri/ =404;
}

}
“`

密码文件 (.htpasswd) 可以使用 htpasswd 工具生成:

“`bash
sudo apt-get update && sudo apt-get install apache2-utils # 安装 htpasswd 工具
sudo htpasswd -c /etc/nginx/.htpasswd admin_user # 创建文件并添加第一个用户 ‘admin_user’

输入并确认密码

sudo htpasswd /etc/nginx/.htpasswd another_user # 添加更多用户 (不用 -c)
“`

3.7 URL 重写与跳转

使用 rewritereturn 指令实现 URL 的重写或浏览器跳转。

“`nginx
server {
listen 80;
server_name old-example.com;

# 将所有来自 old-example.com 的请求永久重定向到 new-example.com
return 301 http://new-example.com$request_uri;

# 或者使用 rewrite
# rewrite ^/(.*)$ http://new-example.com/\ permanent;

}

server {
listen 80;
server_name www.example.com;

# 将所有 www.example.com 的请求永久重定向到 example.com
rewrite ^/(.*)$ http://example.com/\ permanent;

}

server {
listen 80;
server_name example.com;
root /var/www/example.com/html;

location /download/ {
    # 将 /download/some_file 这样的请求重写到 /files/some_file 内部处理
    rewrite ^/download/(.*)$ /files/\ last;
}

location /files/ {
    # 处理重写后的 /files/ 请求
    internal; # internal 指令表示此 location 只能由 Nginx 内部请求访问,不能直接通过浏览器访问
    root /data/; # 假设实际文件放在 /data/ 目录下
    try_files $uri =404;
}

# 简化写法,直接使用 return
location /old-path {
    return 301 /new-path; # 永久重定向 /old-path 到 /new-path
}

}
“`

第四章:配置管理与调试

在修改 Nginx 配置文件后,需要进行检查和重载才能生效。

  1. 检查配置语法:
    bash
    sudo nginx -t

    这个命令会检查配置文件的语法是否正确,并报告文件路径。如果显示 syntax is oktest is successful,则表示配置没有问题。如果有错误,根据提示信息进行修正。

  2. 重载配置:
    bash
    sudo nginx -s reload

    这个命令会平滑地重新加载 Nginx 配置。Nginx 主进程会读取新的配置文件,启动新的工作进程,并优雅地关闭旧的工作进程,不中断现有连接。

  3. 启动 Nginx:
    bash
    sudo systemctl start nginx # 对于使用 systemd 的系统 (如较新的 CentOS/Ubuntu)
    # 或者 sudo service nginx start # 对于使用 SysVinit 的系统

  4. 停止 Nginx:
    bash
    sudo nginx -s stop # 快速关闭,可能中断连接
    # 或者 sudo nginx -s quit # 优雅关闭,等待当前请求处理完毕
    # 或者 sudo systemctl stop nginx # 使用服务管理工具

  5. 重启 Nginx:
    bash
    sudo systemctl restart nginx # 使用服务管理工具 (相当于 stop 后再 start)

日志文件:

Nginx 的错误日志 (error_log) 和访问日志 (access_log) 对于调试和监控至关重要。它们通常位于 /var/log/nginx/ 目录下。查看日志文件可以帮助您了解请求的处理过程、发现错误以及分析流量模式。

  • 查看实时访问日志:tail -f /var/log/nginx/access.log
  • 查看实时错误日志:tail -f /var/log/nginx/error.log

如果遇到问题,首先检查错误日志,通常能找到问题的根源。

第五章:最佳实践和注意事项

  • 模块化配置: 利用 include 指令将不同的功能 (如虚拟主机、upstream 定义、SSL 设置等) 分离到单独的文件中,保持主配置文件的整洁,易于管理。
  • 使用版本控制: 将 Nginx 配置文件存储在版本控制系统 (如 Git) 中,方便追踪修改历史、回滚错误配置以及团队协作。
  • 谨慎使用 rewrite: 尽量使用 returntry_files 代替 rewrite 来实现简单的重定向或文件查找,它们更高效且易于理解。复杂的 URL 重写才考虑使用 rewrite
  • 优化静态文件服务: 开启 sendfiletcp_nopush,为静态资源设置合适的 expires 缓存头。
  • 安全加固 SSL/TLS: 仅使用最新的 TLS 协议版本,使用安全的加密算法列表,并考虑启用 HSTS 和 OCSP Stapling。定期检查 SSL 配置的安全性 (例如使用 SSL Labs’ SSL Server Test)。
  • 配置合理的超时时间: 根据后端应用的响应速度设置合适的 keepalive_timeoutproxy_*_timeout,避免连接过早关闭或等待过久。
  • 限制请求体大小: 使用 client_max_body_size 指令限制客户端上传文件的大小,防止恶意攻击或资源耗尽。
  • 隐藏 Nginx 版本信息:http 块中添加 server_tokens off; 指令可以阻止 Nginx 在响应头中暴露其版本信息,提高安全性。
  • 理解 rootalias 的区别: 它们在 location 块中的行为不同。root 将整个 URI 附加到根目录后,而 alias 替换匹配的 URI 部分。
  • 测试配置: 在重载 Nginx 之前,务必使用 nginx -t 命令检查配置语法。

总结

Nginx 的配置体系强大且灵活,通过模块化的指令和分层级的配置块,可以实现各种复杂的应用场景。本文从基础的文件结构和核心指令讲起,逐步深入到静态文件服务、虚拟主机、反向代理、负载均衡和 SSL/TLS 配置等常见应用。掌握这些基础知识和实践经验,将使您能够高效地配置和管理 Nginx 服务器,为您的 Web 应用提供高性能和高可用性。

Nginx 的官方文档是学习和查找详细指令信息的最佳资源。随着您对 Nginx 的深入使用,建议您随时查阅官方文档,了解更多高级特性和最新的配置建议。通过不断实践和调整,您将能够充分发挥 Nginx 的潜力,构建健壮、高效的网络服务。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部