使用Netty 4.1.23版本需要用到白名單機制,發現網上很多資料都是介紹IpFilterRuleHandler,仔細一看4.x版本中找不到這個,而5.x又不被推薦使用,是以仔細檢視官方4.x文檔發現有個RuleBasedIpFilter可以使用。
RuleBasedIpFilter簡介
RuleBasedIpFilter是基于ip的過濾器,可以自定義哪些ip或者ip範圍允許通過或者被阻止。因為預設情況下,如果不添加任何IpSubnetFilterRule, RuleBasedIpFilter就會允許所有ip。如果我們使用白名單機制,要麼繼承RuleBasedIpFilter類,重寫accept方法,要不在RuleBasedIpFilter, 添加一個rejectAll,并将該rejectAll放在數組的最後。
public class RuleBasedIpFilter extends AbstractRemoteAddressFilter<InetSocketAddress> {
private final IpFilterRule[] rules;
public RuleBasedIpFilter(IpFilterRule... rules) {
if (rules == null) {
throw new NullPointerException("rules");
} else {
this.rules = rules;
}
}
protected boolean accept(ChannelHandlerContext ctx, InetSocketAddress remoteAddress) throws Exception {
IpFilterRule[] var3 = this.rules;
int var4 = var3.length;
for(int var5 = 0; var5 < var4; ++var5) {
IpFilterRule rule = var3[var5];
if (rule == null) {
break;
}
if (rule.matches(remoteAddress)) {
return rule.ruleType() == IpFilterRuleType.ACCEPT;
}
}
return true;
}
}
示例
示例比較簡單,啟動一個server,使用StringDecoder和StringEncoder。
public class NettyServer {
public void bind() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws IOException {
IpSubnetFilterRule rule1 = new IpSubnetFilterRule("192.168.119.1", 24, IpFilterRuleType.ACCEPT);
IpSubnetFilterRule rule2 = new IpSubnetFilterRule("127.0.0.1", 32, IpFilterRuleType.REJECT);
IpFilterRule rejectAll = new IpFilterRule() {
@Override
public boolean matches(InetSocketAddress remoteAddress) {
return true;
}
@Override
public IpFilterRuleType ruleType() {
return IpFilterRuleType.REJECT;
}
};
RuleBasedIpFilter filter = new RuleBasedIpFilter(rule1, rejectAll );
ch.pipeline().addLast("ipFilter", filter);
ch.pipeline().addLast("encoder", new StringEncoder());
ch.pipeline().addLast("decoder", new StringDecoder());
ch.pipeline().addLast(new StringHandler());
}
});
//我本機有多個ip,啟動時不綁定特定ip, 這樣才能友善白名單測試
b.bind(NettyConstant.PORT).sync();
System.out.println("Netty server start successfully: " + (NettyConstant.PORT));
}
public static void main(String[] args) throws Exception {
new NettyServer().bind();
}
}
測試
使用telnet 127.0.0.1 8080 會被自動斷開
使用telnet 192.168.119.1 8080 可以正确連接配接上(我機器的ip是192.168.119.1,白名單允許192.168.119.x連接配接,但是不允許127.0.0.1連接配接).
讀者需要更新允許的ip, 因為我本機是192.168.119.1,是以允許192.168.119.x, 如果你的ip不是這個範圍,需要修改代碼,否則就不能連接配接上8080.