目前常见的VPN协议都有可靠的密码学加密,可以保证我们访问的网站等信息不被他人窃取

但我们的访问请求会被VPN服务器进一步转发,转发出去的流量如果是HTTP请求就会暴露请求内容,如果是HTTPS请求则会泄露SNI,同时还会暴露访问的目标IP地址,DNS的明文查询也不可避免暴露我们的访问网站

为了实现对这一流程的进一步保护,我们可以使用CloudFlare对个人用户免费提供的WARP服务

同时使用WARP服务后,还会增加对IPv6的完整支持,降低网络延时

除此之外,WARP的出口IP目前能解锁Netflix等流媒体,但由于目前该方法的广泛使用,难以保证长期的有效性

[2021-03更新]实现无损双栈

这篇文章发出大概2个月后,在自己的VPS上套WARP实现IPv4/IPv6双栈支持,并解锁流媒体的用法在网上开始广泛流传

例如在文章:https://p3terx.com/archives/use-cloudflare-warp-to-add-extra-ipv4-or-ipv6-network-support-to-vps-servers-for-free.htmlhttps://luotianyi.vc/5252.html 中均提出了让WireGuard只接管系统IPv6或者IPv4路由表以避免服务器上运行服务遭到影响的实现方案,但这个方案仍旧不够完美,不能实现WARP的v6和v4双栈共存

本文于2021-01提出的“大陆白名单”双栈实现方法也存在一定不足,例如如果使用境外中转机或者CDN时,难以进行配置

这里补充一种不使用任何白名单,而且可以不影响VPS上原本部署的网站、SSH等所有服务的无损实现方式

注意,由于这里没有讲解WireGuard的一些基本操作方法,因此最好读完后面的内容后再进行具体操作

  1. 使用ifconfig命令查看VPS出口网卡IP地址,这里的IP地址不一定是你VPS的公网IP地址,例如在腾讯云主机中,就是该主机的内网IP地址

    image-20210313170731812

  2. 在WireGuard配置文件中[Interface] 部分的最后,添加下面的内容

    PostUp = ip rule add from 上面获取的IP地址 lookup main
    PostDown = ip rule delete from 上面获取的IP地址 lookup main
  3. 最后重启WireGuard即可

[2021-03更新] IPv4不通的解决方案

经过在一些VPS上实验发现,有一些VPS连接CloudFlare的WARP后,存在IPv4不通,但是IPv6通的情况,如果只是用来解锁流媒体或者避免Google验证码或是使用Google学术搜索,这样的情况其实没有太大影响

我们只需要让WireGuard只接管我们的IPv6路由,并在代理软件中使用Freenom设置使用IPv6进行优先请求即可

  1. 首先删除WireGuard配置文件中的下述内容,让WireGuard只接管IPv6请求

    AllowedIPs = 0.0.0.0/0
  2. 接下来在代理软件中修改Outbounds部分配置如下

    "outbounds": [
    {
    "sendThrough": "::",
    "protocol": "freedom",
    "settings": {
    "domainStrategy": "UseIP"
    }
    }
    ]

    这里domainStrategy中的UseIP表示使用代理软件的内建DNS服务器,并根据上面的sendThrough指定的IP协议类型进行域名解析,我们这里将sendThrough设定为任意IPv6地址,即::,如果想要优先使用IPv4,可以对应设置为0.0.0.0

  3. 重启代理软件即可

    image-20210313171815450

准备WARP账号

WARP是由CloudFlare向个人用户免费提供的VPN代理服务,其基于WireGuard协议,官网为:https://1.1.1.1/

WARP的旨在保护移动设备的通信流量不被监听,只需要在手机上安装WARP的APP,就可以将全部流量通过CloudFlare的服务器进行中转,当然,WARP服务在中国大陆并不可用

为了能在我们的VPS上部署WARP,我们需要用到Github上的一个开源项目wgcf:https://github.com/ViRb3/wgcf

从该项目的Release页面,可以下载对应系统和CPU架构的预编译版本使用:

image-20210116105805899

下载好后,首先注册WARP账号

wgcf register

注册过程中需要首先同意CloudFlare的用户协议,注册成功会在当前目录下生成一个wgcf-account.toml的用户信息文件

接下来将WARP的账号信息转换为WireGuard的标准配置文件

wgcf generate

生成完毕后会输出wgcf-profile.conf文件,该文件将用于后续WireGuard的启动

配置WireGuard

WireGuard在各个系统下安装的方法各有不同,具体可以参照WireGuard的官方教程:https://www.wireguard.com/install/

在Linux下安装好wireguard-tools后,会默认创建/etc/wireguard目录,用于存放配置文件

直接将刚刚生成的wgcf-profile.conf文件复制到该目录下即可

接下来使用下面的命令启动代理即可

wg-quick up <conf文件名>

例如我将wgcf-profile.conf文件重命名为warp.conf文件拷贝到对应目录下,则启动命令如下

wg-quick up warp

关闭命令如下

wg-quick down warp

但!如果你使用远程方式连接到VPS,切勿直接启动,因为启动后会导致SSH连接中断,所有通向服务器的连接均会中断

这是因为开启VPN后WireGuard会修改系统的路由表,将所有出站流量都导向CloudFlare的服务器造成的

配置路由表

WireGuard的quick配置工具默认不会去修改route命令控制的系统路由表,我们可以通过观察其启动日志发现其配置原理

[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip address add 192.168.128.254/24 dev wg0
[#] ip link set mtu 1420 dev wg0
[#] ip link set wg0 up
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0

从启动日志可以发现,WireGuard创建了一张编号为51820的路由表,并通过添加rule将所有的数据包通过51820的路由表进行路由,从而避开了系统默认路由表

为了避免在我们通过国内IP连接到VPS时也被通过这张路由表进行路由,我们可以在上述命令执行完成后在继续添加rule,将所有的国内IP通过系统的默认main路由表进行路由

其实添加方法非常简单,只需要用CIDR表示法将要例外的IP地址表示一下就可以,例如我想让223.255.252.0/23这个IP段不通过代理返回数据,则执行命令如下

ip -4 rule add to 223.255.252.0/23 priority 1 

其中 to表示目的地址筛选,priority表示规则优先级,数字越小则优先级越高,如果不指定优先级,则系统默认会设定为目前最小的数字,因而该命令必须放在WireGuard启动后执行

同时,该命令还可使用table指定路由表,如果不指定,则是系统默认的main路由表,main路由表可以使用route -n看到

image-20210116113802785

为了将所有的中国IP都包括在内,我们需要将 APNIC Delegated List 的中国IP数据库信息转换为我们对应的配置命令,这里我们可以用到Github项目:https://github.com/fivesheep/chnroutes

但需要注意的是,上述项目的输出命令不能直接使用,需要通过简单的文本替换转换为下面的形式

image-20210116114021934

同样准备对应的清除规则的命令,由于规则添加时会默认以最高优先级添加,因而如果停止时不清除规则,下次启动WireGuard时规则就无法生效,停止的方法很简单,直接将add替换为delete即可

image-20210116114142353

接下来在配置文件中使用WireGuard给我们提供的钩子,直接在启动后和停止后执行这两个sh文件,实现路由表的自动更改

image-20210116114259857

具体方法就是在配置文件中添加上述PostUpPostDown字段,同理其实还可以有PreUpPreDown

接下来如果直接运行命令启动,由于在启动过程中SSH会发生阻断,可能会出现启动不成功的问题,可以使用screen或者将命令添加到rc.local文件中实现开机自启动

测试

如果路由表配置正确,则我们应该可以正常连接到服务器,同时服务器可以正常连接到外网,可以看到,服务器的IP已经变为了CloudFlare Warp服务的IP地址

image-20210116114558251

image-20210116114619475

服务器访问一些网站的网络延迟也明显降低(上:启动前,下:启动后)

image-20210116115117852

image-20210116114649662

IPv6可正常使用

image-20210116114725726

WARP服务可以正常使用Netflix,经过测试,不论是在晚高峰时段还是白天,均可以跑满服务器带宽,还会明显降低在访问一些网站时的延迟。如果有IPLC专线可用,还可以直接转发CloudFlare的EndPoint,在本地直接使用WireGuard客户端,甚至无需境外落地机器。

与此同时,从服务器发出的所有的网络流量(包括DNS请求)都会加密,并发往CloudFlare的节点,不会直接发往目标服务器,主机商无法从任何途径得知你访问的网站和对应内容,非常安全。

参考资料

[1] WireGuard 配置和上网流量优化 https://blog.mozcp.com/wireguard-usage/

[2] 策略路由以及使用 ip route , ip rule , iptables 配置策略路由实例 https://blog.csdn.net/bytxl/article/details/9850803