执子之手

与子偕老


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

  • 搜索
close

从一台没有外网连接的阿里云主机上访问微信API

时间: 2017-02-12   |   分类: 运维     |   阅读: 1404 字 ~3分钟   |   访问: 0

1. 背景

公司的生产环境是部署在阿里云上的。Zabbix最初装在一台没有外网连接的ECS上,通过Nginx进行访问。但是后来发现如果需要报警,需要从Zabbix这台主机访问微信公众号服务器(qyapi.weixin.qq.com)。运维的兄弟最初选择了固定带宽的网络,但是考虑到费用问题,后期想切换到按量付费的网络,但是阿里云居然不支持这种切换(这里吐槽一下阿里的设计)。

由于该主机是按照包月包年方式购买的,退掉重新申请主机安装Zabbix显然不划算。在主机到期之前,必须想办法实现在没有外网的情况下访问微信服务器(考虑到费用问题,原先固定带宽已经被修改成了0M,也就没有费用了)。

2. 解决

考虑到整个生产环境中有多台能够访问Internet的主机,所以自然的想到是不是可以通过其他主机中转这种访问呢?

2.1 Nginx

最先想到的方案是通过Nginx,通过Nginx做一个正向代理,代理到微信公众号服务器( https://qyapi.weixin.qq.com ),然后通过从Zabbix访问Nginx代理后的站点。但是通过搜索发现,Nginx不支持这种代理方式(Forward Proxy)连接https服务器。具体的可以看附录中的连接。以下是Nginx作者的答复:

1> Is there any schedule to support the feathure, forward proxy ?
2Not in near future: there is alreay good forward proxy Squid.

2.2 iptables

然后又想到是不是可以使用iptables进行端口转发呢?但是可能是我对iptables还不够熟悉,按照附录4的命令总也调试不成功,总是会返回超时。这个方法没有解决问题。

2.3 socat

这时想起以前用过一个小工具socat,用它将一个unix socket转换成一个tcp socket,它的用处就是将一个流转换成另一个流。经过尝试果然可以。命令也很简单:

1socat TCP-LISTEN:443,fork,reuseaddr TCP:140.207.127.79:443

然后在Zabbix主机上使用curl访问试试:

1root@prd-zabbix:~# curl https://192.168.61.64
2curl: (51) SSL: certificate subject name 'qy.weixin.qq.com' does not match target host name '192.168.61.64'

已经可以访问了,说明服务已经中转到微信的服务器上了。

3. 后续操作

3.1 域名

上面使用curl出现的提示表明,我们必须使用域名进行访问才能够被正确处理。这一点可以通过本地域名映射进行解决。可以通过修改/etc/hosts增加映射的方式解决。因为我们本地的Zabbix是通过Docker运行的,这个修改就要通过Docker运行。我们使用的是docker-compose,在docker-compose.yaml中增加如下配置即可:

1extra_hosts:
2  - "qyapi.weixin.qq.com:192.168.61.64"

这样,在Zabbix运行的容器中,域名qyapi.weixin.qq.com指向了192.168.61.64这台主机。而对这台主机上的443端口的访问被重定向到了140.207.127.79:443,从而实现了对微信公众号服务器的访问。

3.2 多服务器

使用nslookup查询可以知道对应于域名qyapi.weixin.qq.com,微信是提供了多台服务器的:

 1root@prd-zabbix:~# nslookup qyapi.weixin.qq.com
 2Server:         100.100.2.138
 3Address:        100.100.2.138#53
 4
 5Non-authoritative answer:
 6qyapi.weixin.qq.com     canonical name = qy.weixin.qq.com.
 7Name:   qy.weixin.qq.com
 8Address: 140.207.189.106
 9Name:   qy.weixin.qq.com
10Address: 140.207.127.79

上面的解决方案中只指向了一台服务器,这样如果这台服务器出现问题的时候可能会导致访问失败。可以考虑的一个方案是在另一台主机上使用socat做同样的转发工作,只是转发给另一台主机。这样应该可以解决部分问题。但是还不是最完美的解决方案。有待于以后继续研究。

3.3 自启动

需要考虑服务器重启的情况下,要自动启动socat。这个在Ubuntu上可以通过修改/etc/rc.local文件解决:

1socat TCP-LISTEN:443,fork,reuseaddr TCP:140.207.127.79:443 &
2exit 0

附录A. 参考资料

  • Re: https and nginx as forward proxy
  • Nginx as forward proxy for HTTPS
  • Lets Talk About Proxies, Pt. 2: Nginx as a Forward HTTP Proxy - See more at: https://blog.opendns.com/2015/11/03/lets-talk-about-proxies-pt-2-nginx-as-a-forward-http-proxy/
  • Forward a TCP port to another IP or port using NAT with Iptables
  • socat port forwarding for https
  • Execute a Script at Startup and Shutdown on Ubuntu
#阿里云# #Ubuntu# #微信#
Hexo博客提交搜索引擎
在Mac上启用Docker的Bash Completion
  • 文章目录
  • 站点概览
Orchidflower

Orchidflower

Do one thing at a time, and do well.

77 日志
6 分类
84 标签
GitHub 知乎 OSC 豆瓣
  • 1. 背景
  • 2. 解决
    • 2.1 Nginx
    • 2.2 iptables
    • 2.3 socat
  • 3. 后续操作
    • 3.1 域名
    • 3.2 多服务器
    • 3.3 自启动
  • 附录A. 参考资料
© 2009 - 2024 执子之手
Powered by - Hugo v0.113.0
Theme by - NexT
ICP - 鲁ICP备17006463号-1
0%