使用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.