假设云主机eth0: 47.93.27.106
tun0: inet 10.8.0.1 netmask 255.255.255.0
Show rules for a specific zone (public)
sudo firewall-cmd --zone=public --list-all
Add the tun0
interface to the public
zone:
sudo firewall-cmd --zone=public --add-interface=tun0 --permanent
Check the active zones again to confirm that tun0
has been added:
sudo firewall-cmd --get-active-zones
Add the forward port rules
sudo firewall-cmd --zone=public --add-forward-port=port=14662:proto=tcp:toport=4662:toaddr=10.8.0.2 --permanent
(10.8.0.1)开放端口14662 接收外部流量, 转发到10.8.0.2:4662
修改内核参数支持IPv4转发
sudo sysctl -w net.ipv4.ip_forward=1
sudo sh -c 'echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf'
配置NAT确保public zone的流量转到en0:
sudo iptables -t nat -A PREROUTING -p tcp --dport 14662 -j DNAT --to-destination 10.8.0.2:4662
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
确保iptables-serverices软件包安装了
sudo yum install iptables-services
保存、重启iptables,让配置生效
sudo service iptables save
sudo systemctl restart iptables
sudo systemctl enable iptables
重启防火墙firewalld
sudo firewall-cmd --reload
sudo systemctl restart firewalld
查看改动的配置
sudo firewall-cmd --list-all --zone=public
sudo iptables -L -t nat
在这台VPS上 telnet 10.8.0.2 4662
windows客户端先连接上Open***, 另一台vps
当然也可以用在线工具open-ports, TCP可以支持, UDP还是要自己写个简单的代码测试。
windows客户端
同理udp 4672
sudo firewall-cmd --zone=public --add-forward-port=port=14672:proto=udp:toport=4672:toaddr=10.8.0.2
sudo firewall-cmd --zone=public --add-forward-port=port=14672:proto=udp:toport=4672:toaddr=10.8.0.2 --permanent
sudo firewall-cmd --reload
sudo iptables -t nat -A PREROUTING -p udp --dport 14672 -j DNAT --to-destination 10.8.0.2:4672
sudo service iptables save
sudo systemctl restart firewalld
发送UDP报文
echo -n "Test UDP Packet" | nc -u 47.93.27.106 14672 # 以下C代码同理
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>int main(int argc, char *argv[]) {if (argc != 4) {fprintf(stderr, "Usage: %s <server_ip> <server_port> <message>\n", argv[0]);exit(EXIT_FAILURE);}const char *server_ip = argv[1];int server_port = atoi(argv[2]);const char *message = argv[3];int sockfd;struct sockaddr_in server_addr;// Create socketif ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("Socket creation failed");exit(EXIT_FAILURE);}memset(&server_addr, 0, sizeof(server_addr));// Fill server informationserver_addr.sin_family = AF_INET;server_addr.sin_port = htons(server_port);server_addr.sin_addr.s_addr = inet_addr(server_ip);// Send UDP packetif (sendto(sockfd, message, strlen(message), 0, (const struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {perror("Send failed");close(sockfd);exit(EXIT_FAILURE);}printf("UDP packet sent.\n");// Close socketclose(sockfd);return 0;
}
云主机VPS发到本地Windows:
打开wireshark找到tunnel adpator 用wireshark过滤条件
udp and ip.addr == 10.8.0.2 and udp.port == 4672
如果是从windows端
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <stdio.h>#pragma comment(lib, "Ws2_32.lib")int main(int argc, char* argv[]) {// Validate command-line argumentsif (argc != 4) {printf("Usage: %s <server_ip> <server_port> <message>\n", argv[0]);return 1;}const char* server_ip = argv[1];int server_port = atoi(argv[2]);const char* message = argv[3];// Initialize WinsockWSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {printf("WSAStartup failed. Error Code : %d", WSAGetLastError());return 1;}// Create socketSOCKET sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if (sockfd == INVALID_SOCKET) {printf("Socket creation failed. Error Code : %d", WSAGetLastError());WSACleanup();return 1;}// Server address structuresockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(server_port);inet_pton(AF_INET, server_ip, &serverAddr.sin_addr);// Send UDP packetint bytesSent = sendto(sockfd, message, strlen(message), 0, (sockaddr*)&serverAddr, sizeof(serverAddr));if (bytesSent == SOCKET_ERROR) {printf("Send failed. Error Code : %d", WSAGetLastError());closesocket(sockfd);WSACleanup();return 1;}printf("UDP packet sent.\n");// Close socketclosesocket(sockfd);WSACleanup();return 0;
}
udp_sender.exe 47.93.27.106 14672 "Test UDP Packet"
服务端: sudo tcpdump -i any udp port 14672 -XX
这样,借助Open***, iptables & firewalld 在没有公网IP的条件下把本机TCP 4662 映射到远程云主机 TCP 14662, 把本机UDP 4672映射到远程云主机UDP 14672。花生壳 就赚不到我们的钱了。