使用sshuttle來連接不同環境下的機器

最近由於專案快上線了,所以頻繁的連接在不同的環境下的機器,或是監看機器的使用狀態;在這樣的使用情境下,之前有試著使用Socks5 + SwitchyOmega 的組合來連接,這樣的組合在只用來連接內網的dashboard時是蠻堪用的,但如果其它類型的連線就無法了。

每當要使用像是TCP連線到內網的機器(像是連資料庫之類的),就都要在先連一次VPN,然後才再連線;但連線完VPN以後,又要把SwitchyOmega的設定關閉,不然VPN +Socks5 + SwitchyOmega 的組合無法讓我連到特定的Dashboard…
這其實蠻惱人的,尤其是頻繁的切換使用VPN網路時,或是在開會過程中,又需要連到特定環境下的機器…

通常這問題大概可以使用幾種方式克服:

VPN – Partial Routing

若是使用OpenVPN的話可以在導入Profile時加入以下設定來讓client端可以自訂路由的規則。

route-nopull
route X.X.Y.Z 255.255.255.255

這邊的範例是只有往x.x.y.z 時才會經由vpn。

但這個方案的缺點是,同時間也只能連到一台OpenVPN 伺服器,所以代表同時間也只能連到同一個環境下的機器。

但優點就是所有TCP/UDP的封包都可以經由路由連接到那個環境下的機器。

SSH Tunnel Proxy

其實ssh 已經提供了一個方便的解決方案了,即是使用-L 這個flag,讓我們可以透過中介的jump/proxy server,讓我們的本地主機與遠端主機建立一個虛擬通道。

ssh -NL 5432:staging-postgres.your-domain.com user@jumper-server.your-domain.com

(使用-f 可以讓這個tunnel 在背景下執行。)

透過上面的指令,我們就可以執行下面的psql 指令來連接staging postgres這個資料庫。

psql -U postgres -d postgres -h 127.0.0.1 -p 5432

這個方案的缺點就是,如果有多台主機需要連的話,可能要設定多個Tunnel Proxy。

sshuttle

在Stackoverflow 上剛好看到了這篇文章,其中回應有提到了sshuttle 這個開源的專案可以透過ssh tunnel導流所有TCP的流量到遠端的jump server,也就是類似TCP Proxy的功能。

試了以後還蠻方便的,它底層的原理即是使用了ssh tunnel proxy,所以也是需要一台中介的ssh jump/proxy server。除此之外,它可以讓使用者用根據網段來轉送流量,所以基本可以解決原本在ssh tunnel proxy的一些不方便之處。

安裝

# For Mac
brew install sshuttle

# For ubuntu
sudo apt-get install sshuttle

使用上的基本指令

sshuttle -vr user@jumper-server.your-domain.com 10.0.0.0/8

上面這指令即是把所有往10.0.0.0/8的TCP流量都自動轉往jumper-server.your-domain.com上送…

Reference:

與C/C++整合的語言 – Zig

Hacker News上看到關於一個新的程式語言 – Zig, 從語言的哲學來看,它並不是要完全取代C/C++,相對的它是想要完善C/C++的生態與解決C/C++的痛點。

從生態來看,要在市場上找到很熟悉C/C++的開發者其實是困難的,相較於市場上找到會php/python/javascript 等程式語言的開發者而言;但問題是,目前幾乎所有重要軟體的基石都是使用C/C++來撰寫的。

從痛點來看,常常要編譯C/C++的程式時,可能會需要安裝許多toolchain 與dpendency,且依賴版本的管理上也不像其它語言那麼的平易近人,所以也造成要維護些C/C++專案的門檻也相對高。

所以Zig在這邊找到了它的利基,並提供了下面列出的優勢:

  • 可以整合C/C++的編擇流程,並整合成其編擇工具。
  • 在依賴管理上更貼近於現代程式語言的方式。
  • zig 語言的程式是可以與C/C++互通的,只需要用zig 編譯即可。

相較於把許多程式使用Rust改寫,Zig提供不同的切入角度來完善系統軟體的生態…

Reference:

檔案加密工具 – age

Hacker News上看到的新工具,age,一套可以用來加密檔案的工具;用法看起來也蠻簡單的,可以用其指令產生出public key,再用其來加密需要的檔案。

$ age-keygen -o key.txt 
Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p 
$ tar cvz ~/data | age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p > data.tar.gz.age 
$ age --decrypt -i key.txt data.tar.gz.age > data.tar.gz

另外也支援多組key的加密,只有中其中一把解密的key 就可以解檔案了。

$ age -o example.jpg.age \
  -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p \
  -r age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg example.jpg

透過ssh-rsa key來做加密看也是可以的

$ age -R ~/.ssh/id_ed25519.pub example.jpg > example.jpg.age
$ age -d -i ~/.ssh/id_ed25519 example.jpg.age > example.jpg

看來蠻實用的,之後如果有相關的需求看來可以用來試試。

Reference:

Linux 的log 機制

會有這篇文章,主要還是因為在工作上踩了好幾次坑,很多次都遇到了log檔佔用了太多的硬碟空間,所以趁這機會好好研究一下linux上相關的設定。

在Linux上Distro,Log 相關的 daemon主要有以下幾個:
(1) rsyslogd
(2) systemd-journald
(3) logrotate.d
而它們各自有不同的工作要處理,下面就分別來介紹每個daemon service:

rsyslogd

 rsyslogd is the enhancement of syslogd, a service that takes care of managing centralized log files. Syslogd has been around for a long time.

https://www.golinuxcloud.com/systemd-journald-how-logging-works-rhel-7/

rsyslogd 算是syslogd的進化版本,相對於syslogd, 它提供更有效率的log 處理方式

預設的log 會寫入到/var/log/syslog 裡,而相關的設定檔則是放在/etc/rsyslog.conf/etc/rsyslog.d/50-default.conf裡面。

在ubuntu20.04中,rsyslog.conf 的設定來看,它預設是從imuxsock裡讀取到log 訊息,並寫入到/var/log/syslog之中。相關在rsyslog.conf的設定如下:

module(load="imuxsock") # provides support for local system logging

另外,在ubuntu中,是使用systemctl來執行這個daemon,所以我們可以透過下面這個指令來看其執行狀態:

sudo systemctl status rsyslog.service

而相關的輸出大概會是長這樣:

● rsyslog.service - System Logging Service
      Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
      Active: active (running) since Thu 2021-08-26 11:12:02 UTC; 1 weeks 1 days ago
 TriggeredBy: ● syslog.socket
        Docs: man:rsyslogd(8)
              https://www.rsyslog.com/doc/
    Main PID: 269574 (rsyslogd)
       Tasks: 4 (limit: 9369)
      Memory: 517.1M
      CGroup: /system.slice/rsyslog.service
              └─269574 /usr/sbin/rsyslogd -n -iNONE

簡單講,rsyslogd 主要就是負責系統所有相關的log的寫入,像是/var/log/syslog, /var/log/auth.log, /var/log/kern.log
不過對於log 寫入之外的工作,就不是由它來負責的了,而是由另一個服務logrotate來負責的。

更改設定檔以後,則要使用sudo systemctl restart rsyslog.service來重啟服務以讀取新的設定檔

logrotate

從名稱上就可以看得出,這個service主要負責的工作就是做log file的rotate,所以當我們發現/var/log/syslog的檔案過大時,很大一部分的原因會是我們沒有設定好 /var/log/syslog的rotate設定。

logrotate 的設定檔位置在/etc/logrotate.conf,裡面有定義了預設的log檔案rotate設定;而針對於不同log的rotate 客制化設定,則是放在/etc/logrotate.d/ 這個資料夾下面。

舉例來說,是rsyslog的log rotate 設定的位置就是在/etc/logrotate.d/rsyslog 這裡。而相關的範例設定如下:

/var/log/syslog
 {
     rotate 7
     hourly
     maxsize 100M
     missingok
     notifempty
     delaycompress
     compress
     postrotate
         /usr/lib/rsyslog/rsyslog-rotate
     endscript
 }
 /var/log/mail.info
 /var/log/mail.warn
 /var/log/mail.err
 /var/log/mail.log
 /var/log/daemon.log
 /var/log/kern.log
 /var/log/auth.log
 /var/log/user.log
 /var/log/lpr.log
 /var/log/cron.log
 /var/log/debug
 /var/log/messages
 {
     rotate 4
     weekly
     missingok
     notifempty
     compress
     delaycompress
     sharedscripts
     postrotate
         /usr/lib/rsyslog/rsyslog-rotate
     endscript
 }

NOTE:
如果rotate的timesize都有設定的話,那就會以size為基準。而目前設定檔time最多只能支援到hourly
不過如果是以size為基準的話,應該也可以設定每分鐘的cron job,定期執行logrotate

另外,與一般的system service不一樣的地方是,logrotate是透過cron job的方式執行的,它的基本運作方式是,當我們執行了下面的指令去讀取新的rotate設定時

sudo logrotate /etc/logrotate.conf

logrotate 這個程式除了會去執行對應的rotate工作外,還會根據設定去產生對應的cron jobs。
舉例來說,如果我們設定syslog的rotate檢查頻率為hourly,那我們就可以找到對應的/etc/cron.hourly/logrotate 的cron job。

更改設定檔以後,則要使用sudo logrotate /etc/logrotate.conf來重啟服務以讀取新的設定檔

systemd-journald

 With the introduction of systemd, the journald log service systemd-journald has been introduced also. This service is tightly integrated with systemd, which allows administrators to read detailed information from the journal while monitoring service status using the systemctl status command.

https://www.golinuxcloud.com/systemd-journald-how-logging-works-rhel-7/

journald 是近年來在Linux上常被預設啟用的另一個log deamon service,它主要與systemd services 作整合,而與rsyslogd不同之處可以參考這裡:

Journald provides structure and indexed log files (called journals) in a secure manner. Therefore, not only are the journal files easier to search, it is harder for system intruders to cover their tracks.. Also you can maintain rsyslog messages in structured format.

Another advantage of using the systemd-journald service over traditional logging daemons is that journal files are automatically rotated if they grow above certain limits. This reduces log file maintenance issues and complexity.

The journalctl utility is used to read the journal binary log files and this command provides several means of filtering the data which is very powerful.

https://www.golinuxcloud.com/systemd-journald-how-logging-works-rhel-7/

簡單來說,它可以看成是rsyslogd的加強版,除了提供更安全的log儲存方式外,還額外提供了log rotate的功能,另外其搭配的cli journalctl還可以方便使用者檢索需要的log內容。

基本上journald的儲存相關設定主要是分為runtimesystem:

  • runtime: 所以runtime 相關的journals 會存放在/run/log/journal/下,一旦重新開機以後,舊的journals是不會保留的。
  • system: 如果下面的路徑/var/log/journal 存在且有對應的權限時,那麼journald就不會去寫log到/run/log/journal/底下了,而是持續性的寫入到/var/log/journal/下,在這情況下,即使重開機以後,舊的journals還是會保留的。

在ubuntu20.04中,journald的log 存放位置是在/var/log/journal,而設定檔的位置則是在/etc/systemd/journald.conf。 相關的設定檔說明可以參考ubuntu這文章

journald預設是透過systemd service的方式啟用的,所以透過下面的指令可以看得出目前journald的運作狀況:

sudo systemctl status systemd-journald.service

範例輸出結果為:

● systemd-journald.service - Journal Service
      Loaded: loaded (/lib/systemd/system/systemd-journald.service; static; vendor preset: enabled)
      Active: active (running) since Wed 2021-07-28 09:56:47 UTC; 1 months 7 days ago
 TriggeredBy: ● systemd-journald-dev-log.socket
              ● systemd-journald-audit.socket
              ● systemd-journald.socket
        Docs: man:systemd-journald.service(8)
              man:journald.conf(5)
    Main PID: 186 (systemd-journal)
      Status: "Processing requests…"
       Tasks: 1 (limit: 9369)
      Memory: 39.4M
      CGroup: /system.slice/systemd-journald.service
              └─186 /lib/systemd/systemd-journald
 Warning: journal has been rotated since unit was started, output may be incomplete.

journalctl 指令的使用

通常主要是透過journalctl指令來讀取log與變更log檔的一些設定,一些透過journalctl過濾/讀取log的相關技巧可以參考這邊

而一些常用journal 相關的管理指令如下:

  • 顯示目前所有journal的在硬碟上的使用空間
journalctl --disk-usage

  • 一次性的限制所有journal可以使用的硬碟空間 (e.g. 1GB),另外在清理時只會針對被archived 過的journal作清理。
sudo journalctl --vacuum-size=1G

更多journald 與rsyslog的整合與比較可以參考這裡

相關設定以確保log 檔案不會過大

在了解rsyslog, logroatejournald的一些運作模式以後,接下來回到之前常遇到的問題,log檔案size過大,而導致系統運作不正常的這個問題。

由於ubuntu20.04預設是同時會執行rsyslogdjournald的,所以基本上我們要關注的log檔案有兩個位置,分別是/var/log/syslog/var/log/journal

syslog的相關設定

基本上,針對sysloglogrotate預設是每天會做一次rotate,所以為了避免我們的應用程式在短時間製造過多的log,我們可以修改/etc/logrotate.d/rsyslog如下:

sudo vim /etc/logrotate.d/rsyslog

接著修改設定檔中的/var/log/syslog 部分如下

/var/log/syslog
 {
     rotate 3
     hourly
     maxsize 100M
     missingok
     notifempty
     delaycompress
     compress
     postrotate
         /usr/lib/rsyslog/rsyslog-rotate
     endscript
 }

以這樣來限制syslog的檔案大小

journald

以ubuntu20.04為例,它預設就是寫入到/var/log/journal,也就是說,我們必須去設定/etc/systemd/journald.conf 中的System*相關參數,詳細設定如下:

SystemMaxUse=1G
SystemKeepFree=
SystemMaxFileSize=100M
SystemMaxFiles=10

清除過大的log檔案

SYSLOG

如果目前的syslog 真的長的太大了,且裡面的內容是可丟棄的情況下,則可以使用下面的指令來清空目前的/var/log/syslog

#  this command needs to be ran as root
> /var/log/syslog

JOURNAL

如果是journal的話,則可以先將目前的journal archived,再做清理,詳細指令如下:

sudo journalctl --rotate
sudo journalctl --vacuum-time=1s

其它相關的清理方式可以參考這裡

reference:

新的Docker Desktop 費用

對有在使用Docker 當作日常開發工具的開發者來說,這應該是個值得注意的消息,也就是Docker Desktop 現在已經不是完全免費了!

對稍大型的企業(人數>=250人或年度收入>=$10M USD)來說,它們可能必須購買相關的授權才能夠繼續使用;然後新聞內容有提到,若是使用Docker command line的話,還是維持免費。

Docker Desktop主要是包了很多功能,像是image的管理,container的管理…等等。

UPDATED: DK 的相關文章有提到如何用macport 安裝docker engine,到時真的有需要時可以來參考一下XD

Reference

Docker Desktop no longer free for large companies: New ‘Business’ subscription is here • The Register

Asahi Linux for M1 Mac

這個Asahi Linux專案主要是想要讓M1 版本的MACs可以執行Linux,所以之後如果有相關的需求時,感覺可以來這看看是否可以用。

目前的進度來看,離正常使用應該還有段距離,希望這些類似的專案都能成功;可以想象如果可以有一台執行Linux的筆電,並且同時有M1的高效與不秏電,這個應該是許多開發者都希望有的一台電腦呀XDDD

Reference

Socks5 proxy server的設定

今天跟DK開會時,他利用些片段時間分享了他的工作環境設定,主要是關於他怎麼透過設定他的環境來同時可以連接dev, stage, production的環境。
會有這個分享主要也是因為我們在切換環境時,相對較笨拙點,都是透過連接不同的vpn server來切換到不同的環境下,但同時也只能在同時間點,只能連接到某個環境。

那就來進入主題了,他分享的方式,主要是透過在本機端建立socks5 proxy server, 將對於特定目標位址的流量,proxy到遠端預先設定好的jump server,再到對應的最終目標位址。

Step 1. 建立遠端的jump server

只要遠端的server有開啟ssh server的,就已經可以當成jump server了,而我們的stag jump server 就是這樣設定的。

Step 2. 設定 ~/.ssh/config (optional)

為了更容易的連接jump server,而不用每次都打一大串的ssh 指令,我們可以把連接jump server的相關設定寫到 ~/.ssh/config下,範例如下:

Host staging_jumper
   HostName our-jump-server.com
   IdentityFile ~/.ssh/jump-server.key
   User my-username

Step 3. 在本機端啟動socks5 server

由於剛剛在上一步有設定好連接jump server時,需要的ssh user 與 key,所以這邊可以很簡單的用下面的ssh指令啟動socks5 server

ssh -D 1081 -C -N -f staging_jumper

-D 1080 代表要將連往本機端 port 1081的流量轉送到staging_jumper上。
-f 代表要在背景執行
-C 代表要壓縮資料
-N 代表不執行任何遠端指令,通常做port forwarding 都會代入這flag

如果要關閉在背景的socks5 server,則可以用ps -aux 找出剛啟用的socks5 server pid,接著再使用kill指令去停掉正在運行的sock5 server process。

Step 4. 檢查是否有socks5 server是否有運作正常

curl --socks5 localhost:1081 http://your-staging-service.com

可以簡單透過curl 指令,來發起一個http的request到我們剛啟用的socks5 server port上。 如果成功的話,理論上會看到我們預期的html 網頁了。

Step 5. 設定SwitchyOmega

這是一個browser extension,主要是可以讓我們連接不同的網頁時,可以使用預先設定好的條件或方式來連接。
舉例來說,我們可以設定當接http://192.168.10.2:8080這個位址時,就自動透過我們預先設定好的socks5 server 與jump server 連接,此外,它還可以透過wildcard的方式來導流特定網段或特定domain 的網頁。

如以下範例

當我們啟用本機端的socks5 server以後,就可以到下面的SwitchyOmega頁面去設定代理伺服器。

之後,只需要再設定auto switch來決定哪些目標網頁要使用哪些代理伺服器就完成了

reference:

Mac shell上的快捷鍵

最近看到別人分享的一篇bash shell 快捷鍵對照縮圖以後,感覺可以稍微練一下,對平常工作應該會有不少幫助XD

後來找了一下網路上的資訊,看來Apple 的官方就有放快捷鍵對照表了,決定也順便整理一下我自己的版本:

動作快速鍵Notes
重新放置插入點將游標移至新插入點的同時按住 Option 鍵
將插入點移至該行起始處Control + A
將插入點移至該行結尾處Control + E
將插入點向前移動一個字元向右鍵
將插入點向後移動一個字元向左鍵
將插入點向前移動一個單字Option + 向右鍵我的iterm2這邊要用Control + 向右鍵
將插入點向後移動一個單字Option + 向左鍵我的iterm2這邊要用Control + 向左鍵
刪除行Control + U被刪除的整列會被複製
刪除至文字行結尾處Control + K
向前刪除至文字結尾處Option + D(已選取「使用 Option 鍵作為 Meta 鍵」時可使用)無法使用
刪除前面的一個文字Control + W這個文字會被複製起來
貼上Control+W 所複製的文字Control + Y
刪除一個字元Delete 鍵
調換兩個字元的位置Control + T目前選的字元會與前面的字元對調
https://support.apple.com/zh-tw/guide/terminal/trmlshtcts/mac

References: