Ubuntu 安装 Nginx

网上的很多教程都不全面,或缺斤少两,或过时。以下是2024年在Ubuntu上安装Nginx的教程。

演示系统:Ubuntu 22.04

安装 Nginx

官网教程:https://nginx.org/en/linux_packages.html#Ubuntu

下面是翻译。

  1. 安装依赖:

    1
    sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
  2. 导入Nginx官方签名密钥以验证包的真实性:

    1
    2
    curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
  3. 验证下载的文件包含正确的签名密钥:

    1
    gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
  4. 上面的操作应当会输出完整的指纹573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62,像下面这样:

    1
    2
    3
    pub   rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
    573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
    uid nginx signing key <signing-key@nginx.com>

    如果指纹不一样,则移除该文件。

  5. 为apt设置Nginx仓库,如果想使用稳定版:

    1
    2
    3
    echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
    http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list
  6. 如果想使用开发版:

    1
    2
    3
    echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
    http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list
  7. 设置Nginx官网的版本优先级高于发行商所提供的版本:

    1
    2
    echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
    | sudo tee /etc/apt/preferences.d/99nginx
  8. 最后,安装Nginx:

    1
    2
    sudo apt update
    sudo apt install nginx

安装完后执行

1
systemctl status nginx

查看Nginx是否运行,如果没在运行,建议重启系统然后再查看。

开放防火墙

如果没安装防火墙管理工具ufw,先执行sudo apt install ufw进行安装。

执行

1
ufw app list

如果返回的列表中包含

1
2
3
Nginx Full
Nginx HTTP
Nginx HTTPS

那么,在最初建议只开放最少的端口。各防火墙配置含义如下:

  • Nginx Full: 包含80、443端口
  • Nginx HTTP: 包含80端口
  • Nginx HTTPS: 包含443端口

当前建议仅开放Nginx HTTP,即执行

1
2
ufw allow 'Nginx HTTP'
ufw reload

如果执行ufw app list后没有Nginx Full等配置,则需要手动添加:

  1. 执行vim /etc/ufw/applications.d/nginx.ini
  2. 填入以下内容并保存:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [Nginx HTTP]
    title=Web Server
    description=Enable NGINX HTTP traffic
    ports=80/tcp

    [Nginx HTTPS] \
    title=Web Server (HTTPS) \
    description=Enable NGINX HTTPS traffic
    ports=443/tcp

    [Nginx Full]
    title=Web Server (HTTP,HTTPS)
    description=Enable NGINX HTTP and HTTPS traffic
    ports=80,443/tcp
  3. 执行ufw app update nginx以刷新

之后,再次执行ufw app list查看是否有Nginx Full等配置。

以上操作都做完之后,访问你的服务器IP地址(由于开放的是HTTP,应该在IP地址前面加上http://以免浏览器默认访问https://地址导致无法加载出来),出现以下页面即为成功:
Welcome to Nginx!

防止泄露服务器IP

最佳实践是使用CDN。

这里以Cloudflare CDN为例,在DNS记录那里添加A和AAAA记录的时候开启“小黄云”,这样访问你的域名的时候就走的是Cloudflare CDN的IP地址,不会暴露源站服务器的IP。

但是即使开了“小黄云”,Nginx仍然“有办法”通过80和443端口泄露你的源站IP,即在没有server_name的时候默认执行第一个server块,导致源站IP通过SSL证书泄露。这就不得不进行下面的设置了。

禁止通过IP访问网站

在正常的server块前添加如下server块配置:

1
2
3
4
5
6
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 403;
}

同时在server块前添加以下配置开启ssl_reject_handshake插件:

1
2
3
4
5
6
7
server {
listen 443 default_server;
listen [::]:443 default_server;
server_name _;
ssl_reject_handshake on;
return 444;
}

只允许来自Cloudflare的请求

网络上有很多在不停地扫描全世界服务器地址和端口的网站,没有办法一个个去屏蔽它们,毕竟有些甚至没有公布它们的请求IP。好办法就是既然开启了Cloudflare CDN,那就只允许来自Cloudflare的对80和443端口的请求,其余请求一律丢弃。

在此之前,请先执行

1
ufw status numbered

并找到上文开放防火墙中所提到的Nginx HTTP的编号(ipv4和ipv6都有),然后,执行

1
ufw delete <编号>

来删除它们。把<编号>分别换成Nginx HTTPNginx HTTP (v6)的编号。

使用NodeSeek上这篇帖子中的脚本进行批量添加:

  1. 找一个空白位置,执行vim bash.sh
  2. 输入以下内容并保存
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function Add_List() {
    for line in `curl $1`
    do
    if [[ $line =~ "addresses" ]]
    then
    echo $line
    else
    white_list=${line#*\"}
    white_list=${white_list%\"*}

    echo $white_list

    ufw allow from $white_list to any port 80
    ufw allow from $white_list to any port 443
    fi
    done
    }

    # 允许 Cloudflare IP
    Add_List https://www.cloudflare.com/ips-v6
    Add_List https://www.cloudflare.com/ips-v4
  3. 执行chmod -x bash.sh并执行./bash.sh

之后,执行ufw status查看结果,确认无误后,执行ufw reload

完事后可以rm bash.sh删除该脚本。

返回自签名证书

随便上网找一个SSL自签证书生成,比如这个网站然后生成一个虚假的SSL证书,时间尽量设置长一些,比如5年10年。

注意域名处要随便写一个IP地址,比如192.168.1.1,如下所示:
Generate self-assign SSL certificate

注意要选择RSA密钥算法、SHA256签名算法和2048位密钥强度,如下所示:
Generate self-assign SSL certificate

然后在合适位置放置自签名证书,然后vim server.crt并粘贴公钥,换行,保存;vim server.key并粘贴私钥,换行,保存。

之后,在配置文件中添加如下内容:

1
2
3
4
5
6
7
8
9
server {
listen 80;
listen 443 ssl;
server_name _;
ssl_certificate <公钥路径>;
ssl_certificate_key <私钥路径>;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
return 444;
}

<公钥路径><私钥路径>分别替换为刚刚放在合适位置的自签证书公钥和私钥文件的路径即可。