0%

VPSTOOLBOX核心组件篇--NGINX

VPSTOOLBOX核心组件篇–NGINX

Nginx作为VPSTOOLBOX的核心组件,发挥了至关重要的作用,包括但不限于将各个组件以一定的方式连接在一起,分流请求等。

本文将展示从零开始自己搭建一个NGINX Web Server,开启HTTPS,正常运行以及一些优化的方法,确实,NGINX高级用法很多,因此限于篇幅以及本人的知识水平,我会展示我所学会的,欢迎各位在评论区交流。

注:本文仅适用于无Trojan-GFW的情况下,请注意。


一。 前情提要

问一: 为什么用NGINX而不是Apache/caddy等 ?

答: 因为NGINX高效且资源消耗低,且配置方便直观(其实我确实没用过其他Web server,NGINX太香了)。

问二: NGINX有什么用 ?

答: 我个人就拿来当Web Server,确实,有其他高级用法,但本文不涉及。

问三: NGINX对新手友好吗?

答: 是的,比Apache友好。


二。 准备工作

准备工作很简单,有一台有独立公网ip的非中国大陆LINUX伺服器/VPS以及一个非中国大陆域名即可。


三。 开始搭建

  1. 连接伺服器,我不想教这个,SSH教程请自己搜。

  2. 我个人不使用Centos,因此本教程只涉及Debian/Ubuntu,想看Centos的可以关掉本页面了。

    安装依赖

    1
    apt-get install sudo gnupg2 ca-certificates lsb-release -y

    添加APT源,本文不涉及编译,故deb-src不需要。

    1
    touch /etc/apt/sources.list.d/nginx.list

    Debian

    1
    2
    3
    4
    	cat > '/etc/apt/sources.list.d/nginx.list' << EOF
    deb https://nginx.org/packages/mainline/debian/ $(lsb_release -cs) nginx
    #deb-src https://nginx.org/packages/mainline/debian/ $(lsb_release -cs) nginx
    EOF

    Ubuntu

    1
    2
    3
    4
    	cat > '/etc/apt/sources.list.d/nginx.list' << EOF
    deb https://nginx.org/packages/mainline/ubuntu/ $(lsb_release -cs) nginx
    #deb-src https://nginx.org/packages/mainline/ubuntu/ $(lsb_release -cs) nginx
    EOF

    添加APT公钥以认证APT源,否则会出错。

    1
    2
    curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
    apt-key fingerprint ABF5BD827BD9BF62

    安装NGINX。

    1
    apt-get install nginx -y
  3. 至此,安装完成,接下来我们需要配置NGINX。

注:你确实可以直接apt install nginx,但这样的话就不会是最新版,因此我选择使用上述安装方法。


四。 配置NGINX并开启HTTPS

NGINX的配置目录在/etc/nginx,且分主config以及server config等config以便于阅读与修改,彼此之间使用include语法连接。

  1. NGINX的主config为/etc/nginx/nginx.conf,以下是我个人使用的配置,你可以选择不修改这个文件

    1
    sudo nano /etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 51200;
use epoll;
multi_accept on;
}

http {
autoindex_exact_size off;
http2_push_preload on;
aio threads;
charset UTF-8;
tcp_nodelay on;
tcp_nopush on;
server_tokens off;

proxy_intercept_errors on;
proxy_socket_keepalive off;
proxy_http_version 1.1;
proxy_ssl_protocols TLSv1.2 TLSv1.3;

include /etc/nginx/mime.types;
default_type application/octet-stream;

access_log /var/log/nginx/access.log;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

sendfile on;
gzip on;
gzip_proxied any;
gzip_types *;
gzip_comp_level 9;

include /etc/nginx/conf.d/*.conf;
}

需要注意的是,NGINX的配置是可以覆写的,即HTTP模块里面的配置可以被Server/location模块里面的配置覆写,如果不覆写,则继承原有的配置,且有些配置不能写在HTTP模块里面,具体请自己看NGINX官方文档。

NGINX官方文档

  1. 接下来我们需要配置Server模块,如果你使用我推荐的安装方法,那么Server的配置在 /etc/nginx/conf.d/目录里面。
1
sudo nano /etc/nginx/conf.d/default.conf

我们需要先将这个文件改成以下的样子,否则acme.sh nginx 模式签发证书会失败。

1
2
3
4
5
6
server {
listen 80;
listen [::]:80;
server_name $domain;
root /usr/share/nginx/html;
}

$domain请改成你自己的域名。

启动NGINX并设置开启开机自启。

1
2
systemctl start nginx
systemctl enable nginx
  1. 接下来我们需要安装acme.sh以签发HTTPS证书,我个人不推荐任何人使用不安全的HTTP连接。

安装acme.sh。

1
curl -s https://get.acme.sh | sh

启用acme.sh的自动更新功能。

1
~/.acme.sh/acme.sh --upgrade --auto-upgrade

建立证书存放文件夹

1
mkdir /etc/certs/

使用acme.sh NGINX模式签发证书。如签发成功,则进行下一步。

1
~/.acme.sh/acme.sh --issue --nginx --cert-home /etc/certs -d ${domain} -k ec-256 --log --reloadcmd "nginx -s reload"

注:将证书扔在/root/里面是个糟糕的主意,后期可能碰到权限问题,故我使用/etc/certs/,你可以改成你喜欢的。

给证书以及私钥读取权限。

1
2
chmod +r /etc/certs/${domain}_ecc/fullchain.cer
chmod +r /etc/certs/${domain}_ecc/${domain}.key

使用systemd timer设置证书全自动续签。

1
2
3
4
5
6
7
8
9
10
11
12
13
   cat > '/etc/systemd/system/acme_letsencrypt.service' << EOF
[Unit]
Description=Renew Let's Encrypt certificates using acme.sh
After=network-online.target

[Service]
Type=oneshot
# Directory where the acme.sh script resides.
Environment="HOME=/root/"
ExecStart=/root/.acme.sh/acme.sh --issue --nginx --cert-home /etc/certs -d ${domain} -k ec-256 --reloadcmd "nginx -s reload"
# acme.sh returns 2 when renewal is skipped (i.e. certs up to date)
SuccessExitStatus=0 2
EOF

请自行将${domain}换成你自己的域名。

1
2
3
4
5
6
7
8
9
10
11
12
cat > '/etc/systemd/system/acme_letsencrypt.timer' << EOF
[Unit]
Description=Daily renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true

[Install]
WantedBy=timers.target
EOF
1
2
systemctl daemon-reload
systemctl enable acme_letsencrypt.timer
  1. 开启HTTPS

    1
    sudo nano /etc/nginx/conf.d/default.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl_certificate /etc/certs/${domain}_ecc/fullchain.cer;
    ssl_certificate_key /etc/certs/${domain}_ecc/${domain}.key;
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;
    ssl_early_data on;
    ssl_session_cache shared:SSL:40m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    #ssl_stapling on;
    #ssl_stapling_verify on;
    #ssl_dhparam /etc/nginx/nginx.pem;
    #resolver 127.0.0.1;
    #resolver_timeout 10s;
    server_name ${domain};
    #add_header alt-svc 'quic=":443"; ma=2592000; v="46"';
    #add_header X-Frame-Options SAMEORIGIN always;
    #add_header X-Content-Type-Options "nosniff" always;
    #add_header X-XSS-Protection "1; mode=block" always;
    #add_header Referrer-Policy "no-referrer";
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    #add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://ssl.google-analytics.com https://assets.zendesk.com https://connect.facebook.net; img-src 'self' https://ssl.google-analytics.com https://s-static.ak.facebook.com https://assets.zendesk.com; style-src 'self' https://fonts.googleapis.com https://assets.zendesk.com; font-src 'self' https://themes.googleusercontent.com; frame-src https://assets.zendesk.com https://www.facebook.com https://s-static.ak.facebook.com https://tautt.zendesk.com; object-src 'none'";
    #add_header Feature-Policy "geolocation none;midi none;notifications none;push none;sync-xhr none;microphone none;camera none;magnetometer none;gyroscope none;speaker self;vibrate none;fullscreen self;payment none;";
    #if (\$http_user_agent ~* (360|Tencent|MicroMessenger|MetaSr|Xiaomi|Maxthon|TheWorld|QQ|UC|OPPO|baidu|Sogou|2345|Go-http-client) ) { return 403; }
    #if (\$http_user_agent ~* (wget|curl) ) { return 403; }
    #if (\$http_user_agent = "") { return 403; }
    #if (\$host != "$domain") { return 404; }
    location / { #根目录
    root /usr/share/nginx/html/;
    index index.html;
    }
    }

    server {
    listen 80;
    listen [::]:80;
    server_name ${domain};
    return 301 https://${domain}$request_uri; #HTTPS重定向
    }

    server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _; #若直接ip访问,则返回404,防爬虫必备。
    return 404;
    }

    请自行将${domain}换成你自己的域名。

    注: 注释掉的配置为可选项,多为反爬虫,反spam等用途,详情请看优化篇。

    测试配置是否可用并重载配置文件。

    1
    2
    nginx -t
    nginx -s reload

    看到这两句,则表示可用。

    1
    2
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
  1. 测试伺服器是否运行正常。

    访问https://${domain}若看见Welcome to NGINX以及标志HTTPS的🔒的图案,则表示成功。


五。NGINX优化篇

NGINX提供了许多优化效能,降低带宽消耗,反爬虫等优化功能,本篇主要展示我知道的各种优化方法。

  1. 启用GZIP降低带宽消耗。
1
sudo nano /etc/nginx/nginx.conf

我个人推荐直接将GZIP配置放在主配置文件中。

NGINX GZIP DOCS

1
2
3
4
gzip on;
gzip_proxied any;
gzip_types *;
gzip_comp_level 9; #压缩率,1-9,数字越高则压缩率越高
  1. 启用HSTS,HSTS相关文档
1
sudo nano /etc/nginx/conf.d/default.conf
1
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

注:HSTS只能放在Server配置模块中。

  1. 各种反爬方法(这些为本人搜集得来的,慎用)
1
2
3
4
if ($http_user_agent ~* (360|Tencent|MicroMessenger|MetaSr|Xiaomi|Maxthon|TheWorld|QQ|UC|OPPO|baidu|Sogou|2345|Go-http-client) ) { return 403; } #阻止中国大陆国产垃圾流氓傻逼浏览器访问
if ($http_user_agent ~* (wget|curl) ) { return 403; } #阻止wget/curl访问
if ($http_user_agent = "") { return 403; } #阻止空user-agnet访问
if ($host != "${domain}") { return 404; } #阻止http request中的网站域名和本站不符的访问
  1. 开启HTTP2
1
listen 443 ssl http2; #有http2即表示开启成功

HTTP2在线检测网站

  1. 全自动设置NGINX workers数量
1
sudo nano /etc/nginx/nginx.conf
1
worker_processes auto;

注: NGINX会全自动根据可用的CPU核心数选择workers数量。

  1. 设置NGINX Proxy相关设定
1
sudo nano /etc/nginx/nginx.conf
1
2
3
4
proxy_intercept_errors on;
proxy_socket_keepalive off;
proxy_http_version 1.1; #此项不设置则默认为1.0,因此反代容易出错,因此推荐加上。
proxy_ssl_protocols TLSv1.2 TLSv1.3;

NGINX Proxy Docs

我所知道的差不多就这些了,欢迎各位看官补充,关于HTTP2 Server Push以及ssl ocsp stapling等争议较大的内容本文就不细说了。


六。总结篇

NGINX作为一款强大的现代Web Server软件,确实非常好用,現在,您已經安裝了Web服務器,對於您可以提供的內容類型以及可以用來為用戶創造更豐富的體驗的技術,您有很多選擇。