
Network & DNS:所有服務的定位系統
在 Infra 中,Network & DNS 是「定位系統」。沒有定位系統,服務會存在卻無法被正確找到;有了定位系統,擴充、遷移與維運都會變得有規則可循。這層的重點不是功能多,而是讓後續所有服務都有一致的入口與命名語意。
你需要回答三件事:
- 服務要被誰找到(外部使用者或內部服務)
- 要從哪裡進來(固定 IP / 代理 / VPN)
- 怎麼命名(環境 + 服務 + 角色)
如果這三件事沒有先定義清楚,後面的反向代理、TLS、CI/CD 都會變成「到處補洞」的狀態。
架構概覽
flowchart LR User[使用者] --> Resolver[DNS Resolver] Resolver --> Authoritative[DNS Provider Cloudflare/Route53] Authoritative --> Entry[固定入口 Reverse Proxy] Entry --> AppA[api.example.com] Entry --> AppB[admin.example.com] Entry --> AppC[git.example.com] Dev[工程師] --> VPN[VPN/Bastion] VPN --> InternalDNS[內部 DNS CoreDNS/Unbound] InternalDNS --> DB[(PostgreSQL)] InternalDNS --> Cache[(Redis)] InternalDNS --> Monitor[Prometheus/Grafana]
外部流量透過 DNS → 固定入口 → 反向代理 進入;內部服務則透過 VPN 或 Bastion Host 進入內網,再由內部 DNS 解析。兩者應該分流、分權、分責任,避免外網直接看到內網的 IP 與服務名稱。
核心概念
-
網段分區(Segmentation)
- 依功能切分不同網段,例如:
10.10.10.0/24(應用)、10.10.20.0/24(資料庫)、10.10.30.0/24(監控)。 - 這樣做可以用防火牆規則表達清楚的權限邊界(例如:只有應用網段能連到資料庫)。
- 風險提醒:當服務變多時,未分區的內網會讓「哪台能連哪台」變成口頭默契,事故後難以追查。
- 依功能切分不同網段,例如:
-
DNS 命名語意
- 命名要「看得出用途」,建議
{service}.{env}.example.com。 - 例如
api.prod.example.com與api.staging.example.com,讓人一眼知道環境與角色。 - 延伸:如果有多地區,可加上區域:
api.ap-southeast.prod.example.com,利於流量與維運分工。
- 命名要「看得出用途」,建議
-
固定入口(Single Entry)
- 讓所有外部流量先進入單一入口(Nginx/HAProxy)。
- 方便做統一的 TLS、WAF、流量管控,並避免服務直接暴露在公網。
- 這也讓 DNS 只需要指向入口,而不是指向每一個服務本體。
-
內外網解析隔離
- 內部服務(資料庫、監控)不應該被公網 DNS 解析。
- 常見做法是在內網維護一套 CoreDNS 或 Unbound,專門解析
.internal或.svc域名。 - 理由:避免內部 IP 被外洩,也避免外網誤打內網服務。
-
TTL 與遷移策略
- DNS 不是即時系統,TTL 太長會導致遷移延遲。
- 需要在遷移前先調低 TTL,再切換入口或 IP。
- 通常做法:遷移前 24 小時把 TTL 降到 60~300 秒,完成切換後再調回。
使用情境(具體場景)
-
新服務上線: 你要上線
billingAPI,只需在 DNS 新增一筆billing.prod.example.comCNAME 到infra.example.com,再在反向代理加 upstream,無須變更每台服務的 public IP。 -
多環境控管: 測試環境對外提供 demo 時,以
api.staging.example.com進入;正式環境使用api.prod.example.com,避免測試人員誤打正式資料庫。 -
安全內網: 監控與資料庫使用
grafana.internal、postgres.internal,只允許 VPN 內部解析與存取,外部 DNS 無法查到內部 IP。 -
跨區域部署: 亞太與歐美各自有入口,DNS 使用地理解析將使用者導向最近節點,降低延遲。
實作範例 / 設定範例
1) 公網 DNS 記錄(Cloudflare)
# cloudflare-dns.yaml
records:
- type: A
name: infra.example.com
value: 203.0.113.10
proxied: true
- type: CNAME
name: api.prod.example.com
value: infra.example.com
proxied: true
- type: CNAME
name: admin.prod.example.com
value: infra.example.com
proxied: true
- type: CNAME
name: "*.staging.example.com"
value: infra-staging.example.com
proxied: false2) 內網 DNS(CoreDNS)
# Corefile
internal:53 {
errors
log
hosts {
10.10.20.10 postgres.internal
10.10.20.20 redis.internal
10.10.30.10 grafana.internal
fallthrough
}
forward . 8.8.8.8
}3) 基礎防火牆規則(iptables 示意)
# 預設拒絕入站
iptables -P INPUT DROP
iptables -P FORWARD DROP
# 允許既有連線
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允許 loopback
iptables -A INPUT -i lo -j ACCEPT
# 允許 HTTPS/HTTP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 允許 VPN 網段 SSH
iptables -A INPUT -p tcp --dport 22 -s 10.10.0.0/16 -j ACCEPT
# 僅允許應用網段連 DB
iptables -A INPUT -p tcp --dport 5432 -s 10.10.10.0/24 -j ACCEPT4) 驗證指令與排查
# 查詢 DNS 解析
nslookup api.prod.example.com
# 測試內部 DNS
dig @10.10.0.2 grafana.internal +short
# 追蹤解析路徑
dig +trace api.prod.example.com
# 測試入口連線
curl -I https://api.prod.example.com/health常見問題與風險
-
網段衝突: 使用
192.168.1.0/24常與家用路由器衝突,VPN 進來後路由會混亂。建議使用較少見的10.10.x.x或172.20.x.x。- 如何避免:建立「公司網段白名單」,並在 VPN 或雲端 VPC 建立前即鎖定。
-
TTL 設太長: DNS 切換時,使用者仍可能連到舊 IP。解法是在遷移前 24 小時將 TTL 降到 60~300 秒。
- 為什麼會發生:DNS 由用戶端與 ISP 多層快取控制,TTL 太長就無法快速失效。
-
Wildcard 沒設好預設行為:
*.example.com太寬鬆會導致未知子網域被路由到預設站台,產生資訊外洩。應該設定 default server 回傳 444 或 404。- 避免方式:在反向代理設
default_server,並針對未知 host 直接拒絕。
- 避免方式:在反向代理設
-
入口單點故障: 只有一台入口機,掛掉就全掛。中期要規劃多入口或 health-check failover。
- 避免方式:使用雲端 LB 或 VRRP(Keepalived)搭配浮動 IP。
-
內外 DNS 混用: 公網 DNS 意外暴露內部 IP,容易造成安全風險。內網 DNS 應該獨立且不被外部解析。
- 避免方式:內部域名使用
.internal或私有 TLD,並禁止外網遞迴解析。
- 避免方式:內部域名使用
優點
- 命名一致,服務可快速定位與擴充
- 入口統一,流量管控與 TLS 管理更容易
- 網段分區清楚,安全邊界可控
缺點 / 限制
- 前期規劃成本高,需要盤點服務與用途
- DNS 不是即時系統,變更有延遲
- 固定 IP 與入口 HA 需要額外成本
落地檢查清單
- 網段是否已避免常見衝突(192.168.x.x)
- 是否定義子域名命名規則(服務 + 環境)
- 公網 DNS 與內網 DNS 是否隔離
- 固定入口是否有備援策略
- 防火牆規則是否以「最小權限」為原則