Nginx 的常用配置实践
Nginx 的常用配置实践
1、配置转发请求头
默认情况下,使用了 nginx 代理后,在 Java 后台使用 request 获取到的 ip 或 host 等请求头都是代理后的服务器信息,比如:
- 请求:https://www.a.com/index
- 代理:https://service.a.com:8080/m/index
Java获取:这里得到的端口是8080,host为service.a.com,路径为/m/index
为了解决这个问题,可以设置 nginx 请求头信息,在 nginx.conf 中配置如下:
location / {
# ······
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ······
}2、配置禁止使用服务器 IP 访问
如下添加一个 server 即可(放在第一个,否则指定 default_server)
注意:对于 server_name 配置多个情况下,不是用逗号分隔,而是空格!空格!空格!
server {
listen 80 default_server;
listen [::]:80 default_server;
# 没有匹配到的server_name信息都会走这个默认的server,下划线表示“*”的意思,但根据官网文档描述,“*”不能用作第一个名称(开头),但可以用下划线来代替
server_name _;
# 返回403或者301重定向,按需配置
# return 403;
}3、配置 HTTP 转发到 HTTPS
解决这个问题前,先来熟悉两个知识点。
(1)关于几个 Http 状态码
- 301:永久重定向
- 302:临时重定向
- 307:临时重定向
- 308:永久重定向
唯一区别:301、302 允许把 Post 请求重定向为 Get 请求,而 307、308 则不会
+-----------+-----------+
| Permanent | Temporary |
+------------------------------------------------------------+-----------+-----------+
| Allows changing the request method from POST to GET | 301 | 302 |
+------------------------------------------------------------+-----------+-----------+
| Doesn't allow changing the request method from POST to GET | 308 | 307 |
+------------------------------------------------------------+-----------+-----------+参考资料:
- https://stackoverflow.com/questions/42136829/whats-the-difference-between-http-301-and-308-status-codes
- https://zhuanlan.zhihu.com/p/60669395
(2)关于 nginx 中 rewrite、return 重定向的用法
# permanent:301,redirect:302
rewrite ^/(.*) https://example.com/$request_uri permanent;
# 直接用状态码声明,官方推荐,相比于上面的正则匹配性能更好
return 301 https://example.com$request_uri;所以,掌握了上面的知识点,再来看转发 SSL 的配置就比较简单了:
server {
listen 80;
server_name _;
# 用308可以保持Post请求方式不变,按需配置
return 308 https://$host$request_uri;
}4、配置禁止某些客户端 IP 访问
在 nginx 的 1.20.1 版本中,有一个默认的配置如下:
http{
# ······
include /etc/nginx/conf.d/*.conf;
# ······
}所以,我们按照这个在 conf.d 目录下创建一个 ip 黑(白)名单文件,如:blacklist.conf
# 以下表示除了这个IP其他都可以访问(这个IP访问会报403)
deny 1.2.3.4;
allow all;重新加载 nginx 配置即可生效;当然,还有更多使用方式参考官方文档:https://www.nginx.cn/doc/standard/httpaccess.html
5、解决 WebSocket 连接的问题
server {
# ······
location / {
# ······
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# ······
}
# ······
}6、配置静态资源访问不记录日志
可以在 location 块中使用 access_log off; 即可,如:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
# ······
# 缓存1天
expires 1d;
# 不记录日志
access_log off;
}
location ~ .*\.(js|css)?$ {
# ······
# 缓存12小时
expires 12h;
# 不记录到日志
access_log off;
}除了路径 /demo 下的所有静态资源 可以这样表示(亲测可用,但不知正则对不对):
# 纠正:这个表示匹配非/demo路径下的相关图片资源,逻辑有点牵强
location [^/demo]~.*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
# ······
}合理的配置应该如下:
location ^~ /demo {
# 匹配任何以 /demo 开始的请求,并停止匹配 其它location
# ······
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
# 匹配相关图片请求,但是,如果是/demo路径下的图片,则会按照上面location的规则,因为不会走到这里
# ······
}7、一些实用小配置
http {
···
# server_name 的长度
server_names_hash_bucket_size 96;
# 上传文件时body最大限制
client_max_body_size 10m;
# 关闭请求返回的nginx版本号
server_tokens off;
···
}8、使用 yum 安装的 nginx 想要支持 stream 块
在配置文件中使用 stream 转发非 http 请求时,nginx -t 后报如下错误:
nginx: [emerg] unknown directive "stream" in /etc/nginx/nginx.conf:18
nginx: configuration file /etc/nginx/nginx.conf test failed经过查询得知,使用如下命令安装相应模块即可:
yum install -y nginx-mod-streamTips:网上基本都说安装完了之后需要在配置文件中首行添加 load_module /usr/lib64/nginx/modules/ngx_stream_module.so; 配置,但实践发现并不需要,可能安装之后默认就在 /usr/share/nginx/modules/mod-stream.conf 中添加了。

