零基础搭建Shadowsocks(1) 基础理论

来源:互联网 发布:ubuntu 17.10 安装后 编辑:程序博客网 时间:2024/05/01 23:07

转载自朋友的文章: 原文

前言

科学上网工具是每个程序员必备的,最近一直在用Lantern,但是Windows上的Lantern并不好用,而且迟迟没有发布iOS客户端。因此想折腾一下,搭一个翻墙服务器。想到曾经有一个叫clowwindy的大神,写过一套框架,叫Shadowsocks,用来科学上网,后来由于众所周知的原因,作者自己下架了源码。

关于Shadowsocks的一些八卦就不再讨论,这篇文章主要想聊聊关于科学上网的事情。首先来看一下GFW。

GFW

全名不说了,说多了怕喝茶。其实就是个防火墙,让无数程序员和它斗智斗勇。GFW发展到今天也有很长的历史了,技术上一直不断的迭代更新,越来越智能的阻拦我们通往自由的道路,其阻断方式主要有以下几点:

DNS劫持

DNS劫持是通过劫持DNS服务器,控制某些域名的解析结果,从而返回不正确的IP地址给用户。我们可以用nslookup命令做个小实验,在命令行执行如下命令:

nslookup www.youtube.com

可以看到返回的IP地址是:

Address: 59.24.3.173

我们通过http://59.24.3.173.ipaddress.com 查看IP地址信息,显示如下:

这里写图片描述

归属地是韩国。

接下来我们再用自己搭建的国外VPS执行nslookup命令,看到返回的IP地址是:

Address: 172.217.24.110

归属地信息如下:

油管已经被谷歌收购了,地址也是美国加州,这才是正确的。因此在国内环境下DNS会被劫持。然而劫持者倒不一定是GFW,有可能是网络运营商。

DNS缓存污染

为解决DNS劫持的问题,我们可以指定DNS服务器为8.8.8.8,这是谷歌的DNS服务器。我们执行

nslookup www.youtube.com 8.8.8.8

看到返回结果是:

Address: 243.185.187.39

结果依然不对,这就引出另一个概念——DNS缓存污染,是一种DNS投毒攻击,由于DNS解析域名默认是用无安全认证的UDP协议,因此极易被篡改。只要你的请求和非法关键字匹配上了,GFW就会立刻伪装一个和目标DNS域名一样的服务器,给用户返回一个错误的IP地址。

另外一种情况是DNS服务器会缓存查询结果一段时间,如果某一次的查询被污染了,结果依然会被缓存起来,方便其他计算器访问的时候可以快速返回,导致整个域被污染。

端口封锁

GFW在之前升过一次级,能力大幅提升,加入了特征检测和流量分析。如果你可以通过VPN连接到国外服务器的话,由于VPN在传输过程中特征十分明显,GFW捕捉到后会将你的端口封掉,即使你使用特征不明显的传输方式,还是躲不过流量检测,一但被检测到流量过大的问题,GFW就会立刻进行跟踪,查看你的传输内容,如果你用https进行传输,GFW会进行随机阻断行为。

IP封锁

这个就比较简单粗暴了,多次换端口被检测到后就直接将IP封掉,遇到这种情况只能更换IP了。

上边简单看了下GFW的工作方式,下面我们就来聊聊突破手段。

VPN

VPN是虚拟专用网络的缩写,一般企业会经常用到这项技术。主要是通过企业的VPN服务器,使外网的计算机在验证授权后可以使用内网服务。

以本地用户访问企业Git服务器为例,通过本地的VPN客户端给用户创建一个虚拟网卡,并从企业的VPN服务器地址池中为本地用户分配一个IP地址,例如是192.168.1.2。

访问企业Git服务器时,假设Git服务器的内网地址为10.6.15.2,那么请求的数据包源地址即为192.168.1.2,目标地址是10.6.15.2。

接下来VPN客户端会将此请求进行加密,在发出之前封装上公网IP。假如本地用户的公网IP是2.17.0.2,企业的VPN服务器的公网是6.16.5.6,请求的数据包原地址就变成了2.17.0.2,目标地址为6.16.5.6。

通过公网传输,数据送达到VPN服务器后,会进行解包,发现请求的目标地址是10.6.15.2,就将此请求转发给10.6.15.2的服务器,也就是我们的Git服务器。

用一张图来描述就是这样:

这里写图片描述

VPN是用点对点隧道技术实现的,所谓点对点,即逻辑上将两台计算机连接在一起;所谓隧道,是指建立加密传输隧道、数据封装、加密、传输、解包这些一系列的过程称为隧道。VPN协议一般是工作在数据链路层,常见的协议有PPTP,L2TP,及OpenVPN。

关于协议的解释不再多说,利用VPN翻墙也是VPN技术的一项具体应用,只不过是上述例子中的企业VPN服务器换成用户自己架设在国外的服务器而已。

目前利用VPN进行翻墙越来越困难。由于协议特征明显,很多请求在传输过程中就能被定向拦截下来,导致数据包根本发送不出去。

Shadowsocks

Shadowsocks是利用传输层上的Socks5协议实现的解决方案。他的思想是将本地用户和服务器之间增加SS-Local和SS-Server两端,本地发出的请求,先经过SS-Local,再通过SS-Local将请求加密后发出。

由于SS-Local一般是在本机或路由器起的一个虚拟服务器,因此本地和SS-Local的交互不经过GFW。过程如下图所示:

这里写图片描述

请求发出后,SS-Local到SS-Server是常规的TCP包,特征不明显,因此可以绕过GFW的检测。

这也就是为什么GFW如果要围剿Shadowsocks的话代价很大的原因,如果将所有的TCP包拦下并分析,耗费的成本是巨大的。

因此GFW也只能通过流量分析,当某一IP的访问流量过大时,进行随机阻断。

下篇文章我们将先从准备工作开始,亲手搭建一套完整的Shadowsocks服务器。