atuin

atuin 可以把指令歷史改放到 sqlite db 裡,提供了 fancy 的畫面跟功能,還蠻酷的。它在雲端有提供 sync 伺服器,可以把指令同步上去,我本來在想這會有安全疑慮吧,畢竟有些時候指令就會帶密碼。不過,atuin 已經有做加密了,放上去是安全的。

atuin sync 伺服器也可以自行架設,除了可以同步之外, sync 伺服器還有提供一個類似 github graph 的功能,可以看到活動圖,蠻有趣的。

安裝

bash <(curl https://raw.githubusercontent.com/ellie/atuin/main/install.sh)

如果想試試預設的 sync 伺服器,就先用 atuin register 來註冊

atuin register -u <USERNAME> -e <EMAIL> -p <PASSWORD>

若不需要,就匯入目前的 history

atuin import auto

設定

如果是使用 bash ,就用以下指令,把設定放到 .bashrc

curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh -o ~/.bash-preexec.sh
echo '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' >> ~/.bashrc
echo 'eval "$(atuin init bash)"' >> ~/.bashrc

若是 zsh ,就改用以下指令,把設定放到 .zshrc 裡

echo 'eval "$(atuin init zsh)"' >> ~/.zshrc

設定好,就關掉終端機,開新的終端機,或者是登出,重新再登入,設定就生效了。

使用

使用很簡單,按下 ctrl+r 或是按上,就會看到 atuin 的畫面,輸入字母,上方就會篩選出相關的指令。

那也可以打指令去找,例如找昨天下午3點以前的 ls 指令

atuin search --exit 0 --after "yesterday 3pm" ls

相當簡單。

架設 sync 伺服器的部份有空再來試好了,目前就先都以本機使用為主。

想法

其實就現在來說,使用 ctrl+r 就已經很方便,而且也不需要安裝,直接就能使用。未來會有需要集中管理指令歷史功能的強烈需求嗎?我想可能是沒有,就先用一陣子試試看好了,一周以後再來評估是否要繼續使用。

HAProxy

去年因為需要建置 OpenShift 容器平台而接觸到了 HAProxy,才知道為什麼 AWS 上會有分 Application Load balancer 等不同類型的負載平衡器。

簡單的說,HAProxy 的負載平衡模式分為兩種,一種是 HTTP mode,一種是 TCP mode;也就是 Layer 7 跟 Layer 4。建置 OpenShift 容器平台時,是使用 TCP mode ,Layer 4 的模式,當 HAProxy 收到連線請求時,是直接看哪一個 backend node 可以用,就直接左手給右手,連線到該台 backend node。那 HAProxy 也可以設定為 HTTP mode ,在這種模式下,就像是 nginx/apache 的 reverse proxy ,可以在 frontend 加上憑證跟做 VirtualHost。

安裝很簡單,Ubuntu 跟 RHEL 都有提供

sudo apt install -y haproxy
sudo yum install -y haproxy

安裝以後,設定檔位置是在 /etc/haproxy.cfg

主要需要調整的是 frontend 跟 backend

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 10s
        timeout client  60s
        timeout server  60s
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

frontend http_bind
        bind *:80
        mode tcp
        option tcplog
        default_backend router_http


frontend https_bind
        bind *:443
        mode tcp
        option tcplog
        default_backend router_https

backend router_http
        mode tcp
        server router_server router:80

backend router_https
        mode tcp
        server router_server router:443

frontend 決定 haproxy 要 listen 哪一個 port,backend 決定是由哪個 node 來處理連線,很容易理解。(聽同事說,這跟 F5 的設定也很接近。)

在 RHEL 會比較容易遇到 HAProxy 有問題,主因是 SELinux ,在啟動 HAProxy 前,需要先使用 setsebool 來設定:

getsebool -a | grep haproxy_connect_any
setsebool haproxy_connect_any on

跟 HAProxy 相關的 SELinux 設定可以用 man 8 haproxy_selinux 來查詢。

參考資料

讓 curl 在狀態碼非2XX時,回傳錯誤

一般在使用 curl 去存取某個網路資源時,只要可以連上並存取,curl 的 exit code 就會是 0。

可是很常見的情境是會想要加上 HTTP 狀態碼的判斷,例如 404 表示 not found,這時候就只能用 -I(即 -X HEAD) 再加上 -v 去取得 HTTP 請求回應標頭裡的狀態碼,再來判斷。

curlf() {
  OUTPUT_FILE=$(mktemp)
  HTTP_CODE=$(curl --silent --output $OUTPUT_FILE --write-out "%{http_code}" "$@")
  if [[ ${HTTP_CODE} -lt 200 || ${HTTP_CODE} -gt 299 ]] ; then
    >&2 cat $OUTPUT_FILE
    return 22
  fi
  cat $OUTPUT_FILE
  rm $OUTPUT_FILE
}

還好,在 curl 7.76 以後的版本加入了 --fail-with-body/–fail ,使用這個參數就可以不用那麼複雜的判斷,當 HTTP 狀態碼不是 2XX ,exit code 就不會是 0 了,而會是 22,22 表示 。

curl -sI --fail-with-body http://example.com/not-found/
echo $?
22

這樣以後就不需要解析請求回應標頭裡的狀態碼了。

參考資料

從 JFrog Artifactory 下載 artifact

登入 JFrog Artifactory 以後,進入自己的 Profile,然後點 Generate API Key,取得 API Key。

接下來,就可以在 curl 裡指定 X-JFrog-Art-Api: <token> 這個 Header,這樣就可以下載 artifact 了。

例如

curl -H "X-JFrog-Art-Api: <toen>" -o commons-collections-3.1.jar http://localhost:8081/artifactory/jcenter/apache-collections/commons-collections/3.1/commons-collections-3.1.jar

參考資料

PowerShell-取得磁碟剩餘空間

朋友主機的作業系統是 Windows Server 2012,之後會定期去做維護,那連線因為懶得用滑鼠按鍵去一個一個看,所以參考網路文章,寫了個簡單的腳本來一次印出來。

這腳本我命名為 du.ps1

function Get-FreeSpace {
    param ([string]$path);
    $space = (Get-Volume -FilePath $path).SizeRemaining;
    return [int64]($space / (1024 * 1024)); # this would otherwise be a float
}

$freeSpace = Get-FreeSpace "C:\"
Write-Host $freeSpace, "MB" -Separator " "
$freeSpace = Get-FreeSpace "D:\"
Write-Host $freeSpace, "MB" -Separator " "
$freeSpace = Get-FreeSpace "E:\"
Write-Host $freeSpace, "MB" -Separator " "
Read-Host "Press ENTER to exit"

簡單說明如下:

  1. Get-Volume -FilePath "<path>" 是取得指定路徑的物件,然後取物件的 SizeRemaining 屬性。
  2. 因為單位是 bytes,所以除以 1024 變成 K,再除以 1024 變成 MB
  3. 用 Write-Host 印出來,因為找不到類似 printf 或 print 的函式。Write-Host 的 -Separator 參數是指定分隔符號,這邊我用 ” ” 當作分隔,所以印出時,就會是 “100 MB” 這樣子的字串。
  4. 最後用 Read-Host 等按鍵,因為之後我會用滑鼠點一點來執行,若不加這行,執行完,視窗就會消失。

開啟 PowerShell 終端機視窗來執行 .\du.ps1 時,會有錯誤訊息,說不允許執行。這時候需要先執行下面這行,才能執行

Set-ExecutionPolicy RemoteSigned

參考文章

mysqldump/pgdump 連線密碼的存放

寫資料庫備份腳本時,會避免把密碼放在腳本裡,免得密碼流出去。

這時候密碼要藏在那邊呢?

postgresql

postgresql 的 pg_dump 預設會去讀取 $HOME/.pgpass 檔案,所以可以把帳號跟密碼放在這邊,腳本裡使用 pg_dump 進行備份時就不需要額外用參數指定。

.pgpass 檔案的內容是

hostname:port:database:username:password
  • hostname: 資料庫主機
  • port: 資料庫主機的 port
  • database: 資料庫
  • username: 連線的使用者帳號
  • password: 連線的使用者密碼

使用的時候,就不需要指定密碼了

pg_dump -h <db_host> -U <db_user> -F c -f $dump_file <db_name>

mysql

一般備份 mysql 資料庫會使用 mysqldump,mysqldump 有個參數 --defaults-file=<config_file>

所以可以用這個參數來指定,先在 $HOME/.config 資料夾下新增 backup.my.cnf 檔案,內容如下

[mysqldump]
user=<db_user>
password=<db_pass>
  • <db_user>: 放連線的使用者帳號
  • <db_pass>: 放連線的使用者密碼

至於主機的部份,可以用 mysqldump 參數指定,例如

mysqldump --defaults-file=$HOME/.config/backup.my.cnf -h <db_host> <db_name>

參考資料

vim錄按鍵順序

這用 Google 查好幾次了,決定記錄一下。

在使用 vim 編輯時,難免會遇到重複性很高的工作,vim 有個功能,就是可以錄製按鍵順序。錄製完成以後,可以再次播放剛剛錄製的按鍵順序,這樣就可以省下很多苦工。

要開始錄製,先確定在 normal mode 下,按下 q ,接著按下 a ,這個 a 是 register 的意思,簡單的說,是個代號,表示把按鍵順序放到 a 這個 register 裡。如果你要錄製其他按鍵順序,可以用 b, c, d, e … 以此類推。

接下來,就是要按下你要記錄的按鍵順序,例如移到行首,換掉第一個字元等等的。

等到順序都錄製完了,回到 normal mode ,按下 q 停止錄製。

之後要播放按鍵順序時,就是按下 @ ,然後按下 a ,這就表示要播放 a register 裡的按鍵順序。要重複播放上一次的按鍵順序,用 @@ ;要重複播放 20 次,就用 20@

參考資料

tcpdump小記

以前蠻排斥用 tcpdump 的,因為終端機模式下不容易去看,所以我都是寫到檔案以後,再傳出來用 wireshark 去看。

寫到檔案去,就是用 -w 參數指定要寫入的檔案。下面這行就是監聽 eth0 上的 port 80 封包,然後寫到 /tmp/capture.pcap 檔案。

tcpdump -i eth0 -w /tmp/capture.pcap port 80

昨天查文件學到另外一招,可以在終端機模式下看的方式,用 -X 參數印出 16 進位內容,用 -v 表示要看詳細的內容,越多 v 就越詳細。

tcpdump -i eth0 -vvX

參考資料

microk8s+okd web console

看到這篇:Running the OpenShift console in plain Kubernetes

剛好手頭上有 microk8s ,就裝來試試看。

環境

使用 Ubuntu 22.04

步驟

先安裝 nodejs 16,注意,17 以後的版本因為用了 OpenSSL3 ,所以編譯過程會有錯誤。

curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs

取得 web console 原始碼

git clone https://github.com/openshift/console.git

進入 console 資料夾,進行編譯

./build.sh

再來是啟動

先檢查 default 這個 service account 有沒有 token,這個 service account 是在 kube-system 這個 namespace 裡。

kubectl get serviceaccount default --namespace=kube-system -o jsonpath='{.secrets[0].name}'

如果沒有,就建立 token

kubectl create token default -n kube-system

複製輸出結果,然後建立 secret

kubectl create secret generic default-token-0621 --from-literal=token=<前面的輸出結果>

好了以後,編輯 service account

kubectl edit secret default-token-0621 -n kube-system

在 yaml 裡加入 secrets

apiVersion: v1
kind: ServiceAccount
metadata:
  name: default
  namespace: kube-system
secrets:
- name: default-token-0621

給權限

kubectl create clusterrolebinding default-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default

最後要啟動了,因為我是用 microk8s ,先取得 kubeconfig

microk8s config > ~/.kube/config
export KUBECONFIG=~/.kube/config
source ./contrib/environment.sh
./bin/bridge

預設會啟動在 :9000

在Windows 2019 安裝 OpenSSH server

資料來源:微軟-安裝 OpenSSH

我找不到 GUI 怎麼裝,最後是開 PowerShell 終端機來安裝

檢查是否有安裝

Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

安裝

預設就會安裝 OpenSSH client 了,執行這兩行會需要一點時間,我有遇到錯誤訊息,說安裝失敗,但再執行一次就可以了。

# Install the OpenSSH Client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

# Install the OpenSSH Server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

啟動、設定與開防火牆

用 Start-Service 就可以啟動,用 Set-Service 設定為自動啟動,後面落落長的 if 是檢查,這段檢查,可以開設定裡的防火牆來看,不用執行也可以。

# Start the sshd service
Start-Service sshd

# OPTIONAL but recommended:
Set-Service -Name sshd -StartupType 'Automatic'

# Confirm the Firewall rule is configured. It should be created automatically by setup. Run the following to verify
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) {
    Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
    New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
} else {
    Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists."
}

ssh 與 scp

若要連進來,用 ssh 即可,這邊要注意,當 ssh 進去以後,打的指令不是 linux 指令喔,是 windows 指令。

ssh <user>@<windows-2019>

因為 Windows 路徑跟 Linux 不一樣,所以不能用之前 linux 的方式來複製,得這樣用

scp my_file "john@<windows-2019>:C:\\Users\\John\\"

結語

有了 OpenSSH server ,要遠端管理或複製檔案變得方便許多,以後安裝完 Windows 要順手裝上。

參考資料