穿透内网的反弹代理
舍友滚去实习了,恰好又要选课。学校的教务系统似乎无法从外网访问,于是便考虑给他们搞个代理。
一般情况下,代理服务器需要运行在内网,在公网边界暴露访问端口以便外网用户得以访问。但是很显然我没有校网边界路由器的权限,不可能去改防火墙。
好在我有一台VPS,在这种双方用户无法直连的情况下,就只能反过来利用第三台机器做中转了。思路很直接,校网的代理主动连接到中转服务器,再由中转服务器提供代理服务接收请求转发到校网的代理服务器中。
这种做法被叫做“反弹代理”。
搭建sock5反弹代理
在网上搜了一圈,发现有一个软件sscoks能支持反弹代理。遂下载编译。
在VPS上开放了端口8888用于反弹代理连接,并在1080端口提供Sock5代理服务:
./rcsocks -l 1080 -p 8888 -vv
在校网使用树莓派架设一个反弹代理的客户端,启动时自动连接到VPS的8888端口:
./rssocks -vv -s bakachu.cn:8888
这样,反弹代理就搭建完毕了,之后只要用代理客户端连接VPS的1080端口就能获得服务。
转换成HTTP代理
但是Sock5代理的功能太强大,如果只提供HTTP代理服务就要做转换了。这里,我直接使用tengine配合其上的lua模块编写一个小的转换脚本来将HTTP请求转到本地的sock5代理上。
tengine配置:
server {
listen 8080;
server_name proxy.bakachu.cn;
charset utf-8;
access_log /home/ngx-logs/proxy.access.log;
error_log /home/ngx-logs/proxy.error.log;
location / {
lua_socket_read_timeout 300s;
default_type text/html;
content_by_lua_file /data/proxy.lua;
}
}
lua脚本:
local socks5 = require("resty.socks5")
local base64 = require("base64")
local headers = ngx.req.get_headers()
local proxy_auth = headers["Proxy-Authorization"]
if proxy_auth == nil or proxy_auth == "" then
ngx.header["Proxy-Authenticate"] = 'Basic realm="Passwd required."'
ngx.exit(407)
else
local _, _, base64enc = string.find(proxy_auth, "Basic (.+)")
local authinfo = base64.decode(base64enc)
local _, _, username, passwd = string.find(authinfo, "(.+):(.+)")
if username ~= "proxy_username" or passwd ~= "proxy_passwd" then
ngx.header["Proxy-Authorization"] = ""
ngx.header["Proxy-Authenticate"] = 'Basic realm="Bad username or password."'
ngx.exit(407)
else
socks5.handle_request("127.0.0.1", 1080)
end
end
这样,就可以通过http://proxy.bakachu.cn:8080和用户名密码来访问sock5代理了。