2021年6月26日 星期六

Linux Namespaces

「containers are only isolated groups of processes running on a single host, which fulfill a set of “common” features

  • 只能 single host?
  • 跨 OS
  • 跨處理器架構?

historical beginning

chroot:改變 process 的 root directory。

  • 1979 釋出 UNIX Version 7 首次出現 chroot。
  • 現今 Linux 系統呼叫 chroot()。
  • 1991 亦稱為「jail」,因為用作 honeypot 來觀察駭客。
  • 2000 早期才有「microservices」應用。
  • 準備新的根目錄檔案架構 (複製執行檔、函式庫、設定檔等),然後 chroot。
  • 只是改變 root path,仍然可以跳出。
  • 現在 container runtimes 不再用 chroot,而改用 pivot_root(),好處是會把 old mounts 放到另外的目錄,後續可以卸載,讓檔案系統完全看不到而。
  • 有用的適當根檔案系統 (rootfs) 包含所有執行檔、函式庫、和需要的檔案架構。peeling it from an already existing Open Container Initiative (OCI) container 可透過 skopeo and umoci 輕易達成,但還是可以看到其它 process,網路也不是獨立的。

Linux Namespaces

  • 2002 Linux 2.4.19 開始出現的功能,wrap certain global system resources in an abstraction layer. 讓 namespace 內的 process 只看到自己那部份資源。
  • 2013 Linux 3.8 出現 user namespace 才有完整支援 container,有幾個 distinct namespaces 實作:mnt、pid、net、ipc、uts、user、和 cgroup。
  • 2016 九月提議 2 個額外 namespaces:time 和 syslog。(2019 三月尚未實作完成)
  • Linux namespace API 包含 3 個主要系統呼叫:
    • clone():子 process 繼承部份 execution context,如 memory space、file descriptors, 和 signal handlers。可 pass different namespace flags 給 clone() 建立 new namespaces。
    • unshare():讓 process to disassociate parts of the execution context。
    • setns():reassociates the calling thread with the provided namespace file descriptor. 結合現存的 namespace.
  • /proc/$PID/ns 提供額外 namespace 資訊,可用來 a handle for performing operations (like setns(2)) to the referenced namespace. 讓 us for example to track in which namespaces certain processes reside. One handy tool related to namespaces within this package is lsns. It lists useful information about all currently accessible namespaces or about a single given one.

mnt:不共享掛載的檔案系統

uts (UNIX Time-sharing System):不共享 domainname 和 hostname

ipc:隔離 IPC 資源,也就是 System V IPC objects 和 POSIX message queues。

pid (Process ID):讓 process 在 host 有 PID 外,在 namespace 下有另一組 PID,且可以 nested。在 namespace 內,第 1 個 process 的 PID 是 1,和一般 init process 相同特殊對待,所有 namespace 內 processe 都 re-parented 於 namespace 的 PID 1,結束 PID 1 也結束 namespace 內所有 processe。

net (Network) namespace 用來 virtualize the network stack,每個 network namespace contains its own resource properties within /proc/net. 一開始,一個 network namespace 只有 loopback 界面。每個網路界面只會在一個 namespace 出現,可以移到不同 namespace。每個 namespace 有自己的 IP 位址、routing table、socket listing、connection tracking table、firewall、和其它網路相關資源。刪除 network namespace 會刪除 virtual 界面,physical 界面會回到原本的 network namespace。

user (User ID):讓 process 在 namespace 內有另一套 user ID 和 group ID。unprivileged user ID 的 process 在 namespace 內可以是 privileged。

cgroup (Control Group) 支援 resource limiting, prioritization, accounting and controlling。

Composing Namespaces

Demo Application

2008 發明 cgroup,出現 Linux Containers (LXC) 計畫結合 cgroup 和 namespace 提供執行應用程式的獨立環境。同時,2007 Google 開始稱為 Let Me Contain That For You (LMCTFY) 的 containerization project, 設法提供一個穩定 API 驅動的設定方式,不用了解 cgroup 和內部細節。2013 Docker 基於 LXC,包裝 container 成為 image 而可以在機器間轉移,首先讓 container 成為標準軟體單元。之後一起發展 libcontainer,採用 Go 原生方式 spawn and manage containers。2015,計畫類似 Kubernetes 到 v1.0,成立 CNCF 推行 container,成立 Open Container Initiative (OCI) 致力於建立 container 格式的標準 -- OCI Runtime Specification。libcontainer 捐給 OCI,也誕生 runc 工具直接和 libcontainer 互動、解釋 OCI Runtime Specification 並執行。runc 用在許多 container ecosystem,如 containerd (used by Docker), CRI-O and podman。也有其它計畫採用 OCI Runtime Specification,如 Kata Containers 可以建立和執行包含輕量虛擬機器的 secure containers,用硬體 virtualization 技術作為第二層 defense 提供更強大的 workload 隔離。

參考

  1. https://medium.com/@saschagrunert/demystifying-containers-part-i-kernel-space-2c53d6979504 或 https://github.com/saschagrunert/demystifying-containers

2021年6月19日 星期六

busybox logger

logger [OPTIONS] [MESSAGE]

寫 MESSAGE 或標準輸入到 syslog

選項

  • -s:同時也寫到 stderr。
  • -t TAG:使用 TAG 作為標示,預設是使用者名稱。
  • -p PRIO:numeric 或 facility.level 優先權,預設是 user.notice

範例

  • logger hello

參考

  1. busybox sysklogd 原始碼

2021年6月12日 星期六

busybox syslogd

syslogd [選項]

選項

  • -n:前景執行。
  • -O FILE:日誌檔,預設 /var/log/messages。本地紀錄時,未符合規則、等級小於選項 -l、且不紀錄到 share memory 時使用。
  • -l N:只紀錄小於等級 N (1-8) 的訊息。
  • -S:較小的輸出,不放主機名稱和分類等級。
  • -m MIN:MIN 週期丟 SIGALRM 給自己,在日誌加「-- MARK --」。程式未啟用。參考 alarm()。

功能 ROTATE_LOGFILE

  • -s SIZE:rotation 大小 (KB),預設 200KB,0 不 rotation。
  • -b N:保留 N rotated logs,預設 1,最大 99,0 不保留。

功能 REMOTE_LOG

  • -R HOST[:PORT]:紀錄到遠端 IP 或主機的 PORT,預設 PORT 是 514/UDP。如果本地也要紀錄,選項要開 -L。
  • -L:紀錄到遠端時,同時也紀錄到本地。

功能 SYSLOGD_DUP

  • -D:丟棄重複的訊息。

功能 IPC_SYSLOG

  • -C[size_kb]:未符合規則且等級小於選項 -l 的,紀錄到在 share memory 的 circular buffer,使用 logread 讀取。參考 shmget()、shmat()、shmdt()、shmctl()、semget()、semop()、semctl()。

功能 SYSLOGD_CFG

  • -f FILE:指定設定檔,預設 /etc/syslog.conf。符合規則的就不會再紀錄到指定的日誌檔或 IPC share memory。

範例

  • syslogd -R masterlog:514
  • syslogd -R 192.168.1.1:601

syslogd 動作

  1. 讀取 /dev/log 訊息。
  2. 檢查有沒有重複。
  3. 紀錄到遠端話,送到遠端。沒開 -L 選項則回到 1.。
  4. 預設分類等級是 user.notice,嘗試解析訊息中 <數字>。
  5. 換行替代為空白,TAB 不變,其它 0x1F 以下的碼替代為 ^A、^B、...。
  6. 使用訊息中已有的 timestamp 或產生 timestamp。
  7. 沒設 -S 選項加上主機名稱和分類等級。
  8. 設定檔有符合的分類等級規則,本地紀錄完回到 1.。
  9. 符合紀錄等級以下,紀錄到 share memory,否則本地紀錄到選項 -O 的日誌檔。

本地紀錄的動作

  1. 如果不在同一秒,重新開啟檔案。
  2. 嘗試開啟檔案,失敗改開啟 /dev/console,再不行則用 stderr。
  3. 一般檔案進行 rotate 動作。
  4. 寫入。

參考

  1. busybox sysklogd 原始碼
  2. facilitynames[] 和 prioritynames[] 在 uClibc 的 include/sys/syslog.h

2021年6月8日 星期二

SIP P-Header

SIP 的 Private Header (P-Header) 擴充

3GPP [RFC7315] [RFC7976]

  • P-Associated-URI:在 SIP REGISTER 成功回應時告知所有相關 URI。可有多個。UA 可用這些 URI 身份,但並不表示這些 URI 已註冊。
    P-Associated-URI       = "P-Associated-URI" HCOLON
                             [p-aso-uri-spec]
                             *(COMMA p-aso-uri-spec)
    p-aso-uri-spec         = name-addr *(SEMI ai-param)
    ai-param               = generic-param
    範例 [https://community.cisco.com/t5/ip-telephony-and-phones/cisco-2811-itsp-sip-configuration-was-good-from-a-long-time-but/m-p/4163078]
    P-Associated-URI: <sip:+97440006999@vodafone.qa>
    P-Associated-URI: <tel:+97440006999>
    P-Associated-URI: <tel:+97440006900;wcard-range=+974400069![0-9][0-9]!>
    P-Associated-URI: <sip:+974400069![0-9][0-9]!@vodafone.qa>
    name-addr 的 URI 是 <> 包起來的,其中 user 或 telephone-subscriber 的 wildcard 支援
    • 有沒有標準?一般 wildcard 部份前後用 ! 包起來,放正規表示式語法,但可能不是全部支援。
    • IMS PSI 
    • Alcatel-Lucent 5060 IP Call Server (ICS) 的 wildcard PUID。PrID, pbxPUID, pbxPrID, iDN (individual Directory Number)
  • P-Called-Party-ID
  • P-Visited-Network-ID
  • P-Access-Network-Info [https://datatracker.ietf.org/doc/html/rfc7913]
  • P-Charging-Function-Addresses
  • P-Charging-Vector

Early Media 授權 [https://datatracker.ietf.org/doc/html/rfc5009]

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...