夜空中的笑臉


今天在客戶這邊上完課要回飯店時,一抬頭突然發現夜空中的月亮似乎有些不一樣,怎麼好像一張笑臉似的,感覺月亮上方的兩顆星星超亮的說,趕緊叫住 Jason 與小廖,拿出手機來拍,不過拍出的效果實在@#$%....

於是乾脆到車上拿車相機來拍,回到飯店將照片寄給洋蔥媽咪看,才發現原來大家都看到了啊,上網查詢了一下,原來今天是初四的眉月,月亮如上揚的嘴角,加上月亮上方的那兩顆星星是金星與木星呢,難怪我覺得怎麼今天的星星這麼亮...據說,這種天文景象,下次要到 2036 年才會再出現呢,雖然和洋蔥媽咪及小洋蔥分處在高雄與台北,但我們仍能一起看到同樣的星空,我想,應該也是一種幸福吧~ (詳全文...)

如何在 WindowsXP 上叫出 NetMeeting ㄌㄟ?

同事突然問說 WindowsXP 上怎麼沒有 NetMeeting ㄌㄟ?要怎麼把他叫出來啊?
呵呵,其實,WindowsXP 上面還是有附 NetMeeting 的,只是沒有捷徑罷了,他的路徑就在 C:\Program Files\NetMeeting\conf.exe 啦,直接執行或拉個捷徑出來就行了,當然也可以用下面的方式叫出來:
1. 由左下角的[開始]功能表,選 [執行]:

2. 敲入conf,按下碓定執行:
3. NetMeeting 打開囉...

不過我順便在另一台 Windows Vista 上試了一下,發現原來 Vista 上已經將 NetMeeting 拿掉,改成 Windows 會議室了;以下是 Microsoft 官方網站上的說明:
Microsoft Windows XP 是 Windows 的最後一個用戶端版本,其中包含 NetMeeting。 NetMeeting 並未隨附 Windows Vista。

為了在這種情況下支援目前的共同作業工作階段,Hotfix 是可用可讓您在 Windows Vista 架構的電腦上安裝 NetMeeting。此 NetMeeting 版本被作為轉換工具,可以協助支援共同作業工作階段當您在您的環境中使用 Windows XP 電腦搭配 Windows Vista 架構的電腦。

參考資料:
Microsoft 技術支援服務:Hotfix 是可以在執行 Windows Vista 的電腦上安裝 NetMeeting 3.02
(詳全文...)

SNMP on LINUX server 之 exec 自訂訊息實作

之前我們講到用 snmpd 裡面的 proc + 服務名稱來監視特定的服務狀態,但這只對部分的服務有效,例如 ntpd, snmpd, nfsd, httpd...等等,我不太確定他的抓取方式,但似乎,用 ps 去看如果 process name 沒出現在最前面的,似乎 snmpd 就 monitor 不到,這種狀況像 Tomcat 就會出現。舉例來說,我有個服務是用到 java 去帶起來的,如下面所示:
[root@KHXAAAS1 ~]# ps -aef|grep AAA|grep -v AAA
root 19475 1 0 09:13 ? 00:00:11 java -Xmx512m -Daaa.base=/opt/AAA -Daaa.run=/opt/AAA/run -Daaa.bin=/opt/AAA/bin -Daaa.lib=/opt/AAA/lib -Daaa.jni=/opt/AAA/jni com.lucent.aaa.gui.ServerManagementTool -debug info
root 21631 1 0 Sep12 ? 00:01:39 java -Daaa.base=/opt/AAA -Daaa.run=/opt/AAA/run -Daaa.bin=/opt/AAA/bin -Daaa.lib=/opt/AAA/lib -Daaa.jni=/opt/AAA/jni com.lucent.aaa.ConfigServer
root 26302 1 0 09:41 pts/0 00:00:08 java -Xmx512m -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -Dsun.rmi.dgc.server.gcInterval=0x7FFFFFFFFFFFFFFE -Dsun.rmi.dgc.client.gcInterval=0x7FFFFFFFFFFFFFFE -Daaa.base=/opt/AAA -Daaa.run=/opt/AAA/run -Daaa.bin=/opt/AAA/bin -Daaa.lib=/opt/AAA/lib -Daaa.jni=/opt/AAA/jni com.lucent.aaa.PolicyServer -debug debug
但用 snmpd 去監控 proc AAA 的話,一定看不到東西,(雖然可以用 proc Java 的方式來 monitor,但畢竟用 Java 帶起來的服務越來越多,這樣並不容易區分,容易造成誤判。)這個時候就可以用一個變通的方式來 monitor 我們要的服務狀態,那就是 exec 這個 snmpd.conf 裡的 option,他的用法是:
Usage:
exec MIBOID EXEC-COMMAND
我們直接實作一下好了。

首先假設我們有一個如前面說的服務用 proc AAA 方式加到 /etc/snmp/snmpd.conf 裡面卻無法正常 monitor 到服務的狀態時,而且假設,我們有一個簡單的判斷服務正常啟動的方法時(通常是像我們這裡示範的這種,灌了一個某某廠商的軟體時,想改變他的啟動方式或參數又無從改起時),如下所示,今天的實作目標有兩台 AAA server,上面有兩個主要的 process 要檢查狀態,
其中一個是 Policy server 另一個是 Configuration server,為了待會兒的測試,我先將其中第一台 KHXAAAS1 的 Policy server 先停掉,第二台 KHXAAAS2 的服務全部都讓他正常帶起來:
[root@KHXAAAS1 ~]# /opt/AAA/bin/aaa list all
The server could not be reached: Connection refused
8950 AAA Policy Server: not responding
101 Server active
8950 AAA Configuration Server: responding
[root@KHXAAAS2 ~]# /opt/AAA/bin/aaa list all
101 Server active
8950 AAA Policy Server: responding
101 Server active
8950 AAA Configuration Server: responding
說簡單點,/etc/snmpd/snmpd.conf 裡的 exec 這個 option 其實就是宣告一個 OID,然後當 SNMP server query 到這個 OID 時,就去執行指定的 shell scrpit 然後將直塞回剛剛指定的 OID.101.x 裡面去。接下來我們直接做一個簡單示範:

首先我們先 vi /etc/snmp/snmpd.conf(或用下面的 echo 指令也行)在裡面新加上一行如下的格式:
[root@KHXAAAS1 ~]# echo "exec .1.3.6.1.4.1.2021.51 ApplicationStatusQury /bin/sh /bin/ASQ.sh" >> /etc/snmp/snmpd.conf
檢查一下確實寫進去了:
[root@KHXAAAS1 ~]# grep ApplicationStatusQury /etc/snmp/snmpd.conf
exec .1.3.6.1.4.1.2021.51 ApplicationStatusQury /bin/sh /bin/ASQ.sh
接著我們編輯一個簡單的 shell script 叫 /bin/ASQ-AAA.sh 用來檢查 Policy server 和 Configuration server 的狀態,寫到 /opt/.ASQ-AAA-Policy.prState 與 /opt/.ASQ-AAA-Config.prState 裡面(這裡我先定義一下,如果這個file裡面的值是 responding 代表 服務正常,如果是 not responding 的話,代表服務掛點了,當然也可以用 wc -l 去讓這個 fiie 帶的值為 0 或 1 ):
[root@KHXAAAS1 ~]# cat /bin/ASQ-AAA.sh
#!/bin/sh
/opt/AAA/bin/aaa list policy > /opt/.ASQ-AAA-Policy.prState1
cat /opt/.ASQ-AAA-Policy.prState1|cut -d ":" -f2 > /opt/.ASQ-AAA-Policy.prState2
#grep 'not responding' /opt/.ASQ-AAA-Policy.prState1|wc -l > /opt/.ASQ-AAA-Policy.prState2

/opt/AAA/bin/aaa list config > /opt/.ASQ-AAA-Config.prState1
cat /opt/.ASQ-AAA-Config.prState1|cut -d ":" -f2 > /opt/.ASQ-AAA-Config.prState2
#grep 'not responding' /opt/.ASQ-AAA-Config.prState1|wc -l > /opt/.ASQ-AAA-Config.prState2
exit
然後我們再寫個 /bin/ASQ-AAA.sh 用來檢查 /opt/.ASQ-AAA-Policy.prState2 與 /opt/.ASQ-AAA-Config.prState2 裡面的值,分別寫進 1.3.6.1.4.1.2021.51.101.1 與 1.3.6.1.4.1.2021.51.101.2 這兩個 OID 去,如果你在剛剛的 schipt 裡面有 3 個 output,那就會還有 1.3.6.1.4.1.2021.51.101.3 這個 OID,依此類推...
[root@KHXAAAS1 ~]# cat /bin/ASQ.sh
#!/bin/sh
echo `cat /opt/.ASQ-AAA-Policy.prState2`
echo `cat /opt/.ASQ-AAA-Config.prState2`
exit
接著用 crontab -e 把他加進 cron job 去吧,這裡我們讓他每兩分鐘執行一次 Application Status Qury 的 script,可自行更改。
[root@KHXAAAS1 ~]# crontab -l
*/2 * * * * /bin/PSQ-AAA.sh
剛剛改完 /etc/snmp/snmpd.conf 之後我們還沒重起 snmpd 的服務,所以現在去查詢 .1.3.6.1.4.1.2021.51 這個 OID 應該會得倒下面的回應:
[root@KHXAAAS1 ~]# snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.2021.51
UCD-SNMP-MIB::ucdavis.51 = No Such Object available on this agent at this OID
再來要開始驗證了,先確定一下兩台 AAA server 上的服務是把第一台的 Policy server 停下來的狀態,第二台則是保持 service 正常:
[root@KHXAAAS1 ~]# /opt/AAA/bin/aaa list all
The server could not be reached: Connection refused
8950 AAA Policy Server: not responding
101 Server active
8950 AAA Configuration Server: responding
[root@KHXAAAS2 ~]# /opt/AAA/bin/aaa list all
101 Server active
8950 AAA Policy Server: responding
101 Server active
8950 AAA Configuration Server: responding
接下來先重啟一下 snmpd service 來讓剛剛我們改的部分生效:
[root@KHXAAAS1 ~]# service snmpd restart
Stopping snmpd: [ OK ]
Starting snmpd: [ OK ]
好啦,現在可以查詢看看囉,先在本機上查詢一下(當然你也可以從你的 SNMP server 端來查詢) 我們剛剛新定義的 OID:
[root@KHXAAAS1 ~]# snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.2021.51
UCD-SNMP-MIB::ucdavis.51.1.1 = INTEGER: 1
UCD-SNMP-MIB::ucdavis.51.2.1 = STRING: "ApplicationStatusQury"
UCD-SNMP-MIB::ucdavis.51.3.1 = STRING: "/bin/sh /bin/ASQ.sh"
UCD-SNMP-MIB::ucdavis.51.100.1 = INTEGER: 0
UCD-SNMP-MIB::ucdavis.51.101.1 = STRING: "not responding"
UCD-SNMP-MIB::ucdavis.51.101.2 = STRING: "responding"
UCD-SNMP-MIB::ucdavis.51.102.1 = INTEGER: 0
UCD-SNMP-MIB::ucdavis.51.103.1 = ""
如果是用 wc -l 去 count 的話那應該會像下面這樣:
UCD-SNMP-MIB::ucdavis.51.101.1 = STRING: "1"
UCD-SNMP-MIB::ucdavis.51.101.2 = STRING: "0"
當然在這裡我們需要的是 .1.3.6.1.4.1.2021.51.101.1 and .1.3.6.1.4.1.2021.51.101.2 這兩個 OID,對應到 Policy server 和 Configuration server 的服務狀態。所以由 SNMP server 端就可以直接設定一個 Passive Monitor 來 Polling 這兩個 OID 的值。
[root@KHXEMSS1 ~]# snmpwalk -v 2c -c public khxaaas1 .1.3.6.1.4.1.2021.51.101.1
UCD-SNMP-MIB::ucdavis.51.101.1 = STRING: "not responding"
[root@KHXEMSS1 ~]# snmpwalk -v 2c -c public khxaaas1 .1.3.6.1.4.1.2021.51.101.2
UCD-SNMP-MIB::ucdavis.51.101.2 = STRING: "responding"
[root@KHXEMSS1 ~]# snmpwalk -v 2c -c public khxaaas2 .1.3.6.1.4.1.2021.51.101.1
UCD-SNMP-MIB::ucdavis.51.101.1 = STRING: "responding"
[root@KHXEMSS1 ~]# snmpwalk -v 2c -c public khxaaas2 .1.3.6.1.4.1.2021.51.101.2
UCD-SNMP-MIB::ucdavis.51.101.2 = STRING: "responding"
所以上面就代表第一台 KHXAAAS1 的 Policy server 有問題。OK...報告完畢。
(詳全文...)

用 mysqldump 來 Backup/Restore MySQL 的 DB data

今天收到客戶的要求要把 DB server 上的 MySQL data 做個定期備份,所以就順便實作一下~
首先,這裡的環境是:

兩台 DB server 上都有 MySQL Enterprise v2.0.56,
OS 都是 RedHat EL ES4U5,另外這兩台 DB server 上還有 Veritas 做 HA。
我們就不說廢話了,直接開始吧:

MySQL 備份資料庫主要有兩種方法,一種是用 Hard copy 的方法,也就是直接把 ~/mysql/data/[資料庫名稱]/* 通通備份下來,如果要到回去資料庫,資料庫版本要一樣喔,免得發生非預期的結果。不過這種方法備份還原時最好先把 mysqld 停下來。
要看 MySQL 是否執行中可用下面的指令 "mysqladmin status":
[root@KHXDBS1 ~]# /opt/mysql/enterprise/monitor/mysql/bin/mysqladmin status
/opt/mysql/enterprise/monitor/mysql/bin/mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)'
Check that mysqld is running and that the socket: '/tmp/mysql.sock' exists!
而要檢查剛剛所說的資料庫所在的位置,可以去查看一下 /etc/init.d/mysql 個檔案的內容,由於這裡的環境是兩台 DB server 後面接著一座 Storage,所以我把 datadir (資料庫路徑) 改到 /DB (由後端 Storage mount 過來)底下:
[root@KHXDBS1 ~]# grep "datadir=/" /etc/init.d/mysql
# datadir=/var/lib/mysql
datadir=/DB/var/lib/mysql
[root@KHXDBS1 ~]# cp -pR /DB/var/lib/mysql/AAA /DB/mysql/backup/.
其中 AAA 是這次要備份的的 schema 啦。

還有一種作法是用 mysqldump 將資料倒出來 *.sql,指令格式為:
mysqldump -h [Host] -u[DbUserName] -p[DbPassword] [DbName] > [filename].sql
簡單的例子:
mysqldump -h 127.0.0.1 -uroot -pOOXX AAA > /DB/mysql/backup/dbMysqlArchive_XXXX.sql
要做 Restore 時可以用下面的指令範例來倒:
mysql -h 127.0.0.1 -uroot -pOOXX AAA < /DB/mysql/backup/dbMysqlArchive_XXXX.sql
對了,Restore 之前要先確定 AAA 的 Schema 還存在喔~
下面是附上簡單寫的一個小 script 去每天晚上作個備份...給大家參考一下:
[root@KHXDBS1 ~]# crontab -l 10 2 * * * /bin/DB_archive.sh > /dev/null 2>&1
[root@KHXDBS1 ~]# cat /bin/DB_archive.sh
#!/bin/sh -vx
#
# DB server : Backup DB data
# Version: @01
#
INITIAL_DIR=/opt/logs
HOSTNAME=`hostname |cut -c -7`
LOG_APPENDIX=`date +"%Y-%m%d"`
LOCK_FILE=$INITIAL_DIR/.dbMysqlArchive_lock
LOG_FILE=$INITIAL_DIR/$HOSTNAME-dbMysqlArchive_$LOG_APPENDIX.log
ERR_COUNTER=0
FIX_COUNTER=0
MAIN_SEPERATOR="==============="
SEC_SEPERATOR="#---------------------------------------------------------------------------------------#"
NOW=`date +%Y-%m-%d-%H:%M:%S`
ARC_EXT=`date +%Y%m%d%H`
ARC_DIR=/DB/mysql/backup
ARC_FILE=$ARC_DIR/dbMysqlArchive_$ARC_EXT.sql

if [ ! -f "$LOCK_FILE" ]; then
touch $LOCK_FILE
else
echo $MAIN_SEPERATOR >> $LOG_FILE
echo $NOW >> $LOG_FILE
echo "$LOCK_FILE exist" >> $LOG_FILE
echo $MAIN_SEPERATOR >> $LOG_FILE
exit
fi

if [ `rsh khxdb hostname|cut -c -7|grep $HOSTNAME|wc -l` = 1 ]; then
/usr/bin/find $INITIAL_DIR -name "$HOSTNAME-dbMysqlArchive*.log" -mtime +8 -exec rm {} \;
/usr/bin/find $ARC_DIR -name "dbMysqlArchive_*.sql" -mtime +8 -exec rm {} \;

echo $SEC_SEPERATOR >> $LOG_FILE
echo "# DB server mysql data archive script starting #" >> $LOG_FILE
echo $SEC_SEPERATOR >> $LOG_FILE
#------------------------ Archive MySQL data ----------------------------------------------#
echo "Start to excute mysqldump command at $NOW ..." >> $LOG_FILE
echo "" >> $LOG_FILE
/opt/mysql/enterprise/monitor/mysql/bin/mysqldump -h 127.0.0.1 -uroot -pOOXX AAA > $ARC_FILE
if [ `ls -l $ARC_FILE| wc -l` = 1 ]; then
echo "$ARC_FILE created..." >> $LOG_FILE
else
echo "$ARC_FILE create fail, Please check it now..." >> $LOG_FILE
fi
rm -rf $LOCK_FILE
echo $SEC_SEPERATOR >> $LOG_FILE
echo "# DB server MySQL data archive script finished #" >> $LOG_FILE
echo $SEC_SEPERATOR >> $LOG_FILE
#------------------------------------------------------------------------------------------#
else
echo $NOW >> $LOG_FILE
echo "This server is NOT the active one !!!" >> $LOG_FILE
echo "Check script is stopping !!!" >> $LOG_FILE
echo $SEC_SEPERATOR >> $LOG_FILE
rm -rf $LOCK_FILE
fi
[root@KHXDBS1 ~]#
備份完會像下面所示的例子喔:
[root@KHXDBS1 ~]# ls -alrt /DB/mysql/backup/
total 168
drwxr-xr-x 3 root root 4096 Oct 14 15:25 ..
-rw-r--r-- 1 root root 77092 Oct 15 02:10 dbMysqlArchive_2008101502.sql
drwxr-xr-x 2 root root 4096 Oct 14 15:55 .

搞定!收工。
(詳全文...)

讓 history command 顯示時間記錄 on LINUX

有時候在機器上查詢曾經下過的指令記錄時,多半大家看到的都是如下面的格式吧:
[root@KHXPROVS1 ~]# history
1 ifconfig -a;
2 service ntpd status; ntpq -p;
3 df -h;
4 service vsftpd status;
5 history
[root@KHXPROVS1 ~]#
可是如果這台機器有很多人都會進來用的話呢?那我怎麼知道某個特別的指令是在什麼時間下的呢?能不能在 history 秀出的紀錄裡加上時間戳記呢?當然可以,在 bash 的變數裡面有一個叫 HISTTIMEFORMAT 就可以達到這麼需求,我們就來實作一下吧:

首先,這個變數必須在 BASH 3.0 以上才有提供喔,如果以 RedHat Enterprise 的版本來看 , 要 RHEL 4 ES/AS 以後的版本才行!

先確認一下目前 BASH 的版本吧:
[root@KHXPROVS1 ~]# rpm -q bash
bash-3.0-19.3
看來版本是 OK 的,接著編輯一下 /etc/profile 或者直接用下面的指令把變數宣告進去:
echo "HISTTIMEFORMAT='<%F %T>:'" >> /etc/profile
echo "export HISTTIMEFORMAT" >> /etc/profile
當然,編輯完的話,存檔離開,接著用:
[root@KHXPROVS1 ~]# source /etc/profile
或者離開目前的 shell 再登入一次,然後再敲一次 history 指令看一下結果:
[root@KHXPROVS1 ~]# history
1 <2008-10-08 18:02:22>ifconfig -a;
2 <2008-10-08 18:02:22>service ntpd status; ntpq -p;
3 <2008-10-08 18:02:22>df -h;
4 <2008-10-08 18:02:22>service vsftpd status;
5 <2008-10-08 18:02:22>history
6 <2008-10-08 18:02:22>rpm -q bash
7 <2008-10-08 18:02:22>echo "HISTTIMEFORMAT='<%F %T>:'" >> /etc/profile
8 <2008-10-08 18:02:22>echo "export HISTTIMEFORMAT" >> /etc/profile
9 <2008-10-08 18:02:22>source /etc/profile
10 <2008-10-08 18:03:15>history
[root@KHXPROVS1 ~]#
果然,每個歷史指令的前面都多了時間戳記囉~

參考資料:GNU 官網的 5.2 Bash Variables
(詳全文...)

在 Linux 上增加一個新服務並設為開機啟動

上次裝完 JAVA 跟 Tomcat 之後,是用手動的方式將 Tomcat 的服務帶起來的,(啟動:/opt/tomcat/bin/startup.sh 停止:/opt/tomcat/bin/shutdown.sh)這次我們要做的就是將 Tomcat 加為系統的一個服務,改為可用 service service_name start/stop 的方式來啟動跟關閉:

首先,我們先到 /etc/init.d/ 底下去新增一個 tomcat 的檔案 (記得要改為可執行喔~)
[root@KHXPROVS1 ~]# touch /etc/init.d/tomcat
[root@KHXPROVS1 ~]# chmod 755 /etc/init.d/tomcat
[root@KHXPROVS1 bin]# ls -alrt /etc/init.d/ |grep tomcat
-rwxr-xr-x 1 root root 609 Oct 2 16:10 tomcat
編輯 /etc/init.d/tomcat 的內容,這個檔案的寫法可以參考系統上面 /etc/init.d/ 下的其他檔案;
比較重要的是第二行,其語法為:
# chkconfig: [runlevels] [start number] [stop number]
# runlevels 代表不同的 run level 狀態, start number 與 stop number 則是在 /etc/rc.d/rc[2345].d 內建立以 S90tomcat 及 K80tomcat 為檔名的設定。
[root@KHXPROVS1 ~]# vi /etc/init.d/tomcat
#!/bin/bash
# process init file for tomcat
#
# chkconfig: 2345 90 80
# description: Apache Tomcat Daemon
#
# processname: /opt/tomcat/bin/startup.sh and /opt/tomcat/bin/shutdown.sh

start() {
echo -n "Starting up Tomcat: ";echo "";
/opt/tomcat/bin/startup.sh
}

stop() {
echo -n "Shutting down Tomcat: ";echo "";
/opt/tomcat/bin/shutdown.sh
}

restart() {
echo "Restarting Tomcat:"
stop
start
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "Usage: Tomcat {start|stop|restart}"
exit 1
esac

exit $?
~
~
~
~
"/etc/rc.d/init.d/tomcat" 39L, 524C written
修改完存檔離開,接著我們檢查一下目前 tomcat 是否有啟動:
[root@KHXPROVS1 ~]# ps -aef|grep tomcat
root 22754 22207 0 15:53 pts/2 00:00:00 grep tomcat
好了,現在就來測試一下剛剛的檔案囉,首先,測試一下啟動 tomcat 服務吧:
[root@KHXPROVS1 ~]# service tomcat start
Starting up Tomcat:
Using CATALINA_BASE: /opt/tomcat
Using CATALINA_HOME: /opt/tomcat
Using CATALINA_TMPDIR: /opt/tomcat/temp
Using JRE_HOME: /usr
[root@KHXPROVS1 ~]# ps -aef|grep tomcat|grep -v grep
root 22775 1 30 15:53 pts/2 00:00:11 /usr/bin/java -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties -Djava.endorsed.dirs=/opt/tomcat/endorsed -classpath :/opt/tomcat/bin/bootstrap.jar -Dcatalina.base=/opt/tomcat -Dcatalina.home=/opt/tomcat -Djava.io.tmpdir=/opt/tomcat/temp org.apache.catalina.startup.Bootstrap start
接著,測試一下停止 tomcat 服務吧:
[root@KHXPROVS1 ~]# service tomcat stop
Shutting down Tomcat:
Using CATALINA_BASE: /opt/tomcat
Using CATALINA_HOME: /opt/tomcat
Using CATALINA_TMPDIR: /opt/tomcat/temp
Using JRE_HOME: /usr
[root@KHXPROVS1 ~]# ps -aef|grep tomcat|grep -v grep
最後,測試一下重新啟動 tomcat 服務吧:
[root@KHXPROVS1 ~]# service tomcat restart
Restarting Tomcat:
Shutting down Tomcat:
Using CATALINA_BASE: /opt/tomcat
Using CATALINA_HOME: /opt/tomcat
Using CATALINA_TMPDIR: /opt/tomcat/temp
Using JRE_HOME: /usr
Starting up Tomcat:
Using CATALINA_BASE: /opt/tomcat
Using CATALINA_HOME: /opt/tomcat
Using CATALINA_TMPDIR: /opt/tomcat/temp
Using JRE_HOME: /usr
[root@KHXPROVS1 ~]# ps -aef|grep tomcat|grep -v grep
root 23001 1 99 15:55 pts/2 00:00:07 /usr/bin/java -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties -Djava.endorsed.dirs=/opt/tomcat/endorsed -classpath :/opt/tomcat/bin/bootstrap.jar -Dcatalina.base=/opt/tomcat -Dcatalina.home=/opt/tomcat -Djava.io.tmpdir=/opt/tomcat/temp org.apache.catalina.startup.Bootstrap start
[root@KHXPROVS1 ~]#
接下來要讓 tomcat 在次開機時都會自動啟動,這裡我們用 chkconfig 這個指令來達成,
先用 --list 將目前的各項服務狀態列出來並 grep 一下 tomcat:
[root@KHXPROVS1 ~]# chkconfig --list|grep tomcat
看的出來目前 tomcat 並不在 chkconfig 的管理列表中,所以我們用 --add 來新增 tomcat 的服務 (增加一個服務名稱給 chkconfig 來管理,該服務名稱 必須存在 /etc/init.d/ 內!)
[root@KHXPROVS1 ~]# chkconfig --add tomcat
[root@KHXPROVS1 ~]# chkconfig --list|grep tomcat
tomcat 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@KHXPROVS1 ~]#
我們列出 /etc/rc.d/rcx.d/ 底下關於 tomcat 的部分:
[root@KHXPROVS1 ~]# find /etc/rc.d/ |grep 'tomcat'|sort
/etc/rc.d/init.d/tomcat
/etc/rc.d/rc0.d/K80tomcat
/etc/rc.d/rc1.d/K80tomcat
/etc/rc.d/rc2.d/S90tomcat
/etc/rc.d/rc3.d/S90tomcat
/etc/rc.d/rc4.d/S90tomcat
/etc/rc.d/rc5.d/S90tomcat
/etc/rc.d/rc6.d/K80tomcat
好了,報告完畢~
(詳全文...)

SNMP proxy to Sub-Agent on LINUX server 實作

上次的 snmp 測試中,測試匯入了 RADIUS 相關的幾個 MIB 檔,並用 snmptranslate 確認過 snmpd 已經可以認得我們所新匯入的 OBJECT-TYPE 與 OID了;但是,如果使用 snmpwalk 去查詢相關 OID 的值時,卻會出現查詢不到的窘境。

那麼對於一個系統不認得的 OID 要怎麼辦呢?我們來示範一下用 proxy 的選項達到這個結果。今天的範例是,在原本的 AAA Server 上,除了原本系統的 snmpd 以外,另外啟動一個 AAA 的 snmp Agent,假設這個新的 Agent 所 Listening 的 port 為 1461,那麼,目前系統上就應該有在 listening 下面的這些 ports:
[root@KHXAAAS2 ~]# netstat -an |grep 161
udp 0 0 0.0.0.0:161 0.0.0.0:*
[root@KHXAAAS2 ~]# netstat -an |grep 162
udp 0 0 0.0.0.0:162 0.0.0.0:*
unix 2 [ ACC ] STREAM LISTENING 21620 /tmp/.font-unix/fs7100

[root@KHXAAAS2 ~]# netstat -an |grep 1461
udp 0 0 :::1461 :::*
其中 0 0.0.0.0:161 是系統 snmpd 所使用的,而 0 :::1461 是新 AAA Agent 所使用。

這裡我們先列一下關於 porxy 這個 option 的用法:
proxy [-Cn CONTEXTNAME] [SNMPCMD ARGS] HOST OID [REMOTEOID]
This token specifies that any incoming requests under OID should be proxied on to another HOST instead. If a CONTEXTNAME is specified, it assigns the proxied tree to a particular context name within the local agent. This is the proper way to query multiple agents through a single proxy. Assign each remote agent to a different context name. Then you can use "snmpwalk -n contextname1" to walk one remote proxied agent and "snmpwalk -n contextname2" to walk another, assuming you are using SNMPv3 to talk to the proxy (snmpv1 and snmpv2c context mappings aren't currently supported but might be in the future). Optionally, relocate the local OID tree to the new location at the REMOTEOID. To authenticate to HOST you should use the appropriate set of SNMPCMD ARGS. See the snmpcmd(1) manual page for details.
接下來我們編輯一下 snmp 的設定檔,將下面這一行加到檔案的最後就可以:(這一行便是要將 OID 為 1.3.6.1.2.1.67 以下的轉給 localhost:1461 也就是 AAA Agent 來處理啦 )
[root@KHXAAAS2 ~]# vi /etc/snmp/snmpd.conf
#前面這些設定就省略不列出來了...
proxy -v 2c -c public localhost:1461 .1.3.6.1.2.1.67
~
~
"/etc/snmp/snmpd.conf" 481L, 19481C written
存檔離開,再重啟 snmpd 之前我們先觀察一下目前 snmpwalk 的結果:
首先這是經由 snmpd:161 查詢 SNMPv2-MIB::sysDescr.0 的結果:
[root@KHXAAAS2 ~]# snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.1.1
SNMPv2-MIB::sysDescr.0 = STRING: Linux KHXAAAS2 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:58:04 EST 2007 i686
接著這是經由 snmpd:161 查詢 RADIUS-AUTH-SERVER-MIB::radiusAuthServIdent.0 的結果:
[root@KHXAAAS2 ~]# snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.67.1.1.1.1.1.0
RADIUS-AUTH-SERVER-MIB::radiusAuthServIdent.0 = No Such Object available on this agent at this OID
很明顯的目前透過 snmpd 的 161 port 是查詢不到 RADIUS-AUTH-SERVER-MIB::radiusAuthServIdent.0 的內容的;
接下來我們再試一下經由 AAA Agent:1461 查詢 RADIUS-AUTH-SERVER-MIB::radiusAuthServIdent.0 的結果:
[root@KHXAAAS2 ~]# snmpwalk -v 2c -c public localhost:1461 .1.3.6.1.2.1.67.1.1.1.1.1.0
RADIUS-AUTH-SERVER-MIB::radiusAuthServIdent.0 = STRING: Alcatel-Lucent 8950 AAA PolicyServer, Version 6.0.1
所以目前的狀況就是,分開以 port 161 和 1461 只可以分別查詢到不同 OID 的值;

接著我們重啟一下 snmpd 服務,讓剛剛的 proxy 設定讀進去:
[root@KHXAAAS2 ~]# service snmpd restart
Stopping snmpd: [ OK ]
Starting snmpd: [ OK ]
好了,讓我們再試一次吧:
[root@KHXAAAS2 ~]# snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.67.1.1.1.1.1.0
RADIUS-AUTH-SERVER-MIB::radiusAuthServIdent.0 = STRING: Alcatel-Lucent 8950 AAA PolicyServer, Version 6.0.1
[root@KHXAAAS2 ~]# snmpwalk -v 2c -c public localhost:1461 .1.3.6.1.2.1.67.1.1.1.1.1.0
RADIUS-AUTH-SERVER-MIB::radiusAuthServIdent.0 = STRING: Alcatel-Lucent 8950 AAA PolicyServer, Version 6.0.1
很明顯的,在加上這一行之後,直接查詢 snmpd:161 已經可以看到跟查詢 AAA Agent:1461 相同的結果囉~

這裡有兩篇 snmpd 相關 command 的詳細使用說明可以參考喔:
http://pwet.fr/man/linux/formats/snmp/snmpd_conf
http://pwet.fr/man/linux/commandes/snmpcmd
(詳全文...)

SNMP 匯入新 MIB on LINUX server

這次我們要測試的機器仍然是 RHEL ES4U6 的環境,已經裝好相關的 net-snmp (net-snmp-5.1.2-11.EL4.11) 程式,下面列出測試要匯入的為 RADIUS 相關的幾個 MIB 檔:
RADIUS-AUTH-SERVER-MIB.txt
RADIUS-AUTH-CLIENT-MIB.txt
RADIUS-ACC-SERVER-MIB.txt
RADIUS-ACC-CLIENT-MIB.txt
RADIUS-DYNAUTH-SERVER-MIB.txt
RADIUS-DYNAUTH-CLIENT-MIB.txt
先用 snmptranslate 來確認一下 snmpd 是否可以認得我們要匯入的 OBJECT-TYPE 與 OID:
[root@KHXAAAS2 mibs]# snmptranslate -On -IR radiusAuthServMIBCompliance
Unknown object identifier: radiusAuthServMIBCompliance
[root@KHXAAAS2 mibs]# snmptranslate -Td .1.3.6.1.2.1.67.1.1.2.1.1
SNMPv2-SMI::mib-2.67.1.1.2.1.1
mib-2 OBJECT-TYPE
-- FROM SNMPv2-SMI, RFC1213-MIB
::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) 67 1 1 2 1 1 }
看起來目前是翻譯不出我們所要查 RADIUS 相關的 OBJECT-TYPE 與 OID,好了,接下來就是這次的工作囉:

首先,我們將 RADIUS 這幾個 MIB 檔複製到 /usr/share/snmp/mibs 底下:
[root@KHXAAAS2 ~] mkdir -p $HOME/.snmp
[root@KHXAAAS2 ~] cp -p /tmp/RADIUS* /usr/share/snmp/mibs/
接著就是告訴 snmpd 去 load 這些 MIB:

有兩種方式,暫時測試可用第一種方法,只對目前的 session 有效:
[root@KHXAAAS2 ~] export MIBS=+MY-MIB
或者是第二種方法:
[root@KHXAAAS2 ~] echo "mibs +RADIUS-AUTH-SERVER-MIB" >> $HOME/.snmp/snmp.conf
[root@KHXAAAS2 ~] echo "mibs +RADIUS-AUTH-CLIENT-MIB" >> $HOME/.snmp/snmp.conf
[root@KHXAAAS2 ~] echo "mibs +RADIUS-ACC-SERVER-MIB" >> $HOME/.snmp/snmp.conf
[root@KHXAAAS2 ~] echo "mibs +RADIUS-ACC-CLIENT-MIB" >> $HOME/.snmp/snmp.conf
[root@KHXAAAS2 ~] echo "mibs +RADIUS-DYNAUTH-SERVER-MIB" >> $HOME/.snmp/snmp.conf
[root@KHXAAAS2 ~] echo "mibs +RADIUS-DYNAUTH-CLIENT-MIB" >> $HOME/.snmp/snmp.conf
or
[root@KHXAAAS2 ~] echo "mibs +ALL" >> $HOME/.snmp/snmp.conf
也是可以,用 ALL 會把所有可用的 MIB 都 LOAD 進來,當然包括剛剛的幾個測試 MIB 檔,不過速度上會比較慢喔。(注意喔,如果是用
echo "mibs +RADIUS-DYNAUTH-CLIENT-MIB" 的方式,要記得把後面的 .txt 去掉喔~)

好了,先看一下 MIBDIR 的目錄下有些什麼囉:
[root@KHXAAAS2 mibs]# pwd
/usr/share/snmp/mibs
[root@KHXAAAS2 mibs]# ls -alrt
total 1740
-rw-r--r-- 1 root root 38034 Jul 19 2007 SNMPv2-TC.txt
-rw-r--r-- 1 root root 8924 Jul 19 2007 SNMPv2-SMI.txt
-rw-r--r-- 1 root root 29305 Jul 19 2007 SNMPv2-MIB.txt
-rw-r--r-- 1 root root 8263 Jul 19 2007 SNMPv2-CONF.txt
-rw-r--r-- 1 root root 9106 Jul 19 2007 SNMP-PROXY-MIB.txt
-rw-r--r-- 1 root root 1174 Jul 19 2007 RFC-1215.txt
-rw-r--r-- 1 root root 79667 Jul 19 2007 RFC1213-MIB.txt
-rw-r--r-- 1 root root 3067 Jul 19 2007 RFC1155-SMI.txt
-rw-r--r-- 1 root root 71691 Jul 19 2007 IF-MIB.txt
-rw-r--r-- 1 root root 5066 Jul 19 2007 IF-INVERTED-STACK-MIB.txt
-rw-r--r-- 1 root root 84492 Jul 19 2007 EtherLike-MIB.txt
-rw-r--r-- 1 root root 4076 Jul 19 2007 UDP-MIB.txt
-rw-r--r-- 1 root root 10765 Jul 19 2007 TCP-MIB.txt
-rw-r--r-- 1 root root 2205 Jul 19 2007 SNMP-USM-AES-MIB.txt
-rw-r--r-- 1 root root 147822 Jul 19 2007 RMON-MIB.txt
-rw-r--r-- 1 root root 24723 Jul 19 2007 NOTIFICATION-LOG-MIB.txt
-rw-r--r-- 1 root root 4400 Jul 19 2007 IPV6-UDP-MIB.txt
-rw-r--r-- 1 root root 2367 Jul 19 2007 IPV6-TC.txt
-rw-r--r-- 1 root root 7257 Jul 19 2007 IPV6-TCP-MIB.txt
-rw-r--r-- 1 root root 48703 Jul 19 2007 IPV6-MIB.txt
-rw-r--r-- 1 root root 15936 Jul 19 2007 IPV6-ICMP-MIB.txt
-rw-r--r-- 1 root root 23499 Jul 19 2007 IP-MIB.txt
-rw-r--r-- 1 root root 26781 Jul 19 2007 IP-FORWARD-MIB.txt
-rw-r--r-- 1 root root 12517 Jul 19 2007 INET-ADDRESS-MIB.txt
-rw-r--r-- 1 root root 4660 Jul 19 2007 HCNUM-TC.txt
-rw-r--r-- 1 root root 64311 Jul 19 2007 DISMAN-SCRIPT-MIB.txt
-rw-r--r-- 1 root root 24613 Jul 19 2007 DISMAN-SCHEDULE-MIB.txt
-rw-r--r-- 1 root root 17455 Jul 19 2007 AGENTX-MIB.txt
-rw-r--r-- 1 root root 35242 Jul 19 2007 UCD-SNMP-MIB.txt
-rw-r--r-- 1 root root 8118 Jul 19 2007 UCD-IPFWACC-MIB.txt
-rw-r--r-- 1 root root 2163 Jul 19 2007 UCD-DEMO-MIB.txt
-rw-r--r-- 1 root root 22769 Jul 19 2007 SNMP-TARGET-MIB.txt
-rw-r--r-- 1 root root 4628 Jul 19 2007 SMUX-MIB.txt
-rw-r--r-- 1 root root 4318 Jul 19 2007 NET-SNMP-TC.txt
-rw-r--r-- 1 root root 2036 Jul 19 2007 NET-SNMP-MIB.txt
-rw-r--r-- 1 root root 6741 Jul 19 2007 NET-SNMP-EXAMPLES-MIB.txt
-rw-r--r-- 1 root root 15650 Jul 19 2007 NET-SNMP-AGENT-MIB.txt
-rw-r--r-- 1 root root 4299 Jul 19 2007 IANA-LANGUAGE-MIB.txt
-rw-r--r-- 1 root root 20126 Jul 19 2007 IANAifType-MIB.txt
-rw-r--r-- 1 root root 4743 Jul 19 2007 IANA-ADDRESS-FAMILY-NUMBERS-MIB.txt
-rw-r--r-- 1 root root 10583 Jul 19 2007 HOST-RESOURCES-TYPES.txt
-rw-r--r-- 1 root root 52544 Jul 19 2007 HOST-RESOURCES-MIB.txt
-rw-r--r-- 1 root root 3010 Jul 19 2007 UCD-DLMOD-MIB.txt
-rw-r--r-- 1 root root 3198 Jul 19 2007 UCD-DISKIO-MIB.txt
-rw-r--r-- 1 root root 34162 Jul 19 2007 SNMP-VIEW-BASED-ACM-MIB.txt
-rw-r--r-- 1 root root 5775 Jul 19 2007 SNMPv2-TM.txt
-rw-r--r-- 1 root root 39201 Jul 19 2007 SNMP-USER-BASED-SM-MIB.txt
-rw-r--r-- 1 root root 20014 Jul 19 2007 SNMP-NOTIFICATION-MIB.txt
-rw-r--r-- 1 root root 5496 Jul 19 2007 SNMP-MPD-MIB.txt
-rw-r--r-- 1 root root 22342 Jul 19 2007 SNMP-FRAMEWORK-MIB.txt
-rw-r--r-- 1 root root 15490 Jul 19 2007 SNMP-COMMUNITY-MIB.txt
-rw-r--r-- 1 root root 5931 Jul 19 2007 LM-SENSORS-MIB.txt
-rw-r--r-- 1 root root 68177 Jul 19 2007 DISMAN-EVENT-MIB.txt
drwxr-xr-x 4 root root 4096 Jun 12 04:28 ..
-rw-rw---- 1 root root 28446 Aug 29 00:32 RADIUS-AUTH-SERVER-MIB.txt
-rw-rw---- 1 root root 26373 Aug 29 00:32 RADIUS-AUTH-CLIENT-MIB.txt
-rw-rw---- 1 root root 26281 Aug 29 00:32 RADIUS-ACC-SERVER-MIB.txt
-rw-rw---- 1 root root 23747 Aug 29 00:32 RADIUS-ACC-CLIENT-MIB.txt
-rw-rw---- 1 root root 29247 Aug 29 00:32 RADIUS-DYNAUTH-SERVER-MIB.txt
-rw-rw---- 1 root root 31892 Aug 29 00:32 RADIUS-DYNAUTH-CLIENT-MIB.txt
drwxr-xr-x 2 root root 4096 Oct 2 10:16 .
-rw-r--r-- 1 root root 2058 Oct 2 10:16 .index
不用重起 snmpd 的服務,我們直接再查詢一次試試看:

[root@KHXAAAS2 mibs]# snmptranslate -On -IR radiusAuthServMIBCompliance
.1.3.6.1.2.1.67.1.1.2.1.1
[root@KHXAAAS2 mibs]# snmptranslate -Td .1.3.6.1.2.1.67.1.1.2.1.1
RADIUS-AUTH-SERVER-MIB::radiusAuthServMIBCompliance
radiusAuthServMIBCompliance MODULE-COMPLIANCE
-- FROM RADIUS-AUTH-SERVER-MIB
DESCRIPTION "The compliance statement for authentication
servers implementing the RADIUS Authentication
Server MIB. Implementation of this module is for
IPv4-only entities, or for backwards compatibility
use with entities that support both IPv4 and
IPv6."
::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) radiusMIB(67) radiusAuthentication(1) radiusAuthServMIB(1) radiusAuthServMIBConformance(2) radiusAuthServMIBCompliances(1) 1 }
果然就可以查詢的到 RADIUS 的 OBJECT-TYPE 與 OID 囉...

參考資料:Net-SNMP FAQ How do I add a MIB
(詳全文...)

SNMP on LINUX server 實作(二)--補遺

回到公司測試另外一台機器時才發現,噫?這台機器上怎麼沒有 snmpwalk 之類的指令可以用呢?同樣是 RHEL ES4U6 啊,其實這個問題很簡單,只是因為這一台機器當初安裝只選了部分安裝,所以關於 snmp 的部分僅安裝了 net-snmp 的 package,卻沒有安裝相關的 utility 罷了。

先看一下目前系統上關於 snmp 的指令有哪些:
[root@KHXAAAS2 ~]# ls -al /usr/sbin/snmp*
-rwxr-xr-x 1 root root 25180 Jul 19 2007 /usr/sbin/snmpd
-rwxr-xr-x 1 root root 21700 Jul 19 2007 /usr/sbin/snmptrapd
[root@KHXAAAS2 ~]# ls -al /usr/bin/snmp*
ls: /usr/bin/snmp*: No such file or directory
可以看得出目前只有兩個 snmp daemon 而已,其餘相關的指令都不存在。
再檢查一下目前所安裝的 rpm:
[root@KHXAAAS2 ~]# rpm -qa|grep net-snmp
net-snmp-libs-5.1.2-11.EL4.11
net-snmp-5.1.2-11.EL4.11
[root@KHXAAAS2 ~]#
果然沒有看到 net-snmp-utils-5.1.2-11.EL4.11 的影子啊...

到 Google 上搜尋一下或者直接到 RPM Search 去抓一個回來用吧...



這裡列出這個 RPM 檔的 Requires :
perl(Net::SMTP)
libnetsnmp.so.5
perl(Getopt::Std)
libc.so.6(GLIBC_2.0)
rpmlib(PayloadFilesHavePrefix) <= 4.0-1 /usr/bin/perl libcrypto.so.4 libc.so.6(GLIBC_2.3) libelf.so.1 libm.so.6 rpmlib(CompressedFileNames) <= 3.0.4-1 libc.so.6(GLIBC_2.1) net-snmp = 5.1.2 perl(File::Copy) perl(Data::Dumper) perl(IO::File) perl(Term::ReadLine) libc.so.6
下面是這個 RPM 檔中的可用指令部分:(Content of RPM :)
/usr/bin/encode_keychange
/usr/bin/fixproc
/usr/bin/ipf-mod.pl
/usr/bin/snmpbulkget
/usr/bin/snmpbulkwalk
/usr/bin/snmpconf
/usr/bin/snmpdelta
/usr/bin/snmpdf
/usr/bin/snmpget
/usr/bin/snmpgetnext
/usr/bin/snmpinform
/usr/bin/snmpnetstat
/usr/bin/snmpset
/usr/bin/snmpstatus
/usr/bin/snmptable
/usr/bin/snmptest
/usr/bin/snmptranslate
/usr/bin/snmptrap
/usr/bin/snmpusm
/usr/bin/snmpvacm
/usr/bin/snmpwalk
/usr/bin/traptoemail


抓到了 net-snmp-utils-5.1.2-11.EL4.11.i386.rpm 之後直接 ftp 到待測機器上吧,這次開個目錄 /rpm 專門擺放 RPM packages 好了:
[root@KHXAAAS2 ~]# cd /rpm
[root@KHXAAAS2 rpm]# ls -al
total 184
drwxr-xr-x 2 root root 4096 Sep 24 18:15 .
drwxr-xr-x 27 root root 4096 Sep 24 18:15 ..
-rw-r--r-- 1 root root 162078 Sep 24 18:15 net-snmp-utils-5.1.2-11.EL4.11.i386.rpm
接下來就直接安裝吧:
[root@KHXAAAS2 rpm]# rpm -Uvh net-snmp-utils-5.1.2-11.EL4.11.i386.rpm
warning: net-snmp-utils-5.1.2-11.EL4.11.i386.rpm: V3 DSA signature: NOKEY, key ID 1d1e034b
Preparing... ########################################### [100%]
1:net-snmp-utils ########################################### [100%]
好了,這時我們再檢查一次 snmp 相關的指令吧:
[root@KHXAAAS2 rpm]# ls -al /usr/sbin/snmp*
-rwxr-xr-x 1 root root 25180 Jul 19 2007 /usr/sbin/snmpd
-rwxr-xr-x 1 root root 21700 Jul 19 2007 /usr/sbin/snmptrapd
[root@KHXAAAS2 rpm]# ls -al /usr/bin/snmp*
-rwxr-xr-x 1 root root 6820 May 3 2007 /usr/bin/snmpbulkget
-rwxr-xr-x 1 root root 8560 May 3 2007 /usr/bin/snmpbulkwalk
-rwxr-xr-x 1 root root 21177 May 3 2007 /usr/bin/snmpconf
-rwxr-xr-x 1 root root 15076 May 3 2007 /usr/bin/snmpdelta
-rwxr-xr-x 1 root root 8804 May 3 2007 /usr/bin/snmpdf
-rwxr-xr-x 1 root root 6504 May 3 2007 /usr/bin/snmpget
-rwxr-xr-x 1 root root 6368 May 3 2007 /usr/bin/snmpgetnext
lrwxrwxrwx 1 root root 8 Sep 24 18:16 /usr/bin/snmpinform -> snmptrap
-rwxr-xr-x 1 root root 42948 May 3 2007 /usr/bin/snmpnetstat
-rwxr-xr-x 1 root root 7960 May 3 2007 /usr/bin/snmpset
-rwxr-xr-x 1 root root 10556 May 3 2007 /usr/bin/snmpstatus
-rwxr-xr-x 1 root root 18148 May 3 2007 /usr/bin/snmptable
-rwxr-xr-x 1 root root 11516 May 3 2007 /usr/bin/snmptest
-rwxr-xr-x 1 root root 10912 May 3 2007 /usr/bin/snmptranslate
-rwxr-xr-x 1 root root 9272 May 3 2007 /usr/bin/snmptrap
-rwxr-xr-x 1 root root 17612 May 3 2007 /usr/bin/snmpusm
-rwxr-xr-x 1 root root 15916 May 3 2007 /usr/bin/snmpvacm
-rwxr-xr-x 1 root root 8352 May 3 2007 /usr/bin/snmpwalk
[root@KHXAAAS2 rpm]#
果然多了不少有用的指令囉~

[root@KHXAAAS2 rpm]# rpm -qa|grep net-snmp
net-snmp-libs-5.1.2-11.EL4.11
net-snmp-5.1.2-11.EL4.11
net-snmp-utils-5.1.2-11.EL4.11

各個指令的詳細說明可以參考 Net-SNMP 官方網站的教學:
http://net-snmp.sourceforge.net/wiki/index.php/Tutorials
(詳全文...)

SNMP on LINUX server 實作

這幾天把 site 的幾台機器開始要加到 SNMP server 裡,所以得先把 幾台機器上的 SNMP 打開設定好,至少要能從 SNMP server 去 polling,然後能送 SNMP Traps 到 SNMP server 去...

先檢查一下 snmpd 的狀態,應該是未啟動的:
[root@KHXPROVS1 ~]# service snmpd status
snmpd is stopped
再檢查一下是否開機會啟動 snmpd 的服務:
[root@KHXPROVS1 ~]# chkconfig --list|grep snmpd
snmpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
所以我們先用 chkconfig 的指令讓 snmpd 一開機便會自行啟動:
[root@KHXPROVS1 ~]# chkconfig --level 345 snmpd on
接著打開 snmpd 的服務:
[root@KHXPROVS1 ~]# service snmpd start
Starting snmpd: [ OK ]
再來我們先嘗試著用 snmpwalk 的指令來查詢一下主機:
[root@KHXPROVS1 ~]# snmpwalk -v 1 localhost -c public system
Timeout: No Response from localhost
[root@KHXPROVS1 ~]# snmpwalk -v 2c -c public localhost system
Timeout: No Response from localhost
關於 snmpwalk 的用法,可以直接看 manual:
[root@KHXPROVS1 ~]# snmpwalk
No hostname specified.
USAGE: snmpwalk [OPTIONS] AGENT [OID]

Version: 5.1.2
Web: http://www.net-snmp.org/
Email: net-snmp-coders@lists.sourceforge.net

OPTIONS:
-h, --help display this help message
-H display configuration file directives understood
-v 1|2c|3 specifies SNMP version to use
-V, --version display package version number
SNMP Version 1 or 2c specific
-c COMMUNITY set the community string
SNMP Version 3 specific
-a PROTOCOL set authentication protocol (MD5|SHA)
-A PASSPHRASE set authentication protocol pass phrase
-e ENGINE-ID set security engine ID (e.g. 800000020109840301)
-E ENGINE-ID set context engine ID (e.g. 800000020109840301)
-l LEVEL set security level (noAuthNoPriv|authNoPriv|authPriv)
-n CONTEXT set context name (e.g. bridge1)
-u USER-NAME set security name (e.g. bert)
-x PROTOCOL set privacy protocol (DES|AES)
-X PASSPHRASE set privacy protocol pass phrase
-Z BOOTS,TIME set destination engine boots/time
General communication options
-r RETRIES set the number of retries
-t TIMEOUT set the request timeout (in seconds)
Debugging
-d dump input/output packets in hexadecimal
-D TOKEN[,...] turn on debugging output for the specified TOKENs
(ALL gives extremely verbose debugging output)
General options
-m MIB[:...] load given list of MIBs (ALL loads everything)
-M DIR[:...] look in given list of directories for MIBs
-P MIBOPTS Toggle various defaults controlling MIB parsing:
u: allow the use of underlines in MIB symbols
c: disallow the use of "--" to terminate comments
d: save the DESCRIPTIONs of the MIB objects
e: disable errors when MIB symbols conflict
w: enable warnings when MIB symbols conflict
W: enable detailed warnings when MIB symbols conflict
R: replace MIB symbols from latest module
-O OUTOPTS Toggle various defaults controlling output display:
a: print all strings in ascii format
b: do not break OID indexes down
e: print enums numerically
E: escape quotes in string indices
f: print full OIDs on output
n: print OIDs numerically
q: quick print for easier parsing
Q: quick print with equal-signs
s: print only last symbolic element of OID
S: print MIB module-id plus last element
t: print timeticks unparsed as numeric integers
T: print human-readable text along with hex strings
u: print OIDs using UCD-style prefix suppression
U: don't print units
v: print values only (not OID = value)
x: print all strings in hex format
X: extended index format
-I INOPTS Toggle various defaults controlling input parsing:
b: do best/regex matching to find a MIB node
h: don't apply DISPLAY-HINTs
r: do not check values for range/type legality
R: do random access to OID labels
u: top-level OIDs must have '.' prefix (UCD-style)
s SUFFIX: Append all textual OIDs with SUFFIX before parsing
S PREFIX: Prepend all textual OIDs with PREFIX before parsing
-L LOGOPTS Toggle various defaults controlling logging:
e: log to standard error
o: log to standard output
f file: log to the specified file
s facility: log to syslog (via the specified facility)

(variants)
[EO] pri: log to standard error/output for level 'pri' and above
[EO] p1-p2: log to standard error/output for levels 'p1' to 'p2'
[FS] pri token: log to file/syslog for level 'pri' and above
[FS] p1-p2 token: log to file/syslog for levels 'p1' to 'p2'
-C APPOPTS Set various application specific behaviours:
p: print the number of variables found
i: include given OID in the search range
c: do not check returned OIDs are increasing
t: Display wall-clock time to complete the request
剛剛,我們分別用 v1 跟 v2c 去查詢都沒得到回應,因為 snmpd 的設定檔還沒編輯過,所以我們先編輯一下 /etc/snmp/snmpd.conf 檔,這是 snmpd 的設定檔,其中有幾個地方要改的:

1.首先找一下 com2sec notConfigUser default public 這一段,然後改成如下所示:(其中 10.16.25.25 是 SNMP server 的 IP address)
#com2sec notConfigUser default public
com2sec local localhost public
com2sec mynetwork 10.16.25.25 public
2. 再來是找 group notConfigGroup v1 notConfigUser 這一段,然後改成如下所示:
#group notConfigGroup v1 notConfigUser
#group notConfigGroup v2c notConfigUser
group MyRWGroup v1 local
group MyRWGroup v2c local
group MyROGroup v1 mynetwork
group MyROGroup v2c mynetwork
3. 接著是找 view all included .1 80 這一段,然後改成如下所示:(把前面的 # 去掉)
## incl/excl subtree mask
view all included .1 80
4. 找到 #access MyROGroup "" any noauth 0 all none none 這一段,改成如下所示:
#access MyROGroup "" any noauth 0 all none none
#access MyRWGroup "" any noauth 0 all all all
access MyROGroup "" any noauth prefix all none none
access MyRWGroup "" any noauth prefix all all all
5. 再找一下 syslocation Unknown (configure /etc/snmp/snmp.conf)這一段,改成如下所示:(其中 syslocation 用來告知你機器所在的位置)
syslocation GangShan
syscontact Root (configure /etc/snmp/snmp.local.conf)
6. 接下來是設定 process monitor 的部分,找到 #proc mountd 這一行的位置,這裡假設我們機器上面有 ftp 的服務,而且我們想監視服務的狀態那就可以改成如下所示:
#proc mountd
proc snmpd
proc vsftpd

procfix vsftpd /sbin/service vsftpd restart
(其中 procfix 那一行是在 process 沒有 running 時執行的)。

7. 再來是關於硬碟容量的監視,找到 #disk / 10000 這一段,這裡假設我們要監視 / ,上限是 85% 的使用限制,我們可以設定如下:
#disk / 10000
disk / 15%
好囉,先改這一部分,存檔然後將 snmpd 的服務重啟吧:
[root@KHXPROVS1 ~]# service snmpd restart
Stopping snmpd: [ OK ]
Starting snmpd: [ OK ]
8. 好了,做個簡單的測試吧,先查詢一下硬碟的監視狀況吧:
[root@KHXPROVS1 ~]# snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.2021.9
UCD-SNMP-MIB::dskIndex.1 = INTEGER: 1
UCD-SNMP-MIB::dskPath.1 = STRING: /
UCD-SNMP-MIB::dskDevice.1 = STRING: /dev/sda2
UCD-SNMP-MIB::dskMinimum.1 = INTEGER: -1
UCD-SNMP-MIB::dskMinPercent.1 = INTEGER: 15
UCD-SNMP-MIB::dskTotal.1 = INTEGER: 41286828
UCD-SNMP-MIB::dskAvail.1 = INTEGER: 31760584
UCD-SNMP-MIB::dskUsed.1 = INTEGER: 7428960
UCD-SNMP-MIB::dskPercent.1 = INTEGER: 19
UCD-SNMP-MIB::dskPercentNode.1 = INTEGER: 6
UCD-SNMP-MIB::dskErrorFlag.1 = INTEGER: 0
UCD-SNMP-MIB::dskErrorMsg.1 = STRING:
9. 再來,查詢一下服務的監視狀況吧:
[root@KHXPROVS1 ~]# snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.2021.2
UCD-SNMP-MIB::prIndex.1 = INTEGER: 1
UCD-SNMP-MIB::prIndex.2 = INTEGER: 2
UCD-SNMP-MIB::prNames.1 = STRING: snmpd
UCD-SNMP-MIB::prNames.2 = STRING: vsftpd
UCD-SNMP-MIB::prMin.1 = INTEGER: 0
UCD-SNMP-MIB::prMin.2 = INTEGER: 0
UCD-SNMP-MIB::prMax.1 = INTEGER: 0
UCD-SNMP-MIB::prMax.2 = INTEGER: 0
UCD-SNMP-MIB::prCount.1 = INTEGER: 1
UCD-SNMP-MIB::prCount.2 = INTEGER: 1
UCD-SNMP-MIB::prErrorFlag.1 = INTEGER: 0
UCD-SNMP-MIB::prErrorFlag.2 = INTEGER: 0
UCD-SNMP-MIB::prErrMessage.1 = STRING:
UCD-SNMP-MIB::prErrMessage.2 = STRING:
UCD-SNMP-MIB::prErrFix.1 = INTEGER: 0
UCD-SNMP-MIB::prErrFix.2 = INTEGER: 0
UCD-SNMP-MIB::prErrFixCmd.1 = STRING:
UCD-SNMP-MIB::prErrFixCmd.2 = STRING: /sbin/service vsftpd restart
假設我現在將 vsftpd 服務給停下來,那麼再做一次 snmp query 就會發現 1.3.6.1.4.1.2021.2.1.101 (UCD-SNMP-MIB::prErrMessage.2)的內容變成了:
UCD-SNMP-MIB::prErrMessage.2 = STRING: No vsftpd process running.
10. 接著我們在做個測試,直接用 snmptrap 的指令將 UCD-SNMP-MIB::prErrMessage.2 的值當成 traps 的內容送出到 SNMP server 去:
[root@KHXPROVS1 ~]# /usr/bin/snmptrap -v 2c -c public 10.16.25.25 "" .1.3.6.1.4.1.2021.2.1.101 .1.3.6.1.4.1.2021.2.1.101 s "HOST:KHXP
PROVS1|EVENT=No vsftpd process running."
另外,我們打開 tcpdump 看一下是否有攔到這個 traps 送出:
[root@KHXPROVS1 ~]# tcpdump -vvvXX host 10.16.25.25 -i eth0 and port 162 -s 0
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes


18:23:55.648888 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto 17, length: 165) KHXPROVS1.tatung.net.tw.32796 > 10.16.25.25.snmptrap: [bad udp cksum a09d!] { SNMPv2c { V2Trap(121) R=2145043168 system.sysUpTime.0=37325417 S:1.1.4.1.0=E:2021.2.1.101 E:2021.2.1.101="HOST:KHXPROVS1|EVENT=No vsftpd process running." } }
0x0000: 001d 0926 b7cd 001e c9ad 5464 0800 4500 ...&......Td..E.
0x0010: 00a5 0000 4000 4011 f3ef 0a10 1920 0a10 ....@.@.........
0x0020: 1919 801c 00a2 0091 46fb 3081 8602 0101 ........F.0.....
0x0030: 0406 7075 626c 6963 a779 0204 7fda c2e0 ..public.y......
0x0040: 0201 0002 0100 306b 3010 0608 2b06 0102 ......0k0...+...
0x0050: 0101 0300 4304 0239 8a69 3018 060a 2b06 ....C..9.i0...+.
0x0060: 0106 0301 0104 0100 060a 2b06 0104 018f ..........+.....
0x0070: 6502 0165 303d 060a 2b06 0104 018f 6502 e..e0=..+.....e.
0x0080: 0165 042f 484f 5354 3a4b 4858 5052 4f56 .e./HOST:KHXPROV
0x0090: 5331 7c45 5645 4e54 3d4e 6f20 7673 6674 S1|EVENT=No.vsft
0x00a0: 7064 2070 726f 6365 7373 2072 756e 6e69 pd.process.runni
0x00b0: 6e67 2e ng.

1 packets captured
1 packets received by filter
0 packets dropped by kernel
[root@KHXPROVS1 ~]#
測試完畢,如果這時在 SNMP server 上有 MIB Browser 之類的軟體,便可收到剛剛送出的 ALARM Traps 囉。

下次有機會再把檢查以及送 traps 出去的簡單 scripts 列上來給大家參考吧...


此處列出其他幾個常用的語法:

設定基本的 snmpd 參數:
snmpconf -i -g basic_setup (輔助建立、修改配置文件)
snmpget -v 1 -c public 127.0.0.1 ssCpuRawSystem.0
UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 2377652724

轉換物件名稱的數值形式與可閱讀形式、查詢 MIB 資訊:
snmptranslate -On -Td -IR ssCpuRawSystem
.1.3.6.1.4.1.2021.11.52
ssCpuRawSystem OBJECT-TYPE
— FROM UCD-SNMP-MIB
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION “system CPU time.”
::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) ucdavis(2021) systemStats(11) 52 }
snmptranslate -Td .1.3.6.1.4.1.2021.11.52
UCD-SNMP-MIB::ssCpuRawSystem
ssCpuRawSystem OBJECT-TYPE
— FROM UCD-SNMP-MIB
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION “system CPU time.”
::= { iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) ucdavis(2021) systemStats(11) 52 }
以 SNMP 查詢網路上主機的硬碟用量:
[root@KHXPROVS1 ~]# snmpdf -v 1 -c public -Cu khxprovs1 (<<>
Description size (kB) Used Available Used%
/ 41286828 7433684 33853144 18%
取得網路上主機系統狀態:
[root@KHXPROVS1 ~]# snmpstatus -v 1 -c public khxprovs1 (<<>
[127.0.0.1]=>[Linux KHXPROVS1 2.6.9-55.ELsmp #1 SMP Fri Apr 20 17:03:35 EDT 2007 i686] Up: 16:15:02.30
Interfaces: 0, Recv/Trans packets: 1529/1529 | IP: 38894376/58055763

Net-SNMP 首頁:http://www.net-snmp.org/
查詢 MIB file 或 OID 的好站:ipMonitor Support Portal :: Mibs
(詳全文...)