设置BGP绕过阻塞,或者“我是如何不再害怕并爱上RKN的”

好吧,“爱”这个词有点夸张。 相反,“能够共存”。

众所周知,自 16 年 2018 月 10 日起,Roskomnadzor 一直在极其广泛地阻止对互联网资源的访问,添加了“统一域名注册、互联网网站页面索引和允许识别网站的网络地址”。有时,在互联网上“包含俄罗斯联邦禁止分发的信息”(在文本中 - 只是一个寄存器)。 结果,俄罗斯联邦公民和企业因无法获得他们所需的完全合法的资源而遭受痛苦。

当我在哈布雷的一篇文章的评论中表示我准备帮助受害者建立旁路计划后,有几个人向我寻求此类帮助。 当一切都对他们有用时,其中一个人建议在一篇文章中描述该技术。 经过一番思考,我决定打破网站上的沉默,尝试写一些介于项目和 Facebook 帖子之间的东西,即哈布拉邮政。 结果就在你面前。

免责声明

由于发布绕过阻止访问俄罗斯联邦境内禁止的信息的方法不是很合法,因此本文的目的是讨论一种方法,该方法允许您自动获取对俄罗斯联邦境内允许的资源的访问权限。俄罗斯联邦领土,但由于某人的行为而无法通过您的提供商直接访问。 通过本文中的操作而获得的对其他资源的访问是一个不幸的副作用,并且绝不是本文的目的。

另外,由于我的职业、职业和人生道路主要是一名网络架构师,所以编程和 Linux 并不是我的强项。 因此,当然脚本可以写得更好,VPS的安全问题可以更深入地解决等等。 如果您的建议足够详细,我们将感激地接受 - 我很乐意将它们添加到文章的正文中。

TL博士

我们使用注册表副本和 BGP 协议通过您的现有隧道自动访问资源。 目标是将所有发送至受阻资源的流量移至隧道中。 最少的解释,主要是分步说明。

为此你需要什么?

不幸的是,这篇文章并不适合所有人。 为了使用此技术,您需要将几个元素放在一起:

  1. 您必须在阻塞区域之外的某个地方有一个 Linux 服务器。 或者至少是拥有这样一台服务器的愿望 - 幸运的是它现在的价格从每年 9 美元起,甚至可能更低。 如果您有单独的 VPN 隧道,则该方法也适用,然后服务器可以位于阻止字段内。
  2. 您的路由器应该足够智能,能够
    • 您喜欢的任何 VPN 客户端(我更喜欢 OpenVPN,但它可以是 PPTP、L2TP、GRE+IPSec 或创建隧道接口的任何其他选项);
    • BGPv4 协议。 这意味着对于 SOHO 来说,它可以是 Mikrotik 或任何具有 OpenWRT/LEDE/类似自定义固件的路由器,允许您安装 Quagga 或 Bird。 也不禁止使用 PC 路由器。 对于企业,请在边界路由器的文档中查找 BGP 支持。
  3. 您应该了解 Linux 的使用和网络技术,包括 BGP 协议。 或者至少想得到这样的想法。 由于这次我还没有准备好拥抱浩瀚,所以你必须自己研究一些你自己无法理解的方面。 不过,我当然会回答评论中的具体问题,而且我不太可能是唯一回答的人,所以请毫不犹豫地提问。

示例中使用了什么

  • 登记册副本 - 来自 https://github.com/zapret-info/z-i 
  • VPS-Ubuntu 16.04
  • 路由服务- 鸟1.6.3   
  • 路由器- Mikrotik hAP ac
  • 工作文件夹 - 由于我们以 root 身份工作,因此大部分内容都将位于 root 的主文件夹中。 分别:
    • /root/blacklist - 包含编译脚本的工作文件夹
    • /root/zi - 来自 github 的注册表副本
    • /etc/bird - Bird 服务设置的标准文件夹
  • 带有路由服务器和隧道终结点的VPS的外部IP地址是194.165.22.146,ASN 64998; 路由器的外部 IP 地址 - 81.177.103.94,ASN 64999
  • 隧道内的IP地址分别为172.30.1.1和172.30.1.2。

设置BGP绕过阻塞,或者“我是如何不再害怕并爱上RKN的”

当然,您可以使用任何其他路由器、操作系统和软件产品,根据其逻辑调整解决方案。

简要 - 解决方案的逻辑

  1. 准备行动
    1. 获取 VPS
    2. 建立从路由器到 VPS 的隧道
  2. 我们收到并定期更新注册表副本
  3. 安装和配置路由服务
  4. 我们根据注册表为路由服务创建静态路由列表
  5. 我们将路由器连接到服务并配置通过隧道发送所有流量。

实际解决方案

准备行动

互联网上有许多服务以极其合理的价格提供 VPS。 到目前为止,我已经找到并正在使用 9 美元/年的选项,但即使你不太费心,每个角落都有很多 1E/月的选项。 选择 VPS 的问题远远超出了本文的范围,因此如果有人对此有不明白的地方,请在评论中提问。

如果您不仅将 VPS 用于路由服务,而且还要终止其上的隧道,则您需要建立该隧道,并且几乎可以肯定地为其配置 NAT。 关于这些动作网上有大量的说明,这里不再赘述。 这种隧道的主要要求是它必须在路由器上创建一个单独的接口来支持通往 VPS 的隧道。 大多数使用的VPN技术都满足这个要求——例如,tun模式下的OpenVPN就很完美。

获取注册表的副本

正如贾布雷尔所说:“谁阻碍我们,谁就会帮助我们。” 由于 RKN 正在创建一个禁止资源的寄存器,因此不使用该寄存器来解决我们的问题将是一种罪过。 我们将从 github 收到注册表的副本。

我们进入你的Linux服务器,进入根上下文(须藤苏—) 并安装 git(如果尚未安装)。

apt install git

转到您的主目录并提取注册表的副本。

cd ~ && git clone --depth=1 https://github.com/zapret-info/z-i 

我们设置了一个 cron 更新(我每 20 分钟更新一次,但你可以选择你感兴趣的任何时间间隔)。 为此,我们启动 crontab -e命令 并向其中添加以下行:

*/20 * * * * cd ~/z-i && git pull && git gc

我们连接一个钩子,该钩子将在更新注册表后为路由服务创建文件。 为此,请创建一个文件 /root/zi/.git/hooks/post-merge 内容如下:

#!/usr/bin/env bash
changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
check_run() {
    echo "$changed_files" | grep --quiet "$1" && eval "$2"
}
check_run dump.csv "/root/blacklist/makebgp"

并且不要忘记使其可执行

chmod +x /root/z-i/.git/hooks/post-merge

稍后我们将创建该钩子引用的 makebgp 脚本。

安装和配置路由服务

安装鸟。 不幸的是,目前Ubuntu存储库中发布的bird版本的新鲜度与始祖鸟粪便相当,因此我们需要首先将软件开发人员的官方PPA添加到系统中。

add-apt-repository ppa:cz.nic-labs/bird
apt update
apt install bird

此后,我们立即禁用 Bird 的 IPv6 - 在本次安装中我们不需要它。

systemctl stop bird6
systemctl disable bird6

下面是一个简约的bird服务配置文件(/etc/bird/bird.conf),这对我们来说已经足够了(我再次提醒您,没有人禁止开发和调整这个想法以满足您自己的需求)

log syslog all;
router id 172.30.1.1;

protocol kernel {
        scan time 60;
        import none;
#       export all;   # Actually insert routes into the kernel routing table
}

protocol device {
        scan time 60;
}

protocol direct {
        interface "venet*", "tun*"; # Restrict network interfaces it works with
}

protocol static static_bgp {
        import all;
        include "pfxlist.txt";
        #include "iplist.txt";
}

protocol bgp OurRouter {
        description "Our Router";
        neighbor 81.177.103.94 as 64999;
        import none;
        export where proto = "static_bgp";
        local as 64998;
        passive off;
        multihop;
}

router id - 路由器标识符,看起来像 IPv4 地址,但实际上不是 IPv32 地址。 在我们的例子中,它可以是 IPv4 地址格式中的任何 4 位数字,但它是准确指示设备(在本例中为 VPS)的 IPvXNUMX 地址的良好形式。

直接协议定义了哪些接口将与路由过程一起工作。 该示例提供了几个示例名称,您可以添加其他名称。 您可以简单地删除该行;在这种情况下,服务器将侦听具有 IPv4 地址的所有可用接口。

静态协议是我们的魔法,它从文件中加载前缀和 IP 地址列表(当然,实际上是 /32 前缀)以供后续公告。 下面将讨论这些列表的来源。 请注意,加载IP地址默认被注释掉,原因是上传量较大。 作为比较,在撰写本文时,前缀列表中有 78 行,IP 地址列表中有 85898 行。我强烈建议仅在前缀列表上启动和调试,以及是否启用 IP 加载未来取决于您在尝试使用路由器后做出的决定。 并不是每一个都可以轻松消化路由表中的 85 个条目。

事实上,bgp 协议会与您的路由器建立 bgp 对等互连。 IP地址是路由器外部接口的地址(或者路由器侧隧道接口的地址),64998和64999是自治系统的编号。 在这种情况下,它们可以以任何 16 位数字的形式分配,但最好使用 RFC6996 - 64512-65534 定义的私有范围中的 AS 编号(有 32 位 ASN 的格式,但在我们的例子中,这绝对是矫枉过正了)。 所描述的配置使用 eBGP 对等互连,其中路由服务和路由器的自治系统的编号必须不同。

如您所见,服务需要知道路由器的 IP 地址,因此,如果您有动态或不可路由的专用 (RFC1918) 或共享 (RFC6598) 地址,则您无法选择在外部发起对等互连接口,但服务仍将在隧道内工作。

同样很明显的是,您可以从一项服务提供到多个不同路由器的路由 - 只需通过复制协议 bgp 部分并更改邻居的 IP 地址来复制它们的设置即可。 这就是为什么该示例将隧道外对等互连的设置显示为最通用的设置。 通过相应地更改设置中的 IP 地址,可以轻松将它们删除到隧道中。

处理路由服务的注册表

现在我们实际上需要创建前缀和IP地址列表,这在前一阶段的静态协议中已经提到过。 为此,我们使用以下脚本获取注册表文件并从中生成我们需要的文件,并将其放置在 /根/黑名单/makebgp

#!/bin/bash
cut -d";" -f1 /root/z-i/dump.csv| tr '|' 'n' |  tr -d ' ' > /root/blacklist/tmpaddr.txt
cat /root/blacklist/tmpaddr.txt | grep / | sed 's_.*_route & reject;_' > /etc/bird/pfxlist.txt
cat /root/blacklist/tmpaddr.txt | sort | uniq | grep -Eo "([0-9]{1,3}[.]){3}[0-9]{1,3}" | sed 's_.*_route &/32 reject;_' > /etc/bird/iplist.txt
/etc/init.d/bird reload
logger 'bgp list compiled'

不要忘记使其可执行

chmod +x /root/blacklist/makebgp

现在您可以手动运行它并观察 /etc/bird 中文件的外观。

最有可能的是,bird 目前无法为您工作,因为在前一阶段您要求它查找尚不存在的文件。 因此,我们启动它并检查它是否已启动:

systemctl start bird
birdc show route

第二个命令的输出应该显示大约 80 条记录(这是目前的情况,但是当你设置它时,一切都将取决于 RKN 在阻止网络方面的热情),如下所示:

54.160.0.0/12      unreachable [static_bgp 2018-04-19] * (200)

团队

birdc show protocol

将显示服务内协议的状态。 在您配置路由器之前(请参阅下一点),OurRouter 协议将处于启动状态(连接或活动阶段),连接成功后它将进入启动状态(建立阶段)。 例如,在我的系统上,此命令的输出如下所示:

BIRD 1.6.3 ready.
name     proto    table    state  since       info
kernel1  Kernel   master   up     2018-04-19
device1  Device   master   up     2018-04-19
static_bgp Static   master   up     2018-04-19
direct1  Direct   master   up     2018-04-19
RXXXXXx1 BGP      master   up     13:10:22    Established
RXXXXXx2 BGP      master   up     2018-04-24  Established
RXXXXXx3 BGP      master   start  2018-04-22  Connect       Socket: Connection timed out
RXXXXXx4 BGP      master   up     2018-04-24  Established
RXXXXXx5 BGP      master   start  2018-04-24  Passive

连接路由器

每个人可能都厌倦了阅读这篇脚布,但请放心 - 末日即将来临。 此外,在本节中我将无法给出分步说明 - 每个制造商都会有所不同。

不过,我可以向您展示几个例子。 主要逻辑是提升 BGP 对等互连,并将下一跳分配给所有收到的前缀,指向我们的隧道(如果我们需要通过 p2p 接口发送流量)或下一跳 IP 地址(如果流量将发送到以太网)。

例如,在 RouterOS 中的 Mikrotik 上,解决方法如下

/routing bgp instance set default as=64999 ignore-as-path-len=yes router-id=172.30.1.2
/routing bgp peer add in-filter=dynamic-in multihop=yes name=VPS remote-address=194.165.22.146 remote-as=64998 ttl=default
/routing filter add action=accept chain=dynamic-in protocol=bgp comment="Set nexthop" set-in-nexthop=172.30.1.1

在 Cisco IOS 中 - 像这样

router bgp 64999
  neighbor 194.165.22.146 remote-as 64998
  neighbor 194.165.22.146 route-map BGP_NEXT_HOP in
  neighbor 194.165.22.146 ebgp-multihop 250
!
route-map BGP_NEXT_HOP permit 10
  set ip next-hop 172.30.1.1

如果同一个隧道既用于 BGP 对等互连又用于传输有用流量,则无需设置 nexthop;它将使用协议正确设置。 但如果你手动设置它,也不会变得更糟。

在其他平台上,您必须自己弄清楚配置,但如果您有任何困难,请写在评论中,我会尽力提供帮助。

BGP 会话启动后,到大型网络的路由已到达并安装在表中,流量已流向来自这些网络的地址,幸福就在眼前,您可以返回 Bird 服务并尝试取消注释连接该网络的条目。 IP地址列表,之后执行

systemctl reload bird

看看你的路由器是如何传输这85条路由的。 准备好拔掉电源并思考如何处理它:)

在总

纯粹从理论上讲,完成上述步骤后,您现在拥有一项服务,可以自动将流量重定向到俄罗斯联邦禁止通过过滤系统的 IP 地址。

当然,它还可以改进。 例如,使用 perl 或 python 解决方案很容易总结 IP 地址列表。 使用 Net::CIDR::Lite 执行此操作的简单 Perl 脚本将 85 个前缀转换为 60 个(不是 XNUMX 个),但是当然,覆盖的地址范围比被阻止的地址范围大得多。

由于该服务在 ISO/OSI 模型的第三级运行,因此如果站点/页面解析到注册表中记录的错误地址,它不会阻止您阻止该站点/页面。 但与注册表一起,文件 nxdomain.txt 来自 github,只需编写几笔脚本即可轻松转换为 Chrome 中 SwitchyOmega 插件等的地址源。

还需要指出的是,如果您不仅仅是互联网用户,而且还自己发布一些资源(例如,在此连接上运行网站或邮件服务器),则该解决方案需要额外的细化。 使用路由器的方法,必须严格将此服务的传出流量绑定到您的公共地址,否则您将失去与路由器接收的前缀列表所覆盖的那些资源的连接。

如果您有任何疑问,请提问,我准备好回答。

UPD。 谢谢 导航 и 特安宇 用于减少下载量的 git 参数。

UPD2。 同事们,看来我犯了一个错误,没有在文章中添加在 VPS 和路由器之间建立隧道的说明。 由此引发了很多问题。
为了以防万一,我将再次指出,在开始本指南之前,您已经按照您需要的方向配置了 VPN 隧道并检查了其功能(例如,通过默认或静态将流量转向那里)。 如果您尚未完成此阶段,那么按照本文中的步骤进行操作就没有多大意义。 我还没有自己的文字,但如果你用谷歌搜索“设置 OpenVPN 服务器”以及 VPS 上安装的操作系统的名称,并用你的路由器名称搜索“设置 OpenVPN 客户端” ,您很可能会找到许多关于此主题的文章,包括关于哈布雷的文章。

UPD3。 未牺牲 我编写了一个代码,将 dump.csv 转换为 Bird 的结果文件,并带有可选的 IP 地址汇总。 因此,“处理路由服务的注册表”部分可以通过调用其程序来代替。 https://habr.com/post/354282/#comment_10782712

UPD4。 对错误进行一些处理(我没有将它们添加到文本中):
1)代替 systemctl 重新加载小鸟 使用该命令是有意义的 birdc配置.
2) 在 Mikrotik 路由器中,不要将下一跳更改为隧道第二侧的 IP /路由过滤器添加操作=接受链=dynamic-in协议=bgp注释=»设置nexthop» set-in-nexthop=172.30.1.1 直接指定到隧道接口的路由(无需地址)是有意义的 /routing filter add action=accept chain=dynamic-in protocol=bgp comment=»设置 nexthop» set-in-nexthop-direct=<接口名称>

UPD5。 一项新服务出现了 https://antifilter.download,您可以从中获取现成的 IP 地址列表。 每半小时更新一次。 在客户端,剩下的就是用相应的“路由...拒绝”来构建记录。
在这一点上,也许,让你的祖母伤心并更新这篇文章就足够了。

UPD6。 本文的修订版适合那些不想弄清楚但想开始的人 - 这里.

来源: habr.com

添加评论