当我们使用校园网或者其他其它需要认证的公共热点时候,通常都会在手机连接Wi-Fi的时候,弹出一个web登录界面,让你去登录,或者输入你的手机号码认证。如果不登录,会无法连接外网,无认证访问其它网页(非https页面)时,会自动跳转到认证web界面。这个跳转相当于一个302重定向,把你重定向到另外一个页面,主要是通过篡改http报文,在我的理解来看,应该算作劫持。而https加密传输,所以无法重定向,一般访问直接回显示无法连接之类的。在我的理解来看,应该算作劫持。

回到正题。有些细心的人可能会发现,当我们无认证连接后,会获得一个内网IP地址。(绝大多数情况)如果我们去利用cmd或者(Mac)终端去ping一个域名,我们会发现,可以返回到这个域名的IP地址,但是无法得到延迟(ms),也就是我们无法发包过去。所以,绝大多数需认证热点(也可以是校园网有线等)网关(交换机)都默认放行了dns报文。

具体认证原理详见 http://www.ruijie.com.cn/fw/wt/36502

我们可以通过一个简单的步骤来查询校园网(需认证热点等)网关是否放行了dns报文。一般通过以下步骤:

nslookup www.baidu.com

若成功会显示如下(IP地址不一样无所谓,因为baidu开启了cdn),

AUTUMN:~ AUTUMN$ nslookup www.baidu.com
Server:        119.29.29.29
Address:    119.29.29.29#53

Non-authoritative answer:
www.baidu.com    canonical name = www.a.shifen.com.
Name:    www.a.shifen.com
Address: 183.232.231.173
Name:    www.a.shifen.com
Address: 183.232.231.172

如果可以的话,就可以进入下一步了。若否,那么要说的方法应该是不奏效了。

一般来说,绝大多数的认认证路由器都一般都放行dns报文,有的甚至放行udp 53的所有数据包。下面我要讲的方法是仅允许DNS报文通过的网关(这种方法成功率很高),另外一种情况可能会在下一篇文章提及到。两者的优缺点将会在文末点评一下。

首先,我会利用到两个软件,一个是DNS2TCP,一个是iodine,分别在Windows和Mac OS演示。

准备

一台有公网IP的vps或服务器
一个有自主管理权限的域名

域名准备阶段

不管是用哪个软件,域名设置都是一样的,可以参考我的设置类比一下即可。

a NS b.qiuri.org.
b A YourServerIP

设置好大概是这个样子

这其中的原理我就不具体解释了。

开始阶段

之前讲过,我会利用到两个软件,首先我会讲iodine的配置,在Mac OS上操作,然后再在Windows上演示另外一个软件。

iodine

Server端:

我的vps的操作系统是ubuntu 14.04,因为源里面已经带有了iodine,所以安装可以直接 apt-get install iodine

安装好之后

iodined -f -P YourPassword 192.168.100.1 a.qiuri.org
# -f 开启前台显示
# -P 连接密码,自己设置
# 192.168.100.1 是自设的内网网段 也可用192.168.10.1之类
# a.qiuri.org 监听a.qiuri.org的DNS查询请求

Client端:

我的Mac操作系统是 OS X 10.11.6,一般来说利用homebrew可以直接安装iodine,但我直接安装会提示

AUTUMN:~ AUTUMN$ brew install iodine
Error: No available formula with the name "iodine" 
==> Searching for a previously deleted formula...
iodine was deleted from homebrew/core in commit 17df29ee00:
  iodine: migrate to boneyard
  due to tuntap requirement

To show the formula before removal run:
  git -C "$(brew --repo homebrew/core)" show 17df29ee00^:Formula/iodine.rb

If you still use this formula consider creating your own tap:
  https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap.html

所以我采用编译安装

# git clone https://github.com/yarrick/iodine.git
# cd iodine
# sudo make
# sudo make install

若提示错误,请安装zlib开发包,具体可以用brew安装: brew install zlib

根据我安装成功之后,输入iodine会提示-bash: iodine: command not found,这个问题貌似会出现在10.11以上的系统,这时候我们需要配置一下环境。

在~/.zshrc中写入如下配置:

# iodine
PATH="/usr/local/sbin:${PATH}"
export PATH

然后输入source ~/.zshrc,一般来说,就可以运行iodine命令了。

安装后:

iodine -f YourServerIP a.qiuri.org
# Mac用户需要加 -d utunx 否则会出段错误
例: iodine -f -d utunx YourServerIP a.qiuri.org

运行成功后

bash-3.2# iodine -f -d utunx 101.254.176.228 a.qiuri.org
Enter password: 
Opened utun2
Opened IPv4 UDP socket
Sending DNS queries for a.qiuri.org to 101.254.176.228
Autodetecting DNS query type (use -T to override).
Using DNS type NULL queries
Version ok, both using protocol v 0x00000502. You are user #0
Setting IP of utun2 to 192.168.100.2
Adding route 192.168.100.0/27 to 192.168.100.2
add net 192.168.100.0: gateway 192.168.100.2
Setting MTU of utun2 to 1130
Server tunnel IP is 192.168.100.1
Testing raw UDP data to the server (skip with -r)
Server is at 101.254.176.228, trying raw login: ....failed
Using EDNS0 extension
Switching upstream to codec Base128
Server switched upstream to codec Base128
No alternative downstream codec available, using default (Raw)
Switching to lazy mode for low-latency
Server switched to lazy mode
Autoprobing max downstream fragment size... (skip with -m fragsize)
768 ok.. 1152 ok.. ...1344 not ok.. ...1248 not ok.. ...1200 not ok.. 1176 ok.. 1188 ok.. will use 1188-2=1186
Setting downstream fragment size to max 1186...
Connection setup complete, transmitting data.

这时候我们ping 192.168.100.1,相当于ping了我们的服务器IP。所以可以理解成访问192.168.100.1就等于访问了我们远程服务器。

最后,我们就可以通过dns隧道来进行免费上网。利用ssh或者socks等,这里我用到的是socks,用了大家比较常见的shadowsocks,首先在服务器搭建好shadowsocks。然后直接shadowsocks全局代理即可绕过认证透过dns隧道进行上网了。配置示例如下图。


DNS2TCP

同理,我们在域名准备阶段先解析好域名。

Server端:

因为我使用的vps是ubuntu 14.04,同样的,源里面已经包含了这个软件,所以可以直接apt-get install dns2tcp来进行安装。

运行这个软件之前,我们首先要配置一下:

在 /etc 建立一个名为 dns2tcpd.conf 的文件,然后输入以下内容

listen = 1.2.3.4 #你的远程服务器IP
port = 53
user = nobody
chroot = /tmp
domain =a.qiuri.org #上面配置NS记录的域名
resources = ssh:127.0.0.1:22,socks:127.0.0.1:1082,http:127.0.0.1:3128 #可供客户端使用的资源

大致原理,以ssh为例。客户端本地监听22端口,将数据传送到指定端口,DNS2TCP将数据以dns协议传送到服务器端口,最后服务器再把数据转发到对应资源的端口去。

配置好之后,运行

dns2tcpd -f /etc/dns2tcpd.conf -F -d 2
-f 读取配置文件
-F 强制前台运行
-d 2 开启debug, 等级为2

如无错误,服务端已经没有问题了。

Client端:

Windows的话,我们需要下载一个软件 dns2tcp.zip 解压到任意路径就好

然后运行cmd,进入你刚刚解压软件的目录,也就是dns2tcp.exe所在目录,运行dns2tcp

dns2tcpc -r ssh -z a.qiuri.org 1.2.3.4 -l 6666 -d 2
#-r 后接服务名, 这里我们用到ssh
#-z 后接NS记录的地址和远程服务器IP,Tips:IP地址最好写上, 可以不写
#-l 后接本地端口,可以随意,只要不冲突
#-d 开启 Debug模式

运行成功时候,会显示如下图,这时候就把这cmd放着,切记不要关闭

缺图

接下来我们要配置本地ssh,将会用到xshell,直接去官网下载安装即可 https://www.netsarang.com/products/xsh_overview.html

安装好后,打开,添加如下配置:

缺图

然后连接,直接输入远程服务器账户密码即可。

缺图

连接成功后,我们就可以开始建立ssh代理。

查看–隧道窗格,点击转移规则,然后右键添加,类型选择**Dynamic (SOCK4/5)**,默认端口不必修改,最后确定。

缺图

如果单纯只用浏览器上网的话,我们可以在IE代理进行如下设置。

Internet选项-连接-局域网设置,勾选为LAN使用代理服务器,点击高级,套接字地址127.0.0.1端口填1080

缺图

完成后,即可绕过绝大多数认证。注意,如果xshell连接不上的话,请在远程服务器和本地重启一下dns2tcp,一般多试试就会连接成功了。

两个软件分析和这个方法的利弊。等待更新,还在军训中,抽时间写的。