利用 dnsmasq 和 wireguard 搞一組簡單的內部開發環境。目標是不論在家開桌機、咖啡廳開筆電或是家裡開筆電,都能得到幾乎一樣的體驗。
- 連外網路
- 從外面連回家用的外網 IP (固 I 佳,動態的要另外想辦法處理 DDNS)
- NAT
- 最簡單的方式是買台速度和訊號不錯的分享器,只會用它的路由、撥號和防火牆功能
- 如果選擇自行用 linux 機器做 NAT 的話,可以考慮把兩個主要服務都放在 NAT 機上,減少設定的麻煩
- 其他跑服務的機器 (rpi/舊電腦/準系統)
以我的情況來說
+----------------+
| 中華電信小烏龜 |
+--------+-------+
|
+----------+-----------+
| a.b.c.d (pppoe 固I) |
| 破爛分享器 |
| 192.168.1.1 |
+----------------------+
| | |
+-----------------------+ | +-----------------------+
| 服務機 | | | 桌機/筆電 |
| 192.168.1.2 (static) | | | 192.168.1.x (dhcp) |
| DNS+DHCP (dnsmasq) | | +-----------------------+
| VPN (wireguard) | +-----------------------+
| Reverse proxy (nginx) | | 開發機1~3 |
+-----------------------+ | 192.168.1.3~5 (dhcp) |
| Git (forgejo) |
| DB (postgres) |
| 其他服務 |
+-----------------------+
- 自架 DNS+DHCP 才方便用簡寫連線,調整開發機配置 (增減、改 IP) 後不必在桌機和筆電重覆修改
/etc/hosts - VPN 方便筆電從外面連回家
- nginx 集中處理 git server/issue tracker/music player (!?) 等會在外面用到的服務
- qos/firewall/port forwarding 這些相對麻煩的問題由分享器處理
- 如果想手動處理,建議把 DNS/DHCP/VPN 也放在 NAT 機上,避免封包來回跑
- 你可能會需要 nftables / iproute2 或是其他相關的前端 (例如 firewalld)
- 開發機使用 DHCP 配發的固定 IP,減少 IP 跳動造成內部服務互聯異常
- 桌機和筆電、手機則用動態 IP
- 如果桌機有時也要開服務 (比如 LLM) 也可以用固定 IP
- 公開 IPv6 無法強求,主要看分享器和對外網路
- 三雄似乎都有支援 IPv6 (至少我的種花 IPv6 免費)
- 2022 以後的分享器似乎都有支援 IPv6
- 內部 IPv6 (fdxx:xxxx:xxxx::/48) 不受以上限制
- 普通的把 pppoe 撥號、防火牆規則和 port forwarding 設定好
- 記得把 Wireguard 的 port 開好
血淚教訓
- 記得把 Wireguard 的 port 開好
- 不是自架 NAT 的話,必需把 DHCP 關掉以免和服務機衝突
- 非固 I 的情況下可以搞個 DDNS,這樣筆電上的 Wireguard 設定就不必一直換 IP
重點就是這台,最關鍵的兩個服務 (dnsmasq, wireguard) 都在這。但這兩個服務不太吃效能,rpi1 已經足夠。
值得一提的是,這台機器因為肩負 DNS+DHCP 重任,是唯一一台 不透過 DHCP 設定網路 的主機。
這台我是設成 192.168.1.2 及 fd09:8765:4321:1::2,這會影響底下 dnsmasq 的設定。
先貼個設定檔 /etc/dnsmasq.d/dhcp
# 基本設定
# dhcp 避掉不必要的網卡 (docker 相關)
no-dhcp-interface=veth*
no-dhcp-interface=br*
# 不要吃 /etc/resolv.conf 和 /etc/hosts 以免自己打自己
no-resolv
no-hosts
# 上游 DNS
server=1.1.1.1
server=8.8.8.8
# 本地域名
local=/home/
domain-needed
domain=home
# 服務機設定 (服務機不使用 dhcp)
# fd09:8765:4321:1 裡面,fd 之後的部份可以自己改,跟底下 DHCPv6 的一樣就好
# 要跟服務機的 IP 設定一致
host-record=dns,dns.home,192.168.1.2,fd09:8765:4321:1::2
# DHCPv4 設定
dhcp-range=192.168.1.200,192.168.1.220,255.255.255.0,1h
dhcp-option=option:dns-server,192.168.1.2
dhcp-option=option:domain-name,home
dhcp-option=option:domain-search,home
# wireguard 路由,要指去提供 wg 的機器 (這邊是服務機)
# 192.168.5 是 wireguard 設定的網段,可以自己改,後面會提到
dhcp-option=option:classless-static-route,192.168.5.0/24,192.168.1.2
# default route
dhcp-option=option:classless-static-route,0.0.0.0/0,192.168.1.1
# DHCPv6 設定 (只有內網 IP)
# fd09:8765:4321:1 裡面,fd 之後的部份可以自己改
enable-ra
dhcp-range=fd09:87655:4321:1::200,fd09:8765:4321:1::220,64,1h
dhcp-option=option6:dns-server,[fd09:8765:4321:1::2]
# 固 I 部份 (開發機)
dhcp-host=xx:xx:xx:xx:xx:xx,192.168.1.3,[fd09:8765:4321:1::3],srv1,infinite
dhcp-host=xx:xx:xx:xx:xx:xx,192.168.1.4,[fd09:8765:4321:1::4],srv2,infinite
dhcp-host=xx:xx:xx:xx:xx:xx,192.168.1.5,[fd09:8765:4321:1::5],srv3,infinite
- IPv6 聯外的部份交給分享器 / NAT 處理,這邊只配給內網 IP
- 簡寫 (
srv1/srv2/srv3) 應該要跟那台機器上的/etc/hostname一樣 - 非固 I 的其他機器 (桌機/筆電) 的簡寫也是依
/etc/hostname決定
最重要的,開機自動開啟 dnsmasq 血淚教訓
sudo systemctl enable dnsmasq一樣先上設定 /etc/wireguard/wg.conf
# 服務機
[Interface]
PrivateKey = 秘密
Address = 192.168.5.2/24
ListenPort = 9876
# 讓筆電在外面的時候能透過 wg 網段存取內部資源
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -A FORWARD -o %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -s 192.168.5.0/24 -d 192.168.1.0/24 -j MASQUERADE
PostUp = iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.5.0/24 -j MASQUERADE
PreDown = iptables -D FORWARD -i %i -j ACCEPT
PreDown = iptables -D FORWARD -o %i -j ACCEPT
PreDown = iptables -t nat -D POSTROUTING -s 192.168.5.0/24 -d 192.168.1.0/24 -j MASQUERADE
PreDown = iptables -t nat -D POSTROUTING -s 192.168.1.0/24 -d 192.168.5.0/24 -j MASQUERADE
# 筆電1
[Peer]
PublicKey = 秘密
AllowedIPs = 192.168.5.6/32
# 筆電2
[Peer]
PublicKey = 秘密
AllowedIPs = 192.168.5.7/32
# 手機1
[Peer]
PublicKey = 秘密
AllowedIPs = 192.168.5.8/32
要注意的是,這個設定無法讓筆電1、筆電2跟手機在外面的時候互通:你必需讓服務機當中轉站才行。但如果不考慮資安問題的話 (像我的需求都只是傳個無關緊要的檔案),這實在是脫褲子放屁...
當然,也不能少了 /etc/sysctl.d/99-ipv4_forward.conf
net.ipv4.ip_forward=1
以及最重要的,開機自動開啟 wireguard 血淚教訓
sudo systemctl enable wg-quick@wg基本上就是設定 DHCP、hostname 兩項就好;設定完就能靠 hostname 互通
- hostname:
/etc/hostname和/etc/hosts - DHCP: NetworkManager, connman, ifupdown, systemd, ...
- 如果 ISP/分享器有提供公開的 IPv6,記得把它們提供的 DNS 關掉,以免無法解析內網簡寫
- 以 NetworkManager 來說,把 IPv6 分頁的自動 DNS 關掉
- 以 systemd-networkd 來說,設定
IPv6AcceptRA.UseDNS=false
- 人在家:
ssh srv1/curl -sSL http://srv1:12345/api - 人在外: 打開 Wireguard 然後
ssh srv1/curl -sSL http://srv1:12345/api
基本上只有服務機的 dnsmasq 和 wireguard 設定需要備份。
- 換電腦但簡寫不變: 新機器的設定處理好就好,服務機不用調整
- 換簡寫: 調整服務機的 dnsmasq 設定
- 增減機器: 調整服務機的 dnsmasq 設定
新機器的設定處理好就好,服務機不用調整
IP 設定太多可能,所以你要自己搞
tar zcf bak.tgz /etc/dnsmasq.d /etc/wireguardapt isntall -y dnsmasq wireguard
tar zxf bak.tgz -C /
systemctl enable wg-quick@wg dnsmasq