網路相關

【Cisco】Switch相關指令

LAB 2-1:Switch基本環境設定

清除Switch的組態設定
Switch>enable 
Switch#erase startup-config 
Switch#delete vlan.dat
Switch#reload

Switch設主機名稱
Switch#configure terminal 
Switch(config)#hostname lab2

console閒置設0分,啟用logging訊息輸出後自動換行功能
lab2(config)#line console 0
lab2(config-line)#exec-timeout 0  (閒置登出)
lab2(config-line)#logging synchronous  (訊息同步)

停用網域名稱反查
lab2(config-line)#exit
lab2(config)#no ip domain-lookup

設定界面資訊(description),雙工(duplex)模式及介面速度(speed)
lab2(config)#interface fastEthernet 0/12
lab2(config-if)#description TORouter
lab2(config-if)#duplex auto (預設auto)
lab2(config-if)#speed auto  (預設auto)
lab2(config-if)#exit

設定Switch IP及Gateway (L2 Switch訂IP管理用)
lab2(config)#interface vlan 1
lab2(config-if)#ip address 192.168.0.250 255.255.255.0
lab2(config-if)#no shutdown 
lab2(config-if)#exit
lab2(config)#ip default-gateway 192.168.0.254 (跨網段管理)

show 相關設定,存入NVRAM
lab2#show running-config 
lab2#show vlan 1
lab2#show interfaces fastEthernet 0/12
lab2#copy running-config startup-config 
LAB 2-2:Switch安全防護設定

設定Console及vty密碼
lab2#configure terminal 
lab2(config)#line console 0
lab2(config-line)#password console
lab2(config-line)#login 
lab2(config-line)#exit
lab2(config)#line vty 0 15
lab2(config-line)#password vty
lab2(config-line)#login
lab2(config-line)#exit

設定privileged mode的密碼並檢視
lab2(config)#enable password password
lab2(config)#enable secret cisco
lab2(config)#end
lab2#sh running-config

設定SSH
lab2#configure terminal 
lab2(config)#ip domain-name example.com
lab2(config)#crypto key generate rsa 
lab2(config)#username netadmin password netadmin
lab2(config)#ip ssh version 2
lab2(config)#line vty 0 15
lab2(config-line)#login local
lab2(config-line)#transport input ssh telnet

直接進入特權模式
lab2(config)#no username {netadmin}
lab2(config)#username {name} privilege 15 password {password}

啟用密碼加密服務
lab2#conf t
lab2(config)#service password-encryption 
lab2(config)#do show running-config | begin line

設定Login banner
lab2(config)#banner login >
  HI !!!! >
LAB 2-3:Port Security(防非法MAC存取)

 

Port security 只能針對Access mode的Port設定
enable port security
(Optional)設定最大MAC數量,預設 1 sh不顯示,Cisco設備預設值通常不顯示
違規時switch的動作violation{ shutdown預設 | restrict | protect}
1~4只防阻MAC Flooding攻擊,每一個port只能有1個MAC通過,但還不能防止非法MAC接到設備上,把合法MAC寫到table,只要MAC有錯port shutdown
在Switch上查看MAC-Address-Table
lab2#show mac-address-table (有些版本 show mac address-table)

將FA0/24啟用Port-Security功能,指定只學習一筆MAC資訊,使用Sticky方式學習到PC的MAC,並設定違規處理方式為Shutdown
lab2#configure terminal 
lab2(config)#interface fastEthernet 0/24  (多個Port可用range)
lab2(config-if)#switchport mode access  (將Port改成Access Mode)
lab2(config-if)#switchport port-security  (啟用Port Security)
lab2(config-if)#switchport port-security maximum 1  (設定最大的MAC數量)
lab2(config-if)#switchport port-security mac-address sticky 
lab2(config-if)#switchport port-security violation shutdown(預設,處理err-disabled)
或
lab2(config-if)#switchport port-security violation restrict  (合法MAC接回就會通)


range 多個Port要設定
lab2(config)#interface range fastEthernet 0/4 - 7 , fastEthernet 0/9 - 11
lab2(config-if-range)#switchport mode accesss

檢查所有界面的狀態(Port,Description Name,Status,Vlan,Duplex,Speed,Type)
lab2#sh interfaces status

檢查Switch上有哪些Port啟用Port-security
lab2(config-if)#do sh port-security

檢查Switch上有哪些Port有sticky或手動輸入合法MAC Address
lab2(config-if)#do sh port-security address

檢查Fa0/24的Port-security的詳細設定
lab2(config-if)#do sh port-security interface fastethernet 0/24

檢查Fa0/24的介面狀態(注意err-disabled)
lab2(config-if)#do sh int fa 0/24
            

將Fa0/24接另一台PC,因為Fa0/24有啟用Port-security,並將之前自動學習到的MAC以Sticky記錄,檢查Fa0/24的介面狀態會出現err-disabled:以下處理方法
lab2#sh int fa 0/24
FastEthernet0/24 is down, line protocol is down (err-disabled)
lab2#sh run | begin FastEthernet0/24
!
interface FastEthernet0/24
 switchport mode access
 switchport port-security
 switchport port-security mac-address sticky 
 switchport port-security mac-address sticky 0030.F22D.9A05
!
lab2#conf t
lab2(config)#int fa 0/24
lab2(config-if)#no switchport port-security mac-address sticky 0030.F22D.9A05
lab2(config-if)#do sh int fa 0/24
FastEthernet0/24 is down, line protocol is down (err-disabled)
lab2(config-if)#shutdown 
lab2(config-if)#no shutdown 
LAB 2-4:CDP與檔案備份練習

CDP查詢鄰近設備
lab2#sh cdp neighbors  (Device ID =>ro)
lab2#sh cdp entry ro

將Switch的fa0/3介面CDP功能關閉
lab2(config)#int fa 0/3
lab2(config-if)#no cdp enable

將設備dcp功能關閉
lab2(config)#no cdp run

將Switch的IOS與startup-config複製到TFTP
lab2#sh flash
lab2#copy flash tftp
lab2#copy running-config startup-config 
lab2#copy startup-config tftp

 

show 的使用
lab2#sh running-config | begin line
lab2#sh running-config | include line
lab2#sh interfaces status
lab2#sh mac address-table
#
#
#

 

【Fiddler】玩轉 Fiddler-HTTP(s) 抓包能手

玩轉 Fiddler-HTTP(s) 抓包能手 & 常見「特殊」用途

 

https://ryanlee.tw/2021/08/23/fiddler/

【Mac】透過console連接網路設備

需求:一條usb - console 線

image-1656036189511.png

接上後,打開終端機,使用screen 登入設備

#找到 console 線
ll /dev/tty.*
crw-rw-rw-  1 root  wheel    9,   0  6 22 22:26 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel    9,   2  6 24 09:58 /dev/tty.usbserial-A50285BI

#登入設備
screen /dev/tty.usbserial-A50285BI 9600

screen其他操作

退出後重連失敗

image-1656038788632.png

#找到screen pid
screen -list

There are screens on:
        15520.ttys004.Treeman-Mac       (Attached)
        9100.ttys003.Treeman-Mac        (Detached)
2 Sockets in /var/folders/px/8z7kvlwj5278qcf92c71q6_h0000gn/T/.screen.

#方法一 刪除socket 重新連線
#刪除sccket screen -X -S {pid} quit
# -X: 執行cmd, -S: screen socket name, quit: 離開
screen -X -S 9100.ttys003.Treeman-Mac quit
#在連線一次
screen /dev/tty.usbserial-A50285BI 9600

#方法二 使用screen pid.name重新連線
screen -R 9100.ttys003.Treeman-Mac

#方法三 重新連線上次中斷screen
screen -r

 

 

 

 

【zabbix】自定義通知(轉貼)

 

 開啟 https://notify-bot.line.me/zh_TW/

登入帳號後,下拉選項,選取「個人頁面」→「發行權杖」→「透過1對1聊天接收LINE Notify的通知」

之後就會得到一組權杖「Token」,這組Token務必要記錄下來,出現後便不再顯示

Zabbix Server端

 設定Scritp

sudo vi /usr/lib/zabbix/alertscripts/line_notify.sh

#!/bin/bash
# LINE Notify Token - Media > "Send to".
TOKEN="$1"

# {ALERT.SUBJECT}
subject="$2"

# {ALERT.MESSAGE}
message="$3"

curl https://notify-api.line.me/api/notify -H "Authorization: Bearer ${TOKEN}" -F "message=${message}"

sudo chmod 755 /usr/lib/zabbix/alertscripts/line_notify.sh
sudo chown zabbix:zabbix line_notify.sh

Zabbix Ui 設定

1. 「管理」→「示警媒介類型」→「創建示警媒介類型」

image-1656924835958.png

Name:Line Notify
Type:Script
Script name:line_notify.sh
Script parameters:
{ALERT.SENDTO}
{ALERT.SUBJECT}
{ALERT.MESSAGE}

2.「管理」→「用戶」→「Admin」→「示警媒介」→「新增」

image-1656924854811.png

Send to:填入上面步驟拿到的ˊTOKEN

3.「組態」→「動作」→「創建動作」

image-1656925027773.png

 

{HOST.NAME1}: {TRIGGER.STATUS}: {TRIGGER.NAME}
主機名稱: {HOSTNAME1}
發生時間: {EVENT.DATE} {EVENT.TIME}
警示等級: {TRIGGER.SEVERITY}
警示訊息: {TRIGGER.NAME}
警示項目: {TRIGGER.KEY1}
問題說明: {ITEM.NAME}: {ITEM.VALUE}
當前狀態: {TRIGGER.STATUS}: {ITEM.VALUE1}
事件ID: {EVENT.ID}

備註:Recovery operations 的欄位主旨和訊息都和這邊一樣

 

image-1656925062406.png

image-1656925084845.png

Recovery operations 的操作配置

image-1656925100227.png


配置完成後,進行測試

將監控主機關機,五分鐘後,LINE就會進行報警

image-1656925113010.png

出處:﹝Linux﹞Zabbix LINE Notify 警報通知 | 工程師的江湖 - 點部落 (dotblogs.com.tw)

學習相關連結

《网络工程师的Python之路》教学文章、视频汇总 - 知乎 (zhihu.com)

smokeping install

 

timedatectl set-timezone Asia/Taipei

install docker

curl -fsSL https://get.docker.com | bash -s docker

run smokeping in docker

mkdir -p /home/monitor/smokeping/config
mkdir -p /home/monitor/smokeping/data
chown -R monitor /home/monitor/smokeping/

systemctl enable docker
systemctl start docker

docker pull linuxserver/smokeping
docker run -d \
--name=smokeping \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Taipei \
-p 9080:80 \
-v /home/monitor/smokeping/config:/config \
-v /home/monitor/smokeping/data:/data \
--restart unless-stopped \
linuxserver/smokeping

fix config

路径 /home/monitor/smokeping/config/Targets

#!/bin/bash
docker rm -f smokeping

docker run -d \
--name=smokeping \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Taipei \
-p 9080:80 \
-v /home/monitor/smokeping/config:/config \
-v /home/monitor/smokeping/data:/data \
--restart unless-stopped \
linuxserver/smokeping

page

http://localhost:9080/smokeping/?target=InternetSites

https://www.ssvip.net/971.html

【DNS】台灣地區常用 DNS IP 整合表

🇹🇼 台灣地區常用 DNS IP 整合表:

業者 主用 DNS IP 備用 / 區域性 DNS IP 備註說明
中華電信 168.95.1.1 168.95.192.1 全台通用
台灣大哥大 203.73.24.1 203.73.25.1、61.31.233.1 固網與行動使用者常見 IP,會依區域調整
遠傳電信 (SeedNet) 139.175.1.1 139.175.55.244、8.8.8.8(Google DNS)、其他區域性如下: 官方資料來源 SeedNet
→ 北區 139.175.55.244 139.175.252.16 台北、桃園、新竹等
→ 中區 139.175.150.20 139.175.55.244 台中、彰化、南投等
→ 南區 139.175.10.20 139.175.55.244 高雄、台南、嘉義等
亞太電信 多沿用中華電信   建議手動指定 168.95.1.1
台固媒體 203.75.129.130 203.75.129.131 固定使用者常見 DNS

🌐 國際公共 DNS(可自由選擇):

服務商 主用 DNS IP 備用 DNS IP 備註
Google DNS 8.8.8.8 8.8.4.4 全球穩定快速
Cloudflare 1.1.1.1 1.0.0.1 快速且注重隱私
Quad9 9.9.9.9 149.112.112.112 防惡意網站 DNS
OpenDNS 208.67.222.222 208.67.220.220 可選擇家長過濾功能

【常見問題】通訊協定&port 在呼叫上的差異

以下是針對你提到的三種不同 URL 呼叫方式:

1. https://a.b.com:3000
2. http://a.b.com:3000
3. http://a.b.com

✅ 一、三種呼叫差異總覽

呼叫方式 協定 Port 是否加密 對 Nginx 的需求 常見用途
https://a.b.com:3000 HTTPS 3000 ✅ 是 listen 3000 ssl; 測試自訂 HTTPS port
http://a.b.com:3000 HTTP 3000 ❌ 否 listen 3000; 自訂 HTTP port 開發
http://a.b.com HTTP 80 ❌ 否 listen 80;(預設) 一般公開網站

✅ 二、為什麼會有差異?

1. 協定不同(HTTP vs HTTPS)

2. Port 不同(預設 vs 自訂)


✅ 三、Nginx 實際設定對應

1️⃣ 對應 https://a.b.com:3000

server {
    listen 3000 ssl;
    server_name a.b.com;

    ssl_certificate     /etc/nginx/certs/a.b.com.crt;
    ssl_certificate_key /etc/nginx/certs/a.b.com.key;

    location / {
        proxy_pass http://localhost:4000;
    }
}

🔒 加密連線,必須設定 ssl 與有效憑證。


2️⃣ 對應 http://a.b.com:3000

server {
    listen 3000;
    server_name a.b.com;

    location / {
        proxy_pass http://localhost:4000;
    }
}

🔓 明文傳輸,不需要 SSL 憑證。適用於測試環境或內網。


3️⃣ 對應 http://a.b.com

server {
    listen 80;
    server_name a.b.com;

    location / {
        proxy_pass http://localhost:4000;
    }
}

🌐 最常見的網站 HTTP 配置。不需帶 port。


✅ 四、連線行為對照表

使用者輸入網址 瀏覽器或 curl 發出的請求會去到哪裡?
https://a.b.com:3000 a.b.comport 3000(用 TLS)
http://a.b.com:3000 a.b.comport 3000(無加密)
http://a.b.com a.b.comport 80

✅ 五、常見錯誤與排查

問題 原因 解法
curl https://a.b.com:3000 報錯 TLS 你設定了 HTTPS,但 Nginx 未加上 ssl 或憑證有誤 加上 ssl 並設定憑證
只能用 http://a.b.com,其他都失敗 Nginx 只開 port 80,沒開 3000 增加對應 listen 3000 的設定
呼叫 http://a.b.com:3000 被拒絕 Server 未開啟該 port 檢查防火牆、Nginx、Docker 映射是否有允許 3000

✅ 六、總結:選擇哪一種?

使用場景 建議呼叫方式
內部開發測試 http://a.b.com:3000https://a.b.com:3000
正式站公開服務 https://a.b.com(預設 port 443)
Nginx 反向代理串接後端 視你要轉發的是 HTTP or HTTPS 及 port 而定

如你需要一份完整支援三種 port 的 nginx.conf 以及搭配 Express 的後端範例,我可以幫你整合好。需要嗎?

【常見問題】https 使用domain 與 ip 差異

好的,以下補上:


✅ 比較 https://a.b.comhttps://168.23.1.1 的差異

這兩者協定一樣(都是 HTTPS),但主機名稱(Host)差異會影響 SSL 憑證驗證、DNS 解析、與 Nginx 的設定行為


 差異對照表

項目 https://a.b.com https://168.23.1.1
協定 HTTPS(加密) HTTPS(加密)
主機名稱 網域名稱(FQDN) IP 位址
DNS 解析 會經過 DNS 解析 → IP 不經 DNS
SSL 憑證驗證 通常需要憑證中的 CN/SAN 包含 a.b.com 需要憑證中包含 IP 位址(不常見)
Nginx server_name 配置 server_name a.b.com; server_name 168.23.1.1;(不建議)或 _
常見用法 公網、正式站、內部網域皆可 測試、開發、內網 IP 使用
風險與限制 SSL 憑證驗證容易通過 一般憑證不支援 IP → 會出現 TLS 錯誤
信任憑證 可用 Let's Encrypt、商業憑證 除非特別申請 IP 憑證,否則會有警告

 SSL 憑證驗證差異舉例

https://a.b.com

https://168.23.1.1

 解法(不建議用於正式環境):

curl -k https://168.23.1.1  # 跳過憑證驗證(不安全)

✅ Nginx 設定差異

a.b.com 對應設定:

server {
    listen 443 ssl;
    server_name a.b.com;

    ssl_certificate     /etc/nginx/certs/a.b.com.crt;
    ssl_certificate_key /etc/nginx/certs/a.b.com.key;

    location / {
        proxy_pass http://localhost:3000;
    }
}

IP 直接連線時,通常會用:

server {
    listen 443 ssl;
    server_name _;  # 匹配所有 hostname(或不設定)

    ssl_certificate     /etc/nginx/certs/selfsigned.crt;
    ssl_certificate_key /etc/nginx/certs/selfsigned.key;

    location / {
        proxy_pass http://localhost:3000;
    }
}

🧨 若直接用 IP,也許不會觸發 server_name 對應,取決於 Nginx 設定順序與 SNI。


✅ 小結

URL 適用時機 憑證需求 風險
https://a.b.com 公網、正常使用 CN/SAN 需含 a.b.com 正常通過憑證驗證
https://168.23.1.1 內部測試或特例 憑證需含 IP 或自簽 容易驗證失敗、跳警告

 

✅Curl Domain 與 ip 的 差異

這是一個非常關鍵的細節問題,涉及到 HTTPS、Host Header、SNI(Server Name Indication),我們來完整拆解:


你提供的兩個請求:

curl https://a.b.com
curl https://168.23.1.1 -H 'Host: a.b.com'

看起來類似,實際上在底層行為非常不同


 核心差異一覽

項目 curl https://a.b.com curl https://168.23.1.1 -H 'Host: a.b.com'
連線 IP DNS 解析 a.b.com → IP 直接指定 IP 168.23.1.1
TLS SNI 傳送內容 a.b.com(🔑 用來選擇憑證) 168.23.1.1(🚨 TLS 層不包含 a.b.com
Host Header(HTTP 層) Host: a.b.com(由 curl 自動加) Host: a.b.com(你手動加)
SSL 憑證是否驗證成功? ✅ 通常會成功 ❌ 若憑證是發給 a.b.com 則會 mismatch
Nginx 是否能進到正確的 server ✅ 通常會進到 server_name a.b.com ❌ 取決於 SNI,可能進入 default server

 為何 TLS 憑證驗證會失敗?

 SNI 是什麼?

在兩種情況下比較:

curl https://a.b.com

curl https://168.23.1.1 -H 'Host: a.b.com'


Nginx 對這兩種請求的反應

server {
    listen 443 ssl;
    server_name a.b.com;

    ssl_certificate     /etc/nginx/certs/a.b.com.crt;
    ssl_certificate_key /etc/nginx/certs/a.b.com.key;

    location / {
        return 200 "hello a.b.com\n";
    }
}

server {
    listen 443 ssl default_server;
    server_name _;

    ssl_certificate     /etc/nginx/certs/default.crt;
    ssl_certificate_key /etc/nginx/certs/default.key;

    location / {
        return 200 "default server\n";
    }
}

測試結果:

測試指令 伺服器 block 命中 回傳內容 是否 SSL 通過
curl https://a.b.com server_name a.b.com hello a.b.com ✅ 是
curl https://168.23.1.1 -H 'Host: a.b.com' server_name _(default) default server ⚠️ 通常憑證不符(或需 -k

✅ 解法:讓 IP 請求也能通過 SSL

方法一:用自簽或專門支援 IP 的憑證

但大多數公開 CA(如 Let's Encrypt)不發給 IP 憑證

方法二:用 curl 忽略 TLS 驗證

curl -k https://168.23.1.1 -H 'Host: a.b.com'

方法三:讓 curl 傳送正確的 SNI(推薦)

curl --resolve a.b.com:443:168.23.1.1 https://a.b.com

✅ 總結

比較項目 curl https://a.b.com curl https://168.23.1.1 -H 'Host: a.b.com'
DNS 解析 ✅ 有 ❌ 無
TLS SNI a.b.com 168.23.1.1
Host Header a.b.com a.b.com
SSL 憑證驗證 ✅ 通常成功 ❌ 會失敗(除非用 -k
建議用法 ✅ 正常連線方式 ⚠️ 用於測試或模擬

如果你需要模擬真實請求又繞過 DNS,可使用:

curl --resolve a.b.com:443:168.23.1.1 https://a.b.com

這是最穩定且最貼近瀏覽器 SNI 行為的方式。

 

【PowerDNS】

Lua records

https://doc.powerdns.com/authoritative/lua-records/index.html

-- 返回请求方 IP
who:toString()

-- 根据请求方 IP 不同返回不同地址
view({
  {{'10.10.0.0/16'}, {'10.10.1.1'}}
  {{'0.0.0.0/0'}, {'192.0.2.1'}}
})

-- 返回存活的 IP
-- 异步检测 - 如果都不存活则都返回
ifportup(443, {'192.0.2.1', '192.0.2.2'})
-- 使用 URL 检测存活 - stringmatch 为可选的内容匹配条件
ifurlup("example.com/status", { {"192.0.2.20", "203.0.113.4"}, {"203.0.113.2"} },{stringmatch='ok'})

-- 基于请求方的 HASH(bestwho) 进行返回
pickwhashed({{10,'192.168.0.1'},{100,'192.168.0.2'}})
-- 随机返回 - 有带权重版
pickrandom({{'192.168.0.1'},{'192.168.0.2'}})
pickwrandom({{10,'192.168.0.1'},{100,'192.168.0.2'}})

pdnsutil

下面是 pdnsutil(PowerDNS 的指令工具,用於 DNS 區域與 DNSSEC 管理)的一份常用語法與操作範例教學。你可以把它當作 cheat-sheet 或操作對照表。
(若你的 PowerDNS 版本略有不同或後續改版,部分語法可能略有出入,建議搭配 man pdnsutil 或官方文檔確認) (doc.powerdns.com)


基本語法結構與通用選項

pdnsutil [OPTIONS] COMMAND [ARGUMENTS...]

常見的選項:

選項 說明
-h, --help 顯示協助訊息
-v, --verbose 輸出較詳細訊息
--force 強制執行(覆寫、跳過某些檢查等)
--config-name <NAME> 指定虛擬設定名稱
--config-dir <DIR> 指定 pdns.conf 所在目錄(預設 /etc/powerdns

常見區域 (zone) 管理指令

以下指令幾乎涵蓋新增、查看、編輯、刪除、檢查等需求。

功能 指令範例 說明 / 備註
建立區域 pdnsutil create-zone example.com 建立一個空的 zone example.com,內部會自動加入一条 NS 記錄 (blog.powerdns.com)
刪除區域 pdnsutil delete-zone example.com 將該 zone 從後端資料庫中移除
顯示區域內容 pdnsutil show-zone example.com 列出 zone 的所有 resource record 和 meta 資訊 (blog.powerdns.com)
列出區域 pdnsutil list-zone example.com 列出該區域的所有資料記錄 (blog.powerdns.com)
列出所有區域 pdnsutil list-all-zones 顯示所有已註冊的 zone 名稱 (Debian Manpages)
檢查單個區域 pdnsutil check-zone example.com 檢查該 zone 是否有錯誤(語法、衝突等) (cPanel Support)
檢查所有區域 pdnsutil check-all-zones 對所有 zones 執行檢查 (CloudWizard.nl)
編輯區域(交互式) pdnsutil edit-zone example.com 進入文字編輯介面,可以手動修改 zone 的所有記錄(系統會做基本檢查) (blog.powerdns.com)
增加記錄 pdnsutil add-record example.com sub A 3600 1.2.3.4 example.com 區域新增一條 A 紀錄: sub.example.com TTL 3600 指向 1.2.3.4 (blog.powerdns.com)
更新(替換)整組記錄 pdnsutil replace-rrset example.com sub A 3600 5.6.7.8 將 sub 的 A 類型記錄整組替換為新的值(如果有多條) (blog.powerdns.com)
刪除一組記錄 pdnsutil delete-rrset example.com sub A 刪除 sub 的所有 A 類型記錄(整個 RRset) (HackMD)
增加序號 pdnsutil increase-serial example.com 手動把 SOA 的 Serial 加一(通常在變更後需告知 slave) (CloudWizard.nl)
設定 zone 類型 pdnsutil set-kind example.com MASTER 設定該 zone 為主(zone master)、從(zone slave)或其他類型 (CloudWizard.nl)
設定 meta (zone metadata) pdnsutil set-meta example.com ALLOW-AXFR-FROM AUTO-NS 為該 zone 加上 metadata,例如允許哪些 IP 做 AXFR 等 (blog.powerdns.com)

DNSSEC / 金鑰 (key) 管理指令

如果你要為 zone 啟用 DNSSEC、管理金鑰或做 key rollover 等,這些指令就會派上用場。 (doc.powerdns.com)

功能 指令範例 說明 / 備註
啟用 DNSSEC(簽名 zone) pdnsutil secure-zone example.com 為該 zone 建立金鑰並簽名(預設配置) (doc.powerdns.com)
列出該 zone 的金鑰 pdnsutil list-keys example.com 顯示該 zone 所有的 KSK / ZSK 金鑰資訊 (SIDN - Het bedrijf achter .nl)
新增金鑰 pdnsutil add-zone-key example.com ZSK active 2048 rsasha256 為例:在 zone example.com 新增一組 ZSK 金鑰,256 RSA, 2048 位元長度。可調整參數。 (Debian Manpages)
啟用金鑰 pdnsutil activate-zone-key example.com 12345 啟用某一個金鑰(以其 key-id 為識別) (Debian Manpages)
停用金鑰 pdnsutil deactivate-zone-key example.com 12345 停用該金鑰(使其不再用於簽名) (Debian Manpages)
匯出公鑰與 DS 記錄 pdnsutil export-zone-ds example.com 匯出該 zone 所有 KSK 的 DS 記錄(可提交給上層域名註冊商) (SIDN - Het bedrijf achter .nl)
匯出金鑰 pdnsutil export-zone-key example.com 12345 匯出該 zone 指定金鑰(含私鑰)到檔案或標準輸出 (SIDN - Het bedrijf achter .nl)
移除金鑰 pdnsutil remove-zone-key example.com 12345 將指定金鑰從 zone 中移除(不再保留) (SIDN - Het bedrijf achter .nl)
停用 DNSSEC(取消簽名) pdnsutil disable-dnssec example.com 將 zone 還原為不使用 DNSSEC 狀態 (SIDN - Het bedrijf achter .nl)
修正 (rectify) zone 資料庫 pdnsutil rectify-zone example.com 重建 zone 在資料庫中的 internal 欄位(如 auth / ordername) (SIDN - Het bedrijf achter .nl)
修正所有 zone pdnsutil rectify-all-zones 對所有已存在的 zone 執行 rectify 操作 (SIDN - Het bedrijf achter .nl)

一些操作流程範例

以下是比較常見的操作流程,依步驟示範怎麼做:

範例:建立一個新的 zone 並設定記錄 + 啟用 DNSSEC

假設 domain 為 example.com

pdnsutil create-zone example.com
pdnsutil set-kind example.com MASTER
pdnsutil add-record example.com @ NS ns1.example.com.
pdnsutil add-record example.com @ NS ns2.example.com.
pdnsutil add-record example.com ns1 A 1.2.3.4
pdnsutil add-record example.com ns2 A 5.6.7.8
pdnsutil replace-rrset example.com . SOA 'ns1.example.com. hostmaster.example.com. 1 10800 3600 604800 3600'
pdnsutil secure-zone example.com
pdnsutil increase-serial example.com
pdns_control notify example.com

這樣做完後,你可以用 pdnsutil show-zone example.com 檢查結果。 (CloudWizard.nl)

範例:修改已有記錄

假設要把 www.example.com 的 A 紀錄從 1.2.3.4 換成 5.5.5.5

pdnsutil replace-rrset example.com www A 3600 5.5.5.5
pdnsutil increase-serial example.com
pdns_control notify example.com

或若要直接刪除 www 的 A 紀錄:

pdnsutil delete-rrset example.com www A
pdnsutil increase-serial example.com
pdns_control notify example.com

最後別忘了通知 slave 或其他 server 更新:pdns_control notify example.com


注意事項與建議

  1. 後端限制
    某些後端 (特別是 BIND 後端) 可能不支援修改操作(只能透過 zone transfer)或不支援 pdnsutil 操作。要確認你使用的後端是否允許這些操作。 (Reddit)

  2. 版本差異
    不同 PowerDNS 版本對於 DNSSEC 的預設邏輯、支援的演算法、金鑰長度限制等可能不同。建議查看你系統上 man pdnsutil 或官方版本對照表。 (Debian Manpages)

  3. 序號 (Serial) 管理
    在變更 zone 後,務必更新 SOA 的 serial(可用 increase-serial 或手動編輯 SOA)並通知 slave。否則 slave 可能不會接收到變更。

  4. 測試 / 錯誤檢查
    使用 check-zone / check-all-zones 來檢查語法或邏輯錯誤,以免上線後 DNS 無法解析。 (cPanel Support)

  5. 備份與金鑰匯出
    在做 DNSSEC 金鑰 rollover 或改動前,建議匯出金鑰備份(export-zone-key)及對 DS 記錄操作要小心,避免中斷解析鏈。

 


🧩 一、PowerDNS 查詢流程(簡化版)

當你執行:

dig app-wekan.momoshop.com.tw

時,PDNS 的查詢處理順序如下:

  1. 找 zone(domains 表)

    • domains.name 開始,找最匹配的 zone(例如 momoshop.com.tw)。

  2. 在 records 表中找符合的 name

    • 順序為:

      • 精確比對 name='app-wekan.momoshop.com.tw'

      • 如果找不到,則依序比對:

        • *.momoshop.com.tw

        • *.com.tw

        • *.tw

    • 每一層可能都會回傳多筆記錄。

  3. 根據 type 過濾

    • 只會選出符合查詢類型(例如 A)或可解譯的 LUA record。

  4. 若有 LUA 記錄,執行 Lua 腳本

    • 若多筆 LUA record,PDNS 會依「資料庫記錄順序(id 由小到大)」逐筆執行;

    • 直到第一筆成功產生合法的回應為止。

  5. 若多筆普通記錄(A, CNAME)

    • 全部回傳

    • 若 TTL 不同,取最小 TTL 為最終 TTL。

  6. 若無任何匹配

    • 回覆 NXDOMAINSERVFAIL(視 zone 與設定而定)。


🧠 二、LUA Record 的詳細執行順序

當 PDNS 找到多筆 type='LUA' 的記錄時:

順序 行為
1️⃣ 按照 id 由小到大排序
2️⃣ 依序執行每筆 LUA 程式
3️⃣ 第一個「有成功回傳記錄」的 LUA 結果會被採用
4️⃣ 若 LUA 執行失敗(語法錯誤或回傳空值) → 嘗試下一筆
5️⃣ 全部失敗 → 回 SERVFAIL

✅ 範例:

假設你有:

id | name               | type | content
---+--------------------+------+------------------------------------------
 1 | *.momoshop.com.tw  | LUA  | return getdns("10.2.1.11", qname, qtype)
 2 | *.momoshop.com.tw  | LUA  | return getdns("8.8.8.8", qname, qtype)

查詢 app.momoshop.com.tw 時:

👉 因此你可以用多筆 LUA record 來實作「多層 fallback」。


⚙️ 三、普通記錄(非 LUA)的多筆處理邏輯

若同一個 name 有多筆非 LUA 記錄(例如多個 A 記錄):

記錄 TTL IP
app.momoshop.com.tw 60 10.2.1.11
app.momoshop.com.tw 120 10.2.1.12

PDNS 會:

回覆結果:

app.momoshop.com.tw. 60 IN A 10.2.1.11
app.momoshop.com.tw. 60 IN A 10.2.1.12

🔍 四、查詢過程中,實際的比對順序(Wildcard / LUA 混合時)

PowerDNS 在有通配符與 LUA 混用的情況下,查詢順序如下:

優先順序 比對型態 是否執行 LUA
1️⃣ 精確比對(如 app.momoshop.com.tw 是(若 type=LUA)
2️⃣ wildcard 比對(如 *.momoshop.com.tw 是(若 type=LUA)
3️⃣ 更高層 wildcard(如 *.com.tw 是(若 type=LUA)
4️⃣ zone SOA / NS
5️⃣ 沒有符合 → NXDOMAINSERVFAIL  

🧩 五、如何查看 PowerDNS 真實回應順序

你可以用:

pdnsutil list-zone momoshop.com.tw

觀察記錄順序。
PowerDNS 的執行順序就是按照這個清單的排列(id遞增)。

若你要控制順序,可以直接修改 id 或刪除後重新新增。


🧪 六、測試方式建議

建立多筆 LUA fallback:

INSERT INTO records (domain_id, name, type, content, ttl)
VALUES
  (3, '*.momoshop.com.tw', 'LUA', 'return getdns("10.2.1.11", qname, qtype)', 60),
  (3, '*.momoshop.com.tw', 'LUA', 'return getdns("8.8.8.8", qname, qtype)', 60);

測試:

journalctl -u pdns -f &
dig @127.0.0.1 -p 5501 app.momoshop.com.tw

你會看到:

Executing LUA record id=1: getdns(10.2.1.11)
Failed: timeout
Executing LUA record id=2: getdns(8.8.8.8)
Success → returning result

🔚 結論摘要

類型 行為 回應方式
多筆 A 記錄 全部回傳 TTL 取最小
多筆 LUA 記錄 依 ID 順序執行 第一筆成功即返回
通配符 vs 精確匹配 精確優先於通配符  
LUA 與非 LUA 混用 LUA 先執行 若 LUA 無結果再回傳靜態記錄

是否要我幫你畫一張「PowerDNS 回應決策順序」的流程圖(含 fallback 流程)?
會清楚標出「多筆 LUA record 執行順序 → fallback 判斷 → 最終回應」。

【PowerDNS】Lua Records

這是一份 PowerDNS 官方文件的完整中文翻譯。
它說明了 LUA Record(Lua 動態記錄) 的用途、語法、應用範例、進階用法與安全注意事項。
我保留了原文段落結構與技術名詞,方便你比對。


🧩 PowerDNS — Lua Records 中文說明文件

一、概述

為了提供動態行為(例如全球負載平衡 Global Server Load Balancing),
PowerDNS Authoritative Server 自 4.2 版起 支援 動態 DNS 記錄(LUA Records)

這些記錄中包含了小段設定程式(Lua 程式碼),
可根據「查詢者 IP」、「EDNS Client Subnet」、「伺服器可用性」等因素,
動態決定要回應哪個 IP 或 CNAME。

功能範圍從簡單到複雜,
可實現多池(multi-pool)地理與權重負載平衡(Geo & Weighted Load Balancing)。

雖然使用者不必了解內部原理,
但 PowerDNS 的動態記錄本質上是 嵌入在 DNS 內的小型 Lua 腳本

💡 注意:
這是 PowerDNS 專屬功能,目前尚未成為 IETF 或其他標準機構的標準。
PowerDNS 官方承諾會致力於互通性,並希望最終能成為被廣泛支持的標準。

要啟用此功能,可在設定檔中加入:

enable-lua-records=yes

或對單一 zone 設定 metadata:

ENABLE-LUA-RECORDS=1

若要使用地理位置功能,請確認 launch 設定中包含:

launch=gpgsql,geoip

⚠️ 警告:
使用 AXFR 傳輸包含長 Lua 記錄的 zone 時,請確保每筆記錄內容(TXT 型態傳輸)
不超過 255 bytes。超過時會被分割成多段,導致次伺服器解析錯誤。


二、範例說明

1️⃣ ifportup()

www IN LUA A "ifportup(443, {'192.0.2.1', '192.0.2.2'})"

這會讓 www 這個名稱隨機回應 192.0.2.1192.0.2.2
前提是這些 IP 的 TCP 443 port 是開放的

若其中一個 IP 不再回應 443,則僅回傳另一個。
若全部都不通,則全部地址會被回傳。

多組 IP 可分優先層級,例如:

www IN LUA A "ifportup(443, {{'192.0.2.1', '192.0.2.2'}, {'192.0.3.1'}})"

這表示:

因為 DNS 查詢要求極快回應,PowerDNS 不會即時檢查連線狀態,
而是由背景程序定期檢測這些 IP 是否可用。


2️⃣ pickclosest()

www IN LUA A "pickclosest({'192.0.2.1','192.0.2.2','198.51.100.1'})"

這會根據查詢者的地理位置(GeoIP),
選擇最靠近使用者的 IP 回覆。

也可以與 ifportup() 結合:

www IN LUA A ("ifportup(443, {'192.0.2.1', '192.0.2.2', '198.51.100.1'}, {selector='pickclosest'})")

這會在可用的 IP 中挑出距離使用者最近的一個。


3️⃣ 複雜 Lua 程式碼範例

www IN LUA A ";if country('US') then return {'192.0.2.1','192.0.2.2','198.51.100.1'} else return '192.0.2.2' end"

可同時回傳單一字串或多筆字串(array)。


4️⃣ 使用 qname 的例子

*.example.net 10 IN LUA TXT "; return 'Got a TXT query for ' .. qname:toString() .. '; First label is: ' .. qname:getRawLabels()[1]"

注意:qtype 無法從 Lua 內直接取得(它是固定的)。
可使用預設變數(Preset Variables)取得其他查詢相關資訊。


三、在 SQL 後端使用 Lua Records

LUA Records 可與一般的 gmysql / gpgsql 通用 SQL 後端一起使用。

由於內容同時包含單引號與雙引號,
INSERTUPDATE 時需特別轉義。

範例如下:

-- 建立 zone
INSERT INTO domains (id, name, type) VALUES (1, 'example.com', 'NATIVE');

-- 啟用 Lua 記錄功能
INSERT INTO domainmetadata (domain_id, kind, content)
VALUES (1, 'ENABLE-LUA-RECORDS', 1);

-- 建立 pickclosest() 記錄
INSERT INTO records (domain_id, name, type, content, ttl)
VALUES (
  1,
  'www.example.com',
  'LUA',
  'A "pickclosest({''192.0.2.1'',''192.0.2.2'',''198.51.100.1''})"',
  600
);

這三筆 SQL:


四、LUA Record 格式

💡 名稱由來:
“Lua” 在葡萄牙文中意為「月亮」,不是縮寫
但 DNS 慣例記錄類型一律大寫,因此用 LUA

一筆 LUA Record 結構如下:

LUA <query_type> <Lua 程式>

例如:

www IN LUA A "pickclosest({'1.1.1.1','8.8.8.8'})"

五、更強大的範例

west IN LUA A ("ifurlup('https://www.lua.org/', {{'192.0.2.1', '192.0.2.2'}, {'198.51.100.1'}}, {stringmatch='Programming in Lua'})")

這會:

與地理導向結合:

www IN LUA CNAME (";if(continent('EU')) then return 'west.powerdns.org' else return 'usa.powerdns.org' end")

對應的 usa 名稱配置如下:

usa IN LUA A ("ifurlup('https://www.lua.org/', {{'198.51.100.1'}, {'192.0.2.1', '192.0.2.2'}}, {stringmatch='Programming in Lua'})")

歐洲以外的訪客會優先使用 198.51.100.1
若失效則回到 192.0.2.1 / 192.0.2.2


六、進階主題

(1) 語法模式

若記錄內容未以 ; 開頭,PDNS 會自動加上 return
若要撰寫完整 Lua 腳本,請以分號 ; 開頭。

(2) 可引用其他記錄的設定

可用 include() 引用共用設定:

config IN LUA LUA ("settings={stringmatch='Programming in Lua'} EUips={'192.0.2.1','192.0.2.2'} USAips={'198.51.100.1'}")

usa IN LUA A (";include('config') return ifurlup('https://www.lua.org/', {USAips, EUips}, settings)")
west IN LUA A (";include('config') return ifurlup('https://www.lua.org/', {EUips, USAips}, settings)")

七、安全與同步機制

⚠️ 警告:

若有 DNSSEC 簽章需求,
LUA Record 必須由主伺服器即時簽署(無法預先簽署 zone)。


八、共享 Lua 狀態模式(shared mode)

預設情況下,PDNS 每次查詢都會建立新的 Lua 執行環境。
這樣每筆 LUA Record 彼此獨立,不會污染變數。
但建立 Lua state 很耗時。

可啟用共用模式:

enable-lua-records=shared

九、Reference(函式與物件類別)

PowerDNS 提供的 Lua 內建 API 包含:

預設變數(Preset Variables)

可用函式

物件類別

(這些內容在官方文件的「LUA Reference」章節中詳細列出)


🔚 總結

功能 說明
LUA Record PowerDNS 內建的動態 DNS 回覆機制
語言 Lua
用途 智能選址、健康檢查、地理導向、服務偵測
啟用方式 enable-lua-records=yesENABLE-LUA-RECORDS=1
安全性 僅限信任 zone;建議使用 TSIG
效能優化 enable-lua-records=shared 可大幅提高 QPS

是否要我幫你把這篇翻譯版整理成 可直接放進公司內部 Wiki 的 Markdown 版(含語法高亮與範例區塊)
我可以自動加上標題層級、代碼框、注意區塊與翻譯對照欄位。

【PowerDns】dnsdist

傳遞來源ip
https://www.dnsdist.org/advanced/passing-source-address.html

addLocal("0.0.0.0:53")

-- Recursor 作為唯一後端
-- useClientSubnet=true 傳送ECS 來源端資訊 
newServer({ name="rec", address="127.0.0.1:5301", pool="recursor", useClientSubnet=true })

--設定ipv4顯示的位數 
setECSSourcePrefixV4(32)
setECSSourcePrefixV6(128)

-- 不加任何分流規則,全部都送 recursor
addAction(AllRule(), PoolAction("recursor"))