反向代理企业微信api接口

默认分类 · 2023-11-03

Why

公司因为业务需要,在线下增设了几套新的k8s环境,这几套环境的监控报警都是通过Prometheus+AlertManager来做的,报警消息通过企业微信的api接口推送给指定的用户,但企微新创建的应用必须配置ip白名单才可以推送消息
我司线下环境没有固定的公网ip,ip变动后就必须手动更新企微api的ip白名单,否则AlertManager的告警消息就无法推送到企微

参考企微开发文档:连接

为了企业的数据安全,从2022年6月20号20点之后,新开启的通讯录同步助手与新创建的自建应用必须在管理端配置可信IP,仅配置的可信IP能调用接口

这种情况下,就需要一台具有固定ip的机器,来做企微api的反代,让线下环境的ip变动也不影响消息推送

How

企微的api接口全部采用https协议,https涉及到tls握手的问题,配置传统代理比较麻烦,所以选用sniproxy来直接转发https流量,而不对流量本身做解密

这里提供一个测试代理的方法:

https://qyapi.weixin.qq.com/cgi-bin/get_api_domain_ip

这个接口是用来获取企微api接口ip段的,需要提交access_token才能返回ip段信息,但是不带token返回的错误信息中包含一个from ip值,根据这个ip就可以判断代理是否生效

{"ip_list":[],"errcode":41001,"errmsg":"access_token missing, hint: [id], from ip: 0.0.0.0, more info at https://open.work.weixin.qq.com/devtool/query?e=41001"}

打包镜像

sniproxy包含在alpine的软件源内,不需要自己编译,用下面的Dockerfile打包个镜像就行

FROM alpine:3.18.4

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
    apk update && \
    apk add sniproxy

CMD ["sniproxy", "-f", "-c", "/etc/sniproxy/sniproxy.conf"]

打包好镜像后,将镜像传到用作代理的机器上,我这里是直接将sniproxy架设到线上的k8s集群里,由线上的机器来转发企微的api请求

配置sniproxy

在k8s中添加一个configmap,内容如下:

user root

pidfile /tmp/sniproxy.pid

error_log {
syslog daemon
priority notice
}

listener 0.0.0.0:443 {
protocol tls
table WxWorkAPI
}

table WxWorkAPI {
qyapi.weixin.qq.com qyapi.weixin.qq.com:443 # 代理规则
}
代理规则的前一个域名是sniproxy要代理的目标域名,后面的域名是自动解析成企微api实际的ip,443则是https的默认端口

将这个configmap映射到sniproxy的/etc/sniproxy/sniproxy.conf

除了配置文件外,还要根据情况将sniproxy的端口暴露出去,配置文件里的listener的端口号是可以修改的,我这里能直接连接到线上的k8s内网中,就不额外做端口暴露了

到这一步就可以测试代理是否生效了,修改自己机器的hosts,把qyapi.weixin.qq.com这个域名劫持到代理服务器上面,再访问上面给的测试接口,看看返回的ip是不是变成代理机器的ip了

配置CoreDNS

在需要反代企微的k8s集群中,修改CoreDNS的configmap,添加自定义解析文件

.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}

# 加上下面这段,文件位置无所谓,记得就行
hosts /etc/coredns/NodeHosts {
ttl 60
reload 15s
fallthrough
}

prometheus :9153
forward . "/etc/resolv.conf"
cache 30
loop
reload
loadbalance
} # STUBDOMAINS - Rancher specific change

再创建一对configmap键值,对应上面加的解析文件/etc/coredns/NodeHosts
内容如下,ip换成代理服务器的ip

255.255.255.255 qyapi.weixin.qq.com

配置完成后,重启CoreDNS,在集群里面起一个alpine容器,在容器内请求测试api,返回的ip是代理服务器的ip,则说明反代生效,将代理服务器的ip加到企微应用的ip白名单中即可正常推送消息,不受本地ip变动影响

Theme Jasmine by Kent Liao