某些组织内部关于端口使用有规范要求,比如只允许开放80,8080,8000等标准化端口,而又有资源最大化利用,降低成本的初心,可以考虑通过Nginx监听80端口,根据不同的server_name分别进行转发。某些组织内部

建议结合防火墙使用,iptables添加允许本地IP进行访问,拒绝端口从外部访问:

1
2
3
4
5
6
7
8
9
10
11
# 允许来自本地的 TCP 协议访问端口 8000  
sudo iptables -A INPUT -p tcp -s 127.0.0.1 --dport 8000 -j ACCEPT

# 允许来自本地的 UDP 协议访问端口 8000
sudo iptables -A INPUT -p udp -s 127.0.0.1 --dport 8000 -j ACCEPT

# 阻止其他来源的 TCP 协议访问端口 8000
sudo iptables -A INPUT -p tcp --dport 8000 -j DROP

# 阻止其他来源的 UDP 协议访问端口 8000
sudo iptables -A INPUT -p udp --dport 8000 -j DROP

本篇演示两个示例。首先找到Nginx做反向代理配置目录,使用宝塔等第三方服务器构建的配置文件路径可能略有不同,通常目录为:

1
/etc/nginx/nginx.conf

为了条理清晰可以使用类似参数将配置文件存放在自定义目录:

image-20241016094715316

配置文件大概示例:

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
server {
listen 80;
listen [::]:80;
server_name domain_name;

access_log /var/log/nginx/file.access.log;
error_log /var/log/nginx/file.error.log;

server_tokens off;
error_page 404 /404.html;

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

client_max_body_size 50m;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
proxy_pass http://xx.xx.xx.xx:xx;
proxy_buffer_size 128k;
proxy_buffers 32 128k;
proxy_busy_buffers_size 128k;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
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-Proto http;
}
}

Nginx反向代理Docker容器

以Passbolt密码管理为例,这是它的yaml构建文件:

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
version: "3.9"
services:
db:
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "true"
MYSQL_DATABASE: "passbolt"
MYSQL_USER: "passbolt"
MYSQL_PASSWORD: "*************"
volumes:
- database_volume:/var/lib/mysql

passbolt:
image: passbolt/passbolt:latest-ce
#Alternatively you can use rootless:
#image: passbolt/passbolt:latest-ce-non-root
restart: unless-stopped
depends_on:
- db
environment:
APP_FULL_BASE_URL: https://passbolt.local
DATASOURCES_DEFAULT_HOST: "db"
DATASOURCES_DEFAULT_USERNAME: "passbolt"
DATASOURCES_DEFAULT_PASSWORD: "*************"
DATASOURCES_DEFAULT_DATABASE: "passbolt"
volumes:
- gpg_volume:/etc/passbolt/gpg
- jwt_volume:/etc/passbolt/jwt
command:
[
"/usr/bin/wait-for.sh",
"-t",
"0",
"db:3306",
"--",
"/docker-entrypoint.sh",
]
# 为了符合内部端口标准规范,ports可以直接不写
#ports:
# - 8888:80
# - 4443:443
#Alternatively for non-root images:
# - 80:8080
# - 443:4433

volumes:
database_volume:
gpg_volume:
jwt_volume:

构建Docker容器:

1
docker-compose -f docker-compose-ce.yaml up -d

进入docker容器查看容器分配的ip:

image-20241016101418271

将其与yaml文件中分配的域名,写进本地hosts文件中:

image-20241016101630441

如果是https协议,需要使用HTTPS证书,生成证书签名:

1
2
openssl genrsa -out private.key 2048
openssl req -new -key private.key -out certificate.csr

image-20241016105140711

再生成自签名证书:

1
openssl x509 -req -days 365 -in certificate.csr -signkey private.key -out certificate.crt

构建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
31
32
33
34
35
36
37
38
39
40
41
42
43
server {  
listen 443 ssl;
listen [::]:443 ssl;
server_name your-domain.com; # 确保此hostname与你的域名匹配

# SSL证书配置
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;

# 日志和错误页面设置
access_log /var/log/nginx/your-domain.access.log;
error_log /var/log/nginx/your-domain.error.log;
server_tokens off;

error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

# 最大请求体大小
client_max_body_size 50m;

# 反向代理设置
location / {
proxy_pass http://your-backend-service; # 使用您的实际后端服务地址
root /usr/share/nginx/html; # 如果不需要,可以删除

# Proxy配置项
proxy_buffer_size 128k;
proxy_buffers 32 128k;
proxy_busy_buffers_size 128k;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;

# 设置请求头
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-Proto $scheme; # 使用 $scheme 自动适配协议
}
}

配置完成后更新nginx配置:

1
sudo nginx -s reload

然后使用其他浏览器打开:

image-20241016105830012

非虚拟环境Web:

非虚拟环境Web不需要反代,直接在配置文件中新建解析就行,以Docusaurus应用为例,建议使用HTTPS协议,先生成证书签名:

1
openssl genrsa -out private.key 2048
1
openssl req -new -key private.key -out certificate.csr

image-20241016120337099

生成证书签名:

1
openssl x509 -req -days 365 -in certificate.csr -signkey private.key -out certificate.crt

在配置中添加如下,示例配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {  
listen 443 ssl; # 监听443端口并启用SSL
server_name example.com; # 指定域名

# SSL 证书配置
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private.key;

# SSL 配置
ssl_protocols TLSv1.2 TLSv1.3; # 选择支持的协议版本
ssl_ciphers HIGH:!aNULL:!MD5; # 加密套件配置

# 网站根目录
root /path/to/your/site/root;
index index.html index.htm; # 默认载入页面

location / {
try_files $uri $uri/ =404; # 按文件名尝试加载文件,失败返回404
}

# 日志设置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}

注意事项

如果不想暴露后端证书中的域名,可以为Nginx单独配置一个证书:

1
openssl genrsa -out private.key 2048
1
openssl req -new -key private.key -out certificate.csr

生成签名证书:

1
openssl x509 -req -days 365 -in certificate.csr -signkey private.key -out certificate.crt

然后将其添加到Nginx配置中去:

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _; # 匹配所有未指定的请求

# 证书配置
ssl_certificate /etc/nginx/cert/certificate.crt;
ssl_certificate_key /etc/nginx/cert/private.key;

# 返回 444 状态码,关闭连接而不返回响应
return 444;
}

image-20241016133751469