iptables的端口范围映射
来源:互联网 发布:java urlencode解码 编辑:程序博客网 时间:2024/06/10 05:32
iptables的端口范围映射
使用iptables来进行端口映射我们似乎比较熟悉,指定一个范围的端口映射好像也略懂一二,但实际测试结果却不尽人意。
单个端口映射
一般而言要在路由器里实现一条端口映射规则,需要两个iptables规则,一条是目的地址转换一条是源地址转换。 如下(192.168.40.200是wan口地址,10.0.0.150是LAN侧主机地址):
iptables -t nat -I PREROUTING -p tcp -d 192.168.40.200 --dport 23 -j DNAT --to 10.0.0.150:23
iptables -t nat -I POSTROUTING -p tcp -s 10.0.0.150 --sport 23 -j SNAT --to 192.168.40.200:23
范围端口映射
查看man iptables可知,范围端口映射规则也挺简单,匹配源时写为--sport port[:port]
,target时写为[ipaddr][-ipaddr][:port[-port]]
。即上面单个的端口映射规则改为这种形式:
iptables -t nat -I PREROUTING -p tcp -d 192.168.40.200 --dport 23:100 -j DNAT --to 10.0.0.150:23-100
重点不在于规则怎么写,而是范围端口映射时是怎么映射?因为它可以少对多也可以多对少。例如配置[10-12]映射到[100-102],我怎么知道端口11会映射到具体那个端口,101吗? [100-200]映射到[10-20]时又会怎么样呢?
如果测试一下第一个问题会发现总是映射到100端口,不是想象的101端口。
代码跟踪
内核代码一向难度较高,这里也只是浅浅的忽悠一下。
跟踪一下DNAT target的动作,DNAT动作的代码在net/ipv4/netfilter/nf_nat_rule.c
里的ipt_dnat_target()
函数,然后进入nf_nat_setup_info()
==》 get_unique_tuple()
。
get_unique_tuple函数
1.static void2.get_unique_tuple(struct nf_conntrack_tuple *tuple,3. const struct nf_conntrack_tuple *orig_tuple,4. const struct nf_nat_range *range,5. struct nf_conn *ct,6. enum nf_nat_manip_type maniptype)7.{8. struct net *net = nf_ct_net(ct);9. const struct nf_nat_protocol *proto;10. u16 zone = nf_ct_zone(ct);11.12. /* 1) If this srcip/proto/src-proto-part is currently mapped,13. and that same mapping gives a unique tuple within the given14. range, use that.15.16. This is only required for source (ie. NAT/masq) mappings.17. So far, we don't do local source mappings, so multiple18. manips not an issue. */19. if (maniptype == IP_NAT_MANIP_SRC &&20. !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {21. if (find_appropriate_src(net, zone, orig_tuple, tuple, range)) {22. pr_debug("get_unique_tuple: Found current src map\n");23. if (!nf_nat_used_tuple(tuple, ct))24. return;25. }26. }27. printk("%s(%d)\n", __FUNCTION__, __LINE__);28. /* 2) Select the least-used IP/proto combination in the given29. range. */30. *tuple = *orig_tuple;31. find_best_ips_proto(zone, tuple, range, ct, maniptype);32.33. /* 3) The per-protocol part of the manip is made to map into34. the range to make a unique tuple. */35.36. rcu_read_lock();37. proto = __nf_nat_proto_find(orig_tuple->dst.protonum);38.39. /* Only bother mapping if it's not already in range and unique */40. if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM) &&41. (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||42. proto->in_range(tuple, maniptype, &range->min, &range->max)) &&43. !nf_nat_used_tuple(tuple, ct))44. goto out;45.46. /* Last change: get protocol to try to obtain unique tuple. */47. proto->unique_tuple(tuple, range, maniptype, ct);48.out:49. printk("%s(%d)\n", __FUNCTION__, __LINE__);50. rcu_read_unlock();51.}52.
重点在第40行的判断,里面的proto->in_range(tuple, maniptype, &range->min, &range->max)
会判断原tuple的端口是否在映射的端口范围内,如果在那就基本要直接goto out了。否则会进入proto->unique_tuple
==> tcp_unique_tuple
==>nf_nat_proto_unique_tuple
。
nf_nat_proto_unique_tuple函数,看这一句就好了
1.for (i = 0; ; ++off) {2. *portptr = htons(min + off % range_size);3. if (++i != range_size && nf_nat_used_tuple(tuple, ct))4. continue;5. if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))6. *rover = off;7. return;8. }
portptr为传出的参数,就是映射到这个端口啦。min为映射端口范围的最小值,off为偏移,大多数时候为0,range_size为端口范围大小。所以进到这里一般情况下,就会映射范围端口里面最小的端口。
结论
当匹配的端口在映射端口的区间内时,那么端口号不会被修改。如果匹配端口不在映射端口的区间内,则大多数情况下映射端口号为最小的端口号,即映射端口号是不可预测的。
举例: [1000-2000] 映射到[1000-2000]时会一一映射
[1000-2000] 映射到[3000-4000]结果不可预知,一般会映射到3000端口。
- iptables的端口范围映射
- Linux iptables 端口 映射案例
- Linux下iptables 禁止端口和开放端口(仅供参考,里面含有iptables如何指定允许外网访问的端口号范围,以及对局域网的ip全部开放端口)
- 华为sug 6000 系列防火墙端口范围映射
- 端口范围
- 端口范围
- 用iptables做IP的静态映射
- 用iptables做IP的静态映射
- iptables实现端口转发的过程
- iptables实现端口转发的过程
- 如何利用iptables的端口转发
- 为iptables开放新的网络端口
- iptables开放端口的使用方法总结
- iptables 用于linux端口的开关
- iptables开放端口的使用方法总结
- iptables限制某个端口的连接数
- Linux采用iptables端口转发的配置
- 消息映射范围的处理程序
- Ubuntu如何查看计算机安装好Cuda
- 《申请微信公众号》
- Vijos 1131题:最小公倍数和最大公约数问题
- Windows C++程序崩溃产生dmp调试
- CSS2.0盒模型与层模型
- iptables的端口范围映射
- swap 脚本
- MAC Tomcat 配置
- NS3 可视化工具详解
- HTML4(一)
- ACM 水题
- HTML4(二)
- Unity下实现断点续传的下载方式
- Android 判断app是否第一次安装。