顯示具有 linux 標籤的文章。 顯示所有文章
顯示具有 linux 標籤的文章。 顯示所有文章

2012年7月2日

設定 ssh 免密碼登入需注意 ~/.ssh 目錄和 ~/.ssh/authorized_keys 檔案的權限

通常要利用排程執行 rsync 將檔案在多台設備間同步,都需要先設定 ssh 免密碼登入(利用 RSA / DSA 金鑰認證),之前我都是參考:ssh keygen 免輸入密碼 (需要設定 passphrase 的話參考這篇),但遇到有一台設備不管怎樣設定都不 work。

後來請前輩幫忙看了以後發現,因為 ssh 對檔案/目錄權限控管非常嚴格,因此要 check 以下幾點:

  1. ~/.ssh 目錄的權限必須是 700
  2. ~/.ssh/authorized_keys (/etc/ssh/sshd_config 中的預設金鑰檔) 的權限必須是 644
這兩個權限設定非常重要,必須完全一模一樣才可以,任何一個數字不對就不 work。

通常是不需要特別查這兩個權限設定,但有可能因為 chmod -R 這種指令把整個 home directory  (含 .ssh 這個隱藏目錄)的權限都改了,反而衍生出這個問題。所以說有用到 -R 改權限真的要非常小心阿!

2012年4月11日

在 RHEL 6 設定 NIC Bonding 的注意事項 (&如何正確關閉 NetworkManager)

在 RHEL/CentOS 4/5 上設定 NIC Bonding 我已經很熟悉了(作法: Network Card Bonding On CentOS),但今天要在 RHEL 6 上設定的時候卻發現已經沒有 /etc/modprobe.conf 檔案了,找到參考作法後歷經一番曲折終於設定好,以下是今天設定的筆記:

  1. /etc/modprobe.conf 已經被 deprecated 了,新的 config 檔要自己去 /etc/modprobe.d/ 目錄下新增 bonding.conf 檔案,內容只要寫「alias bond0 bonding」即可,原本的「options bond0 miimon=100 mode=1 primary=eth0」設定改為寫到 ifcfg-bond0 檔案中。
  2. 承上,在 ifcfg-bond0 中要寫「BONDING_OPTS="miimon=100 mode=active-backup primary=eth0"」,比起 mode=1 來說可是一目了然。
  3. 若在安裝過程中僅針對 eth0 設定固定 IP,則 RHEL 6 自動產生的 ifcfg-eth0 和 ifcfg-eth1 檔案內容差會很多,eth0 多了很多設定,例如「NAME」、「UUID」等 eth1 沒有的內容,因此最好分別編輯兩個檔案,不要先改好 eth0 以後直接用新的 eth0 檔案把原本的 eth1 檔案覆蓋掉,否則可能會造成 MAC Address / UUID / NAME 重複,進而衍生其他問題(詳見下一段)。
基本上有異動的地方只有這兩點,但今天修改第一台設備的設定時遇到一個問題,重開機後只看到 eth1 這張網卡,eth0 不見了!檢查 dmesg 以後發現一個訊息:「udev: renamed network interface eth1 to eth0-eth1」,再用 ifconfig 確認網卡狀態,果然 eth0 已經被 rename 為 eth0-eth1 了,最囧的就是就算把原有的 ifcfg-eth0 檔案 rename 為 ifcfg-eth0-eth1 並修改相關設定也沒用,反而造成 bond0 下只看得到 eth0-eth1 這張網卡,eth1 反而消失了。

好心的同事(怪獸先生)幫忙查了資料以後發現,這是因為在設定過程中我改好了 eth0 檔案,然後直接用 eth0 檔案覆蓋原有的 eth1 檔案,造成 eth1 的 MAC Address 改變,因此 /etc/udev/rules.d/70-persistent-net.rules 檔案的內容錯誤(多了好幾個把 eth0 rename 為 eth0-eth1 的 rule),導致網卡異常。最後很幸運的直接編輯這個自動產生的檔案,把多餘的 rule 刪掉以後重開機就恢復正常了。

另一個問題就是如何停止 Red Hat 內建的 NetworkManager,我發現在安裝 OS 的過程中若設定了固定 IP,就會啟用 NetworkManager 來管理網路,若使用 default 的 DHCP 則不會啟用 NetworkManager。停用的方式很簡單,打開一個 Terminal 視窗 (或者在 runlevel 3 下登入系統),執行 setup,到 System Services 裡面把 NetworkManager 關掉即可。若不進行 reboot,需手動執行 service NetworkManager stop 指令來停止運行中的服務,另外也不要忘記執行 chkconfig 來關閉 NetworkManager,以確保下次 reboot 後 NetworkManager 不會再被啟動。

2012年2月20日

[Solaris10/RHEL4/5] 設定允許使用ssh登入主機的網域白名單

最近發現了廠商會透過類似 SSH Over HTTP 的方式從外部網路直接穿透 80 port 連到機房的內部網路(透過一台在公網有開放 80 port 的設備),而後再以該台設備為跳板連到其他機器。雖然說只是要進行維護的動作,但違反了資安規定,也因此讓我們驚覺還有這種無法透過 firewall 控管的漏洞。(查了一些資料以後發現,據說連 L7 Switch 都擋不住)

為了防堵這樣的連線方式,想到可以透過設定白名單的方式,正面表列允許使用 ssh 跟主機通訊的網域白名單,以下分別說明在 Solaris 10 & RHEL/CentOS 4/5 要如何設定。

Solaris10
參考:
  1. Solaris 10 - IPFilter 防火牆
  2. IP Filter FAQ
其實 IPFilter 的功能很強,透過規則的組合可以達到非常細膩的控制,在參考資料中就可以看到一些範例。要限制可透過 ssh 連線的網域白名單就簡單多了,步驟如下:

Step 1: 確認 pfil & ipfilter service 均已啟用

  • 執行 svcs pfil ipfilter,兩個服務的 STATE 應顯示為「online」。
  • 預設 pfil 服務是啟用的,而 ipfilter 則是 disabled,只要執行 svcadm enable ipfilter 就可以啟用 ipfilter 服務。

Step 2: 修改 ipfilter 設定檔 /etc/ipf/ipf.conf

  • 依序加入以下設定 (順序非常重要,block 的設定要放在最後面):
    pass in quick log proto tcp from 10.10.10.0/24 to any port = 22
    pass in quick log proto tcp from 10.10.11.0/24 to any port = 22
    block in log proto tcp from any to any port = 22
  • 上述設定可允許來自 10.10.10.0 ~ 10.10.10.255 & 10.10.11.0 ~ 10.10.11.255 的 ssh 連線 (inbound),其他 source ip 一律會被阻擋。這是比較簡單的設定法,只要把來自非法網域的 inbound traffic 擋住了,就不用考慮 outbound traffic 了。
Step 3: 執行 ipf -Fa -f /etc/ipf/ipf.conf,以 flush all 並重讀 firewall 規則表。可再執行 ipfstat -io 來確認目前inbound & outbound的規則為何。

Step 4: 在背景執行ipmon,紀錄被阻擋的連線
  • ipmon /path/to/ipf/log &
  • 被阻擋的紀錄範例如下:
    20/02/2012 14:14:07.082422 e1000g0 @0:4 b 10.1.xx.xx,40258 -> 10.1.xx.xx,22 PR tcp len 20 60 -S IN
RHEL/CentOS 4/5
參考:
  1. TCP Wrapper for added Security on SSH
  2. /etc/hosts.{allow|deny} 的設定方式
由於 /etc/hosts.{allow|deny} 設定比較簡單,且 RHEL/CentOS 4/5內建的sshd就有支援 TCP Wrapper,所以就用這種方式囉。

Step 1: 確認目前使用的 sshd 是否支援 TCP Wrapper
  • 執行 ldd /usr/sbin/sshd | grep libwrap,應出現以下 output:
    libwrap.so.0 => /usr/lib/libwrap.so.0 (0x00b22000)
Step 2: 編輯 /etc/hosts.allow (不可使用 10.10.0.0/16 表示法):
  • sshd:10.10.10.0/255.255.255.0
    sshd:10.10.11.0/255.255.255.0
Step 3: 編輯 /etc/hosts.deny (不可使用 10.10.0.0/16 表示法):
  • sshd:ALL

Step 4: 設定完畢後不需重起 sshd,會立刻生效。

Step 5: 查看被阻擋的紀錄

  • log 檔位置在 /var/log/secure,可執行 grep refused /var/log/secure 來查看
  • 範例如下:
    Feb 17 17:26:53 [hostname] sshd[3034]: refused connect from ::ffff:xxx.xx.xxx.xx (::ffff:xxx.xx.xxx.xx)

2012-03-03 Update:
有網友留言詢問此設定能否阻擋reverse ssh tunnel over http,找了一下資料,利用這篇文章中的作法實作之後,發現在連線時 source IP 會是 127.0.0.1,因此只要在 /etc/hosts.allow 裡面不要允許來自 127.0.0.1 的連線,reverse ssh tunnel 就不會通了。

雖然這篇的作法看來是沒有「over http」,但應該只要觀察 ssh 連線的 source IP,就可以利用 /etc/hosts.{allow|deny} 來阻擋了。


2010年8月12日

[Linux/Unix] 讓 script 在登出後仍可繼續在背景執行 - at 排程

之前的文章中曾經提到,因為改了 cron job 的執行時間,導致 awstats.pl 執行失敗,必須重跑 cron job。由於是在週末發現這個狀況,因此我透過 VPN 連回公司下指令 (sh /path/to/awstats.pl -update ...),但由於 VPN 有限制幾分鐘內沒有向 server 要求資料就會自動斷線,但 awstats.pl 分析一個網站往往要耗時 15~20 分鐘,且 VPN 連線過程中若登出 server (手動 or 被踢出),則執行中的 script 就會被中斷了,最後發現利用 at 排程 + 背景執行就可以解決這個問題。

只要輸入 at HH:mm YYYY-MM-DD,按 Enter 後,再輸入「perl /path/to/awstats.pl -update ... &」,按 Enter,最後按 ctrl+d 結束 at 排程的編輯即可。

其中關於 at 排程的設定可參考:鳥哥-僅執行一次的工作排程,至於如何讓 script 於背景執行,請參考:鳥哥-job control的管理

利用 at 排程設定的工作,即使在執行此排程的帳號登出系統的狀況下仍然可以正確執行,就和利用 cron job 執行排定的工作一樣。

當然要對每個網站都手動輸入一次指令也太麻煩了,最好是把所有的 awstats.pl -update 指令包成一個 .sh 檔案,之後就只要執行那個 .sh 檔就可以啦!

參考資料:

2010年3月1日

[Linux/Unix] 養成好習慣,使用 passwd 指令要註明欲變更的帳號

今天維護廠商要以 root 帳號登入某台 linux 主機的時候發現無法登入,密碼不知道被誰改掉,查了老半天之後發現兇手就是我 Orz(不過廠商還不知道這件事情=.=) 在將 root 密碼還原以後,從 /var/log/secure 裡面就可以看到 pam_unix 模組所寫的 log 了。


根據 log 可以看出,造成這次意外的原因在於上週剛好進行設備交接,因此在該主機上建立了我的帳號,但我在沒注意到目前使用者身份是 root 的情況下使用 passwd 指令變更密碼,才會造成這樣的結果。因此,養成好習慣,在變更系統狀態前先確認目前的使用者身份是誰,思考一下會不會造成副作用,是很重要的!

先來看一下 passwd 指令的說明:
passwd_1

重點在於 [username] 這個參數,此參數若忽略,表示要變更的是「目前下達 passwd 指令的使用者」的密碼;若加上 [username] 參數,則可變更指定使用者的密碼 (當然前提是執行指令的 user 要有足夠的權限)。由於大部分時候都是用自己的帳號在系統中操作,因此下 passwd 指令也只會影響自己的密碼,因此都養成習慣忽略掉 [username] 參數,這時候如果不小心用「su」或「su -」指令切換為 root 身份,就有可能不小心變更到 root 的密碼 。

雖然下達 passwd 指令後螢幕上會印出一行:Changing password for user [username],但是有時候就是沒注意到,當成功變更密碼後,螢幕上印出的是:passwd: all authentication tokens updated successfully.,看到 successfully 這個字眼以後就覺得很放心,不會想太多了 =.=
所以,在變更 root 密碼的過程中,螢幕上會看到以下資料:

passwd_2

結論:養成習慣加上 [username] 參數是最好的作法,這樣在下指令的時候就會很清楚要變更的密碼是屬於哪個使用者的,例如確實要變更 root 密碼時:
passwd_3

都已經打了「passwd root」了,總該有自覺現在是要變更 root 的密碼了吧!
補充1:雖然上面有出現「BAD PASSWORD: it is based on a dictionary word」的警告訊息,但系統還是讓我成功變更密碼了,為什麼呢?那是因為目前我的執行身份是 root,而 root 的權限是最大的,可以忽略在 pam_unix 模組中所設定的任何限制!

之所以要補充這一點,是因為前陣子我在練習實作帳號管理的功能時,一開始都用 root 帳號登入 (這也是因為當時沒有限制 root 不能以 SSH 連線登入,but … 這個改天再講好了),導致我設定的「密碼必須大於 6 個字元」等等限制看似完全無效,因為 root 是可以為所欲為的!害我一直覺得很奇怪,不是有「BAS PASSWORD:」的 warning 嗎,為甚麼系統還是可以讓我變更密碼 Orz 這又說明了「隨時隨地都要注意到目前是以甚麼身份下達指令」的重要性,否則可是會平白無故的浪費很多寶貴時間的阿!

補充2:若某帳號有 sudo 權限,則 sudo passwd 命令修改的會是 root 的密碼,如下圖:
passwd_4

而透過 sudo 下的指令在 /var/log/secure 中會留下紀錄:
passwd_5

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D