| 关键词: nbsp 规则 port echo proto interface PktFilter pass local pktctl |
PktFilter使用参考 文章属性:整理文章提交:tombkeeper (tombkeeper_at_126.com) PktFilter使用参考 [email protected] /*这份文档主要是基于PktFilter 所附带的PktFilter.pdf,修正了一些原文的错误,增加了一些我自己的使用经验。 我喜欢这个防火墙主要是因为资源占用比较少,UNIX风格,没有图形界面,没有讨厌的的系统托盘图标。 和IP Filter一样,这个防火墙不是为对安全一无所知或者略有所知的人设计的,要打算使用它请确定你了解TCP/IP 协议等基础知识。如果对程序有问题,请写信问程序作者:[email protected]。如果对使用有问题,也请写信问作者。我对这份文档、规则生成脚本、修改过的程序不提供任何支持。*/ PktFilter是一个运行在Windows 2000/XP/2003上的包过滤防火墙。 PktFilter自己并没有实现网络过滤驱动,事实上它是系统本身包过滤机制的一个配置界面。Windows 2000以上的操作系统都有一个IpFilterDriver 服务,但是系统本身却没有提供好用的配置界面。 因为是调用系统自身的机制,所以PktFilter工作得很稳定,占用资源也较少,但也正因为如此,PktFilter的功能实现也受限于系统。 PktFilter的规则语法其实是IP Filter4的一个子集。可以参考http://www.ipfilter.org/。 ----------安装使用:---------- 为PktFilter创建一个目录,将pktfltsrv.exe和pktctl.exe拷贝进来。 创建规则文件。大家可以根据下面介绍的语法自己编写规则。如果把PktFilter安装在一台作为网关的机器上,并编写相应的规则,那么PktFilter 可以很好地作为一个网络防火墙工作。 如果只是用来保护个人计算机,不需要设置太复杂的规则,那么你可以使用我写的脚本rulesbuild.cmd。只需设置文件开头的一些变量,就可以迅速地生成一个规则。 安装启动服务:C:\PktFilter> pktfltsrv -i "C:\PktFilter\PktFilter.conf" "C:\PktFilter\PktFilter.log" C:\PktFilter> net start pktfilter -------------过滤规则介绍:------------- 全局选项 option small_frags, 拒绝太小的的分片包,默认small_frags是指小于16 bytes的 分片包。这个值可以通过建立注册表 HKLM\SYSTEM\CurrentControlSet\Services\IpFilterDriver\FragmentThreshold 来设定。 strong_host, 这个文档里面没说,但是程序支持,MSDN的解释是 “Causes a check of the destination address of incoming packets.” check_frags,这个文档里面没说,但是程序支持,MSDN的解释是 “Causes a check of the fragments from the cache.”过滤动作 pass, 允许 block, 阻塞 方向 in, 进来的 out, 出去的 协议 proto, 包括: tcp, TCP 协议 udp, UDP 协议 icmp, ICMP 协议 [number], 指定其他的IP协议号 [empty], 所有协议 源地址 from [addr], 指定一个IPv4地址 from [subnet/mask],指定一个网络 源端口(仅限TCP/UDP协议) port [表达式] [端口号] 表达式包括: = >= > <= < >< 端口范围 目标地址 to [addr], 指定一个IPv4地址 to [subnet/mask],指定一个网络 目标端口(仅限TCP/UDP协议) port [表达式] [端口号] 表达式包括: = >= > <= < >< 端口范围 ICMP类型和代码 icmp-type [type] icmp-code [code] TCP连接建立 established, 阻塞只有SYN标志位而没有ACK标志位的TCP包,放在规则末尾表示 只允许连接建立后的TCP包通过。 -----例子:----- # drop packets composed of small fragmentsoption small_frags on eth0# default behavior = deny everythingblock in on eth0 allblock out on eth0 all# allow DNS resolution to our nameserverpass out on eth0 proto udp from 192.168.1.1 port > 1023 to 192.168.1.254 port = 53pass in on eth0 proto udp from 192.168.1.254 port = 53 to 192.168.1.1 port > 1023# allow inbound ICMP traffic (ping)pass in on eth0 proto icmp from any to 192.168.1.1 icmp-type echopass out on eth0 proto icmp from 192.168.1.1 type echo-rep to any# allow RDP (Terminal Services) administration from our administration subnetpass in on eth0 proto tcp from 10.42.42.0/24 port > 1024 to 192.168.1.1 port = 3389pass out on eth0 proto tcp from 192.168.1.1 port = 3389 to 10.42.42.0/24 port > 1024 established -------------过滤规则参考:------------- 过滤规则由全局选项(global-option)和普通规则(normal-rule)组成。 全局选项的语法:"option" global_option iface 现在支持的global-option只有"small_frags"。 普通规则的语法:action [in-out] iface [proto_spec] ip [proto-options] action = "pass" | "block"in-out = "in" | "out"iface = "on" ifname digitifname = "eth*" | "ppp" | "sl" | "lo" | "tr" | "fd"proto_spec = "proto" [proto]proto = "tcp" | "udp" | "icmp" | "any" | ip_protoip_proto = decnumberdecnumber = digit [decnumber]ip = "all" | "from" ip-addr [port-comp | port-range] "to" ip-addr[port-comp | port-range]ip-addr = "any" | ip-dotted-addr [ip-mask]ip-dotted-addr = host-num "." host-num "." host-num "." host-numhost-num = digit [digit [digit]]ip-mask = "/" ip-addr | decnumberport-comp = "port" comparator decnumbercomparator = ">" | ">=" | "<" | "<=" | "="port-range = "port" decnumber "><" decnumberproto-options = "icmp-type" icmp-type ["code" icmp-code] | "established"icmp-type = "echorep" | "unreach" | "squench" | "redir" | "echo" | "router_adv"| "router_sol" | "timex" | "paramprob" | "timest" | "timestrep" | "inforeq" | "inforep" | "maskreq" | "maskrep"icmp-code = decnumber -----------------pktctl命令的用法:----------------- pktctl有两种用法:命令行模式和交互模式。pktctl -i进入交互模式。 列出网络接口:C:\> pktctl -Ieth0: (3Com EtherLink PCI): 192.168.0.1 加载规则文件:C:\> pktctl -f rules.txtpktctl> source rules.txt 先清除所有已加载的规则再加载规则文件:C:\> pktctl -F rules.txtpktctl> reload rules.txt 手工临时添加一条规则:C:\> pktctl -a "pass in on eth0 from 10.0.0.42 to any"pktctl> pass in on eth0 proto udp from 10.0.0.42 to any 列出指定接口上的规则:C:\> pktcl -l eth0pktcl> list on eth0 列出指定接口上的规则和规则号:option:C:\> pktcl -L eth0pktcl> List on eth0在删除规则的时候需要指定规则号。 删除规则:C:\> pktctl -d 2 eth0 删除指定接口上的所有规则:C:\> pktctl -Fa eth0pktctl> flush on eth0 删除所有接口上的所有规则:C:\> pktctl -Fa allC:\> pktctl -Fapktctl> flush on all 显示过滤情况的统计数据:C:\> pktctl -s eth0pktctl> stats on eth0 显示过滤情况的详细统计数据:C:\> pktctl -S eth0pktctl> Stats on eth0 ----------------------pktfltsrv的命令行选项:-----------------------i "path_to_rules_file" "path_to_log_file"-u: uninstalls the service. 一些问题: 1、在Windows XP + SP1 上不能记录日志。 这是XP的问题,SP1 iphlpapi.dll的PfSetLogBuffer函数工作不正常。(这个问题是PktFilter邮件列表上的) 2、添加某些格式不正确的规则时可导致服务崩溃。 3、因为只有SDK的WinBase.h才定义了INVALID_SET_FILE_POINTER。所以编译pktfltsrv的时候需要在 VS的tools--options里面把SDK的include目录放到最前面。我现在的机器没有安装SDK, 是把以前的安装目录copy过来用的,所以需要手工设。我不记得直接安装SDK后是否会直接用SDK的文件覆盖VC的文件, 如果那样的话,可能就不需要多此一举了。 4、在Windows 2000 Pro版本上未必能够运行,我没试验,只是MSND谈到那些函数的时候总是说: “Included in Windows 2000 Server and Windows .NET Server.” 5、pktctl.exe -l命令列规则的时候适配器和协议两个字段之间没有空格,我给加了一个。filter_stats.c/70行。 可能作者没留神少了一句,所以ICMP类型和状态码不能记录下来,加上了。logging.c/187行。 不能记录ttl,tcp窗口值等信息,加上了。 有些记录格式我看着不习惯,改了。 6、程序实现原理可以参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rras/rras/packet_filtering_reference.asp 附:规则生成脚本: @echo off echo # 规则由PktFilter 规则生成脚本 RulesBuild.cmd v0.1 生成echo # [email protected]. setlocal rem 不打算填写内容的变量就让它空着, rem 指定要要设置规则的网络接口:set interface=eth0 rem 指定要生成的规则文件:set rules_file=PktFilter.conf rem 指定本机IP,这里只考虑了一个IP的情况:set local_ip=192.168.0.1 rem 指定信任的IP,注意!来自这些IP的访问将完全不受防火墙控制。多个IP之间用逗号分隔:set trust_ip=192.168.0.2,192.168.0.3 rem 指定网关,某些网关会设置会定时ping主机:set gateway=192.168.0.254 rem 指定qq服务器,多个IP之间用逗号分隔:set qq_server=219.133.40.15 rem 是否要使用主动模式ftp:set ftp_active=true rem 是否要访问DNS:set dns=true rem 是否要访问tftp:set tftp=true rem 是否要访问snmp:set snmp=true rem 是否要使用msn直接文件传输:set msn=true rem 是否要使用QQ:set qq=true rem 是否使用金山毒霸在线升级:set kav=true rem 是否使用netbios:set netbios=true rem 其它要开放的TCP端口,多个端口之间用逗号分隔:set other_tcp= echo #####################################################################################echo # 全局规则echo #####################################################################################echo. echo # 丢掉小的分片包echo option small_frags on %interface%echo. echo # 默认阻塞所有进出数据echo block in on %interface% allecho block out on %interface% allecho. echo # 允许 %local_ip% 发起向任意地址的TCP连接echo pass out on %interface% proto tcp from %local_ip% port 1 ^>^< 65535 to any port 1 ^>^< 65535echo pass in on %interface% proto tcp from any port 1 ^>^< 65535 to %local_ip% port 1 ^>^< 65535 establishedecho. :trust_ipif "%trust_ip%"=="" goto tcpecho # 设置信任主机 %trust_ip% 可完全访问 %local_ip%for %%I in (%trust_ip%,) do echo pass in on %interface% from %%I to %local_ip% && echo pass out on %interface% from %local_ip% to %%Irem %trust_ip%后面加一个逗号是考虑只有一个%trust_ip%时候的情况echo. :tcpecho #####################################################################################echo # TCP 规则echo #####################################################################################echo. :ftp_activeif not "%ftp_active%"=="true" goto msnecho # 开放TCP 20 ,FTP 主动模式echo pass in on %interface% proto tcp from any port = 20 to %local_ip% port ^> 1023echo. :msnif not "%msn%"=="true" goto other_tcpecho # 开放TCP 6890 - 6900,允许MSN直接传输文件echo pass in on %interface% proto tcp from any port ^> 1023 to %local_ip% port 6890 ^>^< 6900echo. :other_tcpif "%other_tcp%"=="" goto udpecho # 其他要开放的TCP 端口:%other_tcp%for %%I in (%other_tcp%,) do echo pass in on %interface% proto tcp from any port ^> 1023 to %local_ip% port = %%Iecho. :udpecho #####################################################################################echo # UDP 规则echo #####################################################################################echo. :dnsif not "%dns%"=="true" goto snmpecho # 访问DNS服务echo pass out on %interface% proto udp from %local_ip% port ^> 1023 to any port = 53echo pass in on %interface% proto udp from any port = 53 to %local_ip% port ^> 1023echo. :snmpif not "%snmp%"=="true" goto tftpecho # 访问snmp服务echo pass out on %interface% proto udp from %local_ip% port ^> 1023 to any port = 161echo pass in on %interface% proto udp from any port = 161 to %local_ip% port ^> 1023echo. :tftpif not "%tftp%"=="true" goto netbiosecho # 访问tftp服务echo pass out on %interface% proto udp from %local_ip% port ^> 1023 to any port = 69echo pass in on %interface% proto udp from any port = 69 to %local_ip% port ^> 1023echo. :netbiosif not "%netbios%"=="true" goto kavecho # 访问netbios-ns(UDP 137) netbios-dgm(UDP 138)服务echo pass out on %interface% proto udp from any port = 137 to any port = 137echo pass in on %interface% proto udp from any port = 137 to any port = 137echo pass out on %interface% proto udp from any port = 138 to any port = 138echo pass in on %interface% proto udp from any port = 138 to any port = 138echo. :kavif not "%kav%"=="true" goto qqecho # 访问金山毒霸升级验证端口echo pass out on %interface% proto udp from %local_ip% port ^> 1023 to any port = 6868echo pass in on %interface% proto udp from any port = 6868 to %local_ip% port ^> 1023echo. :qqif not "%qq%"=="true" goto icmpecho # 使用udp方式访问QQfor %%I in (%qq_server%,) do echo pass out on %interface% proto udp from %local_ip% port = 6000 to %%I port = 8000 && echo pass in on %interface% proto udp from %%I port = 8000 to %local_ip% port = 6000rem %qq_server%后面加一个逗号是考虑只有一个%qq_server%时候的情况echo. :icmpecho #####################################################################################echo # ICMP 规则echo #####################################################################################echo. :pingecho # %local_ip% 可以 ping 任意地址echo pass out on %interface% proto icmp from %local_ip% to any icmp-type echoecho pass in on %interface% proto icmp from any to %local_ip% icmp-type echorepecho. :gatewayif "%gateway"=="" goto writeecho # 网关可以ping %local_ip%echo pass in on %interface% proto icmp from %gateway% to %local_ip% icmp-type echoecho pass out on %interface% proto icmp from %local_ip% to %gateway% icmp-type echorep :writecall %0 1> %rules_file% 2>nul@echo offrem 用这种方法写文件就不用每行后面都重定向而多次执行写操作,速度快,便于维护。rem 用call或者cmd /c都可以,写入一次后会因为文件被另起的cmd进程占用而出错退出。rem 如果不用call而直接在批处理中调用,则命令是在同一个cmd进程中执行,会出现死循环。rem 事实上这种写法更适用于在交互脚本中指定要写的文件,rem 譬如前面设定变量的过程就可以用set /p 来分别从控制台上取得。 endlocal @echo on 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/johnathan/archive/2004/08/22/81288.aspx |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|