# 17.2 Nginx Web 服务器

Nginx（发音为“engine X”）是一个采用事件驱动异步架构的高性能 Web 服务器和反向代理服务器，其设计理念聚焦于高并发连接处理能力和低资源消耗，通过多进程单线程的工作模式实现了卓越的性能表现。

本节介绍在 FreeBSD 平台上部署和配置 Nginx Web 服务器的完整流程。

## 安装 Nginx

使用 pkg 包管理器安装 Nginx：

```sh
# pkg install nginx
```

使用 Ports 方式安装 Nginx：

```sh
# cd /usr/ports/www/nginx/ 
# make install clean
```

### 查找相关的软件包

除主程序外，系统还提供多个与 Nginx 相关的软件包，可通过以下方式检索。

使用 pkg 命令可快速检索与 Nginx 相关的软件包：

```sh
$ pkg search -o nginx
```

在 Ports 目录中也可以查找与 Nginx 相关的软件包，这种方式适合需要查看源码的场景：

```sh
$ ls /usr/ports/www/ | grep nginx
```

## 守护进程

为确保 Nginx 在系统启动时自动运行，需先将其配置为开机自启服务，然后再手动启动服务进行测试。

设置 Nginx 服务在系统启动时自动启动：

```sh
# service nginx enable
nginx enabled in /etc/rc.conf
```

启动 Nginx 服务，在启动前系统会自动进行配置文件的语法检查：

```sh
# service nginx start
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
Starting nginx.
```

可通过以下命令查看 Nginx 正在监听的 IPv4 网络连接及端口，这是验证服务运行状态的有效方法：

```sh
# sockstat -4 | grep nginx
www      nginx       1154 6   tcp4   *:80                  *:*
root     nginx       1153 6   tcp4   *:80                  *:*
```

## 浏览网页

确认 Nginx 服务正常运行后，可通过浏览器访问来验证 Web 服务器是否工作正常。

在本机浏览器中打开 `localhost`，或使用服务器 IP 地址访问，例如 `http://192.168.179.150/`：

![Nginx FreeBSD](https://338876981-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCJR3FQGH1PkdRtOljuxb%2Fuploads%2Fgit-blob-415fd6db447be03c144dcec4636ac6cebb49b791%2Fnginx1.png?alt=media)

## 配置文件

Nginx 功能强大且配置灵活，其配置采用模块化的结构设计，详细的配置方法请参阅官方文档。本文仅简要说明在 FreeBSD 中如何启动 Nginx 及其配置文件位置和使用方法。

有关配置教程，请参阅 [官方文档](https://nginx.org/en/docs/)，官方文档提供了最权威和完整的配置说明。

在 FreeBSD 中，Nginx 的配置文件位于 `/usr/local/etc/nginx/` 目录下，主要配置文件为 `/usr/local/etc/nginx/nginx.conf`，该文件采用层次化的结构组织。

目录结构：

```sh
/usr/local/
├── etc/
│   └── nginx/
│       ├── nginx.conf          # Nginx 主配置文件
│       └── mime.types          # MIME 类型定义文件
└── www/
    └── nginx/                  # Nginx 站点根目录
```

默认配置中，Nginx 的站点根目录为 `/usr/local/www/nginx/`。如需更改站点根目录，请在 `/usr/local/etc/nginx/nginx.conf` 中将

```nginx
root	/usr/local/www/nginx;
```

修改为实际需要的目录路径，例如 `root /path/to/new/webroot;`，配置修改后需要重启服务才能生效。

### 示例配置文件（Nginx + Typecho 伪静态 + SSL）

为了更好地理解 Nginx 的配置，下面提供一个完整的示例配置文件，包含 Nginx、Typecho 伪静态规则以及 SSL 配置。

```nginx
user  www;									 	# 指定 Nginx 运行用户（默认使用编译时设置）

worker_processes  auto;                          # 自动根据 CPU 核心数设置工作进程数（现代推荐）

# 错误日志路径（如需开启可取消注释）
#error_log  /var/log/nginx/error.log;

# 主进程 PID 文件
#pid        logs/nginx.pid;


events {                                         # events 模块配置开始
    worker_connections  10240;                   # 单个工作进程允许的最大连接数（提高并发能力）
}                                                # events 模块结束


http {                                           # http 模块配置开始
    include       mime.types;                    # 引入 MIME 类型定义文件
    default_type  application/octet-stream;      # 默认 MIME 类型

    sendfile on;                                 # 启用 sendfile 提高文件传输效率
    tcp_nopush on;                               # 优化数据包发送（配合 sendfile）
    tcp_nodelay on;                              # 减少延迟（小包立即发送）

    keepalive_timeout 65;                        # keepalive 超时时间（秒）
    types_hash_max_size 2048;                    # MIME 类型哈希表大小优化

    server_tokens off;                           # 隐藏 Nginx 版本号（安全）


    # ========================
    # HTTP 虚拟主机
    # ========================
    server {
        listen 80;                               # 监听 80 端口
        server_name localhost;                   # 虚拟主机名

        root /usr/local/www/nginx;               # 网站根目录
        index index.php index.html;              # 默认首页文件顺序（优先 PHP）

        location / {                             # 根路径匹配
            try_files $uri $uri/ /index.php?$query_string; # 替代 if + rewrite
        }

        location ~ \.php$ {                      # 匹配 PHP 请求（更精确）
            include fastcgi_params;              # 引入 FastCGI 参数
            fastcgi_pass 127.0.0.1:9000;         # FastCGI 服务地址（PHP-FPM）

            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 正确的 PHP 脚本路径（关键优化）
            fastcgi_index index.php;             # 默认 FastCGI 索引文件
        }

        location ~ /\. {                         # 禁止访问隐藏文件（如 .htaccess）
            deny all;
        }

        error_page 500 502 503 504 /50x.html;    # 定义 5xx 错误页面
        location = /50x.html {                   # 精确匹配错误页面
            root /usr/local/www/nginx-dist;      # 错误页面目录
        }
    }


    # ========================
    # HTTPS 虚拟主机
    # ========================
    server {
        listen 443 ssl http2;                    # 启用 HTTPS + HTTP/2（现代推荐）
        server_name localhost;                   # 虚拟主机名

        root /usr/local/www/nginx-dist;          # HTTPS 网站根目录
        index index.php index.html;              # 默认首页文件

        ssl_certificate     /usr/local/etc/nginx/fbxs.crt; # SSL 证书路径
        ssl_certificate_key /usr/local/etc/nginx/fbxs.key; # SSL 私钥路径

        ssl_protocols TLSv1.2 TLSv1.3;           # 启用现代 TLS 协议
        ssl_ciphers HIGH:!aNULL:!MD5;            # 使用安全加密套件（避免过时算法）

        ssl_session_timeout 1d;                  # SSL 会话缓存时间
        ssl_session_cache shared:SSL:10m;        # 共享 SSL 会话缓存

        # 基础安全头（现代 Web 推荐）
        add_header X-Frame-Options SAMEORIGIN;   # 防止被嵌入 iframe（点击劫持）
        add_header X-Content-Type-Options nosniff; # 禁止 MIME 嗅探
        add_header X-XSS-Protection "1; mode=block"; # 浏览器 XSS 防护

        # 可选：启用 HSTS（强制 HTTPS）
        #add_header Strict-Transport-Security "max-age=31536000" always;

        location / {                             # 根路径匹配
            try_files $uri $uri/ /index.php?$query_string; # 统一入口（现代框架推荐）
        }

        location ~ \.php$ {                      # HTTPS 下 PHP 处理
            include fastcgi_params;              # 引入 FastCGI 参数
            fastcgi_pass 127.0.0.1:9000;         # FastCGI 服务地址

            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 正确脚本路径
            fastcgi_index index.php;             # 默认索引文件
        }

        location ~ /\. {                         # 禁止访问隐藏文件
            deny all;
        }
    }

}                                                # http 模块结束
```

## 课后习题

1. 在 FreeBSD 中，基于 www/nginx 配置 HTTPS 支持，实现自动签名。
2. 对 Nginx 进行安全加固，使其适用于生产环境。总结并提交 PR 至本文。
3. 在 FreeBSD 中，基于 www/nginx 部署论坛（如使用 Discuz!）。
