最近公司的项目在做漏洞扫描,结果扫出了一堆高危漏洞,其中一个是关于dubbo接口暴露的。我们都知道dubbo接口注册在zookeeper上后,该接口对于所有注册在zk上的消费者都是可见的,为了防止非法调用,我们可以通过配置dubbo白名单来限制接口的访问。

1、在resources目录下新增dubboIpWhiteList.properties,添加以下可以调用的IP信息
ipwhitelist=127.0.0.1,192.168.211.170

2、新增DubboValidationFilter类,该类继承了dubbo的Filter

package com.openapi3.base.filter;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.RpcResult;
import com.alibaba.dubbo.validation.filter.ValidationFilter;

/**
 *
 * @author linzy
 * @create 2019年5月13日上午11:07:43
 */
public class DubboValidationFilter implements Filter {

	@Override
	public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
		Properties prop = new Properties();
		InputStream in = ValidationFilter.class.getResourceAsStream("/dubboIpWhiteList.properties");
		String clientIp = RpcContext.getContext().getRemoteHost();
		// 客户端ip
		try {
			prop.load(in);
			String ipwhitelist = prop.getProperty("ipwhitelist");
			// ip白名单
			if (ipwhitelist.contains(clientIp)) {
				return invoker.invoke(invocation);
			} else {
				return new RpcResult(new Exception("ip地址:" + clientIp + "没有访问权限"));
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (RpcException e) {
			throw e;
		} catch (Throwable t) {
			throw new RpcException(t.getMessage(), t);
		}
		return invoker.invoke(invocation);
	}
}

3、在resources目录下添加纯文本文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter,
文件中写入validationFilter=com.openapi3.base.filter.DubboValidationFilter,validationFilter的值就是上面新增类的包路径

4、修改dubbo服务端配置信息,添加白名单拦截

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
  xsi:schemaLocation="http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans.xsd  
    http://code.alibabatech.com/schema/dubbo  
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">   

  <!-- 提供方应用信息,用于计算依赖关系 -->  
  <dubbo:application name="iot_service_v3_test"  />

  <dubbo:registry address="zookeeper://127.0.0.1:2181"  />
  <!--zookeeper单点变为集群-->
  <!-- <dubbo:registry  protocol="zookeeper" address="zookeeper://192.168.214.203:8090?backup=192.168.214.204:8090,192.168.214.205:8090" /> -->

  <dubbo:protocol name="dubbo" port="10882" />
  <!-- 开启白名单拦截 -->
  <dubbo:provider filter="validationFilter" delay="-1" timeout="6000" retries="0"/>
  
  <!-- 测试使用 --> 
<!--  <dubbo:consumer check="false" />  -->
  
  <!-- 声明需要暴露的服务接口 -->  
  <dubbo:service retries="0" timeout="906000" ref="iotService3" interface="com.openapi3.service.IotService" />
  <dubbo:service retries="0" timeout="180000" ref="triMemberOnoffService" interface="com.openapi3.service.TriMemberOnoffService" />
</beans>

5、测试验证,如果返回以下错误信息,即表示dubbo接口已经成功配置白名单拦截功能