[linux]rsyslogで特定の文字列を含むメッセージを別のファイルに出力させる

rsyslogで特定の文字列を含むメッセージを別のファイルに出力させる方法。

iptablesのログなどを/var/log/messages以外に出力させたいときなどに使用可能。

「iptables」という文字列を含むメッセージを/var/log/iptablesに出力させるにはこんな感じ。「~」で除外して/var/log/messagesに出力させなくするのがポイント。

# vi /etc/rsyslog.conf

:msg,contains,“iptables” /var/log/iptables;LocalFormat
:msg,contains,”iptables” ~

:(省略)
*.info;mail.none;authpriv.none;cron.none                /var/log/messages;LocalFormat

[linux]rsyslog(messagesなど)にログレベル(severity,重大度)を表示する

rsyslogで出力するシステムログにログレベル(シビリティ・重大度)を表示させる方法。

syslogでは起動オプションを付ける方法であったが、rsyslogでは設定ファイルに定義する。

設定ファイル(/etc/rsyslog.conf)には、ログレベルを追加したログフォーマットを「$template」で始まる行で定義し、出力する定義のアクションにログフォーマットを指定する。

# vi /etc/rsyslog.conf
:(省略)
$template LocalFormat,”%timereported% %hostname% %syslogfacility-text%.%syslogseverity-text%: %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n”
:(省略)
*.info;mail.none;authpriv.none;cron.none /var/log/messages;LocalFormat

出力されるログはこんな感じ

Oct 20 03:21:26 hogehoge kern.warning: kernel: [iptables SYN FLOOD] IN=eth0 OUT= MAC=02:16:3e:4f:39:

「%syslogtag%」やら「%syslogfacility-text%」の意味は

# man rsyslog.conf

の「Available Properties」の項に書いてあるので、そっちを見て。

[linux]rshのタイムアウト

残念ながらRHEL(RedHat)のrshコマンドにはタイムアウトのオプションが実装されていない。
rsh実行中にOSPFなどの動的ルーティングで経路が変わったりネットワークの状態に変化があった場合、
rshコマンドのパケットが戻ってこれずに、いつまで経ってもrshコマンドが終了しないという困った状態になる。
rshコマンドのタイムアウトが実装されていない場合の回避方法。
スクリプト使います。
ポイントは

  • rshをバックグラウンド実行
  • bashの特殊変数SECONDSを使用して、スクリプト開始からの経過時間を取得し、それを利用する

です。

#!/bin/bash

# タイムアウト秒数指定
timeoutsec=120

rsh "リモートコマンド" &
# バックグラウンド実行(rsh)のpidを取得
bpid=$!

startsec=${SECONDS}

while [[ 1 == 1 ]]
do

    # rshコマンド終了チェック
    stdout=$( ps auwwwwx | egrep "^.+[[:space:]]${bpid}[[:space:]]")
    if [[ -z "${stdout}" ]];then
        # 終了している
    	break
    fi
    
    # 経過分数を取得
    nowsec=${SECONDS}
    
    # rsh開始からの経過分数取得
    (( divsec=${nowsec}-${startsec} ))
    if (( ${divsec} > ${timeoutsec} ));then
    	# タイムアウト
    	kill -9 ${bpid}
    fi
    
    sleep 10
done

 

[linux]RPMパッケージの依存性を調べる方法

rpmパッケージのパッケージ依存を調べる方法

インストール済みパッケージの場合

rpm -qR [パッケージ名]

で調べられる。

# rpm -qR kernel
rpmlib(VersionedDependencies) <= 3.0.3-1
fileutils
module-init-tools
initscripts >= 8.11.1-1
kernel-firmware >= 2.6.32-220.4.1.el6
grubby >= 7.0.4-1
dracut-kernel >= 002-18.git413bcf78
/sbin/new-kernel-pkg
/sbin/new-kernel-pkg
/bin/sh
/bin/sh
/bin/sh
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(PayloadIsXz) <= 5.2-1
rpmlib(VersionedDependencies) <= 3.0.3-1
fileutils
module-init-tools
initscripts >= 8.11.1-1
kernel-firmware >= 2.6.32-220.4.2.el6
grubby >= 7.0.4-1
dracut-kernel >= 002-18.git413bcf78
/sbin/new-kernel-pkg
/sbin/new-kernel-pkg
/bin/sh
/bin/sh
/bin/sh
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(PayloadIsXz) <= 5.2-1
rpmlib(VersionedDependencies) <= 3.0.3-1
fileutils
module-init-tools
initscripts >= 8.11.1-1
kernel-firmware >= 2.6.32-220.7.1.el6
grubby >= 7.0.4-1
dracut-kernel >= 002-18.git413bcf78
/sbin/new-kernel-pkg
/sbin/new-kernel-pkg
/bin/sh
/bin/sh
/bin/sh
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(PayloadIsXz) <= 5.2-1

 

rpmパッケージファイルから調べる場合

rpm -qpR [パッケージファイルパス]

で調べられる。

# rpm -qpR zabbix-1.8.5-2.el6.JP.x86_64.rpm
警告: zabbix-1.8.5-2.el6.JP.x86_64.rpm: ヘッダ V4 DSA/SHA1 Signature, key ID f32904ff: NOKEY
/bin/sh
/usr/sbin/useradd
logrotate
rpmlib(CompressedFileNames) rpmlib(FileDigests) rpmlib(PayloadFilesHavePrefix) rpmlib(PayloadIsXz)

[linux]パケットキャプチャ

linuxでパケットキャプチャ

通信してるか確かめるだけなら

# tcpdump -i <NICデバイス名> port <ポート番号> and host <IPアドレス>

通信している内容も確かめたいときは

# tcpdump -Xx -s 4096 -i <NICデバイス名> dst port <ポート番号>? and? src host? <IPアドレス>

後でwiresharkで確かめたいときは(ファイルに保存)

# tcpdump -w <保存するファイル名> -s 4096 -i <NICデバイス名> dst port <ポート番号>? and? src host? <IPアドレス>

ってか最初からwiresharkでやれよ!

CUIフェチなもんで。

[linux]syslog(messagesなど)にログレベルを表示する

システムログ(syslogで出力するログ)に、ログレベルを出力させる方法。
ログレベル(重大度)でログ監視させたい場合に非常に便利。

rsyslog版はこちら

syslogdの起動オプションに「-SS」を追加する。
RHEL(CentOS)ならこんな感じ。

# vi /etc/sysconfig/syslog
:(省略)
SYSLOGD_OPTIONS=”-m 0 -SS
:(省略)

オプションを追加したらsyslogdを再起動

# service syslog restart

/var/log/messagesにはこんな感じで出力される

Aug 5 01:19:39 <syslog.info> hostname syslogd 1.4.1: restart.
Aug 5 01:19:39 <kern.info> hostname kernel: klogd 1.4.1, log source = /proc/kmsg started.

[linux]マルチパスSANブート+ボリュームコピー環境でのリストア方法

Linux(RHEL)+マルチパスSANブート+ディスク装置のボリュームコピー環境でのシステムリストア方法。

最近では、ディスク装置の機能として持っている、論理ボリュームを丸ごとコピーする機能を利用して、システムバックアップを取得するのが、お手軽バックアップとして流行っている模様。
これを利用すると、コピー元のディスクがつぶれた場合、コピー先のディスクをホストに見せるようにするだけで(プレゼントやらマッピングやらマスキングやら・・・)リストアできるように見えるが、LInux+マルチパスSANブート環境だと簡単にはいかない。

その解決方法を以下に示す。

※ディスク装置はHP MSAを想定
※このバックアップ方法は、業務を停止することなくバックアップを取得できるメリットがある、とメーカーは言うが、OSが何しようとが関係なしに、ディスク装置側で勝手にバックアップをとってしまうため、不整合なファイルシステムの状態をとってしまうかもしれないリスクがある。(例えば、ファイル書き込み中とか・・・)


1.コピー先のディスクを、ホストに見せる(MSAの場合はマッピング)。これは当然

2.ホストをブートしてみる・・・・

3.するとinitrd処理中にエラーになり、やがてVGの重複が発生し、レスキューのためのパスワード入力プロンプトが表示されて停止する

(エラーになる原因は、ボリュームコピーによりマルチパスを構成するためのwwidが実際の物と異なっているので、マルチパスが構成できず全パスが個別の重複したディスクとして見えてしまう。マルチパスはwwidをヒントに同一ディスクの複数パスを探し出す。)

# ここで、あきらめる人が多いはず・・・

4.rootのパスワードを入力する

5./bootであるデバイスをマウントする(但し/bootのファイルシステムがパーティションの上に直接乗っているときのみ。LVM不可!)
普段/bootが/dev/mapper/mpath0p1なら、/dev/sda1。(sdb1でもsdc1でもsdd1でも可。実体は同じ)

# mount /dev/sda1 /boot

6.initrdを展開する
 initrdの中のファイルをいくつか編集するので、イメージを展開する。

# cd /boot
# cp -p initrd-xxxxx.img initrd-xxxxx.img.bk
# mkdir tmp
# cd tmp
# zcat initrd-xxxxx.img | cpio -i -o

7.論理ボリュームのSCSIシリアル番号(wwid)を調べる

/dev/disk/by-id/ディレクトリにあるシンボリックリンク名の頭「scsi-」を削ったものが論理ボリュームのSCSIシリアル番号。

# ls /dev/disk/by-id/
scsi-1111222233334444aaaabbbbccccdddd
scsi-1111222233334444aaaabbbbccccdddd-part1
scsi-1111222233334444aaaabbbbccccdddd-part2

上の赤太字がSCSIシリアル番号。

8. initスクリプト中のmultipathコマンドで指定してある論理ボリュームのSCSIシリアル番号(wwid)をコピー先ディスクの番号に書き換える(下、赤斜体文字箇所)。

# vi init
:(省略)
/bin/multipath -v 0 1111222233334444aaaabbbbccccdddd
:(省略)

9.etc/multipath.conf中の信頼する論理ボリュームのSCSIシリアル番号(wwid)を新しい番号に書き換える(下、赤斜体文字箇所)。

vi etc/multipath.conf
blacklist_exceptions {
wwid “1111222233334444aaaabbbbccccdddd
}

10.var/lib/multipath/bindingsファイル中のデバイス名エイリアスに紐づける論理ボリュームのSCSIシリアル番号(wwid)をコピー先の番号に書き換える(下、赤斜体文字箇所)。

# vi var/lib/multipath/bindings
mpath0 1111222233334444aaaabbbbccccdddd

 (このファイルで、wwid:1111222233334444aaaabbbbccccddddのディスクはmpath0を使用すると定義している)

11.initrd再作成
 次回以降の起動で使用できるように、編集したinitrdを再作成(イメージ化)する。

# find . | cpio –quiet -o -c | gzip -c > ../initrd-xxxxx.img

12.再起動

# exit

以上で、めでたく起動できる。

viエディタの現在のモードをわかりやすくする

viエディタの現在のモードをわかりやすくする

コマンドモードにして(現在何モードかがわからなければ、とりあえず[Escキー]を連打)

:set showmode

すると、右下(または左下)に現在のモードが表示される。

                   
                   
— 挿入 —

コマンドモードの場合は、何も表示されない。

KSH のコマンド履歴 およびにファイル名補完を有効にする

KSH のコマンド履歴およびにファイル名補完を有効にする方法

シェルのviモードを有効にする。

$ set -o vi

viモードを有効にしたら・・・
Escキーを押して(viでいうところのコマンドモードにする)

[Escキー]

コマンド履歴は

Ctrl+K(一つ前(過去)のコマンド)
Ctrl+J(1つ後(直近)のコマンド)
/<検索ワード>[Enterキー] (コマンド履歴から検索)

ファイル名補完(bashでいうところのタブ補完)は

*(アスタリスクShift+:)
※補完できる状態まで入力している必要あり。候補が複数ある場合は全部rリストされるので注意。

シェルスクリプトでtelnet接続→コマンド実行

シェルスクリプトでtelnet接続→コマンド実行

シェルスクリプトで、他ホストにtelnetログインしてコマンドを実行し情報を取得する方法。

たとえば、L2/L3スイッチの統計情報やarpテーブルの情報を自動的に取得する処理をシェルスクリプトで作成したいとき

telnetの場合、FTP転送をヒアドキュメントを使用して自動的に実行するのと同じ方法では実装できない。理由は、ヒアドキュメントの場合、標準入力に間髪入れずに入力内容を送りこんでしまうので、ログインプロンプトを待つことができないから。

ユーザ名を標準入力に送り込む前に少し待機すると、ログインすることができる。
ポイントは、
・ヒアドキュメントを使用せずに、コマンドのグループ化とパイプを使用してtelnetコマンドの標準入力にコマンドを送り込む
・sleepコマンドで待機

実際のやり方は以下を参照。(Ciscoのスイッチからarpテーブル情報を取得する場合。)

$ (sleep 5; #パスワードプロンプトが表示されるまでsleepコマンドで待つ
echo username;sleep 5; #ユーザ名入力 標準入力に送り込むのでechoで出力(Ciscoスイッチは実際にはユーザ名入力はありません)
echo password;sleep 10; # パスワード入力
enable;sleep 5; #特権モードへ切り替え
echo enablepassword;sleep 1; # 特権モードのパスワード入力
show arp;sleep 1; # arpテーブル取得
exit; ) | telnet 192.168.1.250 >> arp.log # コマンドをグループ化し、その標準出力をパイプでtelnetコマンドの標準入力に送り込む

追記:
 この方法はスクリプトで、passwdコマンドを使ってパスワードを自動設定するときにも使えます!