美文网首页
dubbo 安全方案

dubbo 安全方案

作者: 乘以零 | 来源:发表于2019-11-05 16:49 被阅读0次

    如果dubbo服务必须开放在外网上 如何控制权限验证呢?想了下有一下集中方案

    1.开启linux 防火墙 ,只让白名单中的ip访问固定的端口(或禁止黑名单访问)

    白名单

    iptables -A INPUT -s 192.168.0.0/8 -p tcp --dport 22 -j ACCEPT
    

    黑名单

    iptables -A INPUT -s 192.168.0.0/8 -p tcp --dport 22 -j DROP
    # or
    iptables -A INPUT -s 192.168.0.0/8 -p tcp --dport 22 -j REJECT
    

    2.dubbo 的 token 机制

    http://dubbo.apache.org/zh-cn/docs/user/demos/token-authorization.html

    <dubbo:provider interface="com.foo.BarService" token="true" />
    

    这种方法,防止直连dubbo,只能通过注册中心的方式,然后把注册中心的ip或端口号禁用掉。
    但如果禁用掉了注册中心,服务又不能通过直连的方式调用,那这个服务在外网和内网有区别么???
    如果不禁用注册中心的端口,采用注册中心用户名密码制

    <dubbo:registry username="" password="" />
    

    但是,我们大部分使用的注册中心为zookeeper,zookeeper用的ACL机制,子节点不能继承父节点的权限,所以,当注册中心使用zk时候,这个方法不可行。可以换成别的注册中心。

    3.采用nginx代理

    原dubbo的端口20880,代理后的端口为20881,然后把20880防火墙禁止外网访问,nginx加上权限校验。
    shell 创建用户名 密码

      > cd /etc/nginx/
      > htpasswd -c -d /etc/nginx/passwd.db  username
      > password
    

    nginx.conf

    stream{
        upstream dubbo{
            server 127.0.0.1:20880;
        }
        server{
            auth_basic "User Authentication";
            auth_basic_user_file /etc/nginx/passwd.db;
            listen 20881;
            proxy_pass dubbo;
        }
    }
    

    4.采用dubbo filter机制,这样每个工程都要加上相应的filter

    provider 加

    @Activate(group = Constants.PROVIDER)
    public class AuthProviderFilter implements Filter {
        //这个用户名 密码可以写在配置文件中
        private String username = "abcde";
        private String password = "12345";
    
        @Override
        public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
            RpcContext.getContext().setAttachment("auth.username", username);
            RpcContext.getContext().setAttachment("auth.password", username);
    
            Result result = invoker.invoke(invocation);
            return result;
        }
    }
    
    

    consumer 加

    @Activate(group = Constants.CONSUMER)
    public class AuthConsumerFilter implements Filter {
        //这个用户名 密码可以写在配置文件中
        private String username = "abcde";
        private String password = "12345";
    
        @Override
        public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
            String u = RpcContext.getContext().getAttachment("username");
            String p = RpcContext.getContext().getAttachment("password");
    
            //认证成功
            if (username.equals(u) && password.equals(p)) {
                Result result = invoker.invoke(invocation);
                return result;
            }
            // 认证失败 报错
            throw new RpcException("auth error");
        }
    }
    

    也可以合在一起

    @Activate(group = { Constants.CONSUMER, Constants.PROVIDER })
    public class AuthFilter implements Filter {
        //这个用户名 密码可以写在配置文件中
        private String username = "abcde";
        private String password = "12345";
    
        @Override
        public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
            //如果是消费端
            if (RpcContext.getContext().isConsumerSide()) {
                String u = RpcContext.getContext().getAttachment("username");
                String p = RpcContext.getContext().getAttachment("password");
    
                //认证成功
                if (username.equals(u) && password.equals(p)) {
                    Result result = invoker.invoke(invocation);
                    return result;
                }
            } else {
                RpcContext.getContext().setAttachment("auth.username", username);
                RpcContext.getContext().setAttachment("auth.password", username);
                Result result = invoker.invoke(invocation);
                return result;
            }
            throw new RpcException("auth error");
        }
    }
    
    

    相关文章

      网友评论

          本文标题:dubbo 安全方案

          本文链接:https://www.haomeiwen.com/subject/zgssbctx.html