nginx-记录
nginx-记录
前篇
- a
安装
- 如何在 Ubuntu 20.04 中安装和配置 Nginx - https://kalasearch.cn/community/tutorials/how-to-install-nginx-on-ubuntu-20-04/
修改默认 web 目录
- 修改nginx默认指向目录 - https://segmentfault.com/a/1190000022782499
修改
/etc/nginx/sites-available/default
文件1
root /webapps/myblog; # root 就是默认目录
常用命令
查看版本
1
2
3
4
5
6
7# nginx -V
nginx version: nginx/1.19.8
- 优雅关闭 (不接受新的连接请求,等待旧的连接请求处理完毕再关闭)
```json
# nginx -s quit配置平滑更新
1
# nginx -s reload
测试配置文件是否正确
1
2
3
4
5
6
7
8$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
- 版本信息
```json
# nginx -v系统命令
重启服务
1
# service nginx restart
启动服务:
1
# service nginx start
停止服务
1
2
3
4
5
6# service nginx stop
- 查看状态
```json
# service nginx status
添加配置
在 Nginx 安装目录下的 conf.d
下存放配置, 以 .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[root@hades /etc/nginx/conf.d]# ls
yx.conf
[root@hades /etc/nginx/conf.d]# vim yx.conf
# ipa web 服务
server {
listen 32081;
server_name localhost;
root /webapps/ipa-web;
index index.html;
}
---
### 测试配置是否正确
- 命令
```json
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
tcp 代理配置
- TCP and UDP Load Balancing - https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/
- Nginx 配置TCP代理转发 - https://blog.csdn.net/jeikerxiao/article/details/87863341
修改 主配置文件
/etc/nginx/nginx.conf
, 增加 stream 模块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
44user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/http_*.conf; # 为了方便区分, 只包含 http_ 开头的文件
}
# 增加 stream 模块
stream {
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/tcp_access.log proxy;
open_log_file_cache off;
include /etc/nginx/conf.d/tcp_*.conf; # 为了方便区分, 只包含 tcp_ 开头的文件
}在
/etc/nginx/conf.d
目录下新建一个tcp_01.conf
文件代理到 redis 服务
1
2
3
4server {
listen 11223;
proxy_pass 10.0.3.6:6379; # 内网 redis 服务
}测试一下, golang
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
31func TestConnect(t *testing.T) {
_, err = redis.Dial("tcp", "aaa.bbb.cn:11223")
if err != nil {
panic(err)
}
fmt.Printf("--- connect success")
}
---
### websocket 代理
- 在配置中配置, 例如: 反向代理 http://aaa.bbb.com:1234 到 http://ccc.ddd.com:5678
```json
server {
listen 1234;
server_name aaa.bbb.com;
location / {
proxy_pass http://ccc.ddd.com:5678;
proxy_http_version 1.1;
proxy_connect_timeout 15s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
不带 www 重定向 www
参考配置
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# https www web 服务
server
{
listen 443 ssl;
server_name www.aaa.com;
root /webapps/my_hexo_blog02/public;
# root /webapps/myblog;
index index.html;
add_header Content-Security-Policy upgrade-insecure-requests;
# ssl
ssl_certificate /opt/nginx-cert/any.aaa.com/any.aaa.com.cer;
ssl_certificate_key /opt/nginx-cert/any.aaa.com/any.aaa.com.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/www.aaa.com.log;
}
# http 重定向到 https
server {
listen 80;
server_name www.aaa.com aaa.com;
return 301 https://www.aaa.com$request_uri;
}
# 无 www 重定向到 有 www
server {
listen 443;
server_name aaa.com;
return 301 https://www.aaa.com$request_uri;
}
配置密码访问
生成账号密码文件, 如账号密码为 hello, 123456
1
2
3
4
5$ echo "hello:$(openssl passwd 123456)" > /opt/nginx_passwd
// 查看一下密码是加密后的
$ cat /opt/nginx_passwd
hello:e6CDcfRjlUN2o配置 nginx
1
2
3
4
5
6
7
8server
{
listen 443 ssl;
location / {
auth_basic "Some description"; # 加入这两行配置
auth_basic_user_file /opt/nginx_passwd;
}
}重载配置
1
$ service nginx force-reload
访问时就需要密码了
配置不预览直接下载
有几种方式
add_header 加上 Content-Disposition 为 attachment
1
2
3
4
5
6location / {
if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx|jpg|png)$){
add_header Content-Disposition attachment;
charset utf-8;
}
}add_header 加上 Content-Type 为 octet-stream
1
2
3
4
5
6
7location / {
if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx|jpg|png)$){
# add_header Content-Type "text/plain;charset=utf-8"; # 预览模式
add_header Content-Type "application/octet-stream;charset=utf-8"; # 下载模式
charset utf-8;
}
}
重载 nginx 配置
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$ service nginx force-reload
3. 测试时, 由于游览器有缓存, 所以直接用下载链接测试
- 直接在浏览器中打开测试链接 https://aaa.bbb.cn/aaa.txt, 修改了配置后, 在浏览器上 *ctrl + R* 强刷, 就可以看到是否是 预览 还是 直接下载
---
### header 校验
1. 修改配置文件, 以请求头 *Authorization* 为例
```json
server {
listen 1234;
server_name aaa.bbb.cn;
location / {
# 校验
if ($http_Authorization != "aaabbb") { // 验证的 key 值需要带上 http_ 前缀
return 400 "auth fail!";
}
}请求
1
2
3
4headers = {
"Content-Type": "application/json; charset=utf-8",
"Authorization": "aaabbb",
}
自定义日志输出
在 http 块中定义, 也就是在 /etc/nginx/nginx.conf 中定义
1
2
3
4
5
6
7
8
9http {
log_format custom_log_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_host" "$http_connection" "$http_accept" '
'"$http_accept_language" "$http_accept_encoding" '
'"$http_cache_control" "$http_origin" '
'"$http_x_forwarded_for" "$http_x_real_ip" aaa'; # 加了个 aaa 测试
}- 在 Nginx 中,
log_format
指令只能放在http
块中,而不能直接放在server
块或location
块中。这是因为log_format
定义的是全局的日志格式,所有server
或location
块都可以引用它,但不能在它们里面直接定义。
- 在 Nginx 中,
在 server 快中引用
1
2
3
4
5
6
7server
{
listen 1234 ssl;
server_name aaa.bbb.com;
access_log /var/log/nginx/itsapi_6502.wilker.cn.log custom_log_format; # 引用自定义格式
}重载 nginx 配置
1
$ service nginx force-reload
done. 请求: https://aaa.bbb.com:1234 就能看到自定义输出
1
120.229.3.191 - - [08/Sep/2024:21:00:19 +0800] "GET /favicon.ico HTTP/1.1" 404 18 "https://aaa.bbb.com:1234/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" "https://aaa.bbb.com:1234" "keep-alive" "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8" "zh-CN,zh;q=0.9,en;q=0.8" "gzip, deflate, br, zstd" "-" "-" "-" "-" aaa
踩坑
中文乱码
- nginx访问页面 中文乱码 解决方案 - https://blog.51cto.com/u_13687405/2806180
修改配置文件, 设置字符集
1
2
3
4
5
6
7
8
9
10
11
12
13
14server {
listen 81;
set $root F:/Develop/nginx-1.14.0/html;
root $root;
server_name localhost;
access_log logs/host.access.log main;
index index.html index.php;
charset utf-8; #设置字符集
location / {
root html;
index index.html index.htm;
charset utf-8; #设置字符集
}
}重新加载配置
1
$ nginx -s reload
请求体过大
报错: 413 request entity too large
nginx 默认限制的请求大小, 修改配置
1 | server |
参考: https://juejin.cn/post/6844904120457887751
tcp stream 配置错误
错误: "stream" directive is not allowed here
原配置文件 /etc/nginx/conf.d/tcp01.conf
1
2
3
4
5
6
7
8
9
10
11stream {
upstream mysrv01 {
server 192.168.1.42:22 weight=50;
}
server {
listen 51901;
listen 51901 udp;
proxy_pass mysrv01;
}
}是指在 nginx 默认配置文件 /etc/nginx/nginx.conf 中的 http 模块包含到了这个 /etc/nginx/conf.d/tcp01.conf 文件, 而 stream 是和 http 是同级的, 所以出现层级错误
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
28http {
include /etc/nginx/conf.d/*.conf;
}
- 解决办法就是 http 模块中的不要包含到 */etc/nginx/conf.d/tcp01.conf* 文件即可
---
#### 服务获取 ip 一直是 127.0.01
- 加上 ip 转发配置
```json
server
{
location / {
# 加上这些 ip 配置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Server $host;
client_max_body_size 32m;
proxy_pass http://127.0.0.1:6353;
}
}服务器读取 ip 是使用 头部信息的 ip, 比如: gin
```go
ip := ctx.Request.Header.Get(“X-Forwarded-For”)
// ip := ctx.ClientIP() 不要使用这个 api 获取 ip