公网局域网映射
公网局域网映射
见 "网络工具/转发工具"
GPT
Nginx方案
我有一台公网Debian设备(8.134.151.111)和局域网Ubuntu设备(192.168.31.164),两台机器在不同的环境,我想将公网的8081端口映射到局域网的8081端口
实现这个目标,你需要在公网Debian设备上设置一个反向代理,这样它就可以将来自8081端口的流量转发到局域网Ubuntu设备的8081端口。你可以使用Nginx或者Apache等工具来实现这个功能。这里我提供一个使用Nginx的示例:
首先,在公网Debian设备上安装Nginx:
sudo apt-get update
sudo apt-get install nginx
然后,创建一个新的Nginx配置文件,例如/etc/nginx/conf.d/reverse-proxy.conf
,并添加以下内容:
server {
listen 8081;
location / {
proxy_pass http://192.168.31.164:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
最后,重启Nginx:
sudo service nginx restart
这样,公网的8081端口就被映射到局域网的8081端口了。
但是,请注意,你需要确保公网Debian设备可以访问到局域网Ubuntu设备。如果两台设备在不同的物理网络中,你可能需要设置VPN或者其他的网络转发机制。
ssh隧道方案 (仅TCP)
公网访问不了局域网设备,局域网能访问公网
如果局域网设备可以访问公网设备,但公网设备不能访问局域网设备,那么你可以考虑使用SSH隧道技术来解决这个问题。SSH隧道可以让你在局域网设备上建立一个到公网设备的连接,然后公网设备可以使用这个连接来访问局域网设备。
局域网操作
下面是一个步骤,你可以在局域网设备上运行这些命令,以在公网设备上的8081端口和局域网设备上的8081端口之间创建一个SSH隧道:
在局域网设备上安装
ssh
和autossh
(如果尚未安装的话):sudo apt-get update sudo apt-get install ssh autossh
创建SSH密钥对(如果尚未创建的话):
ssh-keygen # 例如 $ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): id_rsa Enter passphrase (empty for no passphrase): qwe123 Enter same passphrase again: qwe123 Your identification has been saved in id_rsa Your public key has been saved in id_rsa.pub The key fingerprint is: SHA256:uS65+kL6mxnJJFCnF4d2/kVHeTskXOw1yoJFd2PJrBk root@msy The key's randomart image is: +---[RSA 3072]----+ | . o.. .+.=++.| | . ooo. ..*E*=o| |. ...o .o..==o.| | . . . o.. =+ | | . . .S. . . | | +.. .. | | o+ .. | | . .+o. | | .*=oo. | +----[SHA256]-----+
将局域网设备的公钥添加到公网设备的
~/.ssh/authorized_keys
文件中。你可以通过ssh-copy-id
命令来完成这个步骤:ssh-copy-id <公网设备用户名>@8.134.151.111 # 例如 $ ssh-copy-id root@8.134.151.215 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" The authenticity of host '8.134.151.215 (8.134.151.215)' can't be established. ED25519 key fingerprint is SHA256:cnincYMzCu8zoJ+26nAZBdayDT9QS8Mq5Sp3Fmn2zoM. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@8.134.151.215's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'root@8.134.151.215'" and check to make sure that only the key(s) you wanted were added.
使用
autossh
创建一个SSH隧道:autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -R 8081:localhost:8081 <公网设备用户名>@8.134.151.111 # 例如: $ autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -R 8081:localhost:8081 root@8.134.151.215 Enter passphrase for key '/root/.ssh/id_rsa': qwe123 Linux iZ7xv8wxsqxfla1txzmm8lZ 5.10.0-21-amd64 #1 SMP Debian 5.10.162-1 (2023-01-21) x86_64 Welcome to Alibaba Cloud Elastic Compute Service ! Last login: Fri Nov 3 10:58:22 2023 from 27.45.72.99
这样,公网设备上的8081端口就被映射到了局域网设备的8081端口。
公网操作
注意,你可能需要在公网设备上修改SSH配置以允许远程端口转发。这可以通过编辑/etc/ssh/sshd_config
文件并添加或修改以下行来完成:
GatewayPorts yes
然后重启SSH服务:
sudo service ssh restart
这个设置将允许从公网设备的任何地址连接到转发的端口。如果你只想从公网设备本身连接到转发的端口,你可以将GatewayPorts
设置为localhost
。
验证
curl http://localhost:8081
Windows版
与上面差不多,保证好公网配置好和局域网安装好ssh后,powershell:
ssh -R 8080:localhost:8080 root@8.134.151.215
如果你想让这个SSH隧道在后台运行,你可以添加-f -N
参数:
ssh -f -N -R 52955:localhost:52955 <公网设备用户名>@8.134.151.111
iptable方案 (可UDP)
在这种情况下,你可以在Linux A上使用iptables进行端口转发。这需要在Linux A上运行的网络防火墙配置中进行一些修改。
以下是一种可能的iptables规则配置方式:
# 允许转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 设置NAT规则
iptables -t nat -A PREROUTING -p udp --dport 7000 -j DNAT --to-destination [LinuxB的内网IP地址]:7000
iptables -t nat -A POSTROUTING -p udp -d [LinuxB的内网IP地址] --dport 7000 -j SNAT --to-source [LinuxA的公网IP地址]
这里的规则意味着:
- 当一个UDP包到达Linux A的7000端口时,PREROUTING规则会将它的目标地址更改为Linux B的内网IP地址,端口保持为7000。
- 当Linux B向Linux A响应UDP包时,POSTROUTING规则会将源地址更改为Linux A的公网IP地址,这样对于外部的客户端来说,就像是与Linux A进行通信一样。
注意这里的IP地址需要替换为你实际的IP地址。同时,确保Linux A的防火墙允许7000端口的UDP流量。
这种方式需要Linux A具有路由到Linux B的能力,也就是说,Linux A需要知道如何将包发送到Linux B。如果Linux A和Linux B在同一个子网内,或者Linux A知道去往Linux B的路由,那么这通常不是问题。
此外,这种设置可能需要root权限才能进行。如果你没有root权限,你可能需要联系你的系统管理员。
最后,这些更改可能在重启后失效。如果你希望它们在重启后仍然有效,你可能需要将这些命令添加到启动脚本中,或者使用iptables持久化工具,如iptables-persistent
。
这是一个基础的解决方案,实际的网络环境可能会更复杂,需要更多的配置。例如,如果你的网络中有其他的防火墙或路由设备,你可能需要在这些设备上进行额外的配置。
openVPN (可UDP)
对不起,我之前没有完全理解你的问题。你的情况是Linux A无法直接访问Linux B,但Linux B可以访问Linux A,并且你希望进行UDP流量的转发。这确实比我之前描述的更复杂一些。
你可以考虑使用SSH隧道的UDP版本,也就是VPN。如果你有权限在Linux B上运行服务,那么你可以在那里设置一个VPN服务器,然后在Linux A上连接到这个VPN。这样,Linux A就可以访问Linux B了,然后你就可以使用我之前描述的iptables规则进行端口转发。
OpenVPN是一种常见的VPN解决方案,它支持UDP流量。以下是一个简单的OpenVPN配置示例:
在Linux B(VPN服务器)上:
openvpn --remote [LinuxA的公网IP地址] --dev tun --ifconfig 10.8.0.1 10.8.0.2 --cipher none --auth none --proto udp
在Linux A(VPN客户端)上:
openvpn --remote [LinuxB的公网IP地址] --dev tun --ifconfig 10.8.0.2 10.8.0.1 --cipher none --auth none --proto udp
然后在Linux A上设置iptables规则进行端口转发:
iptables -t nat -A PREROUTING -p udp --dport 7000 -j DNAT --to-destination 10.8.0.1:7000
iptables -t nat -A POSTROUTING -p udp -d 10.8.0.1 --dport 7000 -j SNAT --to-source [LinuxA的公网IP地址]
这只是一个基本的示例,实际的配置可能会更复杂。例如,你可能需要考虑安全性问题,例如使用加密和身份验证而不是--cipher none --auth none
。你也可能需要根据你的网络环境调整--ifconfig
参数。
请注意,这种方法需要Linux B可以访问Linux A,而且需要在两台机器上都安装OpenVPN。如果你不能在Linux B上运行服务,那么这种方法可能无法工作。