AliYun 配置 TunnelBroker IPv6 隧道

流程

  1. 编辑 /etc/sysctl.conf,修改以下条目。
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
  1. 执行 sysctl -p 刷新设置文件
  2. 写入配置信息至 /etc/network/interfaces
auto he-ipv6
iface he-ipv6 inet6 v4tunnel
        address [客户端 IPv6 地址]
        netmask 64
        endpoint [隧道服务器 IPv4 地址]
        local [本机 IPv4 地址]
        ttl 255
        gateway [隧道服务器 IPv6 地址]
  1. 执行 ifup he-ipv6 启用隧道

故障

  1. add tunnel sit0 failed: No buffer space available
    隧道已经存在,执行 ip tun del he-ipv6 删除已经存在的隧道。
  2. add tunnel "sit0" failed: No buffer space available
    系统 IPv6 被禁用或者未更新配置文件,检查 /etc/sysctl.conf 中有无禁用 IPv6 的命令

OCServ Netflix 策略路由

背景

Netflix 账号全球通用,流媒体内容取决于用户 IP 地址来源区域。通常来说,“解锁” Netflix 外区服务有两种方式,分别是全局代理和智能解析。前者最稳定但会影响其他应用的访问速度,后者较灵活,但配置过程繁琐,不适用于全平台。本方案通过配置策略路由,极大降低了对其他网络服务的影响并同时具有全局代理的稳定性。

分析

Netflix 采取了多种方式进行代理检测,包括但不限于 IP 地址检测与 DNS 解析比对。其中 DNS 解析测试服务运行于运用了 Anycast 技术的 AWS EC2 上。因此最保险的方法是路由全部 NetflixAWS 的 IP 段。

提取

使用正则表达式对 IPv4 地址段进行提取。
[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}/[0-9]{1,3}

使用一段简单的 C 程序将地址段整理成 [IP]/[子网掩码] 的形式。

#include "bits/stdc++.h"
int main()
{
    freopen("aws.txt", "r", stdin);
    freopen("res.txt", "w", stdout);
    int a, b, c, d;
    int a1, b1, c1, d1;
    while(~scanf("%d.%d.%d.%d", &a, &b, &c, &d))
    {
        a1 = 255;
        b1 = b == 0 ? 0 : 255;
        c1 = c == 0 ? 0 : 255;
        d1 = d == 0 ? 0 : 255;
        if (d1 != 255)
            printf("%d.%d.%d.%d/%d.%d.%d.%dn", a, b, c, d, a1, b1, c1, d1);
    }
    fclose(stdin);
    fclose(stdout);
    freopen("res.txt", "r", stdin);
    freopen("final.txt", "w", stdout);
    char str1[100], str2[100];
    scanf("%s", str1);
    while(~scanf("%s", str2))
    {
        if (strcmp(str1, str2) != 0)
        {
            printf("%sn", str1);
            memcpy(str1, str2, sizeof(str1));
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

然后进行人工整理与去重至两百条以内,并加上 route = 头部,得到最终的配置片段。

# Netflix
route = 23.246.0.0/255.255.0.0
route = 37.77.0.0/255.255.0.0
route = 45.57.0.0/255.255.0.0
route = 64.120.128.0/255.255.0.0
route = 66.197.128.0/255.255.0.0
route = 69.53.224.0/255.255.0.0
route = 69.53.225.0/255.255.0.0
route = 108.175.32.0/255.255.0.0
route = 185.2.220.0/255.255.0.0
route = 185.9.188.0/255.255.0.0
route = 192.173.0.0/255.255.0.0
route = 198.38.0.0/255.255.0.0
route = 198.45.0.0/255.255.0.0
# AWS
route = 13.0.0.0/255.0.0.0
route = 18.130.0.0/255.0.0.0
route = 23.20.0.0/255.255.0.0
route = 27.0.0.0/255.0.0.0
route = 34.192.0.0/255.0.0.0
route = 35.153.0.0/255.0.0.0
route = 43.250.192.0/255.255.255.0
route = 43.250.193.0/255.255.255.0
route = 46.51.128.0/255.255.0.0
route = 46.137.0.0/255.255.0.0
route = 50.16.0.0/255.255.0.0
route = 50.18.0.0/255.255.0.0
route = 50.19.0.0/255.255.0.0
route = 50.112.0.0/255.255.0.0
route = 52.0.0.0/255.0.0.0
route = 52.46.64.0/255.0.0.0
route = 54.64.0.0/255.0.0.0
route = 63.32.0.0/255.255.0.0
route = 64.252.64.0/255.255.255.0
route = 67.202.0.0/255.255.0.0
route = 70.132.0.0/255.255.0.0
route = 71.152.0.0/255.255.0.0
route = 72.21.192.0/255.255.255.0
route = 72.44.32.0/255.255.255.0
route = 75.101.128.0/255.255.255.0
route = 79.125.0.0/255.255.0.0
route = 87.238.80.0/255.255.255.0
route = 96.127.0.0/255.255.0.0
route = 99.79.0.0/255.255.0.0
route = 99.80.0.0/255.255.0.0
route = 100.20.0.0/255.255.0.0
route = 100.24.0.0/255.255.0.0
route = 103.4.8.0/255.255.255.0
route = 103.8.172.0/255.255.255.0
route = 103.246.148.0/255.255.255.0
route = 103.246.150.0/255.255.255.0
route = 107.20.0.0/255.255.0.0
route = 122.248.192.0/255.255.255.0
route = 143.204.0.0/255.255.0.0
route = 172.96.97.0/255.255.255.0
route = 172.96.98.0/255.255.255.0
route = 174.129.0.0/255.255.0.0
route = 175.41.128.0/255.255.255.0
route = 175.41.192.0/255.255.255.0
route = 176.32.64.0/255.255.255.0
route = 176.32.96.0/255.255.255.0
route = 176.32.104.0/255.255.255.0
route = 176.32.112.0/255.255.255.0
route = 176.32.120.0/255.255.255.0
route = 176.32.125.0/255.255.255.0
route = 176.34.0.0/255.255.0.0
route = 176.34.32.0/255.255.255.0
route = 176.34.64.0/255.255.255.0
route = 176.34.128.0/255.255.255.0
route = 177.71.128.0/255.255.255.0
route = 177.72.240.0/255.255.255.0
route = 178.236.0.0/255.255.0.0
route = 184.72.0.0/255.255.0.0
route = 184.72.64.0/255.255.255.0
route = 184.72.128.0/255.255.255.0
route = 184.73.0.0/255.255.0.0
route = 184.169.128.0/255.255.255.0
route = 185.48.120.0/255.255.255.0
route = 185.143.16.0/255.255.255.0
route = 203.83.220.0/255.255.255.0
route = 204.236.128.0/255.255.255.0
route = 204.236.192.0/255.255.255.0
route = 204.246.160.0/255.255.0.0
route = 205.251.192.0/255.255.0.0
route = 207.171.160.0/255.255.255.0
route = 207.171.176.0/255.255.255.0
route = 216.137.32.0/255.255.255.0
route = 216.182.224.0/255.255.255.0
route = 216.182.232.0/255.255.255.0
route = 216.182.236.0/255.255.255.0
route = 216.182.238.0/255.255.255.0
route = 54.228.16.0/255.255.255.0
route = 54.245.168.0/255.255.255.0
route = 54.248.220.0/255.255.255.0
route = 107.23.255.0/255.255.255.0
route = 52.82.188.0/255.0.0.0
route = 54.222.48.0/255.0.0.0
route = 13.52.0.0/255.0.0.0
route = 18.130.0.0/255.0.0.0
route = 23.20.0.0/255.255.0.0
route = 34.192.0.0/255.255.0.0
route = 34.208.0.0/255.255.0.0
route = 34.224.0.0/255.255.0.0
route = 34.240.0.0/255.255.0.0
route = 34.248.0.0/255.255.0.0
route = 35.153.0.0/255.0.0.0
route = 46.51.128.0/255.255.255.0
route = 46.51.192.0/255.255.255.0
route = 46.51.216.0/255.255.255.0
route = 46.51.224.0/255.255.255.0
route = 46.137.0.0/255.255.0.0
route = 46.137.128.0/255.255.255.0
route = 46.137.192.0/255.255.255.0
route = 46.137.224.0/255.255.255.0
route = 50.16.0.0/255.255.0.0
route = 50.18.0.0/255.255.0.0
route = 50.19.0.0/255.255.0.0
route = 50.112.0.0/255.255.0.0
route = 52.0.0.0/255.0.0.0
route = 54.92.0.0/255.0.0.0
route = 63.32.0.0/255.255.0.0
route = 67.202.0.0/255.255.0.0
route = 72.44.32.0/255.255.255.0
route = 75.101.128.0/255.255.255.0
route = 79.125.0.0/255.255.0.0
route = 96.127.0.0/255.255.0.0
route = 99.79.0.0/255.255.0.0
route = 99.80.0.0/255.255.0.0
route = 100.20.0.0/255.255.0.0
route = 100.24.0.0/255.255.0.0
route = 103.4.8.0/255.255.255.0
route = 107.20.0.0/255.255.0.0
route = 122.248.192.0/255.255.255.0
route = 174.129.0.0/255.255.0.0
route = 175.41.128.0/255.255.255.0
route = 175.41.192.0/255.255.255.0
route = 176.32.64.0/255.255.255.0
route = 176.34.0.0/255.255.0.0
route = 176.34.32.0/255.255.255.0
route = 176.34.64.0/255.255.255.0
route = 176.34.128.0/255.255.255.0
route = 177.71.128.0/255.255.255.0
route = 184.72.0.0/255.255.0.0
route = 184.72.64.0/255.255.255.0
route = 184.72.128.0/255.255.255.0
route = 184.73.0.0/255.255.0.0
route = 184.169.128.0/255.255.255.0
route = 185.48.120.0/255.255.255.0
route = 204.236.128.0/255.255.255.0
route = 204.236.192.0/255.255.255.0
route = 216.182.224.0/255.255.255.0
route = 216.182.232.0/255.255.255.0
route = 216.182.236.0/255.255.255.0
route = 216.182.238.0/255.255.255.0
route = 52.95.110.0/255.255.255.0
route = 205.251.192.0/255.255.255.0
route = 13.32.0.0/255.255.0.0
route = 13.35.0.0/255.255.0.0
route = 13.59.250.0/255.255.255.0
route = 13.113.203.0/255.255.255.0
route = 13.124.199.0/255.255.255.0
route = 13.228.69.0/255.255.255.0
route = 34.195.252.0/255.255.255.0
route = 34.216.51.0/255.255.255.0
route = 34.226.14.0/255.255.255.0
route = 35.158.136.0/255.255.255.0
route = 52.46.0.0/255.255.0.0
route = 52.47.139.0/255.255.255.0
route = 52.56.127.0/255.255.255.0
route = 52.57.254.0/255.255.255.0
route = 52.84.0.0/255.255.0.0
route = 52.212.248.0/255.255.255.0
route = 52.220.191.0/255.255.255.0
route = 52.222.128.0/255.255.255.0
route = 54.182.0.0/255.255.0.0
route = 54.192.0.0/255.255.0.0
route = 54.230.0.0/255.255.0.0
route = 54.239.128.0/255.255.255.0
route = 54.239.192.0/255.255.255.0
route = 54.240.128.0/255.255.255.0
route = 64.252.64.0/255.255.255.0
route = 70.132.0.0/255.255.0.0
route = 71.152.0.0/255.255.0.0
route = 143.204.0.0/255.255.0.0
route = 204.246.164.0/255.255.255.0
route = 204.246.168.0/255.255.255.0
route = 204.246.174.0/255.255.255.0
route = 204.246.176.0/255.255.255.0
route = 205.251.192.0/255.255.255.0
route = 205.251.249.0/255.255.255.0
route = 205.251.250.0/255.255.255.0
route = 205.251.252.0/255.255.255.0
route = 205.251.254.0/255.255.255.0
route = 216.137.32.0/255.255.255.0
route = 18.188.9.0/255.255.255.0

注意

  1. 0.10.5 及之前版本 OCServ 需要修改 src/vpn.h 来支持超过96行(OCServ默认值)但不超过 200 行(Cisco 客户端最大值)的路由表:
    #define MAX_CONFIG_ENTRIES 96,96 改为 200 以上。0.10.6 及之后版本 OCServ 不需要修改,参考 https://gitlab.com/ocserv/ocserv/issues/17

  2. 根据 Cisco 官方文档,no-routeroute 不能同时使用。

    You can specify either split-include or split-exclude, but you cannot specify both options.

效果

对于 Netflix 以及 AWS 服务的流量将全部被路由至远程服务器进行中转,但使用 Netflix 进行观看与下载时所产生的流量会走本地直连。Netflix Open Connect 计划使得 Netflix 与 ISP 进行合作,通过应用 CDN 下沉解决方案,减小 Netflix 与运营商的网络负载和建设成本,而这些 CDN 服务器地址并非 Netflix 所属,而是归属地 ISP 的地址,因此数据是由归属地 CDN 直接传输到本地。

本方案有效降低了服务器的网络负载,对于不同平台具有普适性作用。对于有前置路由的网络场景,可以在路由上直接写入精确的路由表,提高服务运行效率。

OCServ DTLS 连接异常

问题症状

环境:Ubuntu 16.04 x64
版本:OCServ 0.10.11-1build1
今日重置了阿里云 ECS 后,选择从 APT 源直接安装 OCServ 而非从官网手动下载安装,随后便发生了一些诡异事情。
service ocserv start 所启动的 OCServ 服务在 IPv4 网络中进行连接时,尽管网络状态良好,仍然回退到了 TLS 链路。而使用 ocserv 命令直接启动服务却能正常建立 DTLS 连接。
使用 lsof -i:443 检查 443 号端口监听状态时发现,前者会由 systemdocserv-main 共四个进程监听 IPv6 协议类型上的 443 号端口的 UDP/TCP,而后者由 ocserv 共两个进程监听 IPv4 协议类型上的 443 号端口的 UDP/TCP。
查看 /etc/init.d/ocserv 文件发现,OCserv Daemon 在启动时会正确调用位于 /etc/ocserv/ocserv.conf 的配置文件,但却没有根据配置文件中的设定进行监听。

解决方案 1

早在 2016 年便有人指出这个缺陷(现已修复),而阿里云 APT 源中的包版本较老,所以没有修复此问题。

Try to go to “/lib/systemd/system/” and modify the file of “ocserv.service”,
1.use vim to change two lines,
2.Remove the line of “Requires=ocserv.socket”
3.Remove the line of “Also=ocserv.socket”
4.save the file,

execute “systemctl daemon-reload”,
then reload the service “service ocserv start”

  1. 编辑 /lib/systemd/system/ocserv.service,移除 Requires=ocserv.socketAlso=ocserv.socket
  2. 重新加载 Systemd 配置文件:执行 systemctl daemon-reload
  3. 重启 OCServ 服务:执行service ocserv start

服务重启后,DTLS 连接可以正常建立,且未与 OpenVZ-BBR 冲突,至此问题得到了完美解决。

解决方案 2

使用 apt remove ocserv 移除旧版本的 OCServ,从 OCServ 项目官网 下载最新版本的 OCServ,然后手动安装。

Rinetd:Linux下的端口转发工具

Linux 环境下使用 iptables 实现端口转发的确是一个很好的选择,不过 Rinetd 提供了一个更简单的端口转发方案。

apt-get install rinted -y
vi /etc/rinetd.conf

以如下格式填入配置信息

bindaddress(绑定IP) bindport(绑定端口)  connectaddress(转发地址)    connectport(转发端口)

“bindaddress”处填写 0.0.0.0 可以将全部来源的流量进行转发。
随后执行 rinetd 开启 rinetd 服务。

EdgeRouter Lite 3 配置 OpenConnect

概览

EdgeOS 是基于 Vyatta 开发的 Debian 系软路由操作系统,具有极高的自由度。然而,由于 EdgeOS 所支持的 VPN 协议较为局限,我们需要手动配置路由的 OpenConnect VPN Client。

缺陷

本方法不具备策略路由等功能,为全局代理,对于国内应用的访问风控会有影响。
适用于需要全天候使用的用户,不适用于需要频繁切换线路的用户。

步骤

1.配置 APT 软件源

configure
set system package repository wheezy components 'main contrib non-free'
set system package repository wheezy distribution wheezy 
set system package repository wheezy url http://http.us.debian.org/debian
commit
save
exit

源也可以更换为 https://mirrors.tuna.tsinghua.edu.cn/debian/

bash
sudo apt-get update

2.安装 OpenConnect VPN Client

因为有数百个依赖需要安装,此时需要等待一段时间。结束后会产生一个缺少 psmisc 依赖的错误,根据官方解释是 Busybox 导致的冲突,忽略即可。

bash
sudo apt-get install openconnect -y

3.编写服务控制脚本

vi /etc/init.d/vpn.sh

完善下列脚本中的信息并写入。

#!/bin/bash
# Path variables
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# VPN Variables
IFACE="sslinterface"
VPN_USER="[[用户名]]"
VPN_HOST="[[服务器地址]]"
VPN_PASS='[[密码]]'
PID="/var/run/openconnect.pid"
TEMP_LOG="/tmp/status.txt"
INFO="

Usage: $(basename "$0") (start|stop|status|restart)

"

# Connect to Cisco SSL VPN using passwords from stdin (passed by VPN_PASS variable created prior)
function connect_vpn(){

if [ -f $PID ]
    then
        printf "\n\tOpenconnect is already running\n"
        exit 1
    else
        echo ${VPN_PASS} | openconnect -b --user=${VPN_USER} --no-dtls ${VPN_HOST} --passwd-on-stdin > $TEMP_LOG 2>&1
        if $(grep -i failed $TEMP_LOG)
            then
                printf "\n\tOpenconnect failed to start!\n"
                cat $TEMP_LOG
                exit 2
            else
                touch $PID
                iptables -I FORWARD -o tun0 -j ACCEPT
                iptables -t nat -A POSTROUTING -s [[本地局域网网段]] -j MASQUERADE
                printf "\n\tOpenconnect started!\n"
        fi
fi
}

# Check if openconnect is running through PID file
function check_openconnect(){

if [ -f $PID ]
    then
        printf "\n\tOpenconnect is running!\n"
    else
        printf "\n\tOpenconnect is stopped\n"
fi
}

# Confirm if PID file exists, then kill it immediately
function kill_openconnect(){

if [ -f $PID ]
    then
        rm -f $PID >/dev/null 2>&1
        kill -9 $(pgrep openconnect) >/dev/null 2>&1
        iptables -D FORWARD -o tun0 -j ACCEPT
        iptables -t nat -D POSTROUTING -s [[本地局域网网段]] -j MASQUERADE
    else
        printf "\n\tOpenconnect is not running!\n"
fi
}

case "$1" in

    start)
    
        connect_vpn
        ;;
    
    stop)
    
        kill_openconnect
        ;;
    
    status)
    
        check_openconnect
        ;;
    
    restart)
    
        $0 stop
        $0 start
        ;;
    
    *)
    
        echo "$INFO"
        exit 0
        ;;
esac

使脚本可被执行

chmod +x vpn.sh

4.设置服务监控与自动启动

实现的方式有很多种,这里采取最简单的定时任务方式。
编辑 root 用户的计划任务。

crontab -e -u root

添加一行内容,使得系统每分钟启动一次服务。由于控制脚本中存在冲突检测,所以配合 crontab 实现了看门狗功能。

* * * * * /etc/init.d/vpn.sh start

5.配置负载均衡[可选]

当前网络模式为 eth0 + eth1 双WAN负载均衡,因此将 tun0 添加到负载均衡组,分配权重为 100,其余各分配 0。这样全部流量会从 tun0 通过,当 tun0 故障时,其余两个端口会自动接管流量。

参考资料

jibla/ubuntu-openconnect-command: Bash script handling openconnect commands for ubuntu cli.
ubnt EdgeOS 下如何固化 iptables 规则,每次开机都生效。 – V2EX
EdgeRouter – Add other Debian packages to EdgeOS