LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2337|回复: 15

做NAT后如何获得从外网访问的真实IP?

[复制链接]
发表于 2005-10-24 21:40:29 | 显示全部楼层 |阅读模式
打算用一台Linux实现共享上网、指向内部一台web服务器,于是按照最傻瓜的思路,准备两个外网IP,一个用于共享上网,一个用于专门访问内网的web服务器
下面是实现脚本,基本实现上面的两个要求
但是我发现web服务器那里不能够取得真实的客户端地址,所有外网访问的客户端IP都变成了10.168.172.254,请问怎么设置才能取得真实的客户端IP呢?
另外,能不能将两个互联网IP精简到一个呢?毕竟互联网的IP比较贵。
最后,当然是希望各位看官能够指出其中不安全的地方,让我好向老板交代吧。谢谢各位!

# eth0 = 10.168.172.254 (内网)
# eth1 = 61.143.A.B (互联网IP)
# eth1:0 = 61.143.A.C (互联网IP)(跟上面的eth1同一个网卡)
# 上述已经设置好,可用。
#
# 操作目标:
# 1.使得内网的计算机的网关用 10.168.172.254 就能访问互联网,浏览网页、上QQ等;
# 2.使得互联网上的用户输入 61.143.A.C 或 www.xxxxxx.com (指向61.143.A.C) 就能访问内网的OA服务器,并且被web识别真实IP(即通过互联网访问时候,web服务器得到客户端的IP不是10.168.172.254而是客户端的互联网IP


# 允许转发

echo 1 > /proc/sys/net/ipv4/ip_forward

# 共享一个Internet连接 针对 61.143.A.B

iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -o eth1 -j SNAT --to 61.143.A.B

# 指向内部OA服务器 针对 61.143.A.C

iptables -t nat -A PREROUTING -d 61.143.A.C -p tcp --dport 80 -j DNAT --to 10.168.172.242
iptables -t nat -A POSTROUTING -d 10.168.172.242 -p tcp --dport 80 -j SNAT --to 10.168.172.254
发表于 2005-10-25 00:26:54 | 显示全部楼层
其实很简单的,你自己把规则给写复杂了:)
iptables -t nat -A POSTROUTING -d 10.168.172.242 -p tcp --dport 80 -j SNAT --to 10.168.172.254

这个SNAT没有必要了,如果有的话,外网来的地址都被SNAT成你的10.168.172.254了,所以都看不见了

或者换成:
iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -d 10.168.172.242 -p tcp --dport 80 -j SNAT --to 10.168.172.254
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-25 14:58:55 | 显示全部楼层
您的意思是三条规则写成一条吗?
就字面上看我认为是不能满足我的要求的,因为我上面要求 61.143.A.B 和 61.143.A.C 两个外网IP实现的功能不同。

补充:
现在我用楼上列的那条规则代替我的第三条规则,结果在互联网访问不了内网的Web服务器。
回复 支持 反对

使用道具 举报

发表于 2005-10-25 23:40:19 | 显示全部楼层
如果删除第三条,默认是可以访问的,如果不能访问,说明你的oa本身访问网络就有问题,检查默认网关是否有设置,但是在内网机器通过使用61.143.A.C就无法访问oa系统了,所以后来我又把第三条改成

iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -d 10.168.172.242 -p tcp --dport 80 -j SNAT --to 10.168.172.254

这个方法肯定是可行的,如果不行,到你的oa上安装一个听包的软件,看看数据包是否收到,如果收到了,看是否有回应(防止防火墙,机器本身的把那些地址给block掉了),如果有回应,到你的NAT网关上使用tcpdump看出入的数据包是否对称
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-26 15:05:46 | 显示全部楼层
OA的网关是 10.168.172.1 而不是 10.168.172.254。 OA本身访问网络是没有问题的,在OA服务器上可以访问自己、内网上其他机器、互联网。

OA上也没有安装任何防火墙软件或者做iptables之类的规则(OA是Windows2000服务器上的)。鉴于《Iptables 指南1.1.19》中说这种情况不能取得真实的IP,我打算放弃这种想法。
回复 支持 反对

使用道具 举报

发表于 2005-10-26 18:01:25 | 显示全部楼层
对于这个问题,我一直坚持我的观点,是可以实现的:
你也可以访问: http://elm.freetcp.com:8080/cgi-bin/test.cgi
在NAT主机上使用:
iptables -t nat -A PREROUTING -p tcp -m tcp -d 202.118.0.251 --dport 8080 -j DNAT --to 192.168.11.18:80
做的端口重定向

测试结果:
[wenzk@lh3k ~]$ telnet elm.freetcp.com 8080
Trying 202.118.0.251...
Connected to elm.freetcp.com (202.118.0.251).
Escape character is '^]'.
GET /cgi-bin/test.cgi HTTP/1.0

HTTP/1.1 200 OK
Date: Wed, 26 Oct 2005 17:56:49 GMT
Server: Apache/2.0.52 (Fedora)
Connection: close
Content-Type: text/plain; charset=UTF-8

REMOTE_ADDR="218.90.169.125"
REMOTE_PORT="55662"
SERVER_ADDR="192.168.11.18"
SERVER_PORT="80"
Connection closed by foreign host.
[wenzk@lh3k ~]$ netstat -na | grep 22
tcp        0      0 :::22                       :::*                        LISTEN
tcp        0     48 ::ffff:192.168.2.50:22      ::ffff:202.118.0.251:37319   ESTABLISHED

同样你也可以看到,我现在登录的这个机器也是NAT后面的机器,这个是netstat的状态

至于那个手册为什么说不行,这个我也不知道:)我是实际试验出来的,因为以前我也这样弄过一台机器,使用netstat的时候发现建立的连接都现实真实IP地址
回复 支持 反对

使用道具 举报

发表于 2005-10-27 04:18:06 | 显示全部楼层
SERVER_ADDR="192.168.11.18"
SERVER_PORT="80"

这个是 elm.freetcp.com 的内网地址,是不是?
回复 支持 反对

使用道具 举报

发表于 2005-10-27 04:25:33 | 显示全部楼层

当匹配了一条规则以后,对于后面的规则是否还需要匹配我也不是很清楚,
所以这里假设匹配了PREROUTING里面的规则后,不是发送给LOCAL的包 在经过FORWARD和POSTROUTING时还需要匹配处理
因为 按照两位在上面所讲的情况 觉得 当匹配了一个chain的规则后 在经过后面的chains时应该是还需要处理的
按三种情况理解了一下上面两位的RULES 因为我也理解不是很清楚 望高手赐教
但是 我觉得 如果不要第三条规则不是很好吗 什么事有没有, 不知道diekiss这第三条规则到底想要干什么(难道是避免回路吗?但是去掉第三条规则,应该一切正常吧,但是我没有试过)
   
iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -o eth1 -j SNAT --to 61.143.A.B

iptables -t nat -A PREROUTING -d 61.143.A.C -p tcp --dport 80 -j DNAT --to 10.168.172.242

iptables -t nat -A POSTROUTING -d 10.168.172.242 -p tcp --dport 80 -j SNAT --to 10.168.172.254

(1)
从内网访问10.168.172.242,直接交付

(2)
从内网10.168.172.3访问61.143.A.C或者www.xxx.com
从eth0收到包 SIP=10.168.172.3         DIP=61.143.A.C
进入PREROUTING  第二条规则生效
SIP=10.168.172.3        DIP=10.168.172.242                           
根据DIP查ROUTE TABEL,连接10.168.172.242的包的DEV是eth0,因为这个包不是给LOCAL的所以再经过FORWARD,
经过POSTROUTING 第三条规则生效
SIP=10.168.172.254 于是WEB纪录的是这个IP
由eth0把这个包交到10.168.172.242

(3)
从外网219.140.X.X访问61.143.A.C或者www.xxx.com
从eth1:0收到包 SIP=10.168.172.3         DIP=61.143.A.C
进入PREROUTING  第二条规则生效
SIP=219.140.X.X        DIP=10.168.172.242                           
根据DIP查ROUTE TABEL,连接10.168.172.242的包的DEV是eth0,因为这个包不是给LOCAL的所以再经过FORWARD,
经过POSTROUTING 第三条规则生效
SIP=10.168.172.254 于是WEB纪录的是这个IP
由eth0把这个包交到10.168.172.242



假如按wenzk改掉第三条

iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -o eth1 -j SNAT --to 61.143.A.B

iptables -t nat -A PREROUTING -d 61.143.A.C -p tcp --dport 80 -j DNAT --to 10.168.172.242

iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -d 10.168.172.242 -p tcp --dport 80 -j SNAT --to 10.168.172.254

对于上面的3种情况 (1)情况下 没有影响
(2)
从内网10.168.172.3访问61.143.A.C或者www.xxx.com
从eth0收到包 SIP=10.168.172.3         DIP=61.143.A.C
进入PREROUTING  第二条规则生效
SIP=10.168.172.3        DIP=10.168.172.242                           
根据DIP查ROUTE TABEL,连接10.168.172.242的包的DEV是eth0,因为这个包不是给LOCAL的所以再经过FORWARD,
经过POSTROUTING 第三条规则生效 SIP 是 10.168.172.0/24网络的 所以改变
SIP=10.168.172.254
由eth0把这个包交到10.168.172.242
这时没有真实纪录IP

(3)
从外网219.140.X.X访问61.143.A.C或者www.xxx.com
从eth1:0收到包 SIP=10.168.172.3         DIP=61.143.A.C
进入PREROUTING  第二条规则生效
SIP=219.140.X.X        DIP=10.168.172.242                           
根据DIP查ROUTE TABEL,连接10.168.172.242的包的DEV是eth0,因为这个包不是给LOCAL的所以再经过FORWARD,
经过POSTROUTING 第三条规则生效,SIP=219.140.X.X 不匹配这条规则 , 于是按照默认处理被DENY掉了
所以从外网连接就访问不了了
回复 支持 反对

使用道具 举报

发表于 2005-10-27 08:14:51 | 显示全部楼层
Post by 黯然销魂
SERVER_ADDR="192.168.11.18"
SERVER_PORT="80"

这个是 elm.freetcp.com 的内网地址,是不是?


elm.freetcp.com 对应的IP地址就是202.118.0.251
只是在这个机器上我把8080 redirect到内网的192.168.11.18的80端口上了
回复 支持 反对

使用道具 举报

发表于 2005-10-27 08:56:40 | 显示全部楼层
Post by ruiqingzheng
当匹配了一条规则以后,对于后面的规则是否还需要匹配我也不是很清楚,


按照iptables的工作机制,在一个chain里面一般来说匹配一条规则后就不匹配后面的规则了,但是也有里外的
如:
iptables -N test
iptables -A INPUT -j test
iptables -A INPUT -s 192.168.0.0/24 -j DROP
iptables -A INPUT -j ACCEPT
iptables -A test -s 192.168.1.1 -j RETURN
iptables -A test -s 192.168.0.1 -j ACCEPT

这样,原地址是192.168.1.1这个规则在INPUT这个chain里面就匹配至少2次
第一次iptables -A INPUT -j test
第二次iptables -A INPUT -j ACCEPT


Post by ruiqingzheng
所以这里假设匹配了PREROUTING里面的规则后,不是发送给LOCAL的包 在经过FORWARD和POSTROUTING时还需要匹配处理
因为 按照两位在上面所讲的情况 觉得 当匹配了一个chain的规则后 在经过后面的chains时应该是还需要处理的
按三种情况理解了一下上面两位的RULES 因为我也理解不是很清楚 望高手赐教
但是 我觉得 如果不要第三条规则不是很好吗 什么事有没有, 不知道diekiss这第三条规则到底想要干什么(难道是避免回路吗?但是去掉第三条规则,应该一切正常吧,但是我没有试过)

iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -o eth1 -j SNAT --to 61.143.A.B

iptables -t nat -A PREROUTING -d 61.143.A.C -p tcp --dport 80 -j DNAT --to 10.168.172.242

iptables -t nat -A POSTROUTING -d 10.168.172.242 -p tcp --dport 80 -j SNAT --to 10.168.172.254


系统必须经过的chain是那是没有什么可说的,如果作路由的话 PREROUTING FORWARD POSTROUTING是必须经过的

如果没有第三条规则,外网访问61.143.A.C是没有问题的,内网就有问题了,因为内网的路径不对称,来回的路径不一致。

Post by ruiqingzheng

(1)
从内网访问10.168.172.242,直接交付


如果内网用户希望和外网一样,不想在DNS下功夫,如: 外网用户 解析www.xxx.com 是 61.143.A.C 内网用户解析的是 10.168.172.242
在这个情况下没有第三条的SNAT就有问题了

Post by ruiqingzheng

(2)
从内网10.168.172.3访问61.143.A.C或者www.xxx.com
从eth0收到包 SIP=10.168.172.3         DIP=61.143.A.C
进入PREROUTING  第二条规则生效
SIP=10.168.172.3        DIP=10.168.172.242                           
根据DIP查ROUTE TABEL,连接10.168.172.242的包的DEV是eth0,因为这个包不是给LOCAL的所以再经过FORWARD,
经过POSTROUTING 第三条规则生效
SIP=10.168.172.254 于是WEB纪录的是这个IP
由eth0把这个包交到10.168.172.242



nod,有第三条规则的时候一切正常

Post by ruiqingzheng

(3)
从外网219.140.X.X访问61.143.A.C或者www.xxx.com
从eth1:0收到包 SIP=10.168.172.3         DIP=61.143.A.C
进入PREROUTING  第二条规则生效
SIP=219.140.X.X        DIP=10.168.172.242                           
根据DIP查ROUTE TABEL,连接10.168.172.242的包的DEV是eth0,因为这个包不是给LOCAL的所以再经过FORWARD,
经过POSTROUTING 第三条规则生效
SIP=10.168.172.254 于是WEB纪录的是这个IP
由eth0把这个包交到10.168.172.242



nod,按照楼主的配置是这样记录的


Post by ruiqingzheng

假如按wenzk改掉第三条

iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -o eth1 -j SNAT --to 61.143.A.B

iptables -t nat -A PREROUTING -d 61.143.A.C -p tcp --dport 80 -j DNAT --to 10.168.172.242

iptables -t nat -A POSTROUTING -s 10.168.172.0/24 -d 10.168.172.242 -p tcp --dport 80 -j SNAT --to 10.168.172.254

对于上面的3种情况 (1)情况下 没有影响
(2)
从内网10.168.172.3访问61.143.A.C或者www.xxx.com
从eth0收到包 SIP=10.168.172.3         DIP=61.143.A.C
进入PREROUTING  第二条规则生效
SIP=10.168.172.3        DIP=10.168.172.242                           
根据DIP查ROUTE TABEL,连接10.168.172.242的包的DEV是eth0,因为这个包不是给LOCAL的所以再经过FORWARD,
经过POSTROUTING 第三条规则生效 SIP 是 10.168.172.0/24网络的 所以改变
SIP=10.168.172.254
由eth0把这个包交到10.168.172.242
这时没有真实纪录IP



nod,否则内网用户访问这个地址肯定有问题
假设没有第三条SNAT的规则
client发出去的报是:
SIP=10.168.172.3       DIP=61.143.A.C
web服务器收到的包是:
SIP=10.168.172.3       DIP=10.168.172.242
所以web服务器的回应的包是:
SIP=10.168.172.242   DIP=10.168.172.3

由于web回应的包的原地址和目的地址都是在一个LAN配,匹配web服务器上的路由表的10.168.172.0/24这条路由,经过本地连接直接递交给client主机10.168.172.3

所以cliet接收的到包是:
SIP=10.168.172.242   DIP=10.168.172.3

而和client发出去的包作比较,client期望收到的数据包是:
SIP=61.143.A.C          DIP=10.168.172.3
所以握手不成功,无法建立连接。

Post by ruiqingzheng

(3)
从外网219.140.X.X访问61.143.A.C或者www.xxx.com
从eth1:0收到包 SIP=10.168.172.3         DIP=61.143.A.C
进入PREROUTING  第二条规则生效
SIP=219.140.X.X        DIP=10.168.172.242                           
根据DIP查ROUTE TABEL,连接10.168.172.242的包的DEV是eth0,因为这个包不是给LOCAL的所以再经过FORWARD,
经过POSTROUTING 第三条规则生效,SIP=219.140.X.X 不匹配这条规则 , 于是按照默认处理被DENY掉了
所以从外网连接就访问不了了


楼主在写规则的时候没有作特殊说明
没有提到楼主的POSTROUTING这个chain的默认动作是DROP,所以我按照系统默认的处理,都是ACCEPT,如果一个chain没有任何一条规则匹配,则执行默认动作

ps:我所用那台机器的 nat table内容
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DNAT       tcp  --  0.0.0.0/0            202.118.0.251       tcp dpt:8080 to:192.168.11.18:80

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            192.168.0.0/16
SNAT       all  --  192.168.8.0/22       0.0.0.0/0           to:202.118.0.251

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination


大家访问http://elm.freetcp.com:8080的时候在POSTROUTING这个Chain也没有规则是匹配的,因为我的路由表是这样的:
202.118.0.192   0.0.0.0         255.255.255.0       U     0      0        0 eth0
192.168.11.0    192.168.11.2    255.255.255.0   UG    0      0        0 tun0
0.0.0.0         202.118.0.xxx   0.0.0.0                   UG    0      0        0 eth0

上面的POSTROUGING两条规则都指明了 -o eth0 所以对我的tun0来说没有效果
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表