Ubuntu 下面搞 Multi-home 架構

家裡的 internet 架構大概是這樣 (省略過其他裝置):

一邊是 HiNet 的線路直接接中華的數據機 (modem),這段是用 PPPoE 撥接;另一邊是第四台網路 (北都),另外上面寫的 Switch 應該是 IP 分享器 (一台 ASUS 的機子,刷 DD-WRT),作圖的時候寫錯了...

最後是電腦的部份,我的桌機是跑 Ubuntu,用兩張個不同的實體線路 (界面分別是中華的 enp4s0 與第四台的 enp6s0f0) 接到了這兩個不同的網段上面。

打算跑 source routing 的架構來善用兩邊的頻寬,想法上面大概是這樣拆解:

  1. 機器本身有個 192.168.3.x 的 static ip。
  2. 針對 source ip 是 192.168.3.x 的封包,預設會往 192.168.3.254 這台分享器丟,然後 NAT 出去。
  3. Squid 在本機上跑一個 proxy server,指定 source ip 是 192.168.3.x

有了這樣的架構,我就可以在瀏覽器上面就透過 SwitchyOmega 這類的套件,指定某些網段要走第四台的頻寬出去了。

另外可以指定 http proxy 的服務也可以透過這個方法往第四台的線路連出去。

其中第二點需要把 source ip 是 192.168.3.x 的封包丟到 192.168.3.254 這段需要一些設定,首先是需要設定一個獨立的 routing table,我是在 /etc/iproute2/rt_tables 裡面放:

2       second

然後因為我是透過 NetworkManager 在管理網路界面的,我希望在 enp6s0f0 啟動時自動設定這個 source routing 邏輯,所以我在 /etc/NetworkManager/dispatcher.d/99-enp6s0f0 這邊寫了:

#!/bin/bash

interface=$1
event=$2

if [[ "$interface" == "enp6s0f0" && "$event" == "up" ]]; then
    ip route add default via 192.168.3.254 table second
    ip rule add from 192.168.3.0/24 table second
fi

然後要記得把這個檔案 chmod 755 讓他可以執行。

接著是 Squid 的設定,在 /etc/squid/squid.conf 裡面這樣寫:

#
http_access allow all
#
access_log /var/log/squid/access.log squid
cache deny all
cache_dir null /tmp
cache_log /dev/null
cache_mem 8 MB
dns_v4_first on
forwarded_for off
http_port 3128
tcp_outgoing_address 192.168.3.x

其中最後的 192.168.3.x 換成自己的固定 IP address。這邊因為 traffic 基本上都是 HTTPS 了,也不需要開 cache,就這樣設定...

這邊比較特別的是 dns_v4_first 的設計,這個是讓 Squid 儘量用 IPv4 的位置連線。這是因為北都的網路沒有提供 IPv6 位置,所以如果網站的 DNS 如果有 IPv6 位置的話就會從 HiNet 這邊的 IPv6 出去了...

另外 ping 與 MTR 之類的工具不會動在這這樣的架構下是正常的,因為這些工具會自己組合 raw packet 丟,不是透過 Linux 的 network stack 處理,所以不會被我們指定的 ip rule 解析。網路上看起來是有方法可以 mitigate,但我就先放著了...

這樣看起來還算堪用,先這樣用一陣子看看... 先前是在 Raspberry Pi 上面跑個 proxy server 導流量,但會受限於 Raspberry Pi 的硬體限制,效能上面就普普通通,現在直接用桌機拼看看...

在 Ubuntu 20.04/22.04 下使用 18.04 的 chromium-browser

Ubuntu 20.04 之後包的 chromium 都是基於 snap 的方案,是個除了 Canonical 的人以外沒人愛的東西,所以大家都在找方法改回 .deb 的版本。

剛剛因為需要測試東西所以才需要找這個方案,發現有個還蠻有趣的解法,是拿 18.04 的 chromium-browser 的套件來裝,因為官方至少會支援到 2023/04:「Is it still possible to install Chromium as a deb-package on 20.04 LTS using some third-party repository?」。

一個 /etc/apt/sources.list.d/bionic-update.list

deb http://archive.ubuntu.com/ubuntu/ bionic-updates universe

另外一個 /etc/apt/preferences.d/chromium-deb-bionic-updates

Package: chromium-browser chromium-browser-l10n chromium-codecs-ffmpeg-extra chromium-codecs-ffmpeg 
Pin: release a=bionic-updates
Pin-Priority: 900

完全還是使用官方套件的解法,唯一的缺點大概就是到明年四月而已,但對要測試來說夠用了...

解決 Ubuntu 重開機後麥克風聲音太小的問題

Ubuntu 桌機重開機後會遇到外接 USB 麥克風 AM310 的聲音會變得太小的問題,常常是開會的時候被同事提醒才去調。

查了一下是不是有 bug,看起來跟「Mic input volume always resets (to middle/low value) on resume or restart」這個 bug 有關,但這個回報是 16.04,到現在 22.04 都出了,好像沒有新進度...

接著就是找看看有沒有 workaround 可以用,其中一種想法是找出用 command line 設定音量的方式,這樣就可以在開機的時候自動執行。

接著就找到「How can i increase microphone volume beyond 100%」這個問答,首先用這個指定列出所有的 source:

pactl list sources

裡面可以看到 AM310 的資料,接著就可以透過 name 的部份指定音量了:

pactl set-source-volume alsa_input.usb-AVerMedia_AVerMedia_AM310_USB_Microphone-00.multichannel-input 70%

放到 startup script 在 login 的時候跑就 OK 了。

Ubuntu 22.04 LTS 出版

Okay,各家 DevOps Engineers & SRE 可能又要忙碌了,兩年一度的盛事,Ubuntu 22.04 LTS 出版:「Canonical Ubuntu 22.04 LTS is released」。

其中有一些比較特別的消息,像是這次是 Ubuntu Desktop 這邊正式支援 Raspberry Pi 4 平台:

For innovators on Raspberry Pi, Ubuntu 22.04 LTS marks the first LTS release with Ubuntu Desktop support on the Raspberry Pi 4.

照慣例先放一個月再看看,通常三個月後應該會把大家常見的問題都修差不多,我這邊 Desktop 是用換成 XfceXubuntu,要再等一下...

Linux 上 fcitx5 的小麥輸入法

Twitter 上看到小麥輸入法宣佈支援 Linuxfcitx5 的消息:

專案在 GitHub 上的「fcitx5-mcbopomofo: 小麥注音輸入法 fcitx5 模組」這邊,因為我自己的 Ubuntu 20.04 桌機還是跑 fcitx 4.x (用酷音輸入法,裝的是 fcitx-chewing 這個套件),暫時先放著好了,但幫忙宣傳一下...

也許可以找機會練習包到 Ubuntu 的 PPA 上面,等有空吧...

jless:檢視 JSON 的工具

前幾天在「Show HN: Jless, a command-line JSON viewer (pauljuliusmartinez.github.io)」這邊看到用 Rust 寫的 jless 這個工具,官網有個動圖可以參考:

這樣方便不少,就不需要自己在對半天...

另外也剛好拿來練手,把 Rust 寫的套件包成 Ubuntu PPA:「PPA for jless」。

主要是 cargo vendor 這個指令可以把相依套件都抓下來放到 vendor/ 下面,然後設定 .cargo/config.toml 後就可以在本地端處理了,這對於 build farm 限制 internet 連線的情況會好用很多...

用 iptables 擋特定國家的封包

這兩天發現 ubuntu-20.04.3-live-server-amd64.iso 這個 BitTorrent 的 ISO image 有大量來自 CN 的連線在狂抓,導致整個上傳頻寬都被吃滿:

沒想到第一次用 iptables 的 xt_geoip 居然是這個用途... 主要是參考「GeoIP Blocking Ubuntu 20.04LTS」這邊的方法,不過因為我的 rtorrent 是跑在 Docker 裡面的,有另外要注意的地方。

首先是安裝軟體,這邊要裝 xtables-addons-commonlibtext-csv-xs-perl

sudo apt install -y libtext-csv-xs-perl xtables-addons-common

再來是建立目錄,並且下載一包 GeoIP 的資料 (從 DBIP 下載) 並且轉成 xt_geoip 可以用的格式:

sudo mkdir /usr/share/xt_geoip
cd /usr/share/xt_geoip
sudo /usr/lib/xtables-addons/xt_geoip_dl
sudo /usr/bin/perl /usr/lib/xtables-addons/xt_geoip_build

然後就是加到 iptables 的條件裡面了,我加到兩個地方,一個是 INPUT chain,另外一個是 DOCKER-USER chain (參考「Docker and iptables」這邊的說明),假設你是用 port 6991 的話就這樣加:

sudo iptables -I INPUT -p tcp -m geoip --source-country CN -m tcp --dport 6991 -j DROP
sudo iptables -I DOCKER-USER -p tcp -m geoip --source-country CN -m tcp --dport 6991 -j DROP

然後可以考慮每個禮拜更新一次資料庫。

另外在找資料的時候發現「Free updated GeoIP legacy databases」這邊有人放出 MaxMind 的版本,不過免費版的應該都差不多,這邊就用 xtables-addons-common 內預設的。

弄完以後就正常多了...

Ubuntu 下的滑鼠滾輪速度

這陣子因為經常切回 WindowsD2R,發現 Windows 下的滾輪速度快多了,回到 Ubuntu 20.04 下發現無法調整滑鼠滾輪的速度,找了一些方案測試,發現居然地雷還是超多 XD

搜尋可以找到「Increase mouse wheel scroll speed」與「How to change my mouse wheel scroll rate?」這兩篇,被推最多的都是 imwheel,但這套軟體的最新版是 2004 年,實際上用就會發現配合現代的系統 bug 很多...

另外用的方案是「Mouse scroll wheel acceleration, implemented in user space」,作者用 Python 去控制加速,測了一下正常多了。範例給的 ./main.py -v --exp 1 其中的 --exp 1 實際用起來有點太快,我改成 0.75 比較習慣。

先照著作者提到的,把 dependency 都裝起來,接下來掛到 Session and Startup 裡面,在登入後跑起來就可以了:

Ubuntu 14.04 與 16.04 的 ESM 從八年延長到十年

本來的舊的 Ubuntu ESM 是額外的三年 (加上本來的 LTS 五年,共八年),14.04 會支援到 2022 年四月 (參考 Internet Archive 上的存檔資料「Ubuntu 14.04 LTS has transitioned to ESM support」),然後 16.04 會支援到 2024 年四月 (參考 Internet Archive 上的存檔資料「Ubuntu 16.04 LTS transitions to Extended Security Maintenance (ESM)」),而 18.04 與 20.04 以後的 Ubuntu ESM 則是額外五年。

現在則是宣佈 14.04 與 16.04 都切齊額外五年了,所以總共都是十年:「Ubuntu 14.04 and 16.04 lifecycle extended to ten years」。

另外在 Hacker News 上的討論可以看一下:「Ubuntu 14.04 and 16.04 lifecycle extended to ten years (ubuntu.com)」,有人覺得這個政策很糟,但我覺得還好,有些商業環境就是花錢解決懶得升級... (沒有 support 只有 security update 的方案,一台實體機器才 USD$225/year,如果是虛擬機的話就更便宜了)

算是對付 legacy application 還蠻重要的方案...

Ubuntu 環境 PPPoE 遇到拿的到 IPv6 address 但是卻不通的問題

Ubuntu 的環境裡透過 PPPoE 上拿 IPv6 address 不是什麼大問題,搜一下大概都可以找到,在 /etc/ppp/options 的最後面加上這串就可以了 (或是在 /etc/ppp/peers/ 裡面的檔案對特定的設定加):

+ipv6 ipv6cp-use-ipaddr

不過我遇到的問題是,ppp0 雖然拿到了 IPv6 address (從 ip addr 或是 ifconfig 可以看到),但 mtr -6 www.google.com 確不通。

找問題時發現 netstat -6rn 有兩筆 IPv6 default gateway,刪掉 enp3s0 的那筆馬上就通了,所以是跟 routing 有關的問題,在本地端收到了 default routing,優先權還比 ppp0 拿到的還高。

因為這台主機是跑 Netplan,所以就用 Netplan 的方式強制關掉本地端的 Router Advertisement (RA):

network:
    version: 2
    renderer: networkd
    ethernets:
        enp3s0:
            accept-ra: false

最後重開機確認後就通了...