Windows下实现屏蔽IP的功能,很多人可能会联想到使用一些复杂的技术来解决,比如NDIS中间层驱动,甚至NDIS钩子驱动。但这些技术太过深奥,只有精通Windows编程的人才玩得转。如果你对Windows编程不是特别了解又没有太多时间,或者你根本一窍不通,那么你可以试试采用Windows网络配置命令netsh来解决这些问题。
本文是采用IPSec策略来实现此功能。Windows 2000/XP/2003平台最早就提供了这个工具,考虑到兼容性的问题Windows之后的版本同样也提供了,只是在此基础上还增加了新的功能advfirewall(本文不予探讨,有兴趣的可以点击链接查看)。
IPSec策略的配置有两种方法,前提是IPSec服务已经启动:
先介绍一下IPSec策略的基本组成:
一个IPSec策略通常由一个或者多个规则组成;每个规则由一个IP筛选器列表和一个对应的筛选器操作组成;这个筛选器列表和筛选器可以是系统本身所没有的,如果没有则需要自行建立,而一个筛选器又由一个或多个筛选器组成。
因此配置IPSec的时候必须要分步进行。规则由筛选器列表和筛选器操作构成,而且存放在策略里,策略器由策略器列表来存储。这样就决定了一个步骤:
建立空的安全策略 -> 建立筛选器列表 -> 建立筛选器操作 -> 指派策略
看一下下面的例子就明白了,这是我从别人博客上拿过来的例子:
'建立一个名字叫XBLUE的安全策略先 netsh ipsec static add policy name=XBLUE '建立一个ip筛选器,指定192.168.1.2 netsh ipsec static add filterlist name=denyip netsh ipsec static add filter filterlist=denyip srcaddr=192.168.1.2 dstaddr=Me dstport=3389 protocol=TCP '建立一个筛选器操作 netsh ipsec static add filteraction name=denyact action=block '加入规则到安全策略XBLUE netsh ipsec static add rule name=kill3389 policy=XBLUE filterlist=denyip filteraction=denyact '激活这个策略 netsh ipsec static set policy name=XBLUE assign=y '把安全策略导出 netsh ipsec static exportpolicy d:\ip.ipsec '删除所有安全策略 netsh ipsec static del all '把安全策略导入 netsh ipsec static importpolicy d:\ip.ipsec '激活这个策略 netsh ipsec static set policy name=策略名称 assign=y
大家可以根据这个例子在命令行里面尝试,同时你也可以在命令行下查看命令参数的说明,很方便。
有了前面的这些做铺垫,后面的程序就好写了。我要实现的功能很简单,可以指定单个IP地址、单个IP地址和端口号或存有IP地址信息的文件(每行可以是单个IP地址或者单个IP地址和端口号)为输入。如果地址没有给定端口号,将该地址屏蔽;如果地址给定了端口号,屏蔽该地址对应端口的TCP和UDP协议。
在实现程序前,编写了两个批处理脚本用来支撑本程序的运行:备份本地安全策略.bat和还原本地安全策略.bat。简而言之就是在程序运行前先备份,必要时还原即可。
1 @echo off 2 cls 3 netsh ipsec static exportpolicy ip.ipsec 4 netsh ipsec static delete all 5 netsh ipsec static add policy name=abandon 6 netsh ipsec static add filterlist name=denyip 7 netsh ipsec static add filter filterlist=denyip srcaddr=192.168.1.2 dstaddr=me dstport=3389 protocol=UDP 8 netsh ipsec static add filteraction name=denyact action=block 9 netsh ipsec static add rule name=killu policy=abandon filterlist=denyip filteraction=denyact 10 netsh ipsec static set policy name=abandon assign=y 11 pause 12 exit
1 @echo off 2 cls 3 4 netsh ipsec static delete all 5 netsh ipsec static importpolicy ip.ipsec 6 netsh ipsec static set policy name=local assign=y 7 pause 8 exit
贴上程序代码,很简单理解,不多说。
1 package cn.edu; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileReader; 6 import java.io.IOException; 7 import java.util.regex.Matcher; 8 import java.util.regex.Pattern; 9 import java.lang.InterruptedException; 10 11 /** 12 * 13 * @author kelvin 14 * 15 * 指定一个IP列表文件或IP地址,并将文件中所有对应的IP地址和端口号或指定的IP地址和端口号过滤 16 * 指令格式: IPFilter type [filename|IPAddr] 17 * type类型:-f表示文件 18 * -a表示IP地址 19 * IP地址格式: [IP]:[port] 或 [IP] 20 * eg: java IPFilter -f ip.txt 21 * java IPFilter -a 192.168.1.1:80 22 * java IPFilter -a 192.168.1.1 23 */ 24 public class IPFilter { 25 26 // [IP]:[port]正则表达式 27 private static final String IPADDRESS_PORT_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." 28 + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." 29 + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." 30 + "([01]?\\d\\d?|2[0-4]\\d|25[0-5]):([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])$"; 31 32 // IP地址正则表达式 33 private static final String IPADDRESS_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." 34 + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." 35 + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." 36 + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; 37 38 // 筛选器列表名称 39 private static final String FILTER_LIST_NAME = "denyip"; 40 41 /** 42 * @param args 43 * @throws IOException, InterruptedException 44 */ 45 public static void main(String[] args) throws IOException, InterruptedException { 46 if (args.length != 2) { 47 printUsage(); 48 return; 49 } 50 51 Pattern ip_port_pattern = Pattern.compile(IPADDRESS_PORT_PATTERN); 52 Pattern ip_pattern = Pattern.compile(IPADDRESS_PATTERN); 53 if (args[0].equals("-f")) { 54 File filterFile = null; 55 BufferedReader br = null; 56 String ipAddr = null; 57 try { 58 filterFile = new File(args[1]); 59 if(!filterFile.exists()) { 60 System.out.println(args[1]+"不存在"); 61 return; 62 } 63 64 br = new BufferedReader(new FileReader(filterFile)); 65 66 while ((ipAddr = br.readLine()) != null) { 67 if (ipAddr.length() <= 0) 68 continue; 69 70 if (ip_port_pattern.matcher(ipAddr).matches()) { // [IP]:[port] 71 72 String ipAddrDetail[] = ipAddr.split(":"); 73 74 // 可保留前两个或后两个,也可以全写 75 // me -> [IP]:[port] TCP 76 Runtime.getRuntime().exec( 77 "netsh ipsec static add filter filterlist=" 78 + FILTER_LIST_NAME 79 + " srcaddr=me dstaddr=" 80 + ipAddrDetail[0] 81 + " dstport=" 82 + ipAddrDetail[1] 83 +" protocol=TCP").waitFor(); 84 85 // me -> [IP]:[port] UDP 86 Runtime.getRuntime().exec( 87 "netsh ipsec static add filter filterlist=" 88 + FILTER_LIST_NAME 89 + " srcaddr=me dstaddr=" 90 + ipAddrDetail[0] 91 + " dstport=" 92 + ipAddrDetail[1] 93 +" protocol=UDP").waitFor(); 94 95 // [IP]:[port] -> me TCP 96 Runtime.getRuntime().exec( 97 "netsh ipsec static add filter filterlist=" 98 + FILTER_LIST_NAME 99 + " srcaddr=" 100 + ipAddrDetail[0] 101 +" dstaddr=me srcport=" 102 + ipAddrDetail[1] 103 + " protocol=TCP").waitFor(); 104 105 // [IP]:[port] -> me UDP 106 Runtime.getRuntime().exec( 107 "netsh ipsec static add filter filterlist=" 108 + FILTER_LIST_NAME 109 + " srcaddr=" 110 + ipAddrDetail[0] 111 +" dstaddr=me srcport=" 112 + ipAddrDetail[1] 113 + " protocol=TCP").waitFor(); 114 115 System.out.println("已过滤" + ipAddr); 116 } else if(ip_pattern.matcher(ipAddr).matches()) { 117 // 保留其中一个即可,也可以全写 118 // me -> [IP] 119 Runtime.getRuntime().exec( 120 "netsh ipsec static add filter filterlist=" 121 + FILTER_LIST_NAME 122 + " srcaddr=me dstaddr=" 123 + ipAddr 124 + " protocol=ANY").waitFor(); 125 126 // [IP] -> me 127 Runtime.getRuntime().exec( 128 "netsh ipsec static add filter filterlist=" 129 + FILTER_LIST_NAME 130 + " srcaddr=" 131 + ipAddr 132 +" dstaddr=me protocol=ANY").waitFor(); 133 System.out.println("已过滤" + ipAddr); 134 } else { 135 System.out.println(ipAddr + "不是合法的格式"); 136 } 137 } 138 } catch (Exception e) { 139 e.printStackTrace(); 140 } finally { 141 if (br != null) { 142 br.close(); 143 br = null; 144 } 145 } 146 System.out.println("done!"); 147 } else if (args[0].equals("-a")) { 148 if (ip_pattern.matcher(args[1]).matches()) { 149 // me -> [IP] 150 Runtime.getRuntime().exec( 151 "netsh ipsec static add filter filterlist=" 152 + FILTER_LIST_NAME + " srcaddr=me dstaddr=" 153 + args[1] 154 + " protocol=ANY").waitFor(); 155 156 // [IP] -> me 157 Runtime.getRuntime().exec( 158 "netsh ipsec static add filter filterlist=" 159 + FILTER_LIST_NAME + " srcaddr=" 160 + args[1] 161 +" dstaddr=me protocol=ANY").waitFor(); 162 163 System.out.println("已过滤" + args[1]); 164 } else if(ip_port_pattern.matcher(args[1]).matches()) { 165 String ipAddrDetail[] = args[1].split(":"); 166 167 // me -> [IP]:[port] TCP 168 Runtime.getRuntime().exec( 169 "netsh ipsec static add filter filterlist=" 170 + FILTER_LIST_NAME 171 + " srcaddr=me dstaddr=" 172 + ipAddrDetail[0] 173 + " dstport=" 174 + ipAddrDetail[1] 175 + " protocol=TCP").waitFor(); 176 177 // me -> [IP]:[port] UDP 178 Runtime.getRuntime().exec( 179 "netsh ipsec static add filter filterlist=" 180 + FILTER_LIST_NAME 181 + " srcaddr=me dstaddr=" 182 + ipAddrDetail[0] 183 + " dstport=" 184 + ipAddrDetail[1] 185 + " protocol=UDP").waitFor(); 186 187 // [IP]:[port] -> me UDP 188 Runtime.getRuntime().exec( 189 "netsh ipsec static add filter filterlist=" 190 + FILTER_LIST_NAME 191 + " srcaddr=" 192 + ipAddrDetail[0] 193 +" dstaddr=me" 194 + " srcport=" 195 + ipAddrDetail[1] 196 + " protocol=UDP").waitFor(); 197 198 // [IP]:[port] -> me TCP 199 Runtime.getRuntime().exec( 200 "netsh ipsec static add filter filterlist=" 201 + FILTER_LIST_NAME 202 + " srcaddr=" 203 + ipAddrDetail[0] 204 +" dstaddr=me" 205 + " srcport=" 206 + ipAddrDetail[1] 207 + " protocol=TCP").waitFor(); 208 209 System.out.println("已过滤" + args[1]); 210 } else { 211 System.out.println(args[1] + "不是合法的格式"); 212 } 213 } else { 214 printUsage(); 215 } 216 217 } 218 219 static void printUsage() { 220 System.out.println("Usage:IPFilter type [filename|IPAddr]"); 221 System.out.println("type: [-f | -a]"); 222 System.out.println(" -f filename"); 223 System.out.println(" -a IPAddr"); 224 } 225 226 }
编译完成后,可以执行查看运行结果:
1. 屏蔽117.30.180.209:19122,执行以下命令:
java cn.edu.IPFilter -a 117.30.180.209:19122
2. 屏蔽屏蔽117.30.180.209,执行以下命令:
java cn.edu.IPFilter -a 117.30.180.209
3. 屏蔽ip.txt中地址信息,执行以下命令:
java cn.edu.IPFilter -f ip.txt
1 118.166.7.250:11638 2 75.40.16.53 3 117.30.189.209:19122