我有一台由提供商托管的服务器,该提供商使用 Cisco ASA 进行 nat。我遇到的问题是,使用公共 IP 进行 nat 的内部服务器会将其公共 IP 视为源 IP。这基本上会破坏出于某种原因尝试绑定到外部 IP 的应用程序。
提供商不会在 ASA 上披露其配置,我想问是否有人可以解释这是什么类型的 nat,以及我可以要求提供商做什么 - 此时他们说这一切对他们来说都有效......
谢谢!
答案1
您的主机是否使用 DNS 名称?如果是,请询问DNS 重写在您的主机的 Cisco ASA NAT 规则上启用。
答案2
应用程序是否允许手动覆盖绑定的位置?我认为这已经排除了。
/etc/hosts 中是否列出了外部 IP?
从这里开始,我将带着这个答案走得更远一些,重点关注应用程序,而不是 nat。特别是,我将探索你可以在应用程序之外做些什么来欺骗它。这只适合绝望的人。这将假设一个 Linux 操作系统。
首先,应用程序必须以某种方式从自身外部获取 IP 地址。这最终将是文件访问 (/sys/...)、C 库调用或外部可执行文件 (/sbin/ifconfig)。我们可以尝试通过 strace 找到它如何获取此信息。
strace -f /path/to/app
输出将非常详细和技术性,但可以帮助您确定应用程序用于确定 IP 的机制。
下面是“hostname -i”的示例,它解析了我的台式机的主 IP:
strace hostname -i
execve("/bin/hostname", ["hostname", "-i"], [/* 69 vars */]) = 0
...
socket(PF_NETLINK, SOCK_RAW, 0) = 3
bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
getsockname(3, {sa_family=AF_NETLINK, pid=17272, groups=00000000}, [12]) = 0
...
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
...
open("/etc/nsswitch.conf", O_RDONLY) = 3
...
open("/etc/host.conf", O_RDONLY) = 3
...
open("/etc/resolv.conf", O_RDONLY) = 3
...
open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3
read(3, "127.0.0.1\tlocalhost\n192.168.1.4\t"..., 4096) = 338
close(3) = 0
...
write(1, "192.168.1.4\n", 12192.168.1.4
我们可以看到它尝试了几种技术,然后实际上在 /etc/hosts 文件中找到了一个匹配项。
现在,来看一下欺骗它的方法:
1) 如果应用程序从 /sys 读取,那么就很难欺骗手工制作的 chroot 环境。
2) 如果应用程序进行 C 库调用,则自定义共享库可能会随应用程序一起加载,以覆盖和更改相应库调用的行为。无关紧要的是,我曾使用过此技巧暂时禁用正常运行时需要该调用的应用程序的“fsync”调用。
3) 如果应用程序调用可执行文件 (/sbin/ifconfig?),则可以用选择性地仅针对此应用程序改变其行为的版本替换此可执行文件。考虑仅为应用程序设置环境变量并检查自定义可执行文件。
这可能与主题无关并且不是具体的,但我只想分享一个高层次的想法,即当所有其他选项都已用尽并且你只需要“让它工作”时,如何欺骗应用程序。
答案3
好吧,我明白了。我对 NAT 路由器也有同样的抱怨。当你无法从内部连接到外部视点时,这真是令人沮丧。许多路由器经常出现这种情况。
您可以通过在 Linux iptables 中使用 NAT 来解决此问题,将尝试连接到外部 IP 的尝试重定向为连接到内部 IP 的连接。应用程序甚至不知道其连接目的地已被更改。出于所有目的,它会认为它已连接到外部。
它可能类似于:
/sbin/iptables -t nat -A OUTPUT \
-p tcp \
-d $EXTERNAL_IP \
--dport $EXTERNAL_PORT \
-j DNAT --to-destination $INTERNAL_IP:$INTERNAL_PORT
您可以随意选择,甚至只对具有“-m Owner!--uid-owner 0”类型匹配的特定用户执行此 NAT。