docker nginx-1.18.0-alpine 配置

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
26
27
28
29
30
#!/bin/sh

# create self-signed server certificate:
read -p "Enter your domain [www.example.com]: " DOMAIN

echo "Create server key..."
openssl genrsa -des3 -out $DOMAIN.key 1024

echo "Create server certificate signing request..."
SUBJECT="/C=US/ST=Mars/L=iTranswarp/O=iTranswarp/OU=iTranswarp/CN=$DOMAIN"
openssl req -new -subj $SUBJECT -key $DOMAIN.key -out $DOMAIN.csr

echo "Remove password..."
mv $DOMAIN.key $DOMAIN.origin.key
openssl rsa -in $DOMAIN.origin.key -out $DOMAIN.key

echo "Sign SSL certificate..."
# 36500 天过期
openssl x509 -req -days 36500 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt

echo "TODO:"
echo "cp $DOMAIN.crt to /etc/nginx/ssl/$DOMAIN.crt"
echo "cp $DOMAIN.key to /etc/nginx/ssl/$DOMAIN.key"
echo "Add configuration in nginx:"
echo "server {"
echo " ..."
echo " listen 443 ssl;"
echo " ssl_certificate /etc/nginx/ssl/$DOMAIN.crt;"
echo " ssl_certificate_key /etc/nginx/ssl/$DOMAIN.key;"
echo "}"

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
version: '3.8'

services:
nginx:
container_name: ts_nginx
image: nginx:1.18.0-alpine
ports:
- "8810:8810"
- "8820:8820"
volumes:
- "./config/nginx.conf:/etc/nginx/nginx.conf"
- "./config/conf.d/:/etc/nginx/conf.d/"
- "./ssl:/etc/nginx/ssl"
- "./html:/usr/share/nginx/html"
- "/etc/localtime:/etc/localtime"
restart: always

注意:其中nginx.confdefault.confserver_*.confupstream_*.conf等是文件,要提前在宿主机建好

/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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
user  nginx;
worker_processes auto;
worker_rlimit_nofile 65535;

error_log /var/log/nginx/error.log error;
pid /var/run/nginx.pid;

events {
use epoll;
worker_connections 65535;
}

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

# ngx_http_core_module
server_tokens off;
client_max_body_size 50m;
underscores_in_headers on;
open_file_cache max=65535 inactive=60s;
open_file_cache_errors on;
open_file_cache_min_uses 2;
open_file_cache_valid 60s;
# ngx_http_core_module

# ngx_http_proxy_module
proxy_set_header Host $http_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-Proto $scheme;
proxy_cache_path /dev/shm/nginx_cache levels=1:2 keys_zone=shmCache:10m max_size=1g inactive=180m use_temp_path=off;
# ngx_http_proxy_module

# ngx_http_limit_conn_module
limit_conn_status 444;
limit_conn_zone $binary_remote_addr zone=perip:32m;
limit_conn_zone $server_name zone=perserver:10m;
# ngx_http_limit_conn_module

# 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;
log_format logJson '{'
'"accessTime": "$time_local", '
'"remote_addr": "$remote_addr", '
'"referer": "$http_referer", '
'"request": "$request", '
'"status": $status, '
'"bytes": $body_bytes_sent, '
'"agent": "$http_user_agent", '
'"x_forwarded": "$http_x_forwarded_for", '
'"up_addr": "$upstream_addr",'
'"up_host": "$upstream_http_host",'
'"up_resp_time": "$upstream_response_time",'
'"request_time": "$request_time"'
'}';
access_log /var/log/nginx/access.log logJson;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

# ngx_http_gzip_module
gzip on;
gzip_comp_level 2;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# ngx_http_gzip_module

# include /usr/local/nginx/conf/objects/server0_default.conf;
# include /usr/local/nginx/conf/objects/server_*.conf;
# include /usr/local/nginx/conf/objects/server6_*.conf;
# include /usr/local/nginx/conf/objects/upstreams_*.conf;
# include /etc/nginx/conf.d/*.conf;

#include /etc/nginx/conf.d/default.conf;
include /etc/nginx/conf.d/server_*.conf;
include /etc/nginx/conf.d/upstreams_*.conf;

server {
listen unix:/tmp/nginx.sock; ##以下配置为符合基线合规化处理
location = /50x.html { # 返回错误页面
limit_conn perip 32; # 每个IP并发连接数为32
limit_conn perserver 32; # 每个主机的最大并发数为32
limit_rate 1024k; # 下载速率为1024k
client_body_timeout 10; #指定客户端与服务端建立连接后发送 request body 的超时时间
send_timeout 10; #服务端向客户端传输数据的超时时间
return 444;
}
client_header_timeout 10; #客户端向服务端发送一个完整的 request header 的超时时间
error_page 400 401 402 403 404 413 500 502 503 504 /50x.html; #自定义nginx返回的错误信息
}
}

/etc/nginx/conf.d/server_0_433.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
server {
listen 8810;
listen [::]:8810;

# ssl_certificate /usr/local/nginx/ssl/4113665.pem;
# ssl_certificate_key /usr/local/nginx/ssl/4113665.key;
# ssl_session_timeout 5m;
# ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_session_cache shared:SSL:10m;
# ssl_prefer_server_ciphers on;

limit_conn perip 50;
limit_rate 15000k;

# 添加几条有关安全的响应头;与 Google+ 的配置类似,详情参见文末。
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

# 指定字符集为 UTF-8
charset utf-8;

# 关闭 [/favicon.ico] 和 [/robots.txt] 的访问日志,即使它们不存在,也不写入错误日志。
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

location ^~ /xmt/ {
proxy_store off;
proxy_redirect off;
# 注意:这里最好不要使用下划线,upstream 最好改成 xmt-srv,具体查看RFC1-1034规范
proxy_pass http://xmt_srv;
}

# 引入公共配置,包括错误页面、维护通知、图标、反爬虫协议等
include /etc/nginx/conf.d/agent_deny.conf;
}

/etc/nginx/conf.d/upstream_0_433.conf

1
2
3
4
5
6
# 注意:这里最好不要使用下划线,最好改成 xmt-srv,具体查看RFC1-1034规范
upstream xmt_srv {
server 192.168.123.1:8015;
server 192.168.123.2:8015;
server 192.168.123.3:8015;
}

/etc/nginx/conf.d/agent_deny.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|Catall Spider|AcoiRobot|Yisou|bingbot|360Spider") {
return 403;
}

if ($http_user_agent ~* "WinHttp|WebZIP|FetchURL|node-superagent|FeedDemon|Jullo|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|MJ12bot|heritrix|EasouSpider|Ezooms|BOT/0.1|YandexBot|FlightDeckReports|Linguee Bot|iaskspider|^$") {
return 403;
}

if ($request_method !~ ^(GET|POST)$) {
return 403;
}

if ($http_user_agent ~* (Python|Wget|Scrapy|Spider)) {
return 403;
}

系统参数优化

修改/etc/sysctl.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#每个网络接口接收数据包速度比内核处理速度快的时候,允许发送队列数目数据包的最大数
net.core.netdev_max_backlog = 102400

#调节系统同时发起的tcp连接数,不应该超过 65535
net.core.somaxconn = 65535

#该参数用于设定系统中最多允许存在多少TCP套接字不被关联到任何一个用户文件句柄上,主要目的为防止Ddos攻击
net.ipv4.tcp_max_orphans = 102400

#该参数用于记录尚未收到客户端确认信息的连接请求的最大值
net.ipv4.tcp_max_syn_backlog = 102400

#nginx服务上建议关闭(既为0)
net.ipv4.tcp_timestamps = 0

#该参数用于设置内核放弃TCP连接之前向客户端发送SYN+ACK包的数量,为了建立对端的连接服务,服务器和客户端需要进行三次握手,第二次握手期间,内核需要发送SYN并附带一个回应前一个SYN的ACK,这个参
数主要影响这个过程,一般赋予值为1,即内核放弃连接之前发送一次SYN+ACK包。
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1

执行生效

1
sudo sysctl -p

net.core.netdev_max_backlog = 102400
net.core.somaxconn = 65535
net.ipv4.tcp_max_orphans = 102400
net.ipv4.tcp_max_syn_backlog = 102400
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1

reload

1
docker exec ts_nginx nginx -s reload

sub_filter

1
2
3
4
5
6
location /test/ {
sub_filter 'src="js/' 'src="/test/js';
sub_filter_types text/html application/json;
sub_filter_once off;
proxy_pass http://localhsot:9090/;
}

注意事项

  • 使用nginx -s reload时,不能删除nginx.confconf.d,可以删除conf.d下的配置,不然会导致nginx reload异常。由于删除文件后,导致链接失效。
  • 本文作者: forever杨
  • 本文链接: https://blog.yl-online.top/posts/8b6eb00b.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。如果文章内容对你有用,请记录到你的笔记中。本博客站点随时会停止服务,请不要收藏、转载!