我有一个应用程序在本地 Linux 计算机 A 上运行,它需要能够与另一台计算机 B 通信,侦听端口 12325。当设备默认情况下无法通信时就会出现问题,因此我在 ACL 中打开端口 12325,但源机器 A 上的应用程序端口是随机的。我可以使用iptables专门将要更改的应用程序的源端口转换为12325吗?它始终在同一用户、同一位置运行。
- 软件不是开源的,所以我无法强制这个软件方面。
- 无法打开机器之间的所有端口。
答案1
选项 1:容器
在具有显式 IP 地址的容器内运行应用程序,然后修改本地防火墙规则以允许出站连接从该特定 IP 地址。这样你就不需要知道端口;您知道特定于该 IP 地址的规则只会影响来自该应用程序的连接,而不会影响其他任何内容。这可能看起来像:
docker network create app_network --subnet 192.168.51.0/24
docker run --network my_app_network --ip 192.168.51.10 myapimage ...
然后在本地防火墙中,您可以添加如下内容:
iptables -A FORWARD -s 192.168.51.10/32 -j ACCEPT
选项 2:函数插入
假设您的应用程序是动态链接的可执行文件,您可以使用函数插入覆盖特定的库调用。在这种情况下,您可能会覆盖该connect
调用,以便bind
在建立连接之前进行调用。这可能看起来像:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#ifndef TARGET_PORT
#define TARGET_PORT 80
#endif
#ifndef SOURCE_PORT
#define SOURCE_PORT 12000
#endif
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
static int (*real_connect)(int, const struct sockaddr *, socklen_t) = NULL;
if (!real_connect)
real_connect = dlsym(RTLD_NEXT, "connect");
/*
* Only makes changes if you are initiating an AF_INET connection to
* a specific remote port. Modify the logic here, or modify
* TARGET_PORT and SOURCE_PORT, above, to change this behavior.
*/
if (
addr->sa_family == AF_INET &&
((struct sockaddr_in *)addr)->sin_port == htons(TARGET_PORT)
) {
const int enable = 1;
// Set SO_REUSEADDR, otherwise subsequent connections will fail until
// the socket exits the TIME_WAIT state.
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
return -1;
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(SOURCE_PORT);
if (bind(sockfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
return -1;
}
}
return real_connect(sockfd, addr, addrlen);
}
将代码编译到共享库:
gcc -shared -ldl -fPIC connect_with_port.c -o connect_with_port.so
然后使用以下命令激活它LD_PRELOAD
:
LD_PRELOAD=./connect_with_port.so nc google.com 80
如果您在执行上述命令时运行,tcpdump
您将看到连接源自 port 12000
。