从零开始:在 WSL 上编译安装 Nginx,配置 HTTPS 访问

背景

为了练习管理服务器,我打算在自己的电脑上模拟一个企业级内部环境。通过调整 hosts 文件或者内部 DNS 服务器设置,我希望能够使用内部域名访问服务器,而且要求使用 HTTPS 进行访问。为此,我选择在 Windows11 上安装 WSL2,并在 WSL2 中编译安装 Nginx,以实现最大程度的自定义配置。

环境

  • 操作系统:Windows 11 23H2
  • 终端:PowerShell 5.1

准备工作

1. 安装 wsl

参考 WSL 官方文档 从零开始:Windows 11 安装使用 WSL

2. 安装编译工具

1
apt update && apt install build-essential zlib1g zlib1g-dev libgd-dev libgdal-dev libpcre3 libpcre3-dev -y

有位不知名大佬推荐安装两遍编译工具,使最后显示 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.,这样做是为了避免在编译和安装过程中出现由于依赖项未满足导致的错误。(有人知道出处的话请联系我更新)

3. 更新 openssl 版本(可选)

来自 openssl 官网:All older versions (including 1.1.1, 1.1.0, 1.0.2, 1.0.0 and 0.9.8) are now out of support and should not be used. Users of these older versions are encouraged to upgrade to 3.2 or 3.0 as soon as possible. 所有旧版本(包括 1.1.1、1.1.0、1.0.2、1.0.0 和 0.9.8)现在都不再支持,不应再使用。使用这些旧版本的用户应尽快升级到 3.2 或 3.0。

  • 访问 openssl 官网 下载并解压源码
  • 指定安装路径,以下的 [path] 需保持一致
1
./config --prefix=`[path]`
  • 开始多线程编译安装
1
make -j $(nproc) && make install -j $(nproc)
  • 添加新版本 openssl 软连接
1
2
ln -s `[path]`/bin/openssl /usr/bin/openssl
ln -s `[path]`/include/openssl /usr/include/openssl
  • 新的库文件地址写入记录 so 库的配置文件中
1
echo "[path]/lib64" >> /etc/ld.so.conf
  • 使配置生效并打印出来。
1
ldconfig -v
  • 查看版本是否更新
1
openssl version

编译安装 Nginx

以下使用 /usr/local/src/ 存放源代码,使用 /usr/local/nginx 存放安装路径

  • 创建一个 nginx 用户,为了降低服务器风险,让 nginx 以最小的权限运行
1
useradd -s /sbin/nologin nginx # 删除用户及其用户目录 userdel -r username

查看所有登录 shell 不为 / sbin/nologin 或 / bin/false 用户:grep -vE ‘/sbin/nologin|/bin/false’ /etc/passwd

1
wget https://nginx.org/download/nginx-x.x.x.tar.gz # x.x.x 为具体的版本号
  • 解压 nginx 源码
1
tar -xzf nginx-x.x.x.tar.gz # x 表示提取 z 表示使用 gzip(通常用户. tar.gz 或. tgz 文件) f 表示指定要操作的文件 v 可选:表示显示详细的操作信息
  • 运行 configure 配置脚本 以下配置项参考 nginx 文档
1
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module #设置安装路径 设置用户 设置用户组 添加 https 支持
  • 编译和安装
1
make -j$(nproc) && make install -j$(nproc) # 自动最大线程编译安装
  • 启动和验证
1
2
3
4
cd /usr/local/nginx/sbin && ./nginx #启动
./nginx -t # 验证配置文件
./nginx -v # 查看版本
curl http://localhost # 访问默认页面,启动成功会回显 nginx 欢迎页面的 html 响应
  • 其他配置

    • 使用软链接将 nginx 添加到系统的可执行路径中
    1
    
    ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
    
    • 编写 / usr/lib/systemd/system/nginx.service,使用 systemctl 管理 nginx 参考 systemd 官网,man 手册 (man systemd.unit)
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    [Unit]
    Description=nginx - high performance web server
    Documentation=http://nginx.org/en/docs/
    After=network.target remote-fs.target nss-lookup.target
    
    [Service]
    Type=forking
    PIDFile=/usr/local/nginx/logs/nginx.pid
    ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
    ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
    ExecReload=/usr/local/nginx/sbin/nginx -s reload
    ExecStop=/usr/local/nginx/sbin/nginx -s stop
    PrivateTmp=true
    
    [Install]
    WantedBy=multi-user.target
    
  • 验证 nginx 是否正常运行:

1
systemctl daemon-reload && systemctl stop nginx.service && systemctl start nginx.service && systemctl reload nginx.service && systemctl restart nginx.service && systemctl status nginx # 应显示 Active: active (running) 开机自启(可选):systemctl enable nginx

配置 HTTPS 访问

  • 生成 SSL 证书

    • 创建.openssl文件夹保存相关文件
    1
    
    mkdir .openssl && cd .openssl
    
    • 生成根 CA 的私钥和证书
    1
    2
    3
    4
    
    # 生成根 CA 的私钥
    openssl genrsa -out rootCA.key 4096
    # 使用私钥生成根 CA 的证书,依次输入国家代码(两个大写字母)、省、市、公司、部门、域名、邮箱
    openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 30 -out rootCA.crt
    
    • 为域名生成私钥和证书请求文件(CSR)
    1
    2
    3
    4
    
    # 生成签发证书的私钥 [domain]替换为自己的域名
    openssl genrsa -out [domain].key 4096
    # 使用私钥生成证书请求文件,依次输入国家代码(两个大写字母)、省、市、公司、部门、域名(可以是泛域名[*.domain])、邮箱、密码(可以为空,不推荐)
    openssl req -new -key [domain].key -out [domain].csr
    
    • 创建证书扩展文件 运行vim v3.ext并添加以下内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName = @alt_names
    
    [alt_names]
    # 这里 DNS 替换成 IP 就可以签名ip了,[domain]替换为自己的域名
    DNS.1 = [domain]
    DNS.2 = [*.domain]
    
    • 使用根 CA 的证书为域名签名证书
    1
    
    openssl x509 -req -in [domain].csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out [domain].crt -days 30 -sha256 -extfile v3.ext
    
  • 修改 Nginx 配置文件

    • 将[domain].crt和[domain].key复制到[ssl-path] cp [domain].crt [domain].key [ssl-path]
    • 推荐在[nginx-home]/conf文件夹下创建一个servers文件夹,然后修改nginx.conf,在http块内添加include servers/*.conf
    • servers文件夹下创建80.conf,强制使用https
    1
    2
    3
    4
    5
    6
    
    server {
      listen 80;
      server_name _;
    
      return 301 https://$host$request_uri;
    }
    
    • servers文件夹下创建443.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    server {
      listen 443 ssl;
      server_name [domain];
    
      ssl_certificate [ssl-path]/[domain].crt
      ssl_certificate_key [ssl-path]/[domain].key
    
      # location配置
    }
    

    验证nginx配置文件和重启nginx使配置文件生效

    1
    
    nginx -t && nginx -s reload
    
  • 安装根证书

    • Ubuntu
    1
    2
    
    cp rootCA.crt /usr/local/share/ca-certificates
    update-ca-certificates
    
    • CentOS
    1
    2
    
    cp rootCA.crt /etc/pki/ca-trust/source/anchors/
    update-ca-trust
    
    • Windows 右键rootCA.crt,选择安装证书,选择个人用户或者本地计算机,选择将所有的证书都放入下列存储,指定安装到受信任的根证书颁发机构,点击确定,提示安全警告,阅读完毕选择,提示导入成功就可以了