我鄉下老家的樹莓派 Pi 位於防火牆內網, 我是利用一個 Python 程式 reportip3.py 定期傳送其外網 IP 到我的 Telegram, 這樣我就能遠端連線 Pi 3, 此外 Pi 3 上用 Nginx+uWSGI 與 PHP 架設的網站也能用 Port forward 開啟 80 埠從遠端訪問, 參考 :
只是每次都要查看目前 IP 有點小煩. 最近搞定了 Mapleboard 的網站設定後, 就想在 Pi 上設定動態網域網址.
首先檢查路由器有沒有支援 DDNS, 鄉下的 Pi 3 是透過信舟 Edimax BR-6228nS 無線路由器上網的, 其管理網址是 192.168.2.2, 輸入帳密登入後, 切到 WAN/DDNS 頁面, 點選啟用後在 "提供" 下拉式選單可看到所支援的 DDNS 服務 :
但是我詢問 AI 意見後才知這些資訊都太舊, 很多已經消失了, 建議我使用 NO-IP 或 DuckDNS 提供的服務, 其中 DuckDNS 不需要路由器支援, 可用 crontab 定時更新 IP, 所以決定用 DuckDNS.
一. 註冊 DuckDNS 網域 :
連線 DuckDNS 官網 :
可用 Twitter/GitHub/Gmail 帳號登入, 我使用 Gmail, 按底下的 reCapcha 鈕進入設定頁 :
上方框的 token 是更新 IP 的指令要用的, 請記下來備用; 然後於下方框的 sub domain 欄位輸入想要的子域名, 例如我是用 tony1966, 那我的域名就是 http://tony1966.duckdns.org, 按 add domain 鈕若顯示 success 表示成功取得此子網域 :
二. 在樹莓派上建立更新 IP 的腳本 :
接下來開啟樹莓派終端機, 在使用者根目錄下新增一個資料夾例如 duckdns :
218.173.4.183pi@raspberrypi:~ $ mkdir duckdns
切換到 duckdns 資料夾 :
pi@raspberrypi:~ $ cd duckdns
用 nano 編輯一個 bash 指令稿 duck,sh :
pi@raspberrypi:~/duckdns $ nano duck.sh
輸入如下指令 :
echo url="https://www.duckdns.org/update?domains=你的子網域&token=你的token&ip=" | curl -k -o ~/duckdns/duck.log -K -
按 Ctrl+O 儲存後按 Ctro+X 跳出 nano, 然後用 chmod 指令將其權限改為可執行 :
pi@raspberrypi:~/duckdns $ chmod +x duck.sh
可用 bash 指令手動執行此指令稿 :
pi@raspberrypi:~/duckdns $ bash duck.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2 0 2 0 0 1 0 --:--:-- 0:00:01 --:--:-- 1
這表示執行 duck.sh 後, DuckDNS 有收到請求並回覆了 "OK", 這表示更新 IP 成功 (就算 IP 沒變也算成功). 此 shell 指令稿執行過一次後就會在目前目錄下產生日誌檔 duck.log :
pi@raspberrypi:~/duckdns $ cat duck.log
OK
顯示 OK 表示已成功更新 IP.
三. 設定 crontab 定時更新 IP :
用 crontab -e 指令編輯排程 (要用 pi 使用者, 不是系統排程不要用 sudo ), 輸入下列指令 :
*/5 * * * * /home/pi/duckdns/duck.sh >/home/pi/duckdns/duck.log 2>&1
按 Ctrl+O 存檔再按 Ctrl+X 跳出 nano.
pi@raspberrypi:~/duckdns $ crontab -e
crontab: installing new crontab
可以用下列指令查詢 Crontab 執行日誌最近 50 筆資料 :
grep CRON /var/log/syslog | tail -n 50
pi@raspberrypi:~/duckdns $ grep CRON /var/log/syslog | tail -n 50
... (略) ...
Aug 5 13:40:01 raspberrypi CRON[16635]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 13:45:01 raspberrypi CRON[16671]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 13:50:01 raspberrypi CRON[16698]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 13:55:01 raspberrypi CRON[16749]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 14:00:01 raspberrypi CRON[16817]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 14:00:01 raspberrypi CRON[16816]: (root) CMD (/usr/bin/python3 /home/pi/reportip5.py)
Aug 5 14:00:01 raspberrypi CRON[16818]: (root) CMD (sudo /usr/local/bin/checkwifi.sh)
Aug 5 14:00:07 raspberrypi CRON[16804]: (CRON) info (No MTA installed, discarding output)
Aug 5 14:05:01 raspberrypi CRON[16863]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 14:09:01 raspberrypi CRON[16888]: (root) CMD ( [ -x /usr/lib/php/sessionclean ] && if [ ! -d /run/systemd/system ]; then /usr/lib/php/sessionclean; fi)
Aug 5 14:10:01 raspberrypi CRON[16946]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 14:15:01 raspberrypi CRON[16975]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 14:17:02 raspberrypi CRON[16999]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
Aug 5 14:20:01 raspberrypi CRON[17022]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
Aug 5 14:25:01 raspberrypi CRON[17051]: (root) CMD (~/duckdns/duck.sh >/dev/null 2>&1)
四. 確認 DNS 網址站是否可連線 :
連線上面獲得的網址 http://tony1966.duckdns.org 會顯示我之前測試 Nginx+uWSGI 時在預設網站下放的測試網頁, 因為是 HTTP 協定, 所以瀏覽器會先出現不安全連線警告 :
按左下角的 "繼續造訪網站" :
哈哈! 又看到多年前學 jQueryUI 時的熟悉畫面啦!
2025-08-25 補充 :
設定好三周以來發現第二周時 Pi 3 的 IP 有變, 但 DuckDNS 上的 IP 卻沒有同時異動, 導致網站連不上, 直到今天才有時間檢查, 發現是 crontab 裡 path 中使用了 ~/, 它不會被展開以至於找不到此 sh 檔, 正確做法應該是使用絕對路徑 /home/pi/duckdns/duck.sh 才對, 約 5 分鐘後網站就可連上了. 上面的筆記已修正.









沒有留言 :
張貼留言