debian搭建簡易路由筆記(未完成外網(wǎng)部分)

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ò)管理軟件(主要針對 networkingNetworkManager ),

  • (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)卡履植,卸載 networkingNetWorkManager 服務(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.network10-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 漆诽、 NEWRELATEDINVALID 锣枝,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:11: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 限制10Mbps

  • burst 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


參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呢诬,一起剝皮案震驚了整個濱河市涌哲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尚镰,老刑警劉巖阀圾,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钓猬,居然都是意外死亡,警方通過查閱死者的電腦和手機撩独,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門敞曹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寓调,“玉大人饮戳,你說我怎么就攤上這事〕憾危” “怎么了剧劝?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵橄登,是天一觀的道長。 經(jīng)常有香客問我讥此,道長拢锹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任萄喳,我火速辦了婚禮卒稳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘他巨。我一直安慰自己充坑,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布染突。 她就那樣靜靜地躺著捻爷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪份企。 梳的紋絲不亂的頭發(fā)上也榄,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音司志,去河邊找鬼手蝎。 笑死榕莺,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的棵介。 我是一名探鬼主播钉鸯,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼邮辽!你這毒婦竟也來了唠雕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤吨述,失蹤者是張志新(化名)和其女友劉穎岩睁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揣云,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡捕儒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了邓夕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刘莹。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖焚刚,靈堂內(nèi)的尸體忽然破棺而出点弯,到底是詐尸還是另有隱情,我是刑警寧澤矿咕,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布抢肛,位于F島的核電站,受9級特大地震影響碳柱,放射性物質(zhì)發(fā)生泄漏捡絮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一莲镣、第九天 我趴在偏房一處隱蔽的房頂上張望锦援。 院中可真熱鬧,春花似錦剥悟、人聲如沸灵寺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽略板。三九已至,卻和暖如春慈缔,著一層夾襖步出監(jiān)牢的瞬間叮称,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓤檐,地道東北人赂韵。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像挠蛉,于是被迫代替她去往敵國和親祭示。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容