安裝 Let’s Encrypt 的憑證與支援 HTTP/2

昨天花了一個多小時的時間,申請了 Let’s Encrypt 的憑證並更新上去,並且升級到 Apache 2.4.17 來安裝 HTTP/2 Module。

Let’s Encrypt 使用的 ACME Client 程式,目前有實驗性的支援 FreeBSD,基本上按照信件中的說明安裝即可。如果是 FreeBSD 9.x 的話,需要按照這個 GitHub Issue 的方式,自行編譯 trunk 版本的 pyca/cryptography,即可完成 ACME Client 的安裝。

安裝完成後,可以指定 webroot 當作認證檔案存放的位置,來給 Let’s Encrypt 驗證這個網域確實是申請人所有:


./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory -a webroot --webroot-path /home/data/websites/jnlin.org/webroot certonly

簽好的憑證會放在 /etc/letsencrypt/ 裡面,效期 90 天。官方建議每 60 天 renew 一次。我自己打算先手動 renew 一次,沒問題的話就丟到 cron 裡面,兩個月自動 renew 一次。

安裝 Apache 2.4 + HTTP/2 Module 就沒什麼特別的,直接 ports 安裝,結束之後,把憑證設定上去,即可打開 HTTP/2 的功能。反倒是解決 WordPress 的 mixed content 問題花了比較多時間 XD

FreeBSD 系統的 auditd

上個月的 17 日,FreeBSD.org cluster 中的兩台機器被入侵,起因是擁有這兩台機器 root 權限的人的 ssh private key 外洩,導致這兩台主機被不明人士登入。由於這兩台主機上有開啟 Audit 機制,因此管理員發現了 root 有異常存取 file system 的行為。今天剛好有空,於是也來幫主機加上 audit 的機制。

步驟非常簡單,只要根據 handbook 重新編譯 Kernel,設定 /etc/security 下的設定檔,再把 auditd 跑起來就可以了。不過一開始跑起來之後並沒有紀錄 Log,花了一點時間找資料,才發現原來是 auditd 跑起來之後,必須要重新登入,才會開始紀錄。

auditd 產生的紀錄大概長這樣:

header,84,11,sudo(1),0,Tue Dec 25 00:00:38 2012, + 49 msec
subject_ex,jnlin,root,wheel,jnlin,1001,93339,93339,42554,192.168.128.100
exec arg,ls,-al
return,success,0
trailer,84

參考資料:FreeBSD 這次的入侵事件

使用 Virtual Box Headless 跑 Virtual Machine

VirtualBox 是 Sun (後來被 Oracle 買下) 開發的一套虛擬化軟體。他的 Host OS 可以是 Windows, Linux, MacOS, FreeBSD。除此之外,VirtualBox 可以在 Terminal 下執行,顯示的畫面由 RDP/VNC 輸出,亦即 Headless 模式。要特別注意的是,RDP 輸出僅限於專屬授權版本,OSE (Open Source Edition) 版本是沒有這個功能的。

要使用 VNC 輸出,必須在安裝的時候加入 VNC 支援:

# cd /usr/ports/emulators/virtualbox-ose; make WITH_VNC=yes all install clean

安裝好 VirtualBox 之後,必須再安裝 kernel module:

# cd /usr/ports/emulators/virtualbox-ose-kmod; make install clean

接著把需要的 Kernel Module 載進來:

# kldload vboxdrv; kldload vboxnetadp; kldload vboxnetflt

之前寫在 /boot/loader.conf 會導致開機時 Kernel Panic,但如果開完機手動載入就不會,目前還沒找出原因。

接下來新增一個 Virtual Machine:(以下都可以不需要 root 權限)

% VBoxManage createvm winxp --register

然後設定 VM 的資源需求:

% VBoxManage modifyvm winxp --acpi on --ioapic on --memory 1024 --cpus 2 --nic1 bridged --nictype 82540EM --bridgeadapter1 em1

以上的範例分配了 1024MB (1GB) 的 RAM 與 2 個 Virtual CPU 給 winxp 這個 VM,另外建立了一張虛擬網卡,型號為 Intel 82540EM,橋接到實體的 em1 這張網卡上。

再來建立一個新的 120GB 虛擬硬碟:

% VBoxManage createhd --filename winxp --size 122880

在 VM 裡增加一個 IDE Controller:

% VBoxManage storagectl winxp --name "IDE Controller" --add ide

把硬碟與安裝 ISO 檔連接到 IDE Controller:

% VBoxManage storageattach winxp --storagectl "IDE Controller" --port 0 --device 0 --type hdd --medium winxp
% VBoxManage storageattachwinxp --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium winxp.iso

接著就可以開機了:

% VBoxHeadless -s winxp --vnc --vncport 5900 --vncpass password

執行成功後,可以用 VNC 連入看到安裝 Windows XP 的畫面:

關機、重開機可以使用 VBoxManage 來完成:

% VBoxManage controlvm winxp poweroff

FreeBSD 的 EC2 AMI…

剛到公司就被DK長輩提醒,Amazon Web Services可以跑FreeBSD 64 bit 的 AMI 了(us-east 的 ami-c69862af)。一樣是Colin Percival做出來的AMI。

然後他的作法居然是開一台Windows的機器,然後把Kernel換掉 XD
這樣確實可以跑 HVM 沒錯,不過缺點是每小時的費用比較高(目前會計入微軟稅)。

作者也希望AWS能夠早日把HVM開放給非微軟平台,這樣就不用繳微軟稅了。

security/pam_google_authenticator: Two Factor Authentication PAM Module

security/pam_google_authenticator 是 Google 推出的 Open Source PAM Module,提供 RFC 4226 (HOTP: An HMAC-Based One-Time Password Algorithm) 的 OTP 功能。

只要使用 Android 手機(未來會支援iOS裝置),安裝 Google  提供的 App,開啟並設定 pam_google_authenticator,之後的 ssh 連線就可以使用 OTP 登入。

Linux 上的安裝方法可以看 @gasol 寫的替主機上第二道鎖 – Google Authenticator,這裡介紹的是 FreeBSD 上的安裝方法:

  1. 先安裝 security/pam_google_authenticator
  2. 執行 google-authenticator ,設定 secret key。螢幕上會出現一個 QR Code,用手機 App 掃描之後就會把 secret key 存到手機內。接著按照螢幕上指示把 secret key 存到 ~/.google_authenticator 裡。記得要 chmod 600。
  3. 設定 /etc/pam.d/sshd,在 auth pam_unix 下面增加一行:

auth required /usr/local/lib/pam_google_authenticator.so

這樣就生效了。要注意的是,這不會影響使用 Public/Private Key Pair 登入的使用者。另外,PAM設定完成之後,如果沒有設定 secret key 的使用者,就不能用帳號密碼登入了。

測試前記得請留下一個連線的 terminal,避免設錯導致人得跑到 console 前去處理。

FreeBSD 的 pf route-to 與 TSO (TCP Segmentation Offload)

之前一直有遇到在 pf 裡面用 route-to 之後網路連線緩慢的問題(大概只有 10kb/s),不過一直沒時間去追。最近花了點時間去追這個問題,發現在使用 route-to 並且開啟 TSO 之後,重送以及 out-of-order 的 packet 變得異常多:

wireshark.png

拿掉 TSO 或是 route-to 其中一個設定,狀況就會變好。在 core team 修正這個 bug 之前,只好先暫時 disable TSO 了。

在 terminal 下用 subtitle2vobsub 生出 .idx 與 .sub

必須的程式:mplayersubtitlerippertranscode

首先先抓出該 DVD 內有幾個字幕軌道:

mplayer -dvd-device $RIPDIR dvd://$TITLE -vo null -ao null -frames 0 -v

$TITLE 是該影片位在 DVD 的哪個 Title 中。

輸出結果應該如下:

......
DVD successfully opened.
audio stream: 0 format: ac3 (5.1) language: en aid: 128.
audio stream: 1 format: ac3 (stereo) language: en aid: 132.
number of audio channels on disk: 2.
subtitle ( sid ): 0 language: en
subtitle ( sid ): 1 language: es
subtitle ( sid ): 2 language: pt
subtitle ( sid ): 3 language: ko
subtitle ( sid ): 4 language: zh
subtitle ( sid ): 5 language: th
subtitle ( sid ): 6 language: es
subtitle ( sid ): 7 language: pt
subtitle ( sid ): 8 language: ko
number of subtitles on disk: 9
......

再接下來抓出字幕:

tccat -i $RIPDIR -T $TITLE -L | tcextract -x ps1 -t vob -a 0x24 > subs-zh

註:0x24 為 0x20 + 4 (language:zh 的 index)

再接下來轉成 idx+sub:

subtitle2vobsub -o vobsubs-zh -i $RIPDIR/VIDEO_TS/VTS_01_0.IFO < subs-zh

就會生出 vobsubs-zh.idx 與 vobsubs-zh.sub 了。

FreeBSD 設定 kern.ipc.nmbclusters="0" 的問題

中了個令人無言的地雷……

FreeBSD 有一個well-known的參數調整:mbuf clusters的最大值(kern.ipc.nmbclusters)。當使用的mbuf clusters超過設定的最大值時,網路就會不通。不過,我們可以在 /boot/loader.conf 裡面把 kern.ipc.nmbclusters 設為 0,表示不設定最大值,這樣他就會被Kernel Space Memory的大小限制住(一個 mbuf cluster 要吃約 2KB 的Kernel Memory)。

最近我們發現這樣設定的機器在有大量 TCP out-of-order 封包的網路環境下,網路效能表現非常差,於是做了很多交叉比對以及測試。最後發現有這樣問題的機器有兩個特點:netstat -s -p tcp 的結果,out-of-order packets 的 counter 都是 0,而且packets discarded due to memory problems 的 counter 很多。

最後找到 Maillist上的資料,發現在 kern.ipc.nmbclusters 設定為 0 的情況下,net.inet.tcp.reass.maxsegments 也跟著被設定成 0 了,調整回預設值 1600 就解決這個問題了。

FreeBSD 的 kernel debugging & textdump(4)

今天因為某組Web機器當機實在當太嚴重了,因為我們發現問題是出在NFS,所以我們把 KDB 跟 DDB 編進去準備來找問題。

當發生問題的時候,由於機器不會當死,所以可以在Console按Ctrl-Alt-ESC進DDB。進了DDB以後,可以用textdump(4)來紀錄所下的指令以及其output。紀錄的資料會dump在dump device(通常是swap),等下次開機的時候會存到/var/crash裡面。

大概的作法是這樣:

  1. 先Ctrl-Alt-ESC進DDB
  2. textdump set # 開始 textdump
  3. capture on # 下面的指令都要記錄下來
  4. show allpcpu; bt; ps; alltrace; show alllock # 要紀錄的資訊
  5. call doadump # dump到dump device
  6. reset # 重開機

如果發現出來的結果會被截掉的話,要把textdump的capture buffer加大:

sysctl debug.ddb.capture.bufsize=196608