使用 Nginx 反向代理钉钉接口
借助 Nginx 的反向代理能力,在不修改代码的前提下,使内网应用可以通过前置机访问钉钉接口。
场景描述
-
应用使用了钉钉SDK,接口地址已经硬编码在SDK中,无法修改;
-
应用服务器无法直接访问钉钉官方接口,需要借助前置机间接访问;
-
接口使用了
oapi.dingtalk.com
和api.dingtalk.com
两个域名,且均为 https 协议;
解决方案
大方向上考虑在前置机通过 Nginx 做一个钉钉接口的反向代理,并修改应用服务器 hosts 文件,将 oapi.dingtalk.com
和 api.dingtalk.com
指向前置机。
细节上通过 stream 方式进行代理避免自签名证书等工作,并借助 stream_ssl_preread_module
模块实现同时代理两个域名。
具体操作
- 在前置机的命令行输入 nginx -V 确认是否安装了 nginx 以及当前安装的版本是否支持
stream_ssl_preread_module
。如果输出的内容中已经包含--with-stream_ssl_preread_module
就可以继续下面的操作,如果没有此模块或着尚未安装 nginx,可以从官网下载最新稳定版。
在我寻找方案的过程中,发现不少文章都提到 Nginx 没有自带 stream_ssl_preread_module 模块,需要自己编译。但事实上,目前 Nginx 官方网站下载的最新稳定版本(1.26,包括Linux 和 Windows 的版本)已经包含了该模块,并不需要自己编译。
- 确认前置机能访问钉钉接口
curl https://oapi.dingtalk.com
正常情况下,会得到如下返回
{"errcode":404,"errmsg":"请求的URI地址不存在"}
- 创建 Nginx 配置文件
/etc/nginx/conf.d/dingtalk.conf
stream {
map $ssl_preread_server_name $name {
oapi.dingtalk.com oapi;
api.dingtalk.com api;
}
upstream oapi {
server oapi.dingtalk.com:443;
}
upstream api {
server api.dingtalk.com:443;
}
server {
listen 443;
ssl_preread on;
proxy_pass $name;
}
}
完成后记得重启 nginx。
如有其他需要,可参照该模块的配置说明
Module ngx_stream_ssl_preread_module
- 开通前置机的防火墙端口
firewall-cmd --permanent --add-port 443/tcp
firewall-cmd --reload
- 在应用服务器上修改 hosts 文件,假设前置机的 ip 是 192.168.100.100
echo 192.168.100.100 oapi.dingtalk.com >> /etc/hosts
echo 192.168.100.100 api.dingtalk.com >> /etc/hosts
- 通过 curl 测试效果
curl https://oapi.dingtalk.com
正常情况下,会得到如下返回
{"errcode":404,"errmsg":"请求的URI地址不存在"}
完成上述步骤后,你就实现了在不修改软件代码的前提下,借助前置机访问到钉钉接口了。