服务网格-流量拦截

1. 根据域名拦截请求

思路:iptables只能通过ip粒度进行拦截转发丢弃,无法通过域名粒度转发。但是iptables可通过ipset进行拦截,并通过dnsmasq将域名对应的ip写入到ipset中,实现了域名粒度的拦截。

域名到ipset绑定的流程

1. 在/etc/resolv.conf 中加入 nameserver 127.0.0.1

2. yum install -y dnsmasq

3. yum install -y ipset

4. ipset create proxyipset hash:ip

5. dnsmasq --ipset=/.baidu.com/proxyipset (监听53端口)

另一中方式(麻烦):

rm -rf /etc/dnsmasq.d/domain.conf

echo 'ipset=/.sougou.com/proxyipset' >> /etc/dnsmasq.d/domain.conf

dnsmasq -C /etc/dnsmasq.conf

6. nslookup www.baidu.com  (或者ping)

7. ipset list 可看到如下:

Name: proxyipset
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 232
References: 0
Members:
110.242.68.3
10.128.236.120
110.242.68.4

Members中添加www.baidu.com多个ip节点

8. 重启 (重启dnsmasq后域名才生效)

ps -ef | grep dnsmasq & kill -15 dnsmasq 删除

(systemctl 在docker中没法用,需特权运行 )

ipset flush proxyipset 清空

2. iptables通过ipset拦截出流量

  • 参考 istio 拦截出站流量

# 出站请求,当TCP请求进入OUTPUT链时全部交给ISTIO_OUTPUT处理
-A OUTPUT -p tcp -j ISTIO_OUTPUT
#请求下一个服务/响应请求,即请求非本地服务同时不来自istio-proxy用户空间,流量被转发至ISTIO_REDIRECT链 
-A ISTIO_OUTPUT -j ISTIO_REDIRECT
# 将发送到此的TCP请求全部重定向至15006端口(Envoy入口流量端口)
-A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006
  • 简化并加入ipset ( 请求目标域名但是流量不来自proxy )

iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner 1337 -m set --match-set proxyipset dst -j REDIRECT --to-ports 2047

TODO:只拦截发往80或者443端口或者用户指定的端口的流量

执行 iptables -L -v -n -t nat 查看

Chain OUTPUT (policy ACCEPT 3 packets, 180 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            ! owner UID match 1337 match-set proxyipset dst redir ports 2047
  • 以proxy启动服务监听2047端口 ( 并且转发请求 www.baidu.com)

参考envoy:

useradd -u 1337 proxy (添加用户)

sudo usermod -a -G root proxy(加入到用户组,之后改成work)

grep proxy /etc/group (查看)

su proxy & ./output_test_server

./output_test_server

请求www.baidu.com/hello 返回真正的数据

[/]$ curl www.baidu.com/hello
<html>
<head>
        <script>
                location.replace(location.href.replace("https://","http://"));
        </script>
</head>
<body>
        <noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>

请求 www.baidu.com/world 返回404 ,说明没转发成功

[/]$ curl www.baidu.com/hel
404 page not found

3. https流量拦截

思路:我们代理容器要解析请求百度的外网流量,首先我们得有百度的证书给客户端,其次我们得有百度的私钥解密客户端的流量,显然我们拿不到百度的私钥。因此我们自己自签百度的证书发给客户端,客户端加密之后我们用自签的私钥解密,拿到请求。但是有个问题,客户端拿到我们的自签的证书里,客户端本地的CA中心的公钥并不认可(不是他们签发的),因此我们将签发自签证书的CA根证书加到客户端本地证书库,客户端就信任了。这样,我们就可以解密https流量。(参考istio的自签证书体系)

CA中心怎么认证证书的正确性,私钥公钥加解密原理,istio安全体系可以查看参考内容。

[ req ]
default_bits       = 4096
distinguished_name = req_distinguished_name
req_extensions     = req_ext


[ req_distinguished_name ]
countryName                 = CN
countryName_default         = GB
stateOrProvinceName         = Beijing
stateOrProvinceName_default = Chinese
localityName                = Beijing
localityName_default        = Beijing
organizationName            = 44
organizationName_default    = 44
organizationalUnitName            = 44
organizationalUnitName_default    = IT
commonName                  = www.baidu.com
commonName_max              = 64
commonName_default          = www.baidu.com


[ req_ext ]
subjectAltName = @alt_names


[alt_names]
DNS.1   = www.baidu.com


  • 创建私钥和证书

openssl genrsa -out server.key 4096
openssl req -new -sha256 \
    -out server.csr \
    -key server.key \
    -config ssl.conf 


openssl x509 -req \
    -days 3650 \
    -in server.csr \
    -signkey server.key \
    -out server.crt \
    -extensions req_ext \
    -extfile ssl.conf
  • golang 将证书加入到本地客户端的信任里

"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
  • java 将证书加入到本地客户端的信任里

keytool -import -trustcacerts -alias proxy -file ~/server.crt -keystore /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre/lib/security/cacerts -storepass changeit -keyalg RSAs -noprompt

4. 其他问题

!!!前置条件: http协议中通过Host字段可以拿到 域名&端口,www.baidu.com:442 这样,我们就知道拦截的请求跟谁新建请求,这样,不同域名不同端口的请求只需要解析到一个listen即可,listen自己拿到连接HOST

5. 相关参考

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值