Hero Image
[授權] OAuth2.0

OAuth 是一個開發標準(Open Standard),用來處理有關「授權」(Authorization)相關的問題 允許授權當下的APP取得使用者在平台的相關資訊 OAuth2 有很多變化 腳色: Resource Owner,也就是使用者。 Client,要向使用者取得權限的應用程式,有自己的 Client ID、 Client Secret。 Authorization Server,負責驗證使用者身分、發 Access Token 給應用程式 Resource Server,存放資源的伺服器,認 Token 給使用者存取資源 用詞 Authorization Grant 同意應用程式取得資源 Redirect URI 驗證伺服器驗證、授權完畢後,返回應用程式的路徑 Scope 授權範圍 OAuth2.0 四種授權類型流程(Grant Types): Authorization Code 最常見,步驟: 應用程式(Client) 將使用者導向 Authorization Server,提供 Redirect URL, scope, 應用程式的 client id… Authorization Server 驗證使用者身分,通過之後發給 Authorization Grant,將網址列帶上 Authorization Grant 後將使用者導回 Redirect URI 回到應用程式(Client)。 應用程式(Client)拿 Authorization Grant 和 Authorization Server 換取 Access Token,Authorization Server 會透過應用程式(Client)專屬的 Client ID、 Client Secret 驗證應用程式身分。 應用程式(Client)帶著 Access Token 向 Resource Server 存取資源 Implicit 適合在 Client-side 運行的應用程式適合使用,例如 SPA(Single Page Application) 跳過交換 Access Token 的過程,由 Authorization Server 直接給予 Access Token 比較不安全

Hero Image
[HA] 使用 Docker Compose 安裝 Home Assistant

這裡是假設手邊已經有一台安裝 docker、docker-compose 的 Linux 系統。 採用的映象檔是 ghcr.io/home-assistant/home-assistant:stable ,因為我需要使用網址來區分服務(同一個 443 port 的情況下),所以採取反向代理的方式,一方面讓之後要部屬其他應用、加上憑證、等等操作都交給 nginx 比較方便,因此不會將 8123 port 直接對外。 建立 mynetwork docker create network mynetwork 建立 ha ha/docker-compose.yml version: '3' services: ha: container_name: homeassistant #image: "homeassistant/home-assistant:stable" image: ${HA_IMAGE} volumes: - ./volume/ha/config:/config - /etc/localtime:/etc/localtime:ro - /run/dbus:/run/dbus:ro restart: unless-stopped privileged: true networks: - mynetwork networks: mynetwork: external: true ha/.env HA_IMAGE="homeassistant/home-assistant:stable" ha/.gitignore volume/ 建立 nginx nginx/docker-compose.yml version: '3' services: web: image: nginx volumes: # - ./templates:/etc/nginx/templates - /usr/share/nginx/html:/usr/share/nginx/html - ./nginx.conf:/etc/nginx/nginx.conf - /etc/letsencrypt:/etc/letsencrypt networks: - mynetwork ports: - "80:80" - "443:443" environment: - NGINX_ENVSUBST_TEMPLATE_SUFFIX=.conf - NGINX_PORT=80 networks: mynetwork: external: true nginx/nginx.conf events { } http { upstream ha { server ha:8123; } error_log /etc/nginx/error_log.log warn; client_max_body_size 20m; # proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m; proxy_cache off; server { server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } } server { listen 80; #listen 443 ssl; #server_name home.example.com; # SSL certificate and key configuration #ssl_certificate /etc/letsencrypt/live/home.example.com/fullchain.pem; #ssl_certificate_key /etc/letsencrypt/live/home.example.com/privkey.pem; # Additional SSL configurations (e.g., enable secure ciphers, etc.) #ssl_protocols TLSv1.2 TLSv1.3; #ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384'; location /.well-known/acme-challenge { root /usr/share/nginx/html; } location / { proxy_pass http://ha; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } } } 啟動服務 docker-compose -f ha/docker-compose.yml up -d docker-compose -f nginx/docker-compose.yml up -d 創建帳號 例如我的 IP 是 192.168.56.100 現在可以進入 http://192.168.56.100/ 開始創建帳號。

Hero Image
[Tools] 在 linux 中使用 google drive cli

重新編譯 gdrive 取得憑證 首先到Google API Console, 建立專案 啟動 Google Drive API。 啟用之後選擇左邊的"設定同意畫面",填寫必要的欄位其他依照需求設置就好 建立一組 OAth2 憑證,會有 Client ID 和 Secret 編譯專案 1.安裝 Golang 2.下載 gdrive 專案 git clone [email protected]:prasmussen/gdrive.git 3.修改專案下的handlers_drive.go,把下列兩行改成拿到的 Client ID、Secret const ClientId = "*************************************.com" const ClientSecret = "*************" 4.取得需要的 golang 套件 go get github.com/prasmussen/gdrive 5.到專案資料夾下編譯,編譯完後就會有得到執行檔 go build 設定 設置環境變數 將編譯好的執行檔上傳Linux,假設放在${HOME}/gdrive-linux-x64: # 建立${HOME}/bin $ mkdir -p ${HOME}/bin # 把gdrive-linux-x64放進去重新命名為gdrive $ mv ${HOME}/gdrive-linux-x64 ${HOME}/bin/gdrive # 賦予gdrive執行權限 $ chmod u+x ${HOME}/bin/gdrive # 如果PATH裡面找不到${HOME}/bin就新增並重新讀取環境設定 $ echo ${PATH} | grep -qE ${HOME}/bin[^/] && \ > echo "PATH=\${HOME}/bin:\${PATH}" >> ~/.bashrc && \ > . ~/.bashrc 連結google帳戶 安裝好Google drive CLI後需要取得雲端硬碟帳戶授權,gdrive預設會在${HOME}/.gdrive底下找授權檔, 由於目前我們沒有任何授權,所以需要先下簡單的指令觸發token請求, 取得token之後會出現一個檔案叫做${HOME}/.gdrive/token_v2.json, 並且在終端機出現雲端硬碟所有檔案及資料夾清單(預設最多出現30筆):

Hero Image
[台灣杉] 一鍵登入國網中心台灣杉(Taiwania)

台灣杉(Taiwania)是國網中心2018年啟用的超級電腦,登入時密碼必須附加OTP (One-time Password),國網中心建議取得OTP的方式是從驗證器取得OTP密碼,但這樣的方式每次都需要打開驗證器(手機、chrome插件… etc),並且需要手動輸入OTP,下面分享我從Windows以及Linux環境下登入台灣杉所使用的一鍵登入方式。 OTP的演算法可粗分為HOTP (HMAC-based OTP);以及基於HOTP的TOTP (Time-based OTP),我們不必瞭解演算法細節,只需知道台灣杉採用Base32編碼作為TOTP金鑰(Secret),時間間格為30秒,每30秒可以根據”Secret”與”當前時間區間”以sha1演算法生成一次性密碼(OTP,或稱為Key),由於這是單向加密的過程所以無法用時間區間與Key逆推Secret,並且OTP在成功使用一次之後就會被伺服器廢棄,以確保安全性。 注意事項 校時 由於TOTP演算法依據當前時間區間產生OTP,如果作業系統的時間不正確則會產生錯誤的OTP,在Windows環境之下可以到國家時間與頻率標準實驗室的網頁下載NTP校時軟體,以管理員身分執行進行校時;Linux環境可以用下述指令更新時間並寫入BIOS: # 從NTP時間伺服器進行網路校時 sudo ntpdate time.stdtime.gov.tw # 將更新的時間寫入BIOS sudo hwclock -w 所有登入行為之間必須間隔30秒(包含使用winSCP、putty或從Linux直接登入)。 每個30秒區間會產生一個OTP,而該OTP一旦經過使用就會被伺服器廢棄而無法再用。我曾經連續登入以為程式壞了,但核對iService上面產生的密碼又是一樣的,後來才發現這件事…中間還因為連登失敗太頻繁還被鎖,因此記得間隔30秒以上再登入。 Linux要登入台灣衫需要將台灣衫加入know host,以生醫節點為例: ssh-keyscan 140.110.148.14 1>>~/.ssh/known_hosts 2>/dev/null 從Windows登入台灣杉 前置工作 安裝Go,並設置GOPATH。 安裝putty。 安裝WinSCP。 知道怎麼打開windows的命令提示字元 (WIN+R、鍵入cmd、enter)。 編譯TOTP產生器 取得TOTP套件 go get github.com/pquerna/otp/totp 撰寫程式碼main.go package main import ( "fmt" "github.com/pquerna/otp/totp" "os" "time" ) func main() { secret := os.Args[1] code, _ := totp.GenerateCode(secret, time.Now().UTC()) fmt.Print(code) } 編譯