firewalld防火墙转发流量到其他端口forward port rules

发布于:2024-07-01 ⋅ 阅读:(22) ⋅ 点赞:(0)

假设云主机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 socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&server_addr, 0, sizeof(server_addr));

    // Fill server information
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(server_port);
    server_addr.sin_addr.s_addr = inet_addr(server_ip);

    // Send UDP packet
    if (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 socket
    close(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 arguments
    if (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 Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("WSAStartup failed. Error Code : %d", WSAGetLastError());
        return 1;
    }

    // Create socket
    SOCKET 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 structure
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(server_port);
    inet_pton(AF_INET, server_ip, &serverAddr.sin_addr);

    // Send UDP packet
    int 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 socket
    closesocket(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。花生壳 就赚不到我们的钱了。


 


 


网站公告

今日签到

点亮在社区的每一天
去签到