問題來源
企業(yè)內(nèi)部應(yīng)用一般部署在內(nèi)網(wǎng),沒有固定的公網(wǎng)IP,這樣在訪問釘釘?shù)腁PI時就會被攔截下來。釘釘?shù)姆?wù)器出口IP只支持一個統(tǒng)配符,出現(xiàn)不匹配的情況就會被攔截。
解決方案比較
當(dāng)然存在多種解決方案,各有差別,但是本質(zhì)都需要一個公網(wǎng)服務(wù)器,公網(wǎng)搭設(shè)一個代理服務(wù):
- 在代碼中使用代理。對代碼具有一定的侵入性。
- 使用系統(tǒng)代理。這樣需要用PAC來選擇代理的網(wǎng)址,對一些程序可能無效。
- 使用iptables轉(zhuǎn)發(fā)到代理軟件。僅限于linux可用。
這里我介紹一種用反向代理的方法解決沒有固定IP的方案。內(nèi)網(wǎng)的windows服務(wù)器只需要一個根證書、改Hosts文件即可。
解決方案
先決條件
- 公網(wǎng)服務(wù)器且系統(tǒng)為Linux、固定的公網(wǎng)IP
步驟
生成自簽名的根證書 + 域名證書
OpenSSL 自簽 CA 及 SSL 證書參考這篇文章即可。注意把域名改成oapi.dingtalk.com,將csr文件轉(zhuǎn)換為pem文件。在公網(wǎng)配置Nginx的反向代理,使用如下配置文件
server {
# SSL configuration
listen 443 ssl;
listen [::]:443 ssl;
ssl on;
ssl_certificate /home/ubuntu/certs/oapi.dingtalk.com.pem; # 公鑰路徑
ssl_certificate_key /home/ubuntu/certs/oapi.dingtalk.com.key; # 私鑰路徑
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
server_name oapi.dingtalk.com;
location ~ / {
proxy_set_header Host $host;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://oapi.dingtalk.com;
}
}
-
在內(nèi)網(wǎng)服務(wù)器,把根證書導(dǎo)入到受信任的根證書頒發(fā)機構(gòu)
安裝CA根證書.png
- 在內(nèi)網(wǎng)服務(wù)器,設(shè)置Hosts文件
<公網(wǎng)ip> oapi.dingtalk.com
- 重啟nginx,即可在內(nèi)網(wǎng)服務(wù)器上訪問反代的釘釘API
簡要分析原理
本地hosts文件強制解析到自有服務(wù)器上,中間的證書是自簽名認(rèn)證的,服務(wù)器獲取到請求后轉(zhuǎn)發(fā)給真正的釘釘服務(wù)器,這樣出口IP就確定了下來,能過驗證。注意根證書的私鑰不要泄露了,否則帶來中間人攻擊的風(fēng)險。
