如何在墙内反代 Gravatar 显示博客头像
生命不息,折腾不止
Gravatar 即全球通用头像 (Globally Recognized Avatar) 服务,用户只要在上面上传了自己的头像,那么在所有支持的网站上发帖时,只要提供与这个头像关联的 Email,就可以显示出自己的 Gravatar 头像。可以说是「一次上传,全网通用」~~
可惜国内的网络环境实在一言难尽,Gravatar 常年都处于无法访问的状态,所以本站一直都是用 v2ex 提供的 CDN 镜像,然而,就在前两周,v2ex 也被墙了,emm… 因为不想再白嫖其他的国内镜像,因此开始考虑自己动手搭建。这个事情其实挺简单的,网上随便搜索一下就有答案,只要有一台墙外的 VPS,用 nginx 给 Gravatar 做个反向代理就好。
但是,如果你的主机在墙内呢,怎么办?
科学上网
无论如何,科学上网是第一件必须解决的事情。如果你的主机甚至都不能访问 Gravatar,反向代理根本就无从谈起。要实现科学上网,你首先需要在墙外有可用的 Shadowsocks 服务用于代理你的流量,至于是使用 VPS 自建也好、直接购买机场的服务也好,这里不作探讨。
安装 Shadowsocks:
1 | apt-get install python-pip |
在 /etc/shadowsocks/config.json
目录创建一个配置文件:
1 | { |
配置完成后,使用 sslocal
命令启动客户端服务:
1 | sslocal -c /etc/shadowsocks/config.json -d start |
这个命令会在本地 1080 端口启动一个 socks5 代理,连接远程的 Shadowsocks 服务,把网络请求转发过去。
接下来检查一下这个代理是否可用,使用 curl
命令查询一下自己的 IP,--socks5-hostname
参数指定 socks5 代理服务的地址:
1 | $ curl --socks5-hostname 127.0.0.1:1080 cip.cc |
可以看到,IP 地址是国外的,证明我们已经可以科学上网了。
启动 socat 转发
照理说,实现科学上网之后,直接在 nginx 配置反向代理就能完成我们的任务。但遗憾的是,nginx 本身并不支持使用系统代理,也不像 curl
那样提供了 --socks5-hostname
参数用于显式指定代理,因此我们只能另谋出路。
这时我想到了 socat,socat 是一个多功能网络工具,它可以在两个网络数据流之间建立通道,实现端口转发的功能,同时还支持代理。但可惜的是,socat 目前只支持 socks4,还不支持 socks5,所以还不能直接用。在 GitHub 搜索发现已经有大佬给 socat 打过补丁,使其支持 socks5,因此决定使用这个补丁版本试试。这里给出项目的地址,有兴趣可以去点个 star:https://github.com/runsisi/socat
要安装这个补丁版的 socat,我们就不能直接使用 yum 或者 apt-get,而是要下载源码自己编译:
1 | apt-get install git curl autoconf yodl make |
注意,上面的第一步首先安装了编译的过程中需要用到的其他工具,其中 yodl 在 CentOs 中可能无法使用 yum 安装,也可以考虑通过下载源码自行编译的方式解决,项目地址:https://gitlab.com/fbb-git/yodl
安装之后,启动 socat,监听 1081 端口,把流量转发给 Gravatar,当然,需要走代理:
1 | socat -d -d TCP4-LISTEN:1081,reuseaddr,fork SOCKS5:127.0.0.1:www.gravatar.com:443,socks5port=1080 |
尝试访问一下 1081 端口,发现已经可以正常获取到头像数据了:
1 | $ curl -v -k -H 'Host: www.gravatar.com' -o /dev/null https://127.0.0.1:1081/avatar/123 |
配置 nginx 反向代理
有了前面的准备工作之后,我们终于可以在 nginx 配置反向代理了,不过这里要注意的是,不能直接把流量转发给 Gravatar,而是转发给刚刚使用 socat 开启的本地 1081 端口。同时,为了减少回源的次数,提高访问速度,我们还可以做一层 proxy_cache
缓存。具体配置如下:
1 | http { |
配置完成后,尝试使用浏览器打开一个头像链接,确认是否能正常访问:https://www.liuwj.me/gravatar/123
大功告成!!一个头像请求,从浏览器发出之后,经过的路径应该是这样子的:
1 | +---------+ +-------+ +-------+ +---------+ +----------+ +----------+ |
可以说是十分曲折了…