使用 Gentoo Linux 搭建简单路由器并支持IPTV功能

背景

现在在软路由方面, OpenWRT已经相当火爆了, 当然 OpenWRT也做的非常好了. 但是对我个人来说, 我觉得还是有一些问题

  • 升级困难, 在内核不升级的情况下, 一些对内核有依赖的包升级都会有问题
  • 升级内核(基于ext4的分区), 升级后, 又会遇到apk包的兼容问题(其实最好的方法就是刷机, 但是我又不想)
  • 刷机的话, 之前做过定制编译的, 又得来一遍, 虽然有了 make oldconfig 但是也不能完全解决问题
  • ssr pluspasswall 都过于复杂
  • luci 中的各插件基本上都是互相隔离的(应该是设计原则), 如 passwall 会自己开一个 dnsmasq
  • 核心命令使用的是 busybox 裁剪过的. 参数和 linux 标准的有差异. (我非常理解, 因为是嵌入式的, 所以裁剪合理. 但是我是一个x86的路由器, 存储空间不是什么问题)
  • ....

总之有很多让我不爽的地方, 所以折腾了一下, 把 OpenWRT 换成了 Gentoo Linux , 本文就是分享一下, 我搭建过程, 其实过程并不复杂, 我看网上也有一些文章有介绍, 可能并不是所有的朋友都明白为何要这样做.

步骤

  • 安装 Gentoo Linux 这个没啥好分享的, 参照官方手册就好了.
  • 配置成路由器
  • 配置 IPTV
  • 配置 xray
  • 提升性能

本文仅分享前三个方面, 后面再发文续

安装 Gentoo Linux

官方的手册写的非常好, 这是所有 Linux 文档中我觉得写的最好的, 这也是我热爱 Gentoo 的原因之一. 我每次安装也要参考手册, 并不是每一个步骤的指令都记的住. Gentoo AMD64 Handbook

参考他的文档就好了, 这里我就不狗尾续貂了. 说一下我的基本配置吧

  • EFI 引导
  • GPT 分区, fstab 使用 uuid
  • kernel 直接使用 genkernel 来生成
  • CFlags 作了针对本机CPU的优化
  • profile 我选的是 default/linux/amd64/23.0/no-multilib (stable). 我个人不是非常喜欢 systemd, 当然我不否认它非常牛! 所以我还是沿用 OpenRC

贴一下我的 make.conf

 1CHOST="x86_64-pc-linux-gnu"
 2
 3COMMON_FLAGS="-march=silvermont -O2 -pipe"
 4#COMMON_FLAGS="-O2 -pipe"
 5CFLAGS="${COMMON_FLAGS}"
 6CXXFLAGS="${COMMON_FLAGS}"
 7FCFLAGS="${COMMON_FLAGS}"
 8FFLAGS="${COMMON_FLAGS}"
 9
10# NOTE: This stage was built with the bindist Use flag enabled
11
12# This sets the language of build output to English.
13# Please keep this setting intact when reporting bugs.
14LC_MESSAGES=C.utf8
15
16# FEATURES="distcc parallel-fetch"
17FEATURES="parallel-fetch"
18
19GENTOO_MIRRORS="https://mirrors.ustc.edu.cn/gentoo/"
20
21## 本机CPU太差了, 所以安装的时候用了一下distcc, 有兴趣的话可以去官方wifi里查一下
22# MAKEOPTS="-j51 -l4"
23# 本机是4核的, 为了平时安装升级软件不影响正常上网, 所以仅使用2核
24MAKEOPTS="-j2"
25
26USE="-kde -X -qt5 -gnome -gtk -dvd -alsa -cdr ipv6"
27
28ACCEPT_LICENSE="*"
29
30# LINGUAS="en en_US zh_CN"
31
32VIDEO_CARDS="intel"
33
34GRUB_PLATFORMS="efi-64"

配置成路由器

其实把 Gentoo 配置成路由器, 官方也是有文档的. 为了更友好一些, 我略补充一下 Home Router 这个我以双网卡的机器来举例.

这里有几个问题需要解决:

  • WAN 网络的配置
  • LAN 网络的配置
  • IPTV 网络的配置
  • 内核转发以及 NAT 的配置
  • DNS 服务器配置

我觉得我越写条理越差, 我是不是应该把IPTV独立一文出来

WAN 网络配置

我的是静态IP, 也就是说没有在光猫上做桥接, 我觉得没有必要, 因为带宽跑的满满的. 光猫拨号其实有一个好处, 就是你的路由器如果挂了, 把家里的交换机的线直接拔到光猫上, 不影响上网(影响科学)

这里补充一个小的姿势点, 如果你的路由器是软路由, 一个 WAN 一个 LAN 就够了, 家里有很多的设置需要接入, 在 LAN 上接一个交换机. 现在很多人家里有NAS 设备, 或是多台内网设备之间拷贝数据. 软路由故明思意, 是通过软件做转发的, 转发数据是要经过 CPU 的, 效率不高. 交换机是有专门的芯片负责转发, 所以效率高很多.

vim /etc/config/net

1config_enp1s0f1="192.168.1.2 netmask 255.255.255.0 brd 192.168.1.255"
2routes_enp1s0f1="default via 192.168.1.1"
3dns_servers_enp1s0f1="114.114.114.114"
1ln -s /etc/init.d/net /etc/init.d/net.enp1s0f1
2/etc/init.d/net.enp1s0f1 restart

LAN 网络配置

LAN 的网段, 我习惯使用 192.168.88.0/24 vim /etc/config/net

1config_enp1s0f0="192.168.88.1 netmask 255.255.255.0 brd 192.168.88.255"
2routers_enp1s0f0="192.168.88.1"
1ln -s /etc/init.d/net /etc/init.d/net.enp1s0f0
2/etc/init.d/net.enp1s0f0 restart

IPTV 网络配置

我的是 vlan id85 . bridgeLinux 内部是交换机的意思, 因为要接收 vlan id85 的数据, 所以需要使用到交换机的功能. vim /etc/config/net

 1vlans_enp1s0f1="85 51"
 2# vlans_enp2s0="85 51"
 3config_enp1s0f1_85="null"
 4config_enp1s0f1_51="null"
 5# bridge_briptv85="enp1s0f1:85 enp2s0:85"
 6bridge_briptv85="enp1s0f1.85"
 7# dhcp_briptv85="nogateway"
 8config_briptv85="dhcp"
 9briptv85_dhcp="nodns nogateway"
10# dns_servers_briptv85="114.114.114.114"
11emtric_briptv85=20
12# dns_servers_briptv51="null"
1/etc/init.d/net.briptv85 start

内核转发以及 NAT 的配置

vim /etc/sysctl.conf

 1# IPv4 forward规则
 2net.ipv4.ip_forward=1
 3net.ipv4.ip_dynaddr = 1
 4### rp_fileter 针对 wan 我使用的是严格模式, 其它的都是不校验, 一是没有安全问题, 二是 IPTV的需要
 5net.ipv4.conf.default.rp_filter = 0
 6net.ipv4.conf.all.rp_filter = 0
 7net.ipv4.conf.enp1s0f1.rp_filter = 1
 8net.ipv4.conf.briptv85.rp_filter = 0
 9net.ipv4.conf.wg0.rp_filter = 0
10net.ipv4.icmp_echo_ignore_broadcasts = 0
11# net.ipv4.conf.briptv85.rp_filter = 0
12# /proc/sys/net/ipv4/conf/all/proxy_arp
13net.ipv4.conf.all.proxy_arp = 0
14
15net.ipv4.tcp_fastopen=3
16
17# 开启 bbr, 都懂的
18net.core.default_qdisc=fq
19net.ipv4.tcp_congestion_control=bbr
1sysctl -p

配置 NAT: Linux 有强大的 iptables 所以 NAT 使用这个就好了, 貌似也没有别的选择, nftables 么? 不想学. 都是操作 netfilter 的, 据说性能有一定的提升, 而且书写规则更友好.

  1export LAN=enp1s0f0
  2export WAN=enp1s0f1
  3export IPTV85=briptv85
  4export IPTV15=briptv15
  5export WG=wg0
  6export TUNSERVER=tun0
  7export TUNFOX=tun1
  8
  9# 清空iptables规则, 和NAT表
 10iptables -F
 11iptables -Z
 12iptables -t nat -F
 13
 14# 允许从 WAN 访问 内部的服务
 15## 允许ping
 16iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
 17iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
 18### iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j DROP # 禁ping
 19
 20# iptables -A INPUT -p TCP --dport 22 -i ${WAN} -j ACCEPT # SSH
 21# iptables -A OUTPUT -p TCP --sport ssh -j ACCEPT
 22### OPEN VPN
 23iptables -A INPUT -p TCP --dport 8194 -i ${WAN} -j ACCEPT # OPENVPN
 24iptables -A INPUT -p UDP --dport 8194 -i ${WAN} -j ACCEPT # OPENVPN
 25### shadowsocks
 26iptables -A INPUT -p TCP --dport 5500 -i ${WAN} -j ACCEPT # shadownsocks TCP
 27iptables -A INPUT -p UDP --dport 5500 -i ${WAN} -j ACCEPT # shadownsocks UDP
 28iptables -A INPUT -p TCP --dport 5560 -i ${WAN} -j ACCEPT # shadownsocks TCP
 29iptables -A INPUT -p UDP --dport 5560 -i ${WAN} -j ACCEPT # shadownsocks UDP
 30### ipsec vpn
 31iptables -A INPUT -p UDP --dport 4500 -i ${WAN} -j ACCEPT # IPSec VPN / IKE
 32iptables -A INPUT -p TCP --dport 4500 -i ${WAN} -j ACCEPT # IPSec VPN / IKE TCP
 33iptables -A INPUT -p UDP --dport 500 -i ${WAN} -j ACCEPT # IPSec VPN
 34iptables -A INPUT -p TCP --dport 500 -i ${WAN} -j ACCEPT # IPSec VPN
 35### wireguard
 36iptables -A INPUT -p UDP --dport 9901 -i ${WAN} -j ACCEPT # IPSec VPN
 37iptables -A INPUT -p TCP --dport 9901 -i ${WAN} -j ACCEPT # IPSec VPN
 38### cloud
 39iptables -A INPUT -p UDP --dport 8443 -i ${WAN} -j ACCEPT # IPSec VPN
 40iptables -A INPUT -p TCP --dport 8443 -i ${WAN} -j ACCEPT # IPSec VPN
 41
 42
 43## 8443 DNAT到 192.168.88.8服务上,  改nginx
 44# iptables -t nat -A PREROUTING -p TCP --dport 8443 -i ${WAN} -j DNAT --to 192.168.88.8:8443
 45# iptables -t nat -A POSTROUTING -p TCP -d 192.168.88.8 --dport 8443 -j SNAT --to 192.168.88.1
 46
 47# 添加NAT规则
 48iptables -A FORWARD -i ${LAN} -d 192.168.88.0/24 -j DROP
 49iptables -A FORWARD -i ${LAN} -s 192.168.88.0/24 -j ACCEPT
 50iptables -A FORWARD -i ${WAN} -d 192.168.88.0/24 -j ACCEPT
 51# iptables -A FORWARD -i ${LAN} -s 192.168.18.0/24 -j ACCEPT
 52iptables -A FORWARD -i ${LAN} -d 192.168.18.0/24 -j ACCEPT
 53iptables -A FORWARD -i ${WAN} -d 192.168.18.0/24 -j ACCEPT
 54iptables -A FORWARD -i ${TUNSERVER} -d 192.168.88.0/24 -j ACCEPT
 55# iptables -A FORWARD -o tun1 -d 192.168.18.0/24 -j ACCEPT
 56# iptables -A FORWARD -i ${WAN} -s 10.8.9.0/24 -j ACCEPT
 57iptables -A FORWARD -i ${WG} -j ACCEPT
 58iptables -A FORWARD -o ${WG} -j ACCEPT
 59iptables -A FORWARD -i ${TUNFOX} -j ACCEPT
 60
 61# 如果遇到奇怪的错误(例如无法访问某些网页,而其他网页加载正常),则可能是“路径MTU发现”(Path MTU Discovery)问题
 62iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
 63
 64## IPTV 的INPUT,OUTPUT,FORWARD都是ACCEPT我也不清楚为什么, 从OPENWRT里抄的, 貌似不需要
 65# iptables -A FORWARD -i ${IPTV85} -s 0.0.0.0/0 -j ACCEPT
 66# iptables -A FORWARD -i ${IPTV15} -s 0.0.0.0/0 -j ACCEPT
 67
 68## 添加路由规则, 把LAN的数据转发WAN (伪装,适合外网IP地址变化的配置)
 69iptables -t nat -A POSTROUTING -d 192.168.18.0/24 -o tun1 -j MASQUERADE
 70iptables -t nat -A POSTROUTING -s 192.168.88.0/24 -o ${WAN} -j MASQUERADE
 71# iptables -t nat -A POSTROUTING -s 10.0.8.0/24 -o ${LAN} -j MASQUERADE
 72iptables -t nat -A POSTROUTING -s 10.8.9.0/24 -o ${WAN} -j MASQUERADE
 73
 74# IPv6
 75ip6tables -A INPUT -p icmpv6 -j ACCEPT
 76
 77# 添加默认规则
 78iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 79iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 80
 81iptables -A INPUT -i ${LAN} -j ACCEPT
 82iptables -A OUTPUT -o ${LAN} -j ACCEPT
 83
 84iptables -A INPUT -i ${WG} -j ACCEPT
 85iptables -A OUTPUT -o ${WG} -j ACCEPT
 86
 87iptables -A INPUT -i lo -j ACCEPT
 88iptables -A OUTPUT -o lo -j ACCEPT
 89
 90iptables -A INPUT -i ${TUNFOX} -j ACCEPT
 91iptables -A OUTPUT -o ${TUNFOX} -j ACCEPT
 92
 93iptables -A INPUT -i ${TUNSERVER} -j ACCEPT
 94iptables -A OUTPUT -o ${TUNSERVER} -j ACCEPT
 95
 96iptables -A INPUT -i ${WAN} -j DROP
 97iptables -A OUTPUT -o ${WAN} -j ACCEPT
 98
 99iptables -A INPUT -i ${IPTV85} -j ACCEPT
100
101### 严口径, 白名单机制
102iptables -P FORWARD DROP
103iptables -P OUTPUT ACCEPT
104iptables -P INPUT DROP

保存为 firewall-init.sh . 运行它

1bash firewall-init.sh

如果需要开机自动配置

1/etc/init.d/iptables save
2rc-update add iptables default

配置 DNS 服务器

个人比较喜欢 Dnsmasq, 就以这个举例子. Dnsmasq 本身也有 dhcp 的功能, 所以就不必为 dhcp 单独再开服务了.

vim /etc/dnsmasq.conf

 1resolv-file=/etc/resolv.dnsmasq.conf
 2no-resolv
 3
 4# only for LAN interface
 5# interface=enp1s0f0
 6# DHCP ip address range
 7# no-dhcp-interface=enp1s0f1
 8dhcp-range=192.168.88.20,192.168.88.99,255.255.255.0,9h
 9# DHCP 下发配置
10# dhcp-option=option:dns-server,192.168.88.1, 114.114.114.114
11dhcp-option=option:dns-server,192.168.88.1
12dhcp-option=option:router,192.168.88.1
13# dhcp-option=option:ntp-server,192.168.88.1
14# Broadcast Address
15dhcp-option=28,192.168.88.255
16
17dhcp-authoritative
18
19## IPTV 伪造报文, 非桥应该不需要的
20dhcp-option-force=125,00:00:00:00:3a:02:06:48:47:57:2d:43:54:03:04:5a:58:48:4e:0a:02:20:00:0b:02:00:55:0d:02:00:2e
21dhcp-option=15
22dhcp-option=28
23dhcp-option=60,00:00:01:00:02:03:43:50:45:03:0e:45:38:20:47:50:4f:4e:20:52:4f:55:54:45:52:04:03:31:2E:30
24
25# 内网域名解析配置 也可以写到 hosts文件了
26# address=/aa.bb.com/192.168.88.8
27
28# NIC MAC address mac与ip绑定
29# dhcp-host=b4:2e:99:d7:33:b1,192.168.88.88 # 举个栗子
30
31
32cache-size=102400
33
34# 上游DNS, 后面配置科学的部分会在xray里拦截这个udp数据包的
35server=114.114.114.114
36conf-dir=/etc/dnsmasq.d
1/etc/init.d/dnsmasq restart

这个时候, 你的路由器就可以正常工作了

IPTV 的是需要 udpxy 转单播的

1emerge udpxy

vim /etc/config/udpxy

1UDPXYOPTS="-S -a 0.0.0.0 -p 4022 -m briptv85"
1/etc/init.d/udpxy restart

关于IPTV播放列表, 自己网上搜

Posts in this series