nginx的一些使用记录

这段时间接触和使用了 nginx,在这里我就记录一些常用的操作与配置。

安装和配置 nginx

在 ubuntu 16.04 下安装 nginx 是一件很简单的事情:

1
$ sudo apt-get install nginx

同样的,启动和关闭也一样简单:

1
2
3
$ sudo service nginx start // 启动
$ sudo service nginx stop // 关闭
$ sudo service nginx restart // 重启

启动 nginx 后,打开 http://localhost 如果可以看到 nginx 的欢迎页面,就说明安装和启动没有什么问题。

安装之后,就要针对自己的项目进行相关配置了,nginx 的配置文件在 /etc/nginx/ 目录下。其中里面 nginx.conf 是主要的配置文件,使用 vim 打开这个文件,我们可以从里面找到这么两行语句:

1
2
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

这说明,我们放在 conf.d 目录下或者放在 sites-enabled 目录下面的自定义配置文件会被引入进来生效。当然具体放在哪里要根据不同的目的。一般我们的站点配置文件是放在 sites-enabled 目录下面。

/etc/nginx/ 目录下,我们可以看到还有一个文件夹名为 sites-available,它和 sites-enabled 很像。巧的是,它们下面都有一个名为 default 的文件,打开来看,内容还一模一样。一开始我也没搞明白它们有什么区别,网上查了一下才明白,setes-enabled 目录里面的 default 文件其实是 sites-available 里面的 default 的软链接。sites-available 目录下面可以写多个配置文件,一般将其中要使用的配置文件软链接到 sites-enabled 目录下面,因为 sites-enabled 里面的配置文件被主配置文件所引入,所以它们就能生效。

启用 nginx HTTP/2.0 协议

最新版的 nginx 支持 HTTP/2.0 协议,但需要配置一下 nginx 配置文件才能生效。
我们在 sites-available 目录下面新建一个配置文件命名为 http2default,然后再里面输入以下配置内容:

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
server {

listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;

root /var/www/html;
index index.html index.htm index.php index.nginx-debian.html;
server_name your.server.name;

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

ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 180m;
resolver 8.8.8.8 8.8.4.4;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

server {
listen 80;
listen [::]:80;
server_name your.server.name;
return 301 https://$server_name$request_uri;
}

在这里,我们新建了两个 server,一个是支持 https 的 HTTP/2.0 的 server,另一个是普通 http 的 server。后者主要是用来将所有非 https 的请求都跳转到 https 上。

两个 server 的 server_name 都填上自己的域名或者主机IP。

在第一个 server 中,我们向所有的 SSL 监听指令中添加 http2 参数来启用 HTTP/2.0。

在配置文件中,我么您可以看到下面三行话:

1
2
3
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;

前面两项是和 SSL 证书有关,后一项与加密有关,需要我们手动生成。
我们当然可以用 openssl 来自己生成 SSL 证书。但是这只能自己玩玩,真正受信任的证书大多数都是要花钱向CA购买。还好前段时间出现了一个免费的CA——Let’s Encrypt,我们可以通过它免费获得 SSL 证书。

Let’s Encrypt 项目发布在 github 上,可以通过 git 来 clone 该项目:

1
$ git clone https://github.com/certbot/certbot

之后进入 letsencrypt 目录,运行一下命令来生成证书:

1
$ sudo ./certbot-auto certonly --standalone

运行之后,会要求填写邮箱、域名等信息,最后就会生成证书。生成的证书会存放在 /etc/letsencrypt/live/{domain}/ 下。
这里需要注意的是,要生成 SSL 证书,必须要使用域名,经测试,Let’s Encrypt 无法为 IP 创建证书。

针对 nginx,我们需要用到证书目录下的 fullchain.pemprivkey.pem 两个文件。将它们拷贝到 /etc/nginx/ssl/ 目录下。

接下来,我们再通过输入以下命令使用一个强 DH 加密算法,这会修改之前的配置文件 ssl_dhparam 所配置的文件:

1
$ sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

修改保存完配置文件后,进入到 sites-enabled 目录中,删掉 原先的 default 软链接,重新创建一个新的软链接,链接到刚刚的 http2default 文件:

1
$ ln -s ../sites-available/http2default

最后,验证 nginx 的配置文件是否正确、能否被 Nginx 网络服务程序应用。然后运行以下命令重启守护进程来观察有什么变化:

1
2
$ sudo nginx -t
$ sudo systemctl restart nginx.service

使用下面的命令来测试 nginx 是否启用 HTTP/2.0 协议:

1
$ openssl s_client -connect localhost:443 -nextprotoneg ''

运行之后,结果会大致如下:

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
CONNECTED(00000003)
Protocols advertised by server: h2, http/1.1
140532064556696:error:140920E3:SSL routines:ssl3_get_server_hello:parse tlsext:s3_clnt.c:1152:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 87 bytes and written 7 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
Next protocol: (2)
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1487249492
Timeout : 300 (sec)
Verify return code: 0 (ok)
---

在第二行中,看到 h2 字样,表明已成功启用 HTTP/2.0 协议。所有最新的浏览器都默认能够支持该协议。

nginx 反向代理简单实战

我这边有一个服务端程序,运行在本机的 8080 端口,现在我希望将所有访问域名的 /api/v1/ 路径的请求都转发到 8080 端口的服务上,那么我们可以在配置文件的 location 部分这样写:

1
2
3
4
5
6
location /api/v1/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

我的 server_nameexercise.imerc.cc
这样所有访问 https://exercise.imerc.cc/api/v1/ 的请求,实际上都访问的是 http://127.0.0.1:8080/

这里有一个小注意点,网上说的很多,就是 proxy_pass 的地址上面带上了路径 /,那么,最后转发的路径就是 /。如果 proxy_pass 后面的地址为 http://127.0.0.1:8080, 那么最后实际访问的是 http://127.0.0.1:8080/api/v1/
其实这个并不复杂,只要记住下面这句话就可以了:proxy_pass 的地址带上了路径,则转发后的路径就是该路径;如果不带路径,那么转发后的路径就是匹配的路径。

假设我需要将所有访问 / 的请求都转发到 /api/v1/ 上,那么可以这么再加上一条 location 配置块:

1
2
3
location =/ {
rewrite / /api/v1/ permanent;
}

这主要使用了 rewritepermanent 表示 301 永久重定向,=/ 表示精确匹配 /

具体的语法可以看网上的教程学习。

点击下面这个链接,就可以看到最后的效果啦
https://exercise.imerc.cc

后记

nginx 有很多的东西,暂时我就用到了这些,所以先记录这些,其他的等以后等用到了再慢慢学吧~~