惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
Jina AI
Jina AI
小众软件
小众软件
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
美团技术团队
V
V2EX
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 聂微东
博客园 - 【当耐特】
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
博客园 - 司徒正美
量子位
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
宝玉的分享
宝玉的分享
月光博客
月光博客
IT之家
IT之家
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
博客园 - Franky

Cyberia

复活吧微软边缘 - Cyberia 从零开始的EAC抓轨教程 - Cyberia Apophenia, 新时代补全工具 - Cyberia 浅谈博客设计 - Cyberia 爱软TV之GitHub - Cyberia 排印演进 - Cyberia EAC相关工具集合 - Cyberia 《C(金钱掌控)》观后感 - Cyberia C#在Windows UI开发中的衰落 - Cyberia 存储退潮 字体padding计算器 开源已死 如何写出优雅完整的音频元数据 自动化EAC音频抓取 起夜级家庭网络正在变得越来越重要 优化Powershell的启动时间 无JavaScript其实没有很重要 你不需要一个电纸书阅读器 文件分享的难题 为什么我不敢看都市 某科学的 SSH 算号指南 时代的辉夜姬 为什么 Pixi 是神 关于神椿的过去,当下以及未来,我的一点看法 Tahoe 的图标令人难评 The EVE of PUSHING LIMITS 在 Word 中通过制表符实现居中对齐等操作 编码之殇:前 Unicode 时代的 WAV 处理 sHELL 即地狱 WR1800K AX NAND 路由器刷入 Immortalwrt
宿舍场景下多人共用路由器下流量分流实践
Nullpinter · 2024-06-14 · via Cyberia

情景#

在校期间(或其他存在需要多人共用网络的情况),私人路由器大概率成为公交车,被所有人连。由于生物多样性,我们会遇到许多需要维护网络主权的情景,包括但不限于:

  • 有人长时间下载占满带宽
  • 半夜三更打游戏影响其他人
  • 大声喊叫
  • 打几小时的电话
  • 弱智设备请求 DHCP 时不发送设备名称,影响管理

在这里,以我本人成功部署的分流方案为例,探讨如何维护自己的网络主权。

Immortalwrt#

最佳的实现方法是使用 Hyper-V 或其他虚拟化技术实现 SDN,但是这种实现方式很明显对硬件要求过高,基本需要一个 X86 的 PC 或服务器才能够实现。因此退而求其次,不追求细粒度的控制,保证路由的性能和稳定性。

为了控制成本,使用成熟完善的 Openwrt 社区资源能够简化很多复杂的环境配置,其中 LEDE is bullshit,原版又不适应中国国情,所以选择较新较稳定的 Immortalwrt。为了处理 WiFi 的问题,可以直接找个能刷机的硬路由来实现本文中的功能。

虽然基于 ARM 的设备多比较起夜级,但是能玩的操作也是很多的(OSPF,多层隧道嵌套,深度包检测等等)。

方案选择#

  • 单设备流量控制
  • 流量优先级控制
  • 针对网段网络质量控制
  • 针对 APP 阻断
  • 上网时间控制

虽然很想说我全都要,但是受限于硬件条件,这里选择只实现针对网段网络质量控制单设备流量控制,这些已经能够达到很好的效果了。

Waiting for api.github.com...

如果你有较强性能的软路由,可以选择直接部署 OpenGFW 来实现 APP 阻断和上网限制,但是 ARM 设备性能羸弱,一开会直接拉爆 CPU。

Waiting for api.github.com...

另一个 APP 访问控制,性能要求更低,但是灵活性不强。

注意

这两个应用都要求关闭硬件NAT才能够正常工作,所以对于 ARM 来说,可能也会造成较大的性能负担。同时,这些规则多是直接阻断链接,特征明显,可能导致邻里关系不和。

nftables 全家桶#

在 21 之后(例如23.05),op全线默认使用 nftables。相比于 iptablesnftables 的规则能够让我们更加方便的编写相关规则。

针对某一 ip 进行百分比丢包#

首先新建一个blocked_ips.txt来存储需要特定的ip。

add.sh

#!/bin/sh

BLOCKED_IPS_FILE="/root/blocked_ips.txt"

IPS=""

while IFS= read -r line; do

if [[ -n "$line" && "$line" != \#* ]]; then

if [[ -z "$IPS" ]]; then

IPS="$line"

else

IPS="$IPS, $line"

fi

fi

done < "$BLOCKED_IPS_FILE"

TEMP_FILE=$(mktemp)

cat <<EOF > $TEMP_FILE

table ip filter {

chain input {

type filter hook input priority 0; policy accept;

iif "lo" accept

ip saddr { $IPS } numgen random mod 100 < 50 drop

}

}

EOF

# 执行nftables规则

/usr/sbin/nft -f $TEMP_FILE

# 删除临时文件

rm $TEMP_FILE

remove.sh

#!/bin/sh

RULE_HANDLES=$(nft --handle list table ip filter | grep -E 'ip saddr ([{} 0-9.,]+) numgen random mod 100 < [0-9]+ drop' | grep handle | awk '{print $NF}')

if [ -z "$RULE_HANDLES" ]; then

echo "cannot find any rules"

else

# 删除每个找到的规则句柄

for HANDLE in $RULE_HANDLES; do

sudo nft delete rule ip filter input handle $HANDLE

echo "del: $HANDLE"

done

fi

这里可以知道,numgen 已经在 nftables 中实现,但是没有出现在文档中。

通过 nfttables 实现了对指定 ip 的百分比丢包。

注意

由于现今网络协议优秀的可靠性(草),这个办法仅对 ICMP 产生显著效果,对于游戏、视频、语音等应用没有明显效果。该方案已废弃,改用其他方案。

控制 TCP 连接数#

如果你的路由性能实在太差,可能连接数一多网络就开始作妖,这里可以使用以下规则添加连接数限制(示例为一分钟10个)

nft add table ip filter

nft add chain ip filter input { type filter hook input priority 0 \; }

nft add rule ip filter input ip protocol tcp ct state new, untracked meter ratemeter { ip saddr timeout 5m limit rate over 10/minute } drop

给来自某 ip 的流量打标#

#!/usr/sbin/nft -f

table ip my_table {

chain prerouting {

type filter hook prerouting priority 0; policy accept;

ip saddr 192.168.1.100 meta mark set 1

}

}

虽然这边使用了更加简单粗暴的方法,但是使用标记对流量进行精细控制可能能够更符合需求。

QoS#

可以直接使用 luci-app-nft-qos 来进行对流量的优先级控制,保证下载的时候不卡。

注意

要求关闭硬件NAT才能够正常工作。

针对网段网络质量控制#

这里需要你安装 kmod-veth,因为我的方案需要用到虚拟以太网。你也可以使用上文的标记流量来解决分类这个问题。

我们在小学一年级就学过,CIDR 掩码可以玩出很多花活。在这里我们以正常网络为例:

  • 192.168.31.0/24 - 192.168.31.0-192.168.31.255
  • 192.168.30.0/24 - 192.168.30.0-192.168.30.255

但是,我们可以将掩码改为 23,让其合二为一

  • 192.168.30.0/23 - 192.168.30.0-192.168.31.255

现在我们有了两个表面看起来互相隔离的网段:D

新建一个虚拟以太网网络设备,并填上正确的 MAC 和其他参数,无需新建对端。例如 veth0 的对端是 veth1,你不用新建 veth1veth1 将会在 veth0 UP 后自动出现。

通过将 veth1 声明成另一网关(192.168.31.1)并将 veth0正确配置完成(网关指向 veth1 的设备能够正常上网),使用 DHCP 设置(tag)将需要管理的设置网关发配到这一虚拟网卡,就完成了第一步。

接下来,我们要用到 tc 进行网络环境模拟,记得安装 kmod-netem

使用tc qdisc del dev veth1 root netem delay 50ms 500ms 40% loss 5% duplicate 1% corrupt 0.2%来模拟一个较差的网络环境,针对长视频和正常网页浏览影响不大,而短视频则会卡顿,游戏则会不能自理。有效控制了网络的使用场景。

使用 tc qdisc del dev veth1 root 清除设置。

结语#

在移动网络越来越便利的时代,一刀切的禁止方式通常会适得其反,精准抓住痛点才能够成功解决问题。

使用 DHCP 的方式分发网关仅会在 renew 时生效,能够降低操作与网络环境变化的关联性,而使用 nftables 配合 tc 的流量控制是立即生效的,有好有坏。