Chinaunix首页 | 论坛 | 博客
  • 博客访问: 363187
  • 博文数量: 64
  • 博客积分: 2975
  • 博客等级: 少校
  • 技术积分: 831
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-14 10:59
文章存档

2014年(2)

2012年(7)

2010年(40)

2009年(5)

2008年(8)

2007年(2)

分类: LINUX

2009-04-09 17:01:53

环境:A(win2k)机器使用内网地址192.168.0.2,它通过B(linux rh9)机器NAT上网,B的eth0是外网地址,B的eth1是内网地址192.168.0.1,由于某些原因,使得这三条线接在同一个交换机上,C(linux rhel4)是另一台NAT服务器(宿舍区用),eth0外网地址,eth1内网192.168.0.1.示意图如下。
 
发生如下问题,B.eth1重启后报地址冲突,配置一个随机地址192.168.0.33,ping 192.168.0.1.arp -n有192.168.0.1的记录,在C.eth0上抓包,发现有arp应答C.eth1的地址,郁闷。
 
|------A
|------eth0 B eth1---
|                   |
|--------------------
|
|------ eth0 C eth1 -----
 
查看内核arp_rcv(kernel 2.4.0)的代码,
arp_rcv()
{
 if (arp->ar_op == __constant_htons(ARPOP_REQUEST) &&/*处理正常的ARP请求*/
     ip_route_input(skb, tip, sip, 0, dev) == 0) {/*且在路由表中找到目标IP得路由信息,并保存在skb->dst中*/
}
C接收到arp请求后会先路由
ip_route_input_slow()
{
 if (res.type == RTN_LOCAL) {//到本机
  int result;
  //验证源地址的有效性
  result = fib_validate_source(saddr, daddr, tos, loopback_dev.ifindex,
          dev, &spec_dst, &itag);
  if (result < 0)//验证失败
   goto martian_source;

}
fib_validate_source()
{
 no_addr = rpf = 0;//反向路径过滤 reserve path filter
 read_lock(&inetdev_lock);
 in_dev = __in_dev_get(dev);
 if (in_dev) {
  no_addr = in_dev->ifa_list == NULL;
  rpf = IN_DEV_RPFILTER(in_dev);
 }
 read_unlock(&inetdev_lock);
}
 
#define IN_DEV_RPFILTER(in_dev)  (ipv4_devconf.rp_filter && (in_dev)->cnf.rp_filter)
 
因此可以在在B和C上打开rp_filter,echo 1 >/proc/sys/net/ipv4/conf/all/rp_filter
这样可以保证C不再响应B上ping 192.168.0.1.
 
但是还B.eth1使用192.168.0.1地址,service network restart还是报地址冲突错
arp_rcv()
{
 if (sip == 0) {//检查IP地址是否重复
  if (arp->ar_op == __constant_htons(ARPOP_REQUEST) &&
      inet_addr_type(tip) == RTN_LOCAL)//到本机的地址/*如果DHCP询问的,且目标地址是本机地址,则ARP响应;否则将包丢弃*/
      //源mac=dev_addr,目的mac=sha,
      //源hw=目的hw=dev_addr
      //源ip=目的ip=tip
   arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr);
  goto out;
 }
}
 
可见需要丢弃这种检测包,那就使用arptables吧,正好B和C都支持
arptables -A INPUT -i eth0 -d 192.168.0.1 -j DROP
 
搞定
 
这个问题的主要症结就是B.eth1和C.eth0在同一个局域网当中,如果能隔离开,就没有这么多麻烦事了.
阅读(1127) | 评论(0) | 转发(0) |
0

上一篇:重定位总结

下一篇:统计named缓存ttl

给主人留下些什么吧!~~