https://avatars.githubusercontent.com/u/6058558

程式狂想筆記

更新 WSL 後無法順利打開 Docker Desktop 解決方法

最近為了跑 CUDA Docker 服務,把 WSL 更新到新版,結果 Docker Desktop 直接打不開。

其實我平常不太敢亂升級,怕的就是這種「看起來只是更新,實際上整個開發流程卡住」的狀況。這次查了很久,最後找到一個看似不相關、但真的有效的修復方式,順手記錄下來,避免下次再踩一次。

深入解析 Nginx location 匹配規則

最近公司專案設定 API Gateway 無法順利導向後端 API 位置。檢查 Azure 的配置時發現,Azure 的路由規則是有上下順序的,但 Nginx 並不是這樣運作。經過研究才發現 Nginx 的 location 匹配規則和 Azure API Gateway 的邏輯完全不同,這裡就做個完整整理。 核心匹配順序 (從高到低) Nginx 在處理請求時,會遵循以下邏輯來決定最終使用的 location: 順序 修飾符 匹配類型 匹配規則與行為 1 = 精確匹配 全字串完全符合。一旦命中,立刻停止搜尋,直接採用此設定。 2 ^~ 前綴匹配 (阻斷) 如果該前綴是「最長匹配」,立即停止搜尋,不檢查正規表達式。 3 (無修飾符) 普通前綴匹配 尋找最長符合的前綴並暫存起來,但會繼續往下檢查正規表達式。 4 ~ / ~* 正規表達式 依據在設定檔中出現的先後順序比對。第一個命中的立刻停止搜尋。 一句話秒懂 「精確優先;最長匹配帶 ^~ 直接贏;否則交給正規表達式按順序比對(先到先得),全都沒命中才由最長前綴保底。」 完整的演算法決策流程 如果我們把 Nginx 的「大腦」拆解成三個階段,邏輯會變得非常清晰: 第一階段:前綴字串比對 (Literal/Prefix Strings) 檢查 = 精確匹配:如果有完全一致的 URI(例如 /index.html),直接採用並結束。 尋找最長前綴:找出所有普通字串(包含無修飾與 ^~)中,匹配長度最長的那一個。 判斷是否阻斷: 如果這個「最長匹配」帶有 ^~ 修飾符,Nginx 認為這已經足夠明確,會直接採用此設定並停止搜尋。 如果只是普通字串(無修飾),Nginx 會將此結果暫存起來作為備選方案,然後進入下一階段。 第二階段:正規表達式比對 (Regular Expressions) 按順序掃描 ~ 或 ~*:從設定檔由上往下逐行讀取。 只要有任何一個正規表達式成功匹配,就會立即採用此規則,並丟棄第一階段暫存的備選方案。 第三階段:最終終點 保底機制:如果所有的正規表達式都沒有匹配成功,Nginx 才會最後採用第一階段暫存的最長普通前綴。 實戰範例與差異對比 透過以下配置,你可以清楚看到不同修飾符帶來的行為差異:

主機跳板本機串接整合測試 API

在進行 OAuth 串接開發時,常會遇到「只有測試環境機器才能存取後端服務」的問題。這時要如何在本地端(Localhost)進行除錯與整合測試?

本文將分享一個實用的解決方案:透過 mkcertSSH Tunneling 以及 Reverse Proxy (Caddy) 的組合,在本地建立一個模擬真實環境的網路架構。

核心概念

當我們在本地開發時,往往無法直接連線到遠端的生產或測試環境 API。透過以下流程,我們可以將流量導向正確的地方:
前端 → Redirect 至後端入口 → 後端 → 目標服務

為什麼內網連内網對外 IP 會不通?淺談 NAT Loopback (Hairpin NAT) 運作原理

對於許多剛接觸網路架構或自建服務的工程師來說,設定 Port Forwarding (DNAT) 讓外部網路能夠存取內網的 Web 服務是家常便飯。然而,當我們嘗試「在內網環境中,直接透過外部 IP (Public IP) 連線到內網伺服器」時,卻常常會遇到一種詭異的現象:有些環境可以通,有些環境卻完全連不上。

最近這篇文章看到有人說這個問題。這讓我回想起自己的經驗:以前在家裡使用中華電信數據機加上 ASUS Router 時,設定好 DNAT 後,內網直接打 Public IP 就能無縫連上 Web 服務。但同樣的操作,在我朋友家那台企業級的 Fortigate 防火牆上卻行不通。

為什麼會有這樣的差異?答案其實藏在一個名為 NAT Loopback(或稱 Hairpin NAT、NAT Reflection)的路由器功能中。

Split DNS 架構整理與小實驗

在網路架構中,Split DNSSplit-horizon DNS 是這類技術的「總稱」。其核心目的在於:根據發出 DNS 查詢的來源(通常是 IP 位址),回傳相對應的解析結果。最常見的應用場景就是讓公司內網與外部網際網路的使用者,在查詢同一個網域名稱時,被導向不同的伺服器 IP。

sshuttle 一個免架設 VPN 的跳板代理工具

平常如果只是臨時要連內網服務,我大多會先想到 SSH Tunnel,通常用 -L-R-D 幾招就很夠用了。不過最近看到 sshuttle 這個工具,研究之後發現它滿有意思的。

它也是建構在 SSH 之上,但用起來比自己手動設定 Dynamic Port Forwarding 再加 SOCKS Proxy 更直接。某些情境下,你甚至可以把它當成「不用另外架 VPN Server,也能快速把指定網段流量送進遠端主機」的跳板工具。

用 Docker 讓 Transmission 自動補上公開 Tracker

有時候 BT 下載速度卡卡,不一定是種子本身的問題,也可能只是 Tracker 太少。最近剛好看到一個小工具,可以自動幫 Transmission 補上公開 Tracker,對於一些老種子或來源比較分散的任務來說,多少還是有幫助。

這篇就簡單記一下怎麼快速掛上去,順便補一下 Docker 環境下比較容易踩到的設定點。

DateTime.Parse 解析文字時間時區會遺失問題

最近接到一個專案,原本時間欄位大多使用 DateTime,但因為要串另外一套 API,對方是使用 DateTimeOffset。我原本以為只要 JSON 裡面有時間字串,應該就會連時區一起帶著走,結果實際追問題時,還真的踩到時間少了 8 小時的坑。

後來往下追,問題點其實就卡在 DateTime.Parse 這種「把字串重新轉回時間」的流程。尤其當字串裡本來就沒有時區資訊時,這一步很容易把原本上下文中的時區概念弄丟。

使用 mkcert 快速建立自簽憑證(Self-Signed Certificate)

常常在本機測試 HTTPS、Webhook、反向代理,或是模擬正式環境時,都會需要一組可以快速拿來用的自簽憑證。以前我自己也會手刻 OpenSSL 指令慢慢生,但後來用了 mkcert 之後,真的方便很多。

它最大的好處是,可以先在本機安裝一個受自己電腦信任的根憑證,後面要再簽出新的測試憑證時,就不用每次都重新匯入。這種做法在內部測試、開發環境,甚至臨時要掛到 Nginx、Kestrel、Traefik 時都很好用。

SSH Tunnel 三種方式備忘錄

最近要連某一台主機上的 Transmission 管理介面,Port 是 9091,但主機本身沒有直接對外開放這個 Port,所以最後還是得靠 SSH Tunnel 裡最常見的 Local Port Forwarding 來處理。

這個功能我以前就知道,只是通常久久才會用一次。每次要用的時候,又得重新想一次 -L-R-D 到底差在哪裡。既然這次剛好重新整理,就乾脆把重點記下來,之後自己複習也比較快。