debian 簡易路由(網(wǎng)關(guān)計算機)筆記
目標,利用已有的軟件包束亏,多網(wǎng)卡配置一個路由器
還需要繼續(xù)的配置學習:
tc流量控制(學習了部分)碍遍,完成基礎(chǔ)流量優(yōu)先級分類
多個wan口配置及均衡負載怕敬,暫未學習
PPPOE撥號(學習了部分),已初步可用
IPTV及多播(涉及軟件包:igmpproxy 或者 pimd )虽填,暫未學習
我在github看到一個關(guān)于pppoe集成到systemd的討論斋日,覺得可以抄一波作業(yè)第献。
路由能力
動態(tài)NAT庸毫,debian默認是nat4(對稱nat)理逊,內(nèi)核支持的masquerade是對稱nat
LAN口可以DHCP動態(tài)分配IP地址晋被,代理DNS服務(wù)挂脑。
防火墻崭闲,實現(xiàn)常規(guī)的流量及安全過濾功能。
可以設(shè)置端口映射
docker擴展
硬件
主機一臺
網(wǎng)卡2口牍戚,一口做wan如孝,一口做lan
涉及軟件包
系統(tǒng) :debian10
防火墻 :nftables(代替iptables)
DHCP/DNS服務(wù) :dnsmasq
網(wǎng)卡接口管理服務(wù) :systemd-udevd systemd-networkd
流量控制和策略路由 :iproute2
需要注意的地方
ssh的22端口不應(yīng)該暴露到公網(wǎng)去。
應(yīng)該盡可能地過濾掉從公網(wǎng)發(fā)往本地的請求但荤,路由器上網(wǎng)發(fā)起請求大部分情況下都是由內(nèi)網(wǎng)往公網(wǎng)方向發(fā)起的連接腹躁。
配置思路
(1)使用 systemd.link 配置網(wǎng)卡命名規(guī)則哑了,固化網(wǎng)絡(luò)接口名弱左, nftables 規(guī)則匹配規(guī)則
(2)使用 networkctl (system-networkd的命令行前端)管理網(wǎng)絡(luò)服務(wù)
(3)使用 nftables 配置 nat 規(guī)則以及其他防火墻規(guī)則
(4)使用 dnsmasq 綁定 lan 口網(wǎng)卡拆火,啟用DHCP服務(wù)/DNS服務(wù)
安裝軟件包
sudo apt install nftables dnsmasq iproute2
新建 systemd.link
規(guī)則修改網(wǎng)卡名
步驟流程:
(1) 卸載掉多余的網(wǎng)絡(luò)管理軟件(主要針對
networking
和NetworkManager
),(2) 通過添加systemd.link規(guī)則規(guī)則模狭,達到修改網(wǎng)卡名的目的(防火墻規(guī)則需要判斷網(wǎng)卡名)
(3) 編寫防火墻規(guī)則,使得內(nèi)網(wǎng)流量出去時會被動態(tài)做NAT锚赤。
(4) 創(chuàng)建DHCP服務(wù)宴树、DNS服務(wù)酒贬,為局域網(wǎng)下的主機分配動態(tài)分配IP。
1.通過 ip addr
查詢 網(wǎng)卡MAC地址
打印網(wǎng)絡(luò)接口相關(guān)信息零如,獲取MAC地址
#ip addr
2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 23:33:33:33:33:04 brd ff:ff:ff:ff:ff:ff
3: enp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 23:33:33:33:33:05 brd ff:ff:ff:ff:ff:ff
inet 192.168.31.33/24 brd 192.168.31.255 scope global dynamic
link/ehter 項目對應(yīng)的是 mac地址,記住他們
wan網(wǎng)絡(luò)接口:
23:33:33:33:33:04
lan網(wǎng)絡(luò)接口:
23:33:33:33:33:05
后續(xù)有用到這兩個MAC地址的配置根據(jù)實際情況替換肖卧。
2.通過mac地址匹配udev規(guī)則來修改網(wǎng)卡名
這一小節(jié)需要參考的文檔有 systemd.link 中文手冊 ,利用mac地址匹配網(wǎng)卡設(shè)備塞帐,更改網(wǎng)卡名荷鼠。
使用systemd.link為 wan允乐、lan 網(wǎng)口創(chuàng)建網(wǎng)絡(luò)接口名稱命名規(guī)則的配置牍疏,創(chuàng)建配置文件:
sudo touch /lib/systemd/network/01-wan.link
sudo touch /lib/systemd/network/01-lan.link
文件內(nèi)容如下挺尿,主要通過MAC地址進行匹配编矾,參數(shù)含義參考 systemd.link 手冊蹂匹,link配置由 systemd-udevd 讀取。
#/lib/systemd/network/01-wan.link
[Match]
MACAddress=23:33:33:33:33:04
[Link]
Name=wan
#/lib/systemd/network/01-lan.link
[Match]
MACAddress=23:33:33:33:33:05
[Link]
Name=lan # 新的接口名稱
切換 systemd-networkd
接管網(wǎng)卡履植,卸載 networking
和 NetWorkManager
服務(wù)
使用
ifupdown
包做網(wǎng)絡(luò)管理,對應(yīng)的服務(wù)為networking.service
使用
network-manager
對應(yīng)的則是NetworkManager.service
網(wǎng)絡(luò)管理軟件可能通過兩個源頭來觸發(fā)網(wǎng)絡(luò)配置:服務(wù)與udev規(guī)則庶近;
如果禁用服務(wù)后仍然受影響鼻种,需要考慮是否因為udev的規(guī)則觸發(fā)事件導致配置變化恬口。
應(yīng)該避免多個網(wǎng)絡(luò)管理服務(wù)對同一個網(wǎng)絡(luò)接口重復配置,這樣會出現(xiàn)配置上到?jīng)_突养铸。
debian默認使用ifupdown作為網(wǎng)絡(luò)管理服務(wù)钞螟,當安裝桌面后,還將使用network-manager拯啦。
桌面環(huán)境通過NetworkManager來配置網(wǎng)絡(luò)的褒链,如需systemd-networkd與NetworkManager共存甫匹,可以用nmcli配置NetworkManager放棄對網(wǎng)絡(luò)接口的管理(unmanaged)。
簡單粗暴的做法是僅保留一個網(wǎng)絡(luò)管理服務(wù)恍箭。
1.卸載其他網(wǎng)絡(luò)管理
sudo apt purge ifupdown network-manager
此處使用 systemd-networkd
作為網(wǎng)絡(luò)管理服務(wù)季惯,它包括:
systemd-networkd.service(網(wǎng)絡(luò)管理服務(wù))
systemd-networkd-wait-online.service(等待網(wǎng)絡(luò)在線服務(wù),用于到達network-online.target阻塞作用)
它還需要域名解釋的相關(guān)服務(wù):systemd-resolved.service
三個相關(guān)服務(wù),對應(yīng)的命令有 networkctl
隐圾、resolvectl
。
2.編寫 systemd.network 配置文件
創(chuàng)建 10-wan.network 、10-lan.network 兩個配置,文件名可自定義县好,后綴要求是 .network
sudo touch /etc/systemd/network/10-wan.network
sudo touch /etc/systemd/network/10-lan.network
3.編輯規(guī)則
wan口通過DHCP方式上網(wǎng)的配置
wan口暫時設(shè)置為DHCP方式上網(wǎng)
wan口網(wǎng)絡(luò)配置文件內(nèi)容如下:
#/etc/systemd/network/10-wan.network
[Match]
MACAddress=23:33:33:33:33:04
[Link]
RequiredForOnline=no
[Network]
DHCP=yes
IPForward=yes
NTP=ntp.aliyun.com
lan口網(wǎng)絡(luò)配置文件內(nèi)容如下:
# /etc/systemd/network/lan.network
# lan口靜態(tài)ip 192.168.31.1
[Match]
MACAddress=23:33:33:33:33:05
[Link]
RequiredForOnline=no
[Network]
Address=192.168.31.1/24
IPForward=yes
4.啟用 systemd-networkd 服務(wù),允許開機自啟
sudo systemctl daemon-reload
sudo systemctl --now enable systemd-networkd
然后重啟使新的網(wǎng)絡(luò)接口名生效晾咪。
5.使用 systemd-resolved.service 管理主機DNS,配置關(guān)閉監(jiān)聽53端口及5355端口
使用systemd-networkd管理網(wǎng)絡(luò)禀酱,還需要啟用systemd-resolved管理本機的DNS服務(wù),確保域名解正常酣藻。
編輯systemd-resolved.service
配置文件如下:
# /etc/systemd/resolved.conf
[Resolve]
DNS=223.5.5.5 223.6.6.6
Cache=yes
MulticastDNS=no
DNSStubListener=no
ReadEtcHosts=yes
LLMNR=no
選項配置如下:
(1) DNS: 空格分隔的上級DNS服務(wù)器,這里使用阿里云dns
(2) Cache:設(shè)置緩存解釋成功的域名
(3) DNSStubListener:禁用本地DNS服務(wù)器税产,這個選項設(shè)置為no避免監(jiān)聽127.0.0.1:53
(4) ReadEtcHosts:設(shè)置為yes,發(fā)送查詢請求前撞羽,會優(yōu)先查詢/etc/hosts
(5) LLMNR:鏈路本地多播名稱解析诀紊,設(shè)置為no邻奠,它將不會監(jiān)聽5355端口杀狡。
(6) MulticastDNS:多播的DNS查詢關(guān)閉
啟動并允許開機啟動:
sudo systemctl --now enable systemd-resolved.service
由于使用了 systemd-resolved 捣卤,dns更新與傳統(tǒng)的保持一致。
讓 /etc/resolv.conf -> /run/systemd/resolve/resolv.conf 子姜,保證更新一致哥捕。
sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
sysctl調(diào)整參數(shù)
對于內(nèi)核網(wǎng)絡(luò)調(diào)整方面接觸較少,本節(jié)網(wǎng)上抄作業(yè)阐肤,但是調(diào)整參數(shù)選項的含義需要參考linux內(nèi)核網(wǎng)絡(luò)文檔愧薛。
主要的調(diào)整目標為:
允許流量轉(zhuǎn)發(fā)
不允許外網(wǎng)ping內(nèi)網(wǎng)的IP地址
在linux下毫炉,IP并不是綁定網(wǎng)卡的,可能出現(xiàn)這樣的情況进陡,A網(wǎng)卡收到一個arp查詢,查詢的目的IP是B網(wǎng)卡的,但是它可能響應(yīng)A網(wǎng)卡的MAC地址戈二,而不是B網(wǎng)卡的。
我不想出現(xiàn)鲜滩,外網(wǎng)企圖詢問lan口ip,也會獲得一個應(yīng)答搞疗。下面的調(diào)整匿乃,將檢查查詢請求的源地址泄隔,它查詢的目的IP佛嬉,不符合規(guī)則赡盘,則不做出響應(yīng)陨享。
添加以下配置:
# /etc/sysctl.conf
net.ipv4.tcp_syncookies=1
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.rp_filter = 0
調(diào)整說明:
accept_source_route = 0 不接受路由報頭赞厕。
arp_announce = 2 這個選項控制系統(tǒng)發(fā)送ARP請求時,如何選擇ARP數(shù)據(jù)包源地址镀虐,定義接口上發(fā)送的ARP請求中的IP報文宣布本端源IP地址的不同限制級別刮便,當值為2時,總是為目的地址使用最佳的本地地址。在這種模式下钝凶,忽略IP包中的源地址桌硫,并嘗試選擇喜歡的本地地址與目標主機進行對話。通過在包含目標IP地址的出接口的所有子網(wǎng)中查找主IP地址來選擇這種本地地址膀钠。如果沒有找到合適的本地地址肿嘲,我們就選擇出接口或所有其他接口上的第一個本地地址,希望能夠收到對請求的回應(yīng)匣屡,甚至有時不管我們宣布的源IP地址是什么。
arp_ignore = 1 這個選項控制系統(tǒng)收到ARP請求的響應(yīng)捣作,對于收到ARP請求誉结,定義不同的應(yīng)答方式,值為1時券躁,只有當目的IP地址為入接口上配置的本端地址時才進行應(yīng)答惩坑。
rp_filter = 0 嚴格模式RFC3704中定義的嚴格反向路徑對每個入方向的報文進行FIB測試掉盅,如果接口不是最佳反向路徑則報文檢查失敗。缺省情況下以舒,失敗的報文將被丟棄奋刽。
編寫防火墻規(guī)則
1.編輯/etc/nftables.conf
,寫入具體規(guī)則
默認從wan側(cè)的訪問應(yīng)該被過濾掉罚攀,如訪問debian的ssh炫掐。
從內(nèi)網(wǎng)(lan側(cè))主動發(fā)起的訪問允許通過。
已經(jīng)建立的連接雙向均可通過抹蚀,外網(wǎng)<->內(nèi)網(wǎng)。
允許局域網(wǎng)內(nèi)訪問網(wǎng)關(guān)計算機朵诫。
ICMP協(xié)議放行(可以被ping)邑滨。
不是從wan口流入到內(nèi)核的,又路由到從wan口流出的流量(即內(nèi)網(wǎng)上網(wǎng)流量),在 postrouting 鉤子下的鏈要做 masquerade 規(guī)則邑飒,做特殊的SNAT乞旦,在本路由器處,做源地址轉(zhuǎn)換闪彼,src替換成
wan
口的網(wǎng)絡(luò)地址,dst不不變况凉,響應(yīng)包從外網(wǎng)返回時知市,將目的地址dst替換本地局域網(wǎng)的ip诽表,src不變汞舱。
此處的規(guī)則有個坑矾兜,因為
input
鉤子下的規(guī)則铣卡,默認的行為是把阻止鏈接,如果網(wǎng)關(guān)計算機要監(jiān)聽某個端口缨伊,需要在/etc/nftables.conf
里添加放行規(guī)則旁趟。
/etc/nftables.conf
文件內(nèi)容(comment關(guān)鍵字可以為規(guī)則添加注釋桩砰,增強可讀性)
flush ruleset
# IPv4協(xié)議簇的表,用于儲存nat相關(guān)的規(guī)則续镇,此處只用到 prerouting 和 postrouting 的鉤子
# 這里有個問題,如果{后的空行,因為對齊的原因被補全了個tab情臭,可能出現(xiàn)語法錯誤筷黔,如果單獨空行眼虱,不應(yīng)該用任何的空白符號占用它,但是可以用回車換行揩悄,單行即無注釋又無定義語句溯泣,且有空白字符占用空行垃沦,可能出現(xiàn)多余的字符造成nft語法解釋錯誤
table ip nat {
chain prerouting-public {
type nat hook prerouting priority 100; policy accept
#如果需要端口轉(zhuǎn)發(fā)纵菌,則在PREROUTING鉤子的鏈做DNAT
iif wan tcp dport 65533 dnat to 192.168.31.2:22 comment "dnat: :65533 => 192.168.31.2:22"
# 把wan口進來的流量桶错,目標端口是65533的發(fā)往192.168.31.2的22端口
}
chain postrouting-public {
type nat hook postrouting priority 100; policy accept;
#做動態(tài)SNAT (備注②)
meta oif wan iif != wan ip saddr 192.168.31.0/24 masquerade comment "外網(wǎng)NAT規(guī)則"
}
}
# IPv4防火墻規(guī)律規(guī)則演闭,主要針對進本機的流量
table ip filter {
ct helper ftp-standard {
type "ftp" protocol tcp;
}
chain input-public {
#默認的策略是不允許流量通過
type filter hook input priority 0; policy drop;
iif {lo,lan} accept comment "允許lo口不跟、lan口流進的內(nèi)網(wǎng)流量通過"
#備注①
ct state {established,related} accept comment "允許從內(nèi)部主動發(fā)起的鏈接通過"
ip protocol { icmp, igmp } counter accept comment "ICMP/IGMP放行"
tcp dport ftp ct helper set "ftp-standard" comment "ftp放行"
ct state invalid counter drop comment "記錄并拋棄不符合ct規(guī)則的流量"
}
chain forward-public {
type filter hook input priority 0; policy drop;
iif {lo,lan} accept comment "允許lo口、lan口流進的內(nèi)網(wǎng)流量通過"
#備注①
ct state {established,related} accept comment "允許從內(nèi)部主動發(fā)起的鏈接通過"
ct status dnat accept comment "dnat狀態(tài)的連接可以通過,作用于端口映射"
}
}
# IPv6防火墻規(guī)律規(guī)則米碰,主要針對進本機的流量
table ip6 filter {
chain input-public {
type filter hook input priority 0; policy drop
ct state established,related accept comment "允許從路由器內(nèi)部主動發(fā)起的鏈接通過"
ct state invalid counter drop comment "記錄并拋棄不符合ct規(guī)則的流量"
iif {lo, lan} accept comment "允許lo口窝革、lan口流進的內(nèi)網(wǎng)流量通過"
ip6 nexthdr { icmp } accept comment "ICMP放行"
}
chain forward-public {
type filter hook input priority 0; policy drop;
iif {lo,lan} accept comment "允許lo口、lan口流進的內(nèi)網(wǎng)流量通過"
}
}
聊一下 ct state
吕座,通過nft describe
命令可以看到它的合法的值
~ $ nft describe ct state
ct expression, datatype ct_state (conntrack state) (basetype bitmask, integer), 32 bits
pre-defined symbolic constants (in hexadecimal):
invalid 0x00000001
new 0x00000008
established 0x00000002
related 0x00000004
untracked 0x00000040
備注①:ct state {established,related} accept; 這條規(guī)則匹配鏈接狀態(tài)的虐译,鏈接狀態(tài)和iptables的保持一致,有4種狀態(tài)吴趴,ESTABLISHED 漆诽、 NEW 、 RELATED 及 INVALID 锣枝,untracked狀態(tài)是被放棄連接跟蹤的厢拭,他是無狀態(tài)的,沒法判斷它到底屬于哪種撇叁。
客戶端發(fā)出請求供鸠,服務(wù)端返回結(jié)果,源地址/目的地址剛好是相反的陨闹,第一個穿越防火墻的數(shù)據(jù)包楞捂,鏈接狀態(tài)是 NEW ,
后續(xù)的數(shù)據(jù)包(無論是請求還是應(yīng)答)鏈接狀態(tài)是 ESTABLISHED 趋厉,有一種情況寨闹,類似于FTP,區(qū)分數(shù)據(jù)端口和控制端口的君账,被動產(chǎn)生的數(shù)據(jù)包繁堡,他需要helper獲取數(shù)據(jù)端口,并在規(guī)則中放行杈绸。
第一個包帖蔓,但是不屬于任何鏈接中的,它的狀態(tài)是 RELATED 瞳脓,而這個鏈接產(chǎn)生后塑娇,這條鏈路后續(xù)的數(shù)據(jù)包狀態(tài)都是 ESTABLISHED ,
invalid 是所有狀態(tài)之外情況的數(shù)據(jù)包劫侧。
又有新的問題來了埋酬,對于端口映射這種情況哨啃,怎么區(qū)分是端口映射的數(shù)據(jù)包并且讓他通過防火墻?
利用另外一種狀態(tài)的判斷写妥,ct status
~ $ nft describe ct status
ct expression, datatype ct_status (conntrack status) (basetype bitmask, integer), 32 bits
pre-defined symbolic constants (in hexadecimal):
expected 0x00000001
seen-reply 0x00000002
assured 0x00000004
confirmed 0x00000008
snat 0x00000010
dnat 0x00000020
dying 0x00000200
由于nat發(fā)生在prerouting上的規(guī)則拳球,dnat后,轉(zhuǎn)發(fā)至其他主機珍特,可能會走forward祝峻,forward默認規(guī)則設(shè)定成了DROP,因此在forward處還得放行ct state不為established扎筒,但是ct status 為dnat的數(shù)據(jù)包莱找。
不滿足條件的數(shù)據(jù)包在forward處丟棄了。
帶狀態(tài)的防火墻具體的情況分析:
input hook 攔截的是流往本機的嗜桌,
(1) debian路由器本機作為客戶端奥溺,主動去訪問服務(wù)端(訪問網(wǎng)站的情況),此時請求包發(fā)送出去骨宠,第一個數(shù)據(jù)包是 NEW 狀態(tài), netfilter 跟蹤這條鏈接的狀態(tài)浮定。
(2) 請求發(fā)出后,被回應(yīng)時层亿,這條連接下一個返回的數(shù)據(jù)包桦卒,已經(jīng)是 ESTABLISHED 狀態(tài),往后都保持這個狀態(tài)棕所,但是如果此時防火墻闸盔,沒有配置允許相關(guān)狀態(tài)的鏈接通過,默認策略又設(shè)定為drop琳省,會導致返回的包可以發(fā)出去,但是回來時被 input 默認 DROP 策略過濾躲撰。
(3) 允許 ESTABLISHED 狀態(tài)的數(shù)據(jù)包通過针贬,可以讓本機主動發(fā)出的請求后,回來的數(shù)據(jù)包也可以順利通過防火墻拢蛋。
備注②:masquerade 是一種特殊的SNAT,按nftables的wiki說明桦他,它只有在postrouting的鉤子下才有意義的,此時谆棱,已經(jīng)選中了路由快压,準備要發(fā)往對應(yīng)網(wǎng)卡發(fā)送隊列了,masquerade會把源ip替換成該網(wǎng)卡對應(yīng)的ip垃瞧,然后記錄這條信息蔫劣,當數(shù)據(jù)返回的時候(prerouting),它會查找記錄个从,又會把NAT前的源ip替換成目的的IP(DNAT)脉幢,這樣歪沃,相當于“隱藏”了網(wǎng)關(guān)計算機自身,把鏈路轉(zhuǎn)發(fā)到masquerade前的源ip主機嫌松。
nftables 不像 iptables 有內(nèi)置的鏈沪曙,它是沒有預設(shè)的鏈的,鏈的名稱可以用戶自定義萎羔,但是nftables兼容iptables的配置液走,如果使用docker的時候,就容易出現(xiàn)一個問題贾陷,docker會改動防火墻規(guī)則缘眶,同時它會清空我的鏈,所以我并不喜歡讓docker使用iptables做端口映射,內(nèi)網(wǎng)直接通過路由轉(zhuǎn)發(fā)來訪問容器IP昵宇,
如果要處理docker的iptables和本機的nftables沖突磅崭,有2種選擇
放棄docker的端口映射(--publish,-p)功能瓦哎,使用路由轉(zhuǎn)發(fā)的方式俺抽,每個容器都是一臺獨立的“主機”,有容器子網(wǎng)的IP壁肋。
讓dockerd跑在另一個名稱空間(name space), 不同的ns揍诽,擁有獨立的防火墻規(guī)則,互不影響犯助,例如
systemd-nspawn
癣漆,用特權(quán)容器跑docker。
DNS/DHCP服務(wù)配置
使用dnsmasq
守護進程作為網(wǎng)關(guān)計算機的DNS以及DHCP服務(wù)剂买。
/etc/systemd/resolved.conf的默認設(shè)置會占用了53端口和5355端口惠爽,需要額外設(shè)置,詳情看前面瞬哼。
1.安裝
sudo apt install dnsmasq
2.配置
把 dnsmasq
默認的配置都不要了,把sysV啟動的軟連接全部刪了婚肆,把 dnsmasq.service
的服務(wù)也刪除了∽浚可以滿足多個網(wǎng)卡配置dnsmasq较性,不應(yīng)該使用包內(nèi)自帶的服務(wù)配置,由自己編輯一個適合情況的配置文件结胀。
#刪除sysV init 開機自啟的軟連接
find /etc/rc[0-9S].d -name "*dnsmasq*" -exec sudo rm {} \;
#刪除dnsmasq默認包的服務(wù)配置
sudo rm sudo rm /lib/systemd/system/dnsmasq.service
#重載配置
sudo systemctl daemon-reload
編寫新的dnsmasq服務(wù)的service模板赞咙,以適應(yīng)多個網(wǎng)卡單獨啟動不同的dnsmasq服務(wù)。
sudo touch /etc/systemd/system/dnsmasq@.service
編寫 /etc/systemd/system/dnsmasq@.service
內(nèi)容:
# /etc/systemd/system/dnsmasq@.service
[Unit]
Description=IPv4 DHCP server on %I
Wants=network.target
After=network.target
[Service]
Type=forking
PIDFile=/run/dnsmasq@%I.pid
ExecStart=/usr/sbin/dnsmasq --except-interface=lo --pid-file=/run/dnsmasq@%I.pid --log-facility=/var/log/dnsmasq/%I.log --interface=%I --conf-file=/opt/router-config/dnsmasq/%I/dnsmasq.conf --dhcp-leasefile=/opt/router-config/dnsmasq/%I/dnsmasq.leases --dhcp-hostsfile=/opt/router-config/dnsmasq/%I/hosts.d/ --resolv-file=/opt/router-config/dnsmasq/%I/resolv.conf --conf-dir=/opt/router-config/dnsmasq/%I/conf.d
KillSignal=SIGTERM
KillMode=control-group
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
%I
是模板實例化后糟港,被替換的名稱攀操,例如,dnsmasq@lan.service
着逐, %I
就會被替換成 lan
軟連接新建一個實例崔赌,這個服務(wù)是針對 lan
網(wǎng)卡的意蛀。創(chuàng)建 dnsmasq
配置存放的文件夾,我放在 /opt/router-config/dnsmasq/lan/
下健芭,
# 針對lan創(chuàng)建dnsmasq服務(wù)軟連接县钥,實例化模板
sudo ln -s /etc/systemd/system/dnsmasq@.service /etc/systemd/system/dnsmasq@lan.service
# 針對lan創(chuàng)建網(wǎng)卡的配置文件夾
sudo mkdir -p /opt/router-config/dnsmasq/lan/
# 創(chuàng)建dnsmasq配置文件
sudo touch /opt/router-config/dnsmasq/lan/dnsmasq.conf
# 創(chuàng)建租約記錄文件(分配的客戶端,都會被記錄到這)
sudo touch /opt/router-config/dnsmasq/lan/dnsmasq.leases
# 創(chuàng)建靜態(tài)分配的IP主機配置(dhcp-host)
sudo mkdir -p /opt/router-config/dnsmasq/lan/
# 創(chuàng)建額外配置目錄conf.d
sudo mkdir -p /opt/router-config/dnsmasq/lan/conf.d
# 創(chuàng)建自定義的resolv.conf文件
sudo touch /opt/router-config/dnsmasq/lan/resolv.conf
# 創(chuàng)建日志存放的文件夾
sudo mkdir -p /var/log/dnsmasq
# 創(chuàng)建pid文件
sudo touch /run/dnsmasq@lan.pid
/var/log/dnsmasq
為日志文件夾慈迈,文件夾下若贮,網(wǎng)卡名.log
為不同服務(wù)實例獨立的日志。例如lan.log
/run/dnsmasq@lan.pid
為守護進程的pid記錄文件痒留。/opt/router-config/dnsmasq/lan/
目錄結(jié)構(gòu)如下:
lan/
├── conf.d
│ └── anti-ad-for-dnsmasq.conf
├── dnsmasq.conf
├── dnsmasq.leases
├── hosts.d
│ └── phone.ip
└── resolv.conf
hosts.d
文件夾記錄了綁定mac分配IP的配置谴麦。conf.d
dnsmasq服務(wù)的補充配置,這里用來設(shè)定屏蔽廣告域名伸头。(anti-ad域名屏蔽列表)
配置說明:
--except-interface 排除監(jiān)聽的網(wǎng)卡匾效,此處設(shè)定不監(jiān)聽lo(127.0.0.1)。
--pid-file 守護進程的pid文件路徑恤磷,此處systemd.service需要通過pid文件確定主進程的PID,精確控制停止進程面哼。
--log-facility 服務(wù)日志保存路徑
--interface dnsmasq服務(wù)綁定的網(wǎng)卡名,模板用%I綁定
--conf-file 配置文件的路徑
--dhcp-leasefile 租約記錄文件的路徑扫步,這個文件由dnsmasq自己管理魔策,不改動內(nèi)容
--dhcp-hostsfile 針對特定的mac,分配ip綁定的主機配置河胎,如果是文件夾闯袒,則讀取文件夾下所有的文件,此處使用的是文件夾游岳,一個文件對應(yīng)一個主機政敢。
--resolv-file 自定義resolv.conf路徑,上游DNS服務(wù)器的配置文件胚迫,此處是阿里云的dns
--conf-dir 導入目的目錄下的所有配置文件堕仔,可以用來導入額外的配置,例如屏蔽部分域名晌区。
dnsmasq.conf
配置文件格式,和命令行參數(shù)保持一致通贞,但是不同的地方是朗若,沒有--
前綴,例如port = 53
等價命令行--port=53
,一行一個參數(shù)昌罩,對于沒有右值的哭懈,則直接填左值,例如log-dhcp
等價命令行參數(shù)--log-dhcp
茎用。其他的選項就可以根據(jù)manpage來配置遣总,主要分成兩部分睬罗,一部分配置dns服務(wù)器的,另外一部分則是關(guān)于DHCP的配置旭斥。此處只配置DHCP部分容达。
主配置文件內(nèi)容:
# /opt/router-config/dnsmasq/lan/dnsmasq.conf
# DNS服務(wù)監(jiān)聽的端口,一般設(shè)置成53垂券,綁定的地址為網(wǎng)卡的ip
port = 53
listen-address=192.168.31.1
# 緩存條目1000條
cache-size=10000
# DNS查詢所有上游的服務(wù)器
all-servers
# 允許dbus總線
enable-dbus
# 本地hosts域名
bogus-priv
##########DHCP#####################
# DHCP 記錄日志
log-dhcp
# dhcp選項 router為默認網(wǎng)關(guān)
dhcp-option=option:router, 192.168.31.1
# netmask 子網(wǎng)掩碼
dhcp-option=option:netmask, 255.255.255.0
# domain
dhcp-option=option:domain-name, "my-router"
# dhcp分配給客戶端的dns服務(wù)器
dhcp-option=option:dns-server, 192.168.31.1
# MTU值
dhcp-option=option:mtu, 1500
# 動態(tài)分配ip的范圍花盐,從2~254,租約時間為10小時
dhcp-range=192.168.31.2, 192.168.31.254, 10h
更多dhcp-option的選項可以通過dnsmasq --help dhcp
查詢到。
/opt/router-config/dnsmasq/lan/resolv.conf
內(nèi)容(它定義了上游查詢服務(wù)器菇爪,最多只能使用2個):
nameserver 223.5.5.5 223.6.6.6
MYCOMPUTER
內(nèi)容算芯,針對mac地址為 23:33:33:33:33:44
的主機固定分配IP為 192.168.31.5
/opt/router-config/dnsmasq/lan/hosts.d/MYCOMPUTER
文件內(nèi)容:
23:33:33:33:33:44, 192.168.31.5
文件格式是 --dhcp-host
選項的右值,以上相當于 --dhcp-host=23:33:33:33:33:44, 192.168.31.5
凳宙,它可以是IPv4的熙揍,也可以是IPv6的,具體參考manpage氏涩。也是一行一個參數(shù)届囚,不同的主機,可以分開不同的文件寫配置削葱,也會被讀入奖亚。
文件配置完畢后,需要嘗試啟動 dnsmasq@lan.service
析砸,并且允許它開機自啟昔字。
sudo systemctl daemon-reload
# 允許開機自啟,并啟動服務(wù)
sudo systemctl --now enable dnsmasq@lan.service
# 查看服務(wù)工作狀況
sudo systemctl status dnsmasq@lan.service
手動 dnsmasq
確實太繁雜了,除了 dnsmasq
還可以用 systemd-networkd
配置簡單的DHCP+DNS server首繁,或者使用 AdguardHome
有個webui界面作郭。
PPPoE方式上網(wǎng)
經(jīng)過一段時間的努力,開始改造成PPPoE撥號上網(wǎng)弦疮,和DHCP方式上網(wǎng)不一樣夹攒,PPPoE方式上網(wǎng)需要額外的配置
PPPoE需要的軟件包
sudo apt install pppoe
pppoe包包含了一些啟動腳本
/usr/sbin/pppoe
/usr/sbin/pppoe-connect
/usr/sbin/pppoe-relay
/usr/sbin/pppoe-server
/usr/sbin/pppoe-sniff
/usr/sbin/pppoe-start
/usr/sbin/pppoe-status
/usr/sbin/pppoe-stop
pppoe包依賴ppp包,而ppp包又包含了一些ppp協(xié)議相關(guān)支持
PPPoE方式上網(wǎng)需要改動wan口的配置胁塞,上述wan采用的是dhcp/靜態(tài)IP上網(wǎng)的方式咏尝,pppoe上網(wǎng)可能需要解決一些問題
- ppp撥號
- 是否需要訪問光貓管理接口
pppoe上網(wǎng),wan口是不需要配置ip地址的啸罢,因為流量經(jīng)過pppoe協(xié)議封裝编检。我將做以下調(diào)整
添加 netdev 配置 ,將一個wan口擴展成兩個 macvtap 虛擬的網(wǎng)絡(luò)接口扰才,一個用于pppoe撥號允懂,一個用于連接光貓的管理接口,注意他們的mac地址是不一樣的衩匣。
添加 .network 配置蕾总,設(shè)定wan口與其他虛擬網(wǎng)絡(luò)接口的綁定關(guān)系粥航,再設(shè)置每個接口的IP設(shè)置。
由于pppoe撥號的接口是不需要IP地址的生百,將DHCP關(guān)閉递雀。
假設(shè)光貓的管理接口是192.168.1.1,虛擬接口與他同網(wǎng)段192.168.1.2的靜態(tài)IP
注意置侍,以下配置中包含多個文件的片段映之,留意注釋中的文件路徑。
# /etc/systemd/network/01-wan-modem.netdev
[NetDev]
Description=wan-modem虛擬網(wǎng)卡用于訪問光貓
Name=wan-modem
Kind=macvtap
MACAddress=23:33:33:33:33:06
[MACVTAP]
Mode=private
#######################################
# /etc/systemd/network/01-wan-ppp.netdev
[NetDev]
Description=wan-ppp 虛擬網(wǎng)卡用于PPPOE撥號
Name=wan-ppp
Kind=macvtap
MACAddress=23:33:33:33:33:07
[MACVTAP]
Mode=private
######################################
# /etc/systemd/network/01-wan.network
[Match]
MACAddress=23:33:33:33:33:04
[Link]
RequiredForOnline=yes
[Network]
Description= wan interface
DHCP=no
########################################
# /etc/systemd/network/01-wan-ppp.network
[Match]
Name=wan-ppp
[Network]
DHCP=no
##########################################
# /etc/systemd/network/01-wan-modem.network
[Match]
Name=wan-modem
[Network]
Address=192.168.1.2/24
更改撥號配置文件
# /etc/ppp/chap-secrets
# 設(shè)定寬帶用戶username 密碼是passwd
"username" * "passwd"
##################################################
# /etc/ppp/pppoe.conf
# 指定pppoe撥號的網(wǎng)絡(luò)接口蜡坊,需要修改成實際的撥號網(wǎng)卡
ETH="wan-ppp"
# 指定撥號使用的上網(wǎng)賬號杠输,修改成實際的寬帶用戶名
USER="username"
DEMAND=no
PEERDNS=no
DNSTYPE="NOCHANGE"
CONNECT_TIMEOUT=30
CONNECT_POLL=2
PING="."
# 指定PIDFILE
CF_BASE=`basename $CONFIG`
PIDFILE="/var/run/$CF_BASE-pppoe.pid"
SYNCHRONOUS=no
CLAMPMSS=1480
LCP_INTERVAL=30
LCP_FAILURE=3
PPPOE_TIMEOUT=100
FIREWALL=NONE
LINUX_PLUGIN="/lib/pppd/2.4.9/rp-pppoe.so"
由于配置了DNS不會被修改,pppoe不會獲取并配置dns到本地秕衙,我需要配置一個靜態(tài)的dns服務(wù)器蠢甲,這里使用 223.5.5.5
,由于使用了
# /etc/systemd/system/pppoe.service
[Unit]
Description=PPPOE service
BindsTo=sys-subsystem-net-devices-wan.device
After=sys-subsystem-net-devices-wan.device
[Service]
Type=forking
ExecStart=/usr/sbin/pppoe-start
ExecReload=/usr/sbin/pppoe-stop;/usr/sbin/pppoe-start
ExecStop=-/usr/sbin/pppoe-stop
Restart=always
[Install]
WantedBy=multi-user.target
這個配置文件可能還是存在一些問題的据忘,但是勉強能用鹦牛,主要是讓這個服務(wù),要在wan接口啟動后勇吊,才能啟動它(我感覺在network-pre.target之后也行曼追。。礼殊。),啟動并允許開啟自啟
sudo systemctl --now enable pppoe
當然這樣LAN下的主機沒法直接上網(wǎng)晶伦,因為老的nft規(guī)則婚陪,只是針對wan口做了masquerade频祝,引進了wan-modem, wan-ppp兩個虛擬接口
所以要進行修改新的規(guī)則以適應(yīng)實際情況泌参。
ppp0網(wǎng)絡(luò)接口是撥號后創(chuàng)建的,它在系統(tǒng)運行期間,因為pppoe重新?lián)芴柨赡軙G接口常空,如果此時使用iif及舍,它找不到這個網(wǎng)口,會報錯窟绷,所以iif用iifname代替,匹配網(wǎng)絡(luò)接口名的字符串咐柜。
wiki描述兼蜈,iif效率更高一些攘残,實際使用起來,因流量較少为狸,可以忽略影響歼郭。
table ip nat {
chain prerouting-public {
type nat hook prerouting priority 100; policy accept
#如果需要端口轉(zhuǎn)發(fā),則在PREROUTING鉤子的鏈做DNAT
iif wan tcp dport 65533 dnat to 192.168.31.2:22 comment "dnat: :65533 => 192.168.31.2:22"
# 把wan口進來的流量辐棒,目標端口是65533的發(fā)往192.168.31.2的22端口
}
chain postrouting-public {
type nat hook postrouting priority 100; policy accept;
#做動態(tài)SNAT (備注②)
meta iif wan-modem oif != wan-modem masquerade comment "內(nèi)網(wǎng)訪問光貓網(wǎng)段"
meta iifname "ppp0" oifname != "ppp0" masquerade comment "pppoe撥號上網(wǎng)NAT規(guī)則"
}
chain forward-public {
type filter hook input priority 0; policy drop;
iif {lo,lan} accept comment "允許lo口病曾、lan口流進的內(nèi)網(wǎng)流量通過"
ct state {established,related} accept comment "允許從內(nèi)部主動發(fā)起的鏈接通過"
ct status dnat accept comment "允許dnat狀態(tài)數(shù)據(jù)通過"
}
}
TC流量控制
有時需要有限部分用戶的流量,例如一些軟件的p2p上傳流量吃非常狠漾根,例如pt/bt泰涂。
流量控制只能控制自己發(fā)送給別人情況。不能阻止別人發(fā)送給自己辐怕。
一般家用帶寬逼蒙,下行1000M是牢,上行可能只有50M驳棱。
如果上行被p2p軟件占滿,也會影響下載的情況罚渐。目前做到初步調(diào)整流量的優(yōu)先級
linux的網(wǎng)絡(luò)接口,可以配置發(fā)送流量的排序關(guān)系源织,qdisc(隊列規(guī)定)谈息,主要有三個配置的元素
- qdisc 隊列規(guī)定
- class 分類
- filter 過濾器
粗略看待,它有兩個操作:
- 把流量放進去
- 把流量拿出來
流量放進去的順序是abc逻炊,但是不同類型的qdisc豹休,拿出來的順序可能不一樣的。
取出可能是abc(例如先進先出的pfifo)洛搀,又或者可能是bac姥卢,cba,都有可能棺榔≈⑿可以粗暴的理解,qdisc是決定流量排序規(guī)律的设塔。
所有從上層下來的流量,先放入qdisc序六,下層驅(qū)動要發(fā)送出去的時候例诀,在從qdisc里取出來暮刃,進出的順序可能被重新排列诸蚕,大概這么一個過程坏瘩。
不同規(guī)律的qdisc效果不一樣,例如先進先出的的pfifo哪自,你按什么順序放進去壤巷。拿出來也是什么順序。
他的目的是調(diào)度上層要發(fā)出去的流量矩动。可能是排序檀训,可能是丟棄(限速是通過丟包實現(xiàn)的)峻凫,
少量丟包是很正常的情況,可能是發(fā)送方發(fā)太狠了堰乔。
class
分類镐侯,是針對某個qdisc的,他不是所有的qdisc都有class崇猫,有些qdsic是沒有分類的,而有些qdisc,他可以自定義多個 class
不同 class
的效果不一樣涕烧,
例如可能存在發(fā)送優(yōu)先級澈魄,例如 prio
的qdisc,他默認分三個 class
,
-
1:1
band 0 -
1:2
band 1 -
1:3
band 2
它按 主要編號:次要編號 這樣的格式標識鲫构,次要編號0為qdsic本身,其他則是該qdisc的class標識炕吸,例如
1:0
是qdisc赫模,而1:1
是它的一個class胸嘴,
它會按優(yōu)先級 先從 1:1
先取出劣像, 高優(yōu)先級的class上沒有數(shù)據(jù)包,才會繼續(xù)提優(yōu)先級稍低的 1:2
吮铭。
qdisc可以嵌套的, 例如癞揉,在分到 1:1
的流量,可以再套多一個 prio
就可以形成以下結(jié)構(gòu)
1:0(qdisc prio)
|
|--1:1(class)--10:0(qdisc prio)
| |
| |--10:1
| |--10:2
| |--10:3
|--1:2(class)
|--1:3(class)
標識(主要編號:次要編號)是唯一的芥牌,這里結(jié)構(gòu)上像一棵樹,取出的時候柏靶,內(nèi)核只會和 1:0
交互痘昌,按qdisc規(guī)則取出,1:1
優(yōu)先被取驻啤,但是 1:1
下又有一個qdisc,它進一步從 10:1
取谢翎,然后取 10:1
上的森逮。
1:1
下掛的qdisc,編號不一定是 10:0
,唯一就好啦闷供。
但是流量放進去歪脏,不一定按 1:0
=> 1:1
=> 10:0
=> 10:2
這樣的順序。
有幾種影響流量放哪個子類的:
netfilter 直接對流量打標豪硅,iptables/nftables可以對流量標記,流量會直接放到具體的編號分類砚著,例如
10:2
它會一步到位放到10:2
赖草。filter規(guī)則秧骑,例如,1:0關(guān)聯(lián)的filter,它可以直接讓流量入
10:3
qdisc默認的存放規(guī)則,例如
prio
隊列規(guī)定坟冲,可以映射IP協(xié)議的TOS字段琳猫,根據(jù)優(yōu)先級把流量分發(fā)到不同的band
band 對應(yīng)它qdisc的class脐嫂,按prio的說明,band 0就是:1, band 1是 :2匀奏,依次類推
prio默認只分了三個band,0 1 2 饲齐,對應(yīng)三個class 1:1
1:2
1:3
靠近樹根的qdisc是 root
每個網(wǎng)卡只有一個的御雕,內(nèi)核與 root
交互酸纲。存入或者取出流量愁溜,樹中其他的qdisc,通過 parent
關(guān)聯(lián)到根部的 class,就可以連成一棵大樹啦。
# 對ppp0創(chuàng)建一個prio
tc qdisc add handle 1: root prio bands 7
handle 1:
指定這個qdisc的標識,也就是上面說的1:0
论悴,可以簡寫成1:
root
指定它是這網(wǎng)卡的root
qdisc,內(nèi)核和這個qdsic交互紫谷。prio
指定要采用哪種qdisc,這里選的prio
,特性是對流量優(yōu)先級做簡單分類bands 7
這是 qdisc 的參數(shù)笤昨,不同的qdisc參數(shù)不一樣,這里是指定7個band,對應(yīng)的class是1:1
到1:7
疑惑拔稳,它怎么確定流量放哪個 class
?
按 prio
的說明,它有個 priomap
參數(shù)锹雏,一共16個數(shù)字
TOS Bits Means Linux Priority Band
------------------------------------------------------------
0x0 0 Normal Service 0 Best Effort 1
0x2 1 Minimize Monetary Cost 0 Best Effort 1
0x4 2 Maximize Reliability 0 Best Effort 1
0x6 3 mmc+mr 0 Best Effort 1
0x8 4 Maximize Throughput 2 Bulk 2
0xa 5 mmc+mt 2 Bulk 2
0xc 6 mr+mt 2 Bulk 2
0xe 7 mmc+mr+mt 2 Bulk 2
0x10 8 Minimize Delay 6 Interactive 0
0x12 9 mmc+md 6 Interactive 0
0x14 10 mr+md 6 Interactive 0
0x16 11 mmc+mr+md 6 Interactive 0
0x18 12 mt+md 4 Int. Bulk 1
0x1a 13 mmc+mt+md 4 Int. Bulk 1
0x1c 14 mr+mt+md 4 Int. Bulk 1
0x1e 15 mmc+mr+mt+md 4 Int. Bulk 1
它是和IP數(shù)據(jù)包巴比,8位的TOS字段對應(yīng)的映射,通過抓包發(fā)現(xiàn)TOS大部分時候取值都是0礁遵。
考慮7個class這樣分配:
1:1 ~ 1:2 保留轻绞,用來做優(yōu)先上網(wǎng)設(shè)備的流量分類
1:3 1:4 1:5 對應(yīng)原來3 band的 0 1 2,主要用來做跑常規(guī)的上網(wǎng)上行流量
1:6 1:7為低優(yōu)先級流量,用來做p2p網(wǎng)絡(luò)流量分類讽挟,例如bt/pt拆檬,放在1:7
那么正常的映射關(guān)系就不能按原來的 0 1 2走前3個class拱镐,計劃7個class,對應(yīng)7個band澈歉,做以下調(diào)整:
0x0 0x2 0x4 0x6 屬于普通流量悟衩。走的默認band1,3 band分類走band 1,也就是1:2,7band分類計劃走1:4凫碌,對應(yīng)的band 3换帜。
0x8 0xa 0xc 0xe 屬于低優(yōu)先級流量疲眷,3band分類時走band 2(也就是1:3),而7 band分類時谆趾,我想要它走1:7性芬,對應(yīng)的band 6,彭沼。
0x10 0x12 0x14 0x16 屬于高優(yōu)先級流量,3band分類時走1:1,7band分類計劃走1:3,對應(yīng)band 2倾剿。
0x18 0x1a 0x1c 0x1e 也是設(shè)置成普通流量優(yōu)先級芝硬,對應(yīng)的band 3悠反。
于是得到16個數(shù)字
3 3 3 3
6 6 6 6
2 2 2 2
3 3 3 3
創(chuàng)建 ppp0 的root qdisc的tc命令修改成
tc qdisc add handle 1: root prio bands 7 priomap 3 3 3 3 6 6 6 6 2 2 2 2 3 3 3
到此,正常的流量走的的 1:4
,通過bmon命令應(yīng)該可以看到1:4有上傳流量(測速試試)酿炸。
但是prio實際測試胶台。它并不能保證高優(yōu)先級分類的一定能吃滿帶寬,它沒辦法去搶低優(yōu)先級p2p流量的帶寬。但是至少它不會被壓榨的根本沒法用的地步碍现。
如果對p2p流量進行限速慢睡,則需要對 1:7
纬纪,再掛一個qdisc,例如tbf,它的作用是限制流量通過的速率蔬咬,如果超出速率鲤遥,還繼續(xù)往tbf塞流量,它可能會丟掉林艘,達到限速的效果盖奈。
但是這些qdisc它并不知道實際可用的物理帶寬。如果是固定的帶寬狐援,可以創(chuàng)建tbf時指定卜朗。
限速10Mbit
tc qdisc add dev ppp0 parent 1:7 handle 70: tbf rate 10mbit burst 1000kb limit 100mbit
和先前創(chuàng)建root qdisc類似,但是它指定的不是root咕村,而是parent 1:7场钉,1:7是它的父級。
handle 70:
指定這個qdisc的表示懈涛,70: 70:0都是一個意思tbf
選定的qdisc類型逛万,tbf的作用是限制速率。后續(xù)跟著它的設(shè)置參數(shù)rate 10mbit
限制10Mbpsburst 10000kb
按手冊的說法是令牌桶的大小limit 100mbit
排隊等待令牌的字節(jié)數(shù)
我粗淺的理解批钠,是這樣的宇植,把tbf想象成一個桶,有按一定的速度往桶里放球(令牌)埋心。
而流量要進tbf指郁,也是放在一個隊列里(和這個桶無關(guān))。
桶只能裝busrt指定若干個球拷呆,如果桶滿了闲坎。暫時不會往里放。
tbf流量從隊列里出隊茬斧,每次出去一些流量腰懂,必須從桶里拿走一些小球。
如果沒有球拿项秉,那流量就不可以出去绣溜。在隊列堆積著。
如果球放入的速度和流量出去的速度剛好相同娄蔼,這些流量那就完美通過tbf怖喻,不會被丟底哗。
如果小球放入的速度太快,桶一直不會是空的狀態(tài)锚沸,那么流量也是有多少走多少艘虎,也不會出現(xiàn)丟,沒有"限速"的感覺咒吐,因為流量太少了。
所以限速調(diào)的很寬属划,桶里一直有球的恬叹。流量都能按最大的速率進出,就沒有限速的效果同眯,只有小球不夠用绽昼,才有限速的效果,
如果小球放入的速度很低须蜗,即限速太死了硅确,就會出現(xiàn)這種情況:
桶里沒球了,流量堆積在隊列里明肮,塞不下了菱农。再往里灌流量。直接會被丟掉柿估。這個是時候發(fā)生了丟包循未。
如果發(fā)送方能降低發(fā)送速率以匹配限速是最好的,如果沒有措施秫舌,丟包情況會很糟糕的妖。
但是總體出去的流量速度得到了限制,限速的效果有了足陨。
如果桶調(diào)的很大嫂粟,如果長時間沒有流量,桶滿了墨缘,突然有一波流量要進出星虹。他就會在短時間內(nèi)消耗掉小球,速率很快镊讼,一直等到通空了搁凸,只能等待一點點放進桶里的小球。
如果排隊的隊列調(diào)得(limit)很大狠毯,(burst)桶又很小护糖,限速(rate)也很慢,短時間內(nèi)沖去一波大流量嚼松,桶空了嫡良,隊列迅速堆積锰扶,但是它就是沒有堆滿,它以低速率出去寝受,高速率進來坷牛,這段時間的流量,延遲就高了很澄,但是它丟包情況可能還好京闰。后續(xù)隊列滿,上層流量往里再沖甩苛,就得丟包了蹂楣。
看tbf的說明,rate burst limit要按一定的配比讯蒲,工作才更完美痊土。
對于英特爾的 10mbit/s,如果您想達到配置的速率墨林,至少需要 10KB 的burst赁酝!
tbf限速,要考慮丟包和延遲的平衡旭等。
除了對應(yīng)qdisc的分類規(guī)則酌呆,還可以通過tc-filter或者nftables對數(shù)據(jù)包打標,讓流量落入具體某個標識的qdisc搔耕。
對于debian本機的流量肪笋,可以通過多種條件匹配,例如:
- 進程的cgroup
- 進程的用戶身份:uid或者gid
域名或者根據(jù)端口限速是麻煩的度迂。因為域名對應(yīng)的ip可能發(fā)生變化藤乙,需要不斷更新。
如果本地有下載服務(wù)惭墓。那種p2p的坛梁,可以根據(jù)p2p源端口限速,或者通過cgroup
cgroups
table inet qos {
chain qos-bt {
type filter hook output priority 0; policy accept;
iifname != "ppp0" accept comment "不從ppp0接口發(fā)出的流量不處理"
# 讓uid用戶1000的流量優(yōu)先級提高到1:2
meta skuid 1000 meta priority set 1:2 counter accept comment "用戶上網(wǎng)流量優(yōu)先"
# 限制bt下載軟件上傳端口網(wǎng)速腊凶,假設(shè)qbitorrent使用51234端口
udp sport 51234 meta priority set 1:7 counter accept comment "qb上傳優(yōu)先級調(diào)低"
}
}
上述在 output hook中的規(guī)則只能處理debian本機發(fā)出的流量划咐。應(yīng)該根據(jù)不同的流量特點。在合適的hook中添加規(guī)則钧萍,例如socket cgroupv2 相關(guān)的只能在ouput處有效褐缠。
不同的nft版本支持的特性在變化,應(yīng)該要參考使用的nft在哪個版本引入支持风瘦。
TODO:
IPv6分配队魏,由于IPv4和IPv6的DHCP分配地址方式不一樣,具體詳細的選項,還需要琢磨下手冊胡桨。
網(wǎng)卡啟動和關(guān)閉時官帘,觸發(fā)服務(wù)重啟
筆記最后更新時間:2022-2-10
筆記最后更新時間:2023-12-21
參考文檔
IPv6分配,由于IPv4和IPv6的DHCP分配地址方式不一樣昧谊,具體詳細的選項刽虹,還需要琢磨下手冊。