FreeBSD 設置 NFS v4

首先修改 /etc/rc.conf:

啟動 nfsd:

修改 /etc/exports:

參考資料:
http://www.blissfulidiot.com/2013/06/configuring-nfsv4-on-freebsd.html
https://www.freebsd.org/cgi/man.cgi?query=nfsv4&sektion=4
https://www.freebsd.org/cgi/man.cgi?query=exports&sektion=5
http://www.jasonvanpatten.com/2015/11/26/freebsd-as-my-network-storage-server-part-2/

Nagios Plugin PATH 問題

今天在寫 Nagios Plugin 遇到的,從 Nagios 可以正常執行,但是從 NRPE 去執行就會失敗。失敗的時候顯示這個訊息:

使用下面的 script 來檢查,最後查出是因為 PATH 的問題:

這段程式在 Nagios 顯示:

但是在 NRPE 卻是:

因此就會發生某些程式無法執行的問題,最簡單的方法就是用完整路徑去執行程式,這樣也比較容易安裝到其它機器去執行。

另外,從本機測試 NRPE 會比每次都從遠端 Nagios 來的方便:

Apache mod_rewrite 筆記

官網的說明在此:
http://httpd.apache.org/docs/current/mod/mod_rewrite.html

mod_rewrite對我來說算是常用的一個功能, 但是網路上很少找到完整的教學. 所以就只好自己看官網的文件邊啃邊測試了.

注意事項:

  1. 要使用 mod_rewrite 的虛擬主機或資料夾, 必須設定 Options FollowSymLinks, 否則無法運作.
  2. Pattern 比對的可能是 URL, 也可能是檔案路徑, 這要看我們在何處使用 RewriteRule. 差別在於 URL 開頭會有斜線, 路徑不會, 因此在寫 Pattern 時要注意.
  3. 有可能形成無限迴圈. 這會嚴重影響效能. 在新版 Apache 若改寫前後的檔案相同, 會自動停止.

設定紀錄檔:

在 httpd.conf 中加入以上設定, 就可以開啟 log 功能. log 等級從 1 到 9, 數字越大越詳細. 開發或除錯時可以很方便的瞭解實際的運作情形. 我們可以給每個虛擬主機設定不同的紀錄檔, 但無法給資料夾設定紀錄檔. 例如以下這段設定, 上面的可以執行, 下面的則會出現錯誤訊息

錯誤訊息會抱怨說 RewriteLog 這個設定不能使用在這邊

基本語法:

這個設定就是 mod_rewrite 真正在做事情的地方了, Pattern 是用來比對我們想要改寫的原始內容, Substitution 則是我們要將其改寫成什麼樣子. 換句話說, 只有符合 Pattern 的情況下才會進行改寫的動作. flags 可以設定一些選項, 例如說不想區分大小寫, 就可以使用 [NC] 這個 flag.

在一般情況下, RewriteRule 是照順序一個一個執行下去的, 且前面一條改寫過的輸出會成為下一條的輸入, 所以安排好合理的順序會是很重要的關鍵. 下面的例子, 首先 about.htm 符合 Pattern, 變成 about1.php, 然後執行下一條規則, about1.php 又符合 Pattern, 所以最後會跑去 about2.php

兩種情境:

當使用在 VirtualHost 標籤中, 或是不在任何標籤中, 將會以 Host 情境執行. 在這個情況下, 拿來與 Pattern 比對的是 URL, 包含開頭的斜線. 反之, 若我們是在 Directory 或是 htaccess 檔案中使用, 則會以 per-directory 情境執行, 這時會用檔案路徑去與 Pattern 比對. 例如我們分別用上面的設定來執行以下例子, 會發現在 log 中它是用不同的字串去與 Pattern 比對:

Pattern 的用法:

Pattern 的部份是使用正則表達式(Regular Expression), 在大部分常見的用途當中, 其實並不會用到太複雜的語法. 然而它畢竟是個威力強大的表示方法, 一有不小心就可能產生預期之外的結果, 例如:

注意這個例子前後 url 的變化, 路徑不見了, 只剩下檔名. 這是因為 Pattern 給的不夠精確, 造成我們不管存取任何路徑的 about.htm, 都會符合 Pattern. 而改寫時, Substitution 又不包含路徑, 所以路徑也就自然不見了.

單一入口頁面:

另外, 一個經典的使用方法, 是將所有的網頁請求交給單一頁面處理, 例如:

但這邊用來判定檔案是否存在的方法需要注意, 若是在VirtualHost中使用, %{REQUEST_FILENAME}得到的是 /something.php 這樣的路徑, 於是rewrite會去檢查系統根目錄底下的something.php, 而不是網頁根目錄底下的檔案, 這會造成功能不正常, 可以說完全無法使用.
解決辦法, 就是加上<Location />, 並在其中設置rewrite的語法:

強制使用 https :

如果想要將整個網站改成使用 https, 這是其中一種方法

使用 systemd.timer 代替 crontab

systemd 提供的 timer 功能,可以用來代替 crontab,且其功能更多一些,也可達成類似 anacron 的功能。但設置起來當然也就複雜了一點點,習慣用 crontab 的人應該會強烈的感到麻煩吧 :p

這邊要紀錄的是基本功能,也就是在指定的時間,或是定期執行某個 script。

systemd 的概念,是將你要執行的 script 先設置成 service,然後你應該可以手動執行這個 service,也可以透過 timer 去執行它。也就是說,要將原本 crontab 做的項目改用 systemd,一個項目就會對應到兩個檔案,service 與 timer。

先從 service 開始,現在我們有個 script 需要每分鐘定期執行,這個 script 個工作很簡單,紀錄下自己執行的時間,寫到 logs 資料夾內。

將這個 script 存放到 /root/bin/log_time.sh 這個位置。接著就可以建立 service 了:

Unit 那邊只是給個描述,說明這個的用途。Service 那邊就比較重要了,其中 Type=simple 表示這個 service 是標準行為。若將 Type 設為 oneshot 就只會被執行一次。ExecStart 則是要執行的 script,要加上參數也是直接接在後面就可以了喔。

這個 service 檔案應該要存放在 /etc/systemd/system/logtime.service,然後就可以測試看看是否能夠執行了:

看起來成功執行嘍,接著就是要讓它定期能夠運作了。我們開啟一個新的 timer 檔案:

Timer 那邊是指定要執行的時間與 service。時間的格式很簡單,由左到右分別是 年-月-日 時:分:秒。以 * 代表的話就表示任意。上面的例子裡我們讓 timer 在每分鐘 00 秒時執行。最底下的 install 也很重要,它決定這個 timer 在什麼情況下會啟動。WantedBy=multi-user.target 意思是在多人模式下會自動啟動這個 timer。我想大部分應該都是用這個才對。

最後我們一樣將這個 timer 檔案存放到 /etc/systemd/system/logtime.timer 就可以了。設置到這個階段,還需要將這個 timer 啟用。其中包括了開機時自動啟用,以及現在不重開機的狀況下開始執行。

用下列命令來開機自動啟用:

用這個命令來檢查是否已啟用:

啟用後的 timer 會在開機後自動執行,但是若不想重開機就開始的話,得手動去執行它:

然後這樣檢查是否有在執行:

去檢查一下 logs 資料夾,果然每分鐘都會出現新的 log 了:

同場加映

上面講的是系統層級的設定方法,那麼有沒有使用者個人的 timer 與 service 可以用呢?

有的。首先要說明的是,systemd 只會在使用者有登入的狀態才會幫它執行 timer。若是要讓使用者登出後還能正常運作,需要做這個設置:

你可以這樣檢查 linger 是否啟用:

接著,使用者的 service 與 timer 檔應該要放在 ~/.config/systemd/user 裡面。啟用 timer 的方式基本上相同,但是要多加一個參數 –user:

參考資料

  • https://wiki.archlinux.org/index.php/Systemd
  • https://wiki.archlinux.org/index.php/Systemd/Timers
  • https://wiki.archlinux.org/index.php/Systemd/User
  • https://sevenbyte.org/2014/11/15/cron-jobs-with-systemd-timer/
  • http://jason.the-graham.com/2013/03/06/how-to-use-systemd-timers/
  • http://www.freedesktop.org/software/systemd/man/systemd.unit.html

BSD Packet Filter 筆記

系統更新之後 IPF 跑起來怪怪的,換成 PF 試試看會不會正常一點。兩者語法差異並不大,但 PF 多出比較方便的功能。

官方文件:
https://www.freebsd.org/doc/handbook/firewalls-pf.html

MAN:
https://www.freebsd.org/cgi/man.cgi?query=pf.conf

rc.conf 選項

port 表示法

語法:
[in/out] [quick] [on if] [proto tcp/udp/…] [from ip/CIDR] [to ip/CIDR] [port ports] [flags S/SA/…] [keep-state]

以前若是機器有多個 IP,需要根據 IP 來選擇路由的時候,使用 IPF 會這樣做:

PF 沒有支援類似的語法,同樣的功能需要用 reply-to 來達成:

若要加上詳細的條件:

差別在原本是封包出去的時候再重導,現在變成封包進來時就先決定回應要往哪裡丟。

PF 的規則是最後比對到的優先,而且對於順序有一定的要求,必須是按照 options, normalization, queueing, translation, filtering 由上往下列出。因此像是變數的設定,或是選項的調整都要放在最前面,接著是 NAT 的功能,最後才是放過濾的條件。

SSH 用戶登入時發信件通知管理者

一個控制慾很強稱職的管理者可能會想要 SSH 用戶登入時能有郵件通知,網路上有些 Linux 的文件可以參考,這邊紀錄一下 FreeBSD 的作法。

比較簡單的方式,是利用 PAM 模組來發送這個訊息。PAM 有一個 pam_exec.so 可以用來執行指令,所以運作原理就是當用戶登入時,去執行發送郵件的 script。

首先你要有個 script 用來發郵件,PAM 會將各種資訊以環境變數的方式傳入 scirpt 中,所以我們可以利用這些變數來做判斷,達成不同的目的。

就我所知不同平台可能有不同的變數名稱,若是想知道有哪些變數可用,可以在 script 內,將 env 輸出的內容寄給自己。
完成後大概長這樣:

將上面的 script 存放在 /root/notify.sh,並使用 chmod 加上可執行的權限。
再來修改 /etc/pam.d/sshd,加上這一行:

其中的 optional 表示不管 script 執行是否成功,都不影響用戶的登入。若是將 optional 改為 required,則 script 若執行失敗也會阻擋用戶登入。

接著就可以嘗試登入看看,並檢查是否有收到郵件了。

svn log 顯示 no author

今天在查 svn log 時,發現作者那一個欄位都顯示 no author,在官方 FAQ 裡面可以查到原因:http://subversion.apache.org/faq.html#no-author

就是當 svn 沒有做存取限制時,整個檔案庫是公開的,就會造成這個結果。
其實我是有做限制的,只是從 Apache 2.2 升級到 2.4 以後,權限設定的語法改變了。如果前面已經有 Require all granted,後面的 Require valid-user 就會失效。只要把這部份處理好就行了。

OpenVZ 安裝紀錄

隨著各家虛擬化的競爭越來越激烈,好像後來都沒聽到 OpenVZ 的消息了,但其實 OpenVZ 還是持續有在發展與更新的。
要安裝 OpenVZ,建議使用 CentOS 6 或是 Debian 7,安裝會比較順利。這邊使用的是 CentOS 6。

官方的安裝說明:https://openvz.org/Quick_installation
首先是設定 repository 並安裝 vzkernel 與工具:

接著需要修改 /etc/sysctl.conf,增加以下設定,有些設定原本就在裡面,需要註解掉:

最後修改 /etc/sysconfig/selinux 關閉 selinux,重開機後應該會使用 OpenVZ 的核心開機,這樣就完成安裝了。

主機的環境準備好後,我們接著可以去下載官方準備好的各個 Linux 發行版 template:http://openvz.org/Download/template/cache
下載後放到 /vz/template/cache 並注意 **不需要解壓縮**。這邊我是下載 debian-7.0-x86_64.tar.gz 這一個做練習。
另外,如果要讓 VPS 的網路正常運作,還得修改 iptables 設定,或是關閉 iptables。

有了虛擬機的 template,就可以開始創建 VPS,官方說明在:https://openvz.org/Basic_operations_in_OpenVZ_environment
首先要決定 VPS 的 id,id 就是一個數字,官方保留了 0 到 100 不能使用,100 以上的數字都可以自行選用。

我這邊使用的 id 是 1000,並一併設定了 VPS 的 IP 與 DNS。
–save 表示會將此設定寫在 /etc/vz/conf/1000.conf(1000是 VPS id),若是沒有 save,重開機設定就會消失。最後一行是啟動 VPS 的命令。啟動之後可以用 vzctl enter 1000 進入到 VPS 的環境中,輸入 exit 返回主機環境。

每台 VPS 在建立之後,設定檔會存放在 /etc/vz/conf/ 裡邊,而檔案系統則是放在 /vz/private/ 裡。如果將來需要搬移或是整合,只需要將這兩邊的檔案複製過去即可。假如目的地已經有同樣 id 的 VPS 在運作,也可以很輕易的更換一個新的 id 就可運行。更換的方式就只要把 /etc/vz/conf/1000.conf 及 /vz/private/1000 這兩邊的 1000 改成你要用的數字即可,不需要再做額外的設定。

建立 VPS 之後,防火牆是不可或缺的東西,但是網路上許多相關的文章都有點舊了。例如,若是要使用 state 來設定 iptables 規則,可能會遇到這樣的錯誤:

網路上很多都提到需要修改 vz.conf 之類的,其實都不需要嘍。這個時候,正確的處理方法應該是:

系統資源的分配也是很重要的一環,至少硬碟空間與記憶體都需要做限制:

另外,預設的檔案系統 Layout 是 ploop,若是想要使用 simfs 的話,就只能在創建 VPS 時指定,建好以後就不能修改嘍:

常用命令整理:

Apache log 與 Squid log 的流量差異

同時有 Apache 與 Squid 提供 proxy 服務
在看報表的時候,發現這兩個 proxy 的流量差異有點大
查到最後發現是 Apache 在處理 https 時,不會紀錄到真正的資料流量

60 KB 與 0 的差別…數量一多就會發現差距變很大。

另外,用 tcpdump 驗證了一下這些 log 的資料大小到底包含了哪些部份,結論是與 TCP 的資料長度一致,也就是包含了 HTTP Header,但不含 TCP/IP Header。