0%

nginx | 转发 tcp 端口流量

这里借助 nginx ,将 tcp + socket 请求发到一个代理服务器上,然后代理服务器再转发给目标服务器。

其中,nginx 是配置在代理服务器上的。

首先,我们要知道一些前提。

转发 TCP 端口是要配置在 stream 里面。

stream 模块的配置需要特定的位置。常见的位置包括:

  • /etc/nginx/nginx.conf :如果你的 nginx.conf 文件是单一的配置文件。
  • /etc/nginx/conf.d/ 目录下的一个单独配置文件,例如 tcp_forward.conf

一个配置如下「下面只是简单配置」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# /etc/nginx/nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;

# http模块配置
http {
...
}

# stream模块配置
stream {
server {
listen 17777;
proxy_pass 172.31.1.194:13000;
}
}

这里说一下这个配置的点

  • 代理服务器开启 17777,然后转发到目标服务器 13000 端口
  • 172.31.1.194 是局域网 IP,需要保证两台服务器位于同一网段
  • 目标服务器的安全组的 13000 端口的入流量规则,只接收来自代理服务器的流量,也填写局域网的 IP

咱们使用脚本验证。

首先,代理服务器配置好之后,必须重新启动 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
# 服务端代码 server.py
import socket

# 定义主机和端口
HOST = '0.0.0.0' # 使用回环地址,也可以是服务器的公共 IP 地址
PORT = 25535 # 端口号,可以自定义一个未被占用的端口号

# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定主机和端口
server_socket.bind((HOST, PORT))

# 开始监听,允许最多一个连接请求
server_socket.listen(1)
print(f"Server is listening on {HOST}:{PORT}...")

# 等待客户端连接
client_socket, client_address = server_socket.accept()
print(f"Connected by {client_address}")

# 接收数据并回显
while True:
data = client_socket.recv(1024) # 接收数据,最多 1024 字节
if not data:
break
print(f"Received from client: {data.decode()}")
client_socket.sendall(data) # 将接收到的数据返回给客户端

# 关闭连接
client_socket.close()
server_socket.close()

本地脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 客户端代码 client.py
import socket

# 定义服务端的主机和端口
HOST = '代理服务器的域名或者 IP' # 使用回环地址,也可以是服务器的公共 IP 地址
PORT = 17777 # 与服务端相同的端口号

# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接服务端
client_socket.connect((HOST, PORT))
print(f"Connected to server at {HOST}:{PORT}")

# 发送数据
message = "Hello, server!"
client_socket.sendall(message.encode())

# 接收数据
data = client_socket.recv(1024) # 接收数据,最多 1024 字节
print(f"Received from server: {data.decode()}")

# 关闭连接
client_socket.close()

经过 nginx 代理后,对外面暴漏的 IP 只是代理服务器 IP

请我喝杯咖啡吧~