從實務經驗重新認識 TLS

因為工作需要部署 grafana,重新認識了 TLS 的流程,藉此機會把學習過程紀錄下來。 主要分為理論與案例分享兩個大章節,理論章節主要是在講「應該要知道但學過就會忘」的內行,案例分享則為這一次部署 grafana 時的經驗分享。 理論 介紹 TLS 是什麼 TLS(Transport Layer Security,傳輸層安全協議)是用來保護互聯網通訊安全的協議。它能夠確保數據在互聯網上傳輸過程中的機密性、完整性和真實性。TLS 是從 SSL(Secure Sockets Layer)發展而來的,因此我們可能也可以把它稱為 SSL/TLS。 為什麼需要 TLS 在現代互聯網環境中,數據安全性變得至關重要。無論是電商、網路銀行或是社交平台,都需要確保用戶的機敏資訊不會被攔截或篡改。TLS 可以加密通訊內容,防止第三方竊聽,並且能驗證通訊雙方的身份,防止中間人攻擊(MITM)。 TLS 的應用場景 TLS 被廣泛應用於各種需要保護數據傳輸的場景,包括但不限於: 網站和應用程式的 HTTPS 通訊 電子郵件的加密傳輸(如 SMTPS、IMAPS、POP3S) VPN 通訊 即時消息應用程式 各類雲服務和 API TLS 基本概念 公鑰加密和私鑰加密 公鑰加密和私鑰加密是 TLS 的基礎。每個參與通訊的實體都擁有一對密鑰:公鑰和私鑰。公鑰是公開的,任何人都可以用來加密訊息,而私鑰是保密的,只有擁有者可以用來解密訊息。這樣的機制確保了即使加密訊息被攔截,也只有擁有私鑰的人能夠解密,細節可以回顧密碼學或計算機概論。 對稱加密和非對稱加密 對稱加密使用相同的密鑰來加密和解密數據,而非對稱加密則使用一對密鑰(公鑰和私鑰)。TLS 結合了這兩種加密方式:在握手階段使用非對稱加密來安全地交換對稱加密的密鑰,之後的通訊則使用對稱加密來提高效率。 數位證書和證書授權機構(CA) 數位證書是用來證明公鑰擁有者身份的電子文件,通常由證書授權機構(CA)簽發。證書包含公鑰、擁有者訊息以及 CA 的數字簽名。瀏覽器和其他應用程式可以驗證證書的真實性,確保通訊對象的身份。 數位證書的主要類型有: 域名驗證(DV)證書:僅驗證域名的所有權。 組織驗證(OV)證書:除了驗證域名,還驗證組織的合法性。 擴展驗證(EV)證書:提供最高級別的驗證,包括嚴格的身份檢查,瀏覽器地址欄顯示綠色的公司名稱。 TLS 的工作原理 握手過程(Handshake Process) TLS 握手過程是建立安全連接的第一步,確保通訊雙方能夠安全地交換加密訊息。握手過程大致分為以下幾個步驟: 客戶端問候(Client Hello):客戶端發送一個問候消息給伺服器,包含支持的 TLS 版本、加密算法、隨機數和其他必要訊息。 伺服器問候(Server Hello):伺服器回應客戶端的問候消息,選擇一個加密算法,並發送伺服器的隨機數。 伺服器證書(Server Certificate):伺服器發送其數位證書給客戶端,用於驗證伺服器的身份。證書包含伺服器的公鑰和由 CA 簽名的證書。 密鑰交換(Key Exchange):伺服器和客戶端交換密鑰訊息,使用非對稱加密算法(如 RSA、ECDHE)安全地生成會話密鑰。這個會話密鑰將用於之後的對稱加密通訊。 加密通訊(Encrypted Communication):客戶端和伺服器使用協商好的會話密鑰進行加密通訊。這確保了後續的數據傳輸是安全的。 以 TLS 1....

2024-06-22 · 10 min · 2085 words

透過 throughput 與 latency 的關係解決高延遲問題

在軟體工程中,我們常會面臨服務 high latency 的問題,而要解決這個問題,理解 throughput 與 latency 的關係是關鍵。 名詞定義 什麼是 throughput 與 latency? latency:指從 server 收到請求到回應的時間,通常以毫秒為單位計算。latency 越低,代表回應速度越快。 throughput:指 server 在特定時間內處理的請求數量,通常以每秒請求數(RPS 或 QPS)表示。throughput 越高,代表 server 處理能力越強。 server 如何工作 server 接收請求後,由一個或多執行緒(threads)處理請求並生成回應。單執行緒 server 一次只能處理一個請求,而多執行緒 server 可以同時處理多個請求。 舉例說明:自助洗衣店 latency:從顧客開始操作洗衣機到洗衣完成的時間。這包括顧客等候空閒洗衣機的時間,以及實際洗衣的時間。等候時間越長,latency 越高。 throughput:洗衣店每小時完成的洗衣次數。洗衣機數量越多,洗衣店能處理的顧客數量越多,throughput 越高。 latency 與 throughput 的關係 latency 與 throughput 之間存在緊密的關係,通常在系統負載增加時,latency 也會增加。當請求數量超過 server 的處理能力時,請求會被排隊等待處理,這就是 queueing latency。 例如,一個洗衣店有四台洗衣機,每台洗衣機需要30分鐘來完成一輪洗衣。當顧客數量增加,所有洗衣機都在運作時,新來的顧客需要等候空閒洗衣機,這樣就產生了 latency。如果每小時來的顧客數量超過洗衣機的處理能力,就會導致顧客排隊等候,latency 增加。 解決方法 增加處理能力:增加洗衣機的數量,提升洗衣店的最大 throughput。 增加洗衣機數量或開設更多分店,可以有效提升最大 throughput,減少顧客等候時間。 優化內部處理:降低單個洗衣過程的時間,減少內部 latency。 通過使用更高效的洗衣機,縮短洗衣時間,可以降低單次洗衣的時間。 實例分析 假設一個洗衣店有四台洗衣機,每台洗衣機需要30分鐘來完成一輪洗衣。當每小時來的顧客數量增加到5人時,洗衣店的最大 throughput 為每小時8人次,因此新來的顧客需要排隊等候空閒洗衣機,導致 latency 增加。通過增加洗衣機數量,可以提高洗衣店的最大 throughput,減少顧客排隊等候,降低 latency。...

2024-06-16 · 2 min · 251 words

基於 Golang 的 Grafana Dashboard 與 JWT 認證的前後端實作

在工作上有一個需求是需要做一些 OLAP,原訂計畫是使用 Google Looker(ver. Google Cloud Core),礙於量小不符合經濟效益,決定用 Grafana 這個較熟悉的開源套件來幫助我們做視覺化的處理。 這篇文章的範例可以在 omegaatt36/grafana-embed-example 中找到所有的 source code 我的 Use Case 為已經有一組 SHA512 產生的 Key,以下的內容為使用 HS512 進行簽名與認證。 流程 sequenceDiagram autonumber participant U as User participant B as Browser participant I as iframe participant S as Server participant G as Grafana rect rgb(236,239,244) U->>B: Open Web Page B->>S: Request JWT Token S->>B: Return JWT Token B->>I: Load iframe I->>G: Request Dashboard with JWT Token G->>I: Return Dashboard I->>B: Display Dashboard in iframe B->>U: Show Dashboard end Grafana 配置 主要是針對 grafana....

2024-06-10 · 5 min · 959 words

從 vuepress 遷移到 hugo 的心得

前言 在網頁開發中,選擇合適的靜態網站生成器非常重要。過去我們使用 VuePress 來建立部落格網站,但在使用過程中遇到了一些痛點,最終決定遷移到 Hugo。本篇文章分享遷移過程中的一些心得。 當初選擇 VuePress 而非 Hugo 的原因 最初想要撰寫部落格時,已經有再 hugo 與 vuepress 間做選擇,當時覺得 hexo 與 hugo 實在是爛大街了,想要一些與眾不同的體驗。 選擇 VuePress 是基於以下幾點考量: 朋友推薦,他是一名資深前端工程師,是 vuepress core-team 成員。 僅需要撰寫 markdown,便能產生靜態的部落格。 使用 theme plugin,可以方便的美化部落格,僅需要專注在內容的撰寫,不需要操心部落格是不是白底黑字而已。 使用 VuePress 的痛點 起初我所使用的 theme plugin 為 vuepress-theme-reco(1.x),並且搭配 vuepress 1.x 來進行建構。或是 vitepress,然而,在使用 VuePress 的過程中,我們也遇到了一些問題: 構建速度 我的部落格是無付費的使用 Netlify 進行託管,使用 vuepress 進行建構總是會花超過三分鐘,當進行 pr 的 preview build 時將會耗費大量的執行時間。 版本更新 過了一兩年,vuepress 官方開始推動 vuepress next(2.x),vuepress-theme-reco 的作者也著手更新 next(2.x) 版本。期間從 alpha 版本到 beta 版本,當 vuepress 與 theme plugin 有 API 不同不的問題,就容易導致 build failed,這個情況到了 rc 版本也沒有改善。...

2024-06-10 · 2 min · 239 words

使用內建的 rsync 備份 Truenas Scale 到 Proxmox Backup Server

前言 過去我會使用 backup script 配合 crontab 來定期的備份 nas 的資料,這次更換了 Proxmox Backup Server 的物理機後,多了一個硬碟的空間好讓我實驗 Truenas Scale 的備份機制。 差異 rsync 本身並沒有 server/client 的概念,只有 source 與 destination。 過去我會在備份主機上透過 samba 來 mount Nas 到資料夾內,檢查有沒有 mount 成功才在備份主機上使用 rsync。 而 Truenas Scale 提供的 Data Protection 功能中,內建了 Rsync Tasks 模組,透過預先建立好的 ssh credential 來呼叫備份主機進行 rsync。 同樣都是由備份主機來進行 rsync,主要是任務的執行呼叫是 Truenas Scale 本身還是備份主基本身。 在 Truenas Scale 上建立備份任務 建立 SSH Pair 首先到 Credentials -> Backup Credentials 的頁面 點擊 SSH Configurations 中的 Add...

2024-05-19 · 1 min · 174 words

用 testcontainers 在本地開發 Go 應用程式

介紹 使用 testcontainers 是在本地開發 Golang 應用程式的一個高效方式。這可以讓我們在不需要依賴外部環境的情況下,模擬應用程式在實際生產環境中的運行狀況。 安裝 testcontainers 在 Go 專案中,我們可以通過以下指令來導入 testcontainers go get github.com/testcontainers/testcontainers-go 透過 Redis 實踐一個 rate limiter package user type Limiter struct { client *redis.Client limit int limitPeriod time.Duration // 1 hour for limitPeriod counterWindow time.Duration // 1 minute for example, 1/60 of the period } func NewLimiter(client *redis.Client, limit int, period, expiry time.Duration) *Limiter { return &Limiter{ client: client, limit: limit, limitPeriod: period, counterWindow: expiry, } } func (r *Limiter) AllowRequest(ctx context....

2024-05-19 · 3 min · 474 words

透過 Distrobox 解決 Linux 環境依賴問題

前言 自從一年前嘗試使用 KDE Neon 後,主要的桌面開發環境就從 wsl 整個遷移到 Linux 上。這一年來感受到,KDE Neon 可能正如 reddit 上的留言闡述的那樣,只是 KDE 團隊的「實驗場」,可以享受到「最」新的 Plasma 與「較」新的 Kernel,卻始終是基於 Ubuntu 22.04 LTS,即便 Ubuntu 24.04 LTS 推出之際,也不再讓我感受性感。 因緣際會,在 Ubuntu 24.04 LTS 發布之際,我決定從 KDE Neon distro hopping 到 OpenSUSE Tumbleweed,這是一個由 SUSE 公司推出的滾動式發行版,軟體包在 SUSE 測試過後便會推送到 OpenSUSE 的 Repo(其他 OpenSUSE 的功能省略)。這次的轉換主要是為了獲得最前沿的 Linux 體驗。OpenSUSE Tumbleweed 的滾動更新模式能確保我始終使用最新的軟體和技術,這對我來說是一個有趣的選擇,即便有可能收到有問題的 xz 更新 XD。 ❯ fastfetch ...... raiven@raiven-suse .,cdxxxoc,. .:kKMMMNWMMMNk:. ------------------ cKMMN0OOOKWMMXo. A ;0MWk:' ':OMMk. OS: openSUSE Tumbleweed 20240517 x86_64 ;WMK;' 'lKMMNM, :NMK' 'OMW; Host: FMV UH-X cMW; WMMMN ,XMK' oMM....

2024-05-18 · 6 min · 1213 words

如何不啟動 container 從 image 中提取可執行檔

::: info 雖然文章內大多指令都是使用 docker,但由於是標準的 OCI image,使用 Podman 也是一樣的效果。 ::: 某段時間內,我會將所有需要執行的 binary 使用 containerize 給打包起來執行,例如: 需要將前端環境給跑起來,我會啟動一個 node 環境的 container: docker run --rm -it --name f2e --net=host -v $(pwd):/app \ docker.io/library/node:20-bookworm \ bash 需要安裝某個基於 golang 的 cli 工具,會使用自己寫的腳本,在 container 內進行建構。 需要透過 Liquibase 來進行 db migration,並不會選擇在本地安裝 maven 環境,一樣是啟動一個 container 來執行。 這麼做的好處是,「目前」大多數的 server/cli tools 至少會編譯 x86 架構下的可執行檔,我只需要確保 container 環境內可以工作,就可以在不同硬體的開發環境下游走。極度偏激的來說,無法確保安裝的 binary 有沒有受過污染,無論開源或閉源與否,也可以透過 Podman 來啟動 rootless 的 container 確保本機的安全。 但有時候會遇到別人打包的 image 十分肥大,即便程式可執行檔只需要幾 MB,編譯後的 image 確有幾百 MB(大多數是腳本語言),蒙生了從 image 中提取 executable 的想法,藉此也學習 docker layer 間的關係。...

2024-04-14 · 4 min · 806 words

如何利用 Open Policy Agent 配合 Golang 建構彈性的 RBAC 模組

RBAC 概念簡介 在我們探討如何利用 Open Policy Agent (以下簡稱 OPA) 和 Golang 建立一個彈性的 RBAC 模組之前,先讓我們來了解一下 RBAC的基本概念。 RBAC(Role-Based Access Control,基於角色的訪問控制)是一種廣泛應用的訪問控制策略,在軟體安全性領域尤為重要。其核心思想是將系統訪問權限與用戶的角色(職位、責任或職務)關聯起來,而不是直接與個別用戶關聯。這意味著訪問權限被捆綁到角色上,然後將用戶分配給這些角色。舉個例子,一個「管理員」角色可能有權訪問系統的所有資源,而「員工」角色則只能訪問特定部分的資源。 RBAC 的主要優勢在於其靈活性和簡化的權限管理。當需要變更權限時,只需修改角色的訪問權限,而不需要為每個用戶單獨設定。這不僅使權限管理更為高效,也減少了錯誤配置的可能性,提高了整體的系統安全性。 在實踐中,RBAC 允許創建精細且靈活的策略,以滿足複雜的商業和安全需求。無論是大型企業還是小型團隊,RBAC 都提供了一個可靠的框架,來確保正確的用戶擁有適當的訪問權限,從而保護關鍵資源免受未授權訪問。 可以參考 Cloudflare 的文章,簡單來說就是什麼「角色」能夠對什麼「資源」做什麼「操作」。 Open Policy Agent (OPA) 介紹 OPA 是一個「Strategy as Code」的開源專案,專門設計用於統一地管理和執行跨不同系統的策略。它不僅提供了一個高級的策略語言——Rego,還支援將策略作為代碼與應用程式的其他部分一同存儲、版本控制和部署。OPA 的這種設計使其能夠輕鬆集成到微服務、Kubernetes、CI/CD 管道、API 網關等多種環境中。顯著特點是其策略的編寫方式。Rego 是一種專門為策略和規則定制的查詢語言,它使開發者能夠以聲明式方式描述策略和規則,從而確保這些策略既容易理解又易於維護。這對於建立複雜的 RBAC 系統尤為重要,因為它允許策略的靈活性和可擴展性,同時又保持了清晰和易於審查的結構。 我們可以利用 OPA 提供的 API 來評估和執行這些策略。這意味著開發者可以在 Golang 程式碼中直接嵌入策略判斷的邏輯,從而實現動態、細粒度的訪問控制。這種方法的一個優點是,它支援在 runtime 動態更新策略,或是編譯進 binary,從而提供更大的靈活性和即時性。 整合 OPA 與 Golang 透過官方案例來了解如何使用 參考了 OPA 官方的 rbac 章節,並加以修改。使用最簡單的例子: admin can read user bob is admin ------------------- bob can read user 轉化成 RBAC 模型即為:...

2024-04-04 · 4 min · 724 words

Golang 1.22 中 http routing 的改進

Golang 作為一個偏向 server 應用的程式語言,一般的 web server 並不會直接使用原生的 package net/http,而更多的使用 gin-gonic/gin 或是 gorilla/mux,後來也有 labstack/echo 以及 go-chi/chi 等等選擇,在效能、輕量、好維護、好擴充中,都能找到對應的 third party package,其中的原因不外乎是原生的 package 提供的功能過於簡潔。 好在 1.22 中,官方改進了 net/http 中對於多工器、路由,甚至出了一篇部落格,現在更可以「大膽的」直接使用 standard library。 Path Parameter 若要將應用的 Web API 定義成 RESTful,我們會使用 /資源/{資源唯一識別符}/子資源/{子資源唯一識別符} 來定義路徑。假如要獲取一個使用者的訂單,則會使用 GET /users/1/orders 來獲取。在 1.22 以前,我們只能定義到 /users,再自行解析往後的 path: http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { subPath := strings.TrimPrefix(req.URL.Path, "/users/") if len(subPath) == 0 { xxx } else { ooo } ... }) 而在 1.22 中新增了 net....

2024-03-31 · 3 min · 469 words