[Node.js] 学校网关登陆脚本

虽然现在我在的学校很辣鸡,但是偶然间发现所有的教学区设备,在通过网关认证后,就可以获得一个江苏省常州市教育网的公网 IP 地址,同时拥有 10Mbps 的上下对等带宽,还是蛮良心的(

然后我们就在某办公室内放置了一个配置极其破烂的台式机,用来转发内网端口,VPN 远程接入和其他奇奇怪怪的服务。然而所有这些的前提就是通过了网关认证。比较尴尬的是那台电脑并没有显示器,所以我们只能想其他办法实现这一步骤。

最初我们使用了 VPN ——搭建一个 PPTP VPN 服务器并配置好 NAT 和 IP Forward,然后在内网使用 PPTP 连接至服务器,打开浏览器访问任意非 SSL 网站,就会被 Redirect 到网关认证,然后浏览器里操作就可以完成了。

后来发现 PPTP 的配置实在是比较繁琐(虽然比较其他形式的 VPN,PPTP 是搭建最快速的一个),同时存在各种各样的问题导致 PPP 认证不通过,进而无法建立 PPTP 连接,我们开始改用 Shadowsocks,在需要认证的机器上搭建一个 ss-server,在内网的其他机器上配置好 Shadowsocks 客户端,就可以和 PPTP 一样进行操作了。

再后来发现 Shadowsocks 的编译还是要准备一堆依赖,配置也不足够简单。反思 PPTP,我们使用 PPTP 的目的就是将两个机器组成一个虚拟专用网络,然后所有流量从待认证机器出去以实现认证。仔细想想不难发现其实我们用来认证的机器和待认证机器本来就在一个网段了,为什么还要专门组一个呢?(智商-10)所以我们只需要在待认证服务器上执行这句 iptables 语句:

iptables -t nat -A POSTROUTING -s 219.230.153.0/24 -j MASQUERADE

然后再另一个设备上,将默认网关调整至待认证设备IP,就可以和之前一样操作并通过认证了。

今天在数据结构上机的时候,突然想到,我们进行网关的认证,其实就是在网页上填写一个表单,并提交这个表单到认证服务器,随后就解锁了国际互联网访问。那为什么要搞的这么复杂绕了一大圈就为了进行一个 POST 呢?(智商+10)

想到这些就随后几分钟写了段 JavaScript,来实现这些个操作,实测可行。代码如下:

var request = require('request');
request = request.defaults({jar: true});

// Your login info here.
var uname = '';
var passwd = '';

request.get('http://www.bilibili.com/', (err, res, body) => {
    var loginURL = body.substr(28, body.length - 38);
    request.get(loginURL, (err, res, body) => {
        request.post({
            url: 'http://219.230.159.25/eportal/webgateuser.do?method=login_ajax_pure_internet¶m=true&' + loginURL.substr(40) + '&username=' + uname + '&pwd=' + passwd,
            form: {
                is_auto_land: false,
                usernameHidden: uname,
                username_tip: 'Username',
                username: uname,
                strTypeAu:null,
                uuidQrCode:null,
                authorMode:null,
                pwd_tip: 'Password',
                pwd: passwd
            },
            referer: loginURL,
            headers: {
                'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36',
                'Connection': 'keep-alive',
                'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'Accept-Encoding': 'gzip, deflate',
                'Accept-Language': 'zh,zh-CN;q=0.8,en-US;q=0.6,en;q=0.4'
            }
        }, (err, res, body) => {
            if (res.caseless.dict['auth-result'] == 'success') {
                console.log('Login Success.');
            }
            else {
                console.log('Something happened.');
            }
        });
    })
})

这段代码需要一个叫 `request` 的依赖,直接输入 `npm insall request` 即可完成安装。将个人的登录信息修改好后,执行脚本:`node login.js`,如果看到输出`Login Success.`,就表明认证通过,可以开始上网啦((

现在看来当时的解决方案真是智障(不)