免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2731 | 回复: 0
打印 上一主题 下一主题

1个ipfw规则脚本(feebsd+ipfw+dummynet+http透明代理) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-11-02 17:44 |只看该作者 |倒序浏览
本帖最后由 kkkggg 于 2013-11-21 17:01 编辑

备忘。
dummynet的动态带宽分配功能很好用。在共享上网的环境下,要限制某些上传流量过大堵塞网络的ip的时候,按ip数动态分配带宽比按优先级或分配固定带宽的方式要更有效。

下面先简单描述一下数据包经过本防火墙规则匹配的流程,方便理清规则制定思路。复杂的地方在于本规则同时使用了透明代理和单ip流量控制以及状态规则。
以下规则适用于系统参数net.inet.ip.fw.one_pass为1时的情况。即数据包只在同一方向放行一次。

如果把数据包按经过接口方向划分类别的话,ipfw规则主要有in和out两大方向,再乘以接口数就等于数据包接口方向类型总数。每种类型的数据包只匹配于同种类型的规则(一条规则可能属于多种类型)。比方说通常一个数据包从内网传输到外网被看做是经过一个方向,但实际上这个数据包要至少匹配ipfw规则中的两种规则:内网in方向和外网out两种规则。
一般情况下(有一块内网网卡,一块外网网卡)的ipfw规则按接口方向分为6类
环路接口in
环路接口out
内网接口in
外网接口out
外网接口in
内网接口out


#环路接口in

放行所有数据包

#环路接口out

放行所有数据包

#内网接口in

拒绝指定的数据包
check-state
skipto跳转需要放行并进行上行流量控制的数据包到拒绝规则后面,并加上keep-state
拒绝未匹配到的数据包
动态单个ip上行流量控制(因为涉及http代理,所以在这里进行每个ip上行流量控制。因为在外网接口那里已经分不出经过代理的http数据包原始源ip,无法很好的为每个ip分配带宽)

#外网接口out

skipto跳转不需要http代理的数据包到fwd规则后面
fwd重定向访问http端口的数据包到本地http代理服务端口
nat源地址转换

#外网接口in

拒绝指定的数据包
nat目的地址转换

#内网接口out

check-stat
放行所有数据包


制定规则时,可以先按各个方向分别制定规则,然后把各个方向的规则根据优先级顺序拼在一起。规则匹配次数不一样,对CPU造成的负荷不一样。所以应该把匹配最频繁、最多数量的数据包的规则尽量靠前。check-state规则在每个方向上都进行匹配,要特别小心。由于本规则在内网in和外网out方向均有跳转语句,且跳转到的规则动作不同。要想两个这方向的规则互不影响的话,要把外网out规则放到前面,check-state放到中间,带状态的内网in规则放到后面。

下面是规则代码,nat用的是libalias
  1. #定义网络接口名变量

  2. ext_if="tun0"
  3. int_if="xl0"
  4. lan_net="10.0.0.0/22"

  5. #定义细分类端口变量(规则中不直接引用此类变量名,只为方便标识,后面会合并到主要分类中)

  6. general_tcp_ports="25,53,110,143,443,636,993,995"        #smtp,dns,pop3,imap,https,ldap,ipops,imaps
  7. general_udp_ports="53,123"                #dns,ntp
  8. msn_tcp_ports="569,1503,1863,5061,7001"
  9. government_tcp_ports="5222,5678,7002,7888,8980"                #某些政府服务器端口
  10. working_tcp_ports="212,1433,3306"        #,mssql,mysql
  11. qq_udp_ports="8000"

  12. #定义主要分类端口变量(会在规则中直接引用的变量名)

  13. http_proxy_ports="80"

  14. #用户组1额外开放的端口
  15. group1_tcp_ports="22,6618,8000,8080,9898"      #ssh,酷狗,手机软件,手机软件,手机软件
  16. group1_udp_ports="3545,6618"             #酷狗,酷狗

  17. #定义特殊应用1的目的端口
  18. special_app1_tcp_ports="8080"                #手机QQ

  19. #合并先前的细类,注意引号内不能有空格,一条规则端口参数项最多为30个
  20. permitted_tcp_ports_1="$general_tcp_ports,$msn_tcp_ports,$government_tcp_ports,$working_tcp_ports"
  21. permitted_udp_ports_1="$general_udp_ports,$qq_udp_ports"

  22. #本机开启服务端口
  23. localhost_tcp_service="3000,3128,10000"                #ntop,squid,webmin
  24. localhost_udp_service="53,123"                #dns,dhcp,ntp

  25. #清空系统中已有的规则
  26. ipfw -q flush
  27. ipfw -q table all flush
  28. ipfw -q pipe flush

  29. #定义ip地址表

  30. #定义私有网络地址表priv_net
  31. ipfw table 5 add 127.0.0.0/8
  32. ipfw table 5 add 192.168.0.0/16
  33. ipfw table 5 add 172.16.0.0/12
  34. ipfw table 5 add 10.0.0.0/8

  35. #定义拒绝的外网源地址
  36. ipfw table 10 add 200.0.0.1/32                #sample

  37. #定义无网络权限客户机ip
  38. ipfw table 15 add 10.0.1.25/32                #xxx

  39. #定义拒绝访问目的地址ip
  40. ipfw table 20 add 220.164.144.207

  41. #无限制端口服务器地址
  42. ipfw table 25 add 202.105.113.38/32

  43. #定义允许访问所有tcp端口的目的地址(http端口数据包依然要通过代理服务)
  44. ipfw table 30 add 116.228.70.245/32     #圆通物流

  45. #定义高访问权限客户机ip地址(除了不允许访问的外网ip不能访问外)
  46. ipfw table 35 add 10.0.0.9/32                #test
  47. ipfw table 35 add 10.0.0.63/32                #voip

  48. #定义不经过squid代理,直接访问的服务器ip地址
  49. ipfw table 40 add 202.128.247.44/32        #海关物品编码查询
  50. ipfw table 40 add 58.61.142.185/32        #顺丰快递查单
  51. ipfw table 40 add 14.17.29.0/24                #qq离线文件服务器
  52. ipfw table 40 add 113.108.0.0/19        #qq离线文件服务器
  53. ipfw table 40 add 113.142.0.0/19        #qq离线文件服务器
  54. ipfw table 40 add 115.236.128.0/19        #qq离线文件服务器
  55. ipfw table 40 add 124.115.10.0/24        #qq离线文件服务器
  56. ipfw table 40 add 182.131.0.0/19        #qq离线文件服务器
  57. ipfw table 40 add 182.140.128.0/19        #qq离线文件服务器
  58. ipfw table 40 add 119.146.200.0/27        #网易云阅读

  59. #定义不经过squid代理的客户机ip
  60. ipfw table 45 add 10.0.1.64/32                #xxx

  61. #定义访问与$special_app1_tcp_ports端口对应的地址
  62. ipfw table 50 add 121.14.64.0/18        #手机QQ

  63. #定义用户组group1地址
  64. ipfw table 55 add 10.0.0.3/32                #xxx
  65. ipfw table 55 add 10.0.1.64/32                #xxx





  66. #规则开始


  67. #允许本地lo0接口双向访问
  68. ipfw -q add 100 allow all from any to any via lo0

  69. #放行发往内网的数据包
  70. ipfw -q add 200 allow all from any to $lan_net out xmit $int_if

  71. #丢弃指定外网ip发过来的数据包
  72. ipfw -q add 300 deny ip from table\(10\) to any in recv $ext_if

  73. #拒绝无网络权限客户机ip
  74. ipfw -q add 400 reject ip from table\(15\) to any in recv $int_if

  75. #丢弃ip分片包
  76. ipfw -q add 500 deny ip from any to any in frag

  77. #拒绝欺骗数据包进入
  78. ipfw -q add 600 deny ip from me to any in
  79. #ipfw -q add 700 deny ip from table\(5\) to any in recv $ext_if

  80. #NAT接收到的外网接口的数据包
  81. ipfw -q nat 1 config if $ext_if                #nat绑定到外网接口
  82. ipfw -q add 999 nat 1 ip from any to any in recv $ext_if                #nat从外网来的数据包

  83. #放行管理员客户机
  84. #ipfw -q add 1100 allow ip from 10.0.1.10/32 to any in
  85. #ipfw -q add 1200 allow ip from any to 10.0.1.10/32 out

  86. #允许内网ssh连接本机(没使用状态规则,避免刷新规则时断开连接)
  87. ipfw -q add 1300 allow tcp from any to me 22 in recv $int_if
  88. #ipfw -q add 1400 allow tcp from me 22 to any out xmit $int_if

  89. #允许本机dhcp服务
  90. ipfw -q add 1500 allow udp from any 68 to any 67 in recv $int_if
  91. #ipfw -q add 1600 allow udp from me 67 to any 68 out xmit $int_if

  92. #让不使用http代理的数据包跳过下面的2999转发规则
  93. ipfw -q add 1700 skipto 3999 tcp from any to table\(25\) out recv $int_if        #无限制外网ip
  94. ipfw -q add 1800 skipto 3999 tcp from table\(35\) to any out recv $int_if        #无限制用户
  95. ipfw -q add 1900 skipto 3999 tcp from any to table\(40\) $http_proxy_ports out recv $int_if        #访问指定不使用http代理的服务器地址
  96. ipfw -q add 2000 skipto 3999 tcp from table\(45\) to any $http_proxy_ports out recv $int_if        #指定不使用http代理的客户机

  97. #转发从内网接口进入的要出去的端口为$http_proxy_ports的非本机数据包到本机的3128端口(squid代理)
  98. ipfw -q add 2999 fwd 127.0.0.1,3128 tcp from $lan_net to not me $http_proxy_ports out recv $int_if

  99. #NAT要从外网接口出去的数据包
  100. ipfw -q add 3999 nat 1 ip from $lan_net to any out xmit $ext_if

  101. #状态检查
  102. ipfw -q add 4999 check-state

  103. #拒绝访问指定目的地址
  104. ipfw -q add 5100 reject ip from any to table\(20\) in recv $int_if

  105. #允许指定放行的上行数据跳到规则10100进行流量控制

  106. #放行访问指定本地服务端口的数据包(带状态)
  107. ipfw -q add 5200 skipto 10100 udp from any to me $localhost_udp_service in recv $int_if keep-state
  108. ipfw -q add 5300 skipto 10100 tcp from any to me $localhost_tcp_service in setup recv $int_if keep-state

  109. #放行访问任意端口的指定服务器地址
  110. ipfw -q add 5400 skipto 10100 ip from any to table\(25\) in recv $int_if keep-state

  111. #放行内网进入,访问网页代理端口$http_proxy_ports的数据包
  112. ipfw -q add 5500 skipto 10100 tcp from any to any $http_proxy_ports in recv $int_if

  113. #放行内网进入,$permitted_tcp_ports_1指定tcp端口的数据包
  114. ipfw -q add 5600 skipto 10100 tcp from any to any $permitted_tcp_ports_1 in setup recv $int_if keep-state

  115. #放行内网进入,$permitted_udp_ports_1指定udp端口的数据包
  116. ipfw -q add 5700 skipto 10100 udp from any to any $permitted_udp_ports_1 in recv $int_if keep-state

  117. #允许访问所有tcp端口的指定目的地址(http依然要通过代理)
  118. ipfw -q add 5800 skipto 10100 tcp from any to table\(30\) in setup recv $int_if keep-state

  119. #放行高访问权限客户机
  120. ipfw -q add 5900 skipto 10100 ip from table\(35\) to any in recv $int_if keep-state

  121. #放行指定group1用户组指定tcp端口的数据包
  122. ipfw -q add 6000 skipto 10100 tcp from table\(55\) to any $group1_tcp_ports in setup recv $int_if keep-state

  123. #放行指定group1用户组指定udp端口的数据包
  124. ipfw -q add 6100 skipto 10100 udp from table\(55\) to any $group1_udp_ports in recv $int_if keep-state

  125. #放行访问特殊应用1目的地址和tcp端口的数据包
  126. ipfw -q add 6200 skipto 10100 tcp from any to table\(50\) $special_app1_tcp_ports in setup recv $int_if keep-state        #手机QQ

  127. #放行icmp
  128. ipfw -q add 6300 skipto 10100 icmp from any to any in recv $int_if keep-state

  129. #拒绝以上规则未匹配到的内网数据包并返馈回源地址
  130. ipfw -q add 9999 reject ip from $lan_net to any in recv $int_if

  131. #流量控制(包括http代理在内的本机外出数据包没有到达这里的流量控制规则)

  132. #内网接口上绑定队列
  133. ipfw -q add 10100 queue 1 ip from $lan_net to not me in recv $int_if
  134. ipfw -q add 10200 queue 1 tcp from $lan_net to me 3128 in recv $int_if        #直接访问本机http代理的数据包

  135. #为队列指定pipe下,设定源地址匹配掩码,按实时ip数平分带宽
  136. ipfw -q queue 1 config pipe 1 mask src-ip 0x000003ff

  137. #设定管道带宽(adsl上传带宽本应为500Kbit左右,但要为本机发出的数据包留出部分带宽,否则http代理可能无法正常工作)
  138. ipfw -q pipe 1 config bw 420Kbit/s

  139. #最后一条
  140. ipfw -q add 65000 allow ip from any to any
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP