2026年3月23日 星期一

在 Linux/Win 上用 Shell/powershell 函式自動更新 DuckDNS

在主機上自動更新 DuckDNS


前言

DuckDNS 是免費的 DDNS 服務,適合家用伺服器或 Raspberry Pi 等動態 IP 環境。本文介紹如何在 ~/.profile 中建立一個 Shell 函式,隨時手動執行更新,也可搭配 cron 排程自動執行。


前置作業

  1. 前往 duckdns.org 註冊並登入
  2. 建立一個子網域(例如 my-host
  3. 在頁面上方複製你的 token

Linux設定函式

編輯 ~/.profile,加入以下函式:

duckdns() {
    local result
    local domain="my-host"
    local token="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    result=$(echo url="https://www.duckdns.org/update?domains=${domain}&token=${token}&ip=&verbose=true" | curl -s -k -K -)
    local status=$(echo "$result" | head -1)
    local ip=$(echo "$result" | sed -n '2p')
    if [ "$status" = "OK" ]; then
        echo -e "\033[1;32m[OK] ${domain}.duckdns.org → ${ip}\033[0m"
    else
        echo -e "\033[1;31m[FAILED] ${domain}.duckdns.org update failed\033[0m"
        return 1
    fi
}

將 domain 和 token 替換成你自己的值。


使用方式

# 載入設定(僅首次需要,新開終端機會自動載入)
source ~/.profile

# 執行更新
duckdns

成功會顯示:

[OK] my-host.duckdns.org → 123.45.67.89


搭配 cron 自動排程

如果希望每 5 分鐘自動更新,執行 crontab -e 加入:

*/5 * * * * . $HOME/.profile; duckdns > /dev/null 2>&1


運作原理

  • 使用 DuckDNS API 的 verbose=true 參數,回傳更新狀態與實際註冊的 IP
  • 不帶 ip= 參數時,DuckDNS 會自動偵測請求來源 IP
  • 函式會驗證 API 回傳狀態,成功顯示綠色,失敗顯示紅色





Windows開機自動更新DDNS

在PowerShell中執行以下的函式註冊工作排程

先載入函式

function Register-DuckDNS {
    param(
        [Parameter(Mandatory)][string]$Domain,
        [Parameter(Mandatory)][string]$Token,
        [int]$Interval
    )
    Get-ScheduledTask -TaskName "DuckDNS_9615e983" -ErrorAction SilentlyContinue |
        Unregister-ScheduledTask -Confirm:$false
    $url      = "https://www.duckdns.org/update?domains=$Domain&token=$Token"
    $action   = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -Command `"Invoke-RestMethod '$url'`""
    $triggers = @(New-ScheduledTaskTrigger -AtStartup)
    if ($Interval) {
        $triggers += New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes $Interval) -RepetitionDuration (New-TimeSpan -Days 9999)
    }
    $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
    Register-ScheduledTask -TaskName "DuckDNS_9615e983" -Action $action -Trigger $triggers -Settings $settings -User "SYSTEM" -RunLevel Highest
}


或是從gist上抓取

irm https://gist.githubusercontent.com/hunandy14/c7fa21d0e2ad88a7443e9aef3010f89c/raw/Register-DuckDNS.ps1 | iex


然後註冊工作排程

Register-DuckDNS -Domain "duck-dns-domain" -Token "duck-dns-token"

重開機就會自動更新IP了


如果需要每5分鐘同步一次就添加 -Interval 5 進去
執行後會追加一個名稱固定不變的 DuckDNS_9615e983 排程
重複執行 Register-DuckDNS 會覆蓋同一個排程

(如果要多個排程自己從函式改名稱吧,刻意寫死是怕重複執行跑出一堆幽靈排程)



刪除排程

Unregister-ScheduledTask -TaskName "DuckDNS_9615e983" -Confirm:$false






2026年3月17日 星期二

Pnp.PowerShell 如何從IDCRL改用OAuth 2.0憑證登入

Pnp.PowerShell 如何從IDCRL改用OAuth 2.0憑證登入

記得先更新pnp到最新版本: CHG: Pnp.PowerShell 如何安裝 與 基本用法
以及參考上一篇文章創建應用程式: CHG: 2024-09-09 SharePoint 禁用帳密登入改動 如何使用Application應用程式登入

2026-05-01 即將停用委託登入了,再來強迫必須用證書登入了,在舊文章裡有說如何直接註冊應用程式+創建證書,這邊單獨講在現有的應用程式裡添加證書


這是生成證書的指令 (再次提醒 pnp 要更新到最新版本)

$params = @{
    CommonName          = "PnP_Rocks"
    ValidYears          = 10
    OutPfx              = "./secrets/PnP_Rocks.pfx"
    OutCert             = "./secrets/PnP_Rocks.cer"
    CertificatePassword = ConvertTo-SecureString -String "<YourPassword>" -AsPlainText -Force
}; New-PnPAzureCertificate @params

CertificatePassword 是可選項可以不設就空白密碼,要設記得改成自己的密碼

生成之後把 PnP_Rocks.cer 上傳到應用程式上就可以用了



連接方式有幾種這個是從檔案直接連(以檔案方式儲存比較不安全)

Connect-PnPOnline -Url "https://<tenant>.sharepoint.com/sites/<SiteName>" `
  -ClientId "<YourClientId>" `
  -Tenant "<tenant>.onmicrosoft.com" `
  -CertificatePath "./secrets/PnP_Rocks.pfx" `
  -CertificatePassword (ConvertTo-SecureString "<YourCertPassword>" -AsPlainText -Force)

這個是加到信任區之後用指紋連接 (這才是真正安全的方式)

Connect-PnPOnline -Url "https://<tenant>.sharepoint.com/sites/<SiteName>" `
  -ClientId "<YourClientId>" `
  -Tenant "<tenant>.onmicrosoft.com" `
  -Thumbprint "<YourCertThumbprint>"

這樣就可以應付 5/1 的改版了




關於權限限縮的問題用 Sites.Selected 可以限制僅能單一網站,下面是範例。

先到應用程式中新增該權限


然後再用超級管理員設置App允許哪些網站 (目前只能用 pnp.powershell 設置的樣子)

# 用管理員帳號 DeviceLogin 登入
Connect-PnPOnline -Url "https://<tenant>.sharepoint.com/sites/<SiteName>" -Interactive -ClientId "<YourClientId>"

# 授權 App 只能存取指定網站
Grant-PnPAzureADAppSitePermission -AppId "<YourClientId>" -DisplayName "<AppName>" -Site "https://<tenant>.sharepoint.com/sites/<SiteName>" -Permissions Write

這樣就可以指定該APP僅允許操作哪些網站


然後如果要把憑證加入憑證商店用下面的指令

$params = @{
    FilePath          = "./secrets/PnP_Rocks.pfx"
    CertStoreLocation = "Cert:\CurrentUser\My"
    Password          = ConvertTo-SecureString "<YourCertPassword>" -AsPlainText -Force
}; Import-PfxCertificate @params

匯入後會自動顯示指紋,用那個指紋就能登入了

要直接看指紋的話是這個指令

(New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("./secrets/PnP_Rocks.pfx", (ConvertTo-SecureString "<YourCertPassword>" -AsPlainText -Force))).Thumbprint







2026年1月20日 星期二

WinScp 如何以 sudo 權限登入複製 root 權限的檔案

WinSCP 如何以 sudo 權限登入複製 root 權限的檔案

首先要先確保可以無密碼使用 sudo 由於無法保存密碼,這個沒有任何替代方案是最後的妥協了,然後再到 WinSCP 中設置 SFTP 伺服器用 sudo su -c 執行 sftp-server 即可。



Step1: 設置免密碼 sudo 指令

輸入以下命令打開編輯器

sudo visudo

在檔案最後加入一行

<你的使用者4名稱> ALL=(ALL) NOPASSWD: ALL

然後存檔即可。重新登入後 sudo 就不需要密碼了



Step2: 設置 WinSCP 用 sudo 登入

搜尋 sftp-server 位置

find /usr -name "sftp-server" -type f

在 wsl 中位置是 /usr/lib/openssh/sftp-server 。


在 WinSCP 站臺進階設定 > SFTP 的頁面中,找到 SFTP 伺服器這一欄



貼上以下命令 (後方路徑自行修改成剛剛查到的位置)

sudo su -c /usr/lib/openssh/sftp-server

然後確定後登入就是有 root 權限的 WinSCP 了