ラベル [2010]サーバアーキテクチャ の投稿を表示しています。 すべての投稿を表示
ラベル [2010]サーバアーキテクチャ の投稿を表示しています。 すべての投稿を表示

2011年1月20日木曜日

[SA-6-1] Uploader

APIの動作確認と作成したWEBサービスの提出は,こちらのアップローダーを利用してください.


※他ユーザーの作品と混ざらないように,必ずファイル名の先頭に自身の名前を付けてください.

[SA-6] 外部APIの利用

各種WEBサービスを外部から利用する為のAPI.
(マッシュアップとかWEB2.0とか呼ばれていたアレ)
これらを用いることで,自前でデータや機能を用意することなく,迅速かつ用意にサービスを開始する事が可能となる.
(ただし,あくまでも他社のサービスを流用している事から,サービスの継続性については,疑問が残る)

代表的な外部API
SITEURL
googlehttp://code.google.com/intl/ja/apis/
flickrhttp://www.flickr.com/services/api/
Yahoo!http://developer.yahoo.co.jp/
Amazonhttp://www.amazon.co.jp/gp/feature.html?ie=UTF8&docId=451209
Facebookhttp://developers.facebook.com/
twitterhttp://apiwiki.twitter.com/w/page/22554648/FrontPage

2010年12月16日木曜日

[SA-5-1-4] Perlを用いたCGIを使ってWEBアプリ化(完成)

index.html
<HTML>
<HEAD>
 <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=UTF-8">
 <TITLE>Connect MySQL(Perl) 1</TITLE>
</HEAD>

<BODY>
<FORM ACTION="/cgi-bin/connectDB3.cgi" METHOD="get" ENCTYPE="application/x-www-form-urlencoded">
 num       :<INPUT TYPE="TEXT" NAME="num" SIZE="4"><BR>
 host_name :<INPUT TYPE="TEXT" NAME="host_name" SIZE="12"><BR>
 ip_address:<INPUT TYPE="TEXT" NAME="ip_address" SIZE="24"><BR>
 <INPUT TYPE="hidden" name="command" value="insert">
 <INPUT TYPE="SUBMIT" NAME="Submit" VALUE="実行"><BR>
</FORM>
</BODY>

</HTML>

connectDB3.cgi
#!/usr/bin/perl

use DBI;
$user = '[user]';
$passwd = '[pass]';
$db = DBI->connect('DBI:mysql:sa:localhost', $user, $passwd);

if( $ENV{'REQUEST_METHOD'} eq "GET" ) {
    $std = $ENV{'QUERY_STRING'};
} else {
    read( STDIN, $std, $ENV{'CONTENT_LENGTH'} );
}
print "Content-Type: text/html\n\n\n";

print <<HEADER;
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=UTF-8">
<title>Connect MySQL(Perl) 2</title>
</head>
<body>
HEADER

print "Method :", $ENV{'REQUEST_METHOD'},"<br>\n";
print "Data   :", $std, "<br>\n";

print "<br>";

my @pairs = split(/&/,$std);
foreach $pair (@pairs){
    my($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
#    print "$name : $value<br>";
    $form{$name} = $value;
    print "\$form{$name} = $value<br>"
}

print "<br>";

if($form{command} eq 'insert'){
 if($form{num} eq '' || $form{host_name} eq '' || $form{ip_address} eq ''){
  print "登録できません";
 }else{
  $sth = $db->prepare("INSERT INTO server_list (num,host_name,ip_address) VALUES ('$form{num}','$form{host_name}','$form{ip_address}')");
  $sth->execute;
  print "登録完了";
  $sth->finish;
 }
}
$db->disconnect;

print <<FOOTER;
</body>
</html>
FOOTER

[SA-5-1-2] PerlでCGI

1.Hello World!
#vi /var/www/cgi-bin/hello.cgi

hello.cgi
#!/usr/bin/perl

print "Content-type: text/html\n";
print "\n";
print "Hello World!";

#chmod 755 hello.cgi
ブラウザから
http://(サーバのIPアドレス)/cgi-bin/hello.cgi
を確認.


2.GET/POST
connectDB3.cgi
#!/usr/bin/perl

# GETメソッドの場合
if( $ENV{'REQUEST_METHOD'} eq "GET" ) {
    $std = $ENV{'QUERY_STRING'};
# POSTメソッドの場合
} else {
    read( STDIN, $std, $ENV{'CONTENT_LENGTH'} );
}
print "Content-Type: text/html\n\n\n";
print "Method :", $ENV{'REQUEST_METHOD'},"<br>\n";
print "Data   :", $std, "<br>\n";

my @pairs = split(/&/,$std);
foreach $pair (@pairs){
    my($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    print "$name : $value<br>";
}

ブラウザから,[SA-5-1-2]で作成したファイル
http://(サーバのIPアドレス)/index.html
を確認.
(Method, Data, num, host_name, ip_address, num, host_nameの各項目の値が表示されます)

2010年12月15日水曜日

[SA-5-1-3] Perlを用いたCGIを使ってWEBアプリ化

index.html(sample)
<HTML>
<HEAD>
 <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=UTF-8">
 <TITLE>Connect MySQL(Perl) 1</TITLE>
</HEAD>

<BODY>
<FORM ACTION="cgi-bin/sample3.cgi" METHOD="POST" ENCTYPE="application/x-www-form-urlencoded">
 num:<INPUT TYPE="TEXT" NAME="num" SIZE="4"><BR>
 host_name:<INPUT TYPE="TEXT" NAME="host_name" SIZE="12"><BR> ip_address:<INPUT TYPE="TEXT" NAME="ip_address" SIZE="24"><BR>

 <SELECT NAME="command">
  <OPTION SELECTED VALUE="insert">INSERT</OPTION>
 </SELECT>

 <INPUT TYPE="SUBMIT" NAME="Submit" VALUE="実行"><BR>
</FORM>
</BODY>

</HTML>



connectDB3.cgi(sample)
#!/usr/bin/perl
use DBI;
$user = '[user name]';
$passwd = '[password]';
$db = DBI->connect('DBI:mysql:sa:localhost', $user, $passwd);

# FORMからデータを読み込む
$len = $ENV{'CONTENT_LENGTH'};
read(STDIN, $std, $len);
@args = split(/&/, $std);
foreach $arg ( @args ){
 ($name, $val ) = split(/=/, $arg);
 $val =~ s/\+/ /g;
 $form{$name} = $val;
}

print <<HEADER;
Content-type: text/html
<html>
 <head>
 <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=UTF-8">
 <title>Connect MySQL(Perl) 2</title>
 </head>
 <body>
HEADER

if($form{command} eq 'insert'){
 if($form{name} eq '' ){
  print "<h1>nameが空白では登録できません</h1>";
 }else{
  $sth = $db->prepare("insert into list (num,host_name,ip_address) values ('$form{num}','$form{host_name}','$form{ip_address}')");
  $sth->execute;
  print "<h1>登録完了</h1>";
  $sth->finish;
 }
}

$db->disconnect;

print <<FOOTER;
</body>
</html>
FOOTER

WebサーバのCGI関連の設定確認
vi /etc/httpd/conf/httpd.conf
AddHandler cgi-script .cgi .pl

2010年12月9日木曜日

[SA-5-1-1] PerlからDBへの接続

Perlを用いてDBに接続する.

[user name]
[password]
[DB name]sa

DBIの導入
$ cpan
CPAN> install DBI

DBに値を挿入する.
[insert value]'','13','sa012','10.2.3.112'

connectDB.pl
#!/usr/bin/perl
use DBI;

$user = '[user name]';
$passwd = '[password]';
$db = DBI->connect('DBI:mysql:[DB name]:localhost', $user, $passwd);
$sth = $db->prepare("INSERT INTO server_list VALUES ([insert value])");
$sth->execute;
$sth->finish;
$db->disconnect;


DBに格納されている値を取り出し,全て表示する.
connectDB2.pl
#!/usr/bin/perl
use DBI;

$user = '[user name]';
$passwd = '[password]';
$db = DBI->connect('DBI:mysql:[DB name]:localhost', $user, $passwd);
$sth = $db->prepare("[検索条件]");
$sth->execute;
$num_rows = $sth->rows;
print "該当 $num_rows 件\n";
for ($i=0; $i<$num_rows; $i++) {
 @a = $sth->fetchrow_array;
 print "[値の表示]";
}
$sth->finish;
$db->disconnect;

[検索条件]
SELECT * FROM server_list

[値の表示]
id=$a[0], num=$a[1] host_name =$a[2] ip_address =$a[3] \n

2010年12月2日木曜日

[SA-4-6] FTPによるファイル送信(Shell Script)

バックアップしたファイルは,そのままサーバ上に保管するのではなく,ロケーションの異なるサーバにコピーすると,より安全である(ディザスタリカバリ).
そこで,定期的にファイルの転送をサーバに行わせるために,ファイルの転送を自動的に行うShellScriptを作成する.

内部でFTPクライアントを使用しているため,事前にFTPクライアントをインストール
#yum install ftp

また,ファイルの送信先サーバがFTPサーバとしてもどう際してる必要がある為,ローカルで動作確認を行う為には,FTPサーバをインストールする必要がある.
#yum install vsftpd
#service vsftpd start
#chkconfig vsftpd on

転送試験に使用するファイル用意
$vi ~/script/test.txt

転送試験の際の受信用ディレクトリ用意
$mkdir ~/script/receive


ftp_put.bash
#!/bin/bash

################################################
# 設定
################################################
# 送信するファイル
L_FILE="/home/(ユーザー名)/script/test.txt"
# 送信先ホスト
R_HOST="localhost"
# 送信先ディレクトリ
R_DIR="/home/(ユーザー名)/script/receive"

################################################
# 関数
################################################
# ファイルを FTP で送信する
# 入力
#   $1: 送信するファイル名
#   $2: 送信先ホスト名
#   $3: 送信先ディレクトリ
#   $4: 一時作業ディレクトリ
# 終了ステータス
#   0: 成功
#   1: 失敗
ftp_put_file () {
    local l_file="$1"
    local r_host="$2"
    local r_dir="$3"
    local tmpdir="$4"

    local filename="${l_file##*/}"
    local r_file="${r_dir}/${filename}"
    local log="${tmpdir}/ftp_put.log"

    local status

    # FTP を実行
    ftp -v -g "${r_host}" <<-EOF > "${log}" 2>&1
 quote NOOP
 put "${l_file}" "${r_file}"
 quote NOOP
 EOF

    # 結果チェック(1)
    status=$?
    if [ "${status}" -ne 0 ]; then
 return "${status}"
    fi

    # 結果チェック(2)
    ftp_chk_transfer "${log}"

    # 失敗した場合にはエラーメッセージ(かもしれないもの)
    # の最後の3行を標準エラー出力に表示
    if [ $? -ne 0 ]; then
 grep -v '^[123][0-9][0-9]' "${log}" | tail -3 1>&2
 return 1
    fi

    return 0
}

# FTP によるファイル送受信を、ログからチェックする
# 入力
#   $1: 転送ログ
# 終了ステータス
#   0: 転送成功
#   1: 転送失敗
ftp_chk_transfer () {
    local state="START"
    local code
    local msg_first
    local msg_rest

    # ログファイルを読みながらのループ
    while read code msg_first msg_rest; do
 case "${state}" in
 # 最初の NOOP 実行前
 START)
     if [ "${code} ${msg_first}" == "200 NOOP" ]; then
  state=TRANS_START
     fi
     ;;
        # PASV/PORT でのコネクション確立中
 TRANS_START)
     case "${code}" in
     125 | 150)
  state=TRANS_DATA
  ;;
     200)
  if [ "${msg_first}" == NOOP ]; then
      # 想定外
      state="ERROR"
      break
  fi
  ;;
     esac
     ;;
 # データ転送中
 TRANS_DATA)
     case "${code}" in
     226 | 250)
  # 転送成功
  state=SUCCESS
  break
  ;;
     200)
  if [ "${msg_first}" == NOOP ]; then
      # 想定外
      state="ERROR"
      break
  fi
  ;;
     esac
     ;;
 esac
    done < "$1"

    # 以下の test の結果が関数の終了ステータス
    [ "${state}" == "SUCCESS" ]
    return
}

################################################
# メイン処理
################################################
# util_common.bash を読み込む(make_tmp_dir/clean_tmp_dir)
FILE_UTIL=util_common.bash
. "${FILE_UTIL}" 2> /dev/null \
    || . "${0%/*}/${FILE_UTIL}" 2> /dev/null
if [ $? -ne 0 ]; then
    echo "Can't load ${FILE_UTIL}!" 1>&2
    exit 1
fi

# 作業ディレクトリの作成
tmpdir=$(make_tmp_dir 2>/dev/null)
if [ $? -ne 0 ]; then
    echo "Can't create temporary directory!" 1>&2
    exit 2
fi

# trap の設定
SIGNALS="HUP INT QUIT PIPE TERM"
trap "{ clean_tmp_dir; exit; }" ${SIGNALS}

ftp_put_file \
    "${L_FILE}" \
    "${R_HOST}" \
    "${R_DIR}" \
    "${tmpdir}"

status=$?

# 作業ディレクトリの削除と trap 解除
clean_tmp_dir
trap ${SIGNALS}

# スクリプトの終了ステータスを
#  ftp_put_file の終了ステータスに
exit ${status}

.netrc(設定ファイル)
machine localhost login <ユーザー名> password <パスワード>

2010年12月1日水曜日

[SA-4-5] ファイル差分バックアップ(Shell Script)

内部でrcsコマンドを使用しているため,事前にrcsをインストール
#yum install rcs

backup_etc.bash
#!/bin/bash
# usage:
# 1. BACKUP_ROOT(/var/tmp/backup) に、バックアップをとりたいファイルへの
#    シンボリックリンクを張ります
#    例: cd ${BACKUP_ROOT}; ln -s /etc/nsswitch.conf
# 2. backup_etc.bash を引数なしで実行します

# バックアップ作成用ディレクトリ
BACKUP_ROOT="/var/tmp/backup"

# バックアップ作成用ディレクトリ内の最大の深さ
MAX_DEPTH=2

# RCS のチェックインメッセージ(空白/タブを入れないこと)
CHECKIN_MSG="Automatic_RCS_backup"

# 引数に応じて、
#   「ディレクトリの深さ + 1」
# を表す glob パターンを生成する
# usage: make_pattern <depth>
# ex. make_pattern 1 → "*/*"
make_pattern () {
    local -i i=$1
    local pattern="*"

    while [ $i -gt 0 ]; do
        pattern="${pattern}/*"
        let "i--"
    done

    echo "${pattern}"
}

# RCS の ci (チェックイン)コマンドを使って差分バックアップをとります
# 引数: なし
make_rcs_backup () {
    local dir
    local pattern=$(make_pattern ${MAX_DEPTH})
    local lock_user
    local file
    local msg

    # CHECKIN_MSG が設定されている場合だけ
    # msg 変数の内容を -m"メッセージ" とします
    msg=${CHECKIN_MSG:+"-m${CHECKIN_MSG}"}

    # BACKUP_ROOT に移動
    pushd "${BACKUP_ROOT}" > /dev/null

    # RCS という名前以外のディレクトリを探す
    # ※BSDシステムでは find -x . -type d ... とすること
    find . -xdev -type d \( -name RCS -prune -o -print \) | \
        while read dir; do
            case "${dir}" in
                ${pattern})
                    # MAX_DEPTH を越えたものは対象外
                    continue
                    ;;
            esac

     # 対象ディレクトリに移動
            cd "${BACKUP_ROOT}/${dir}"
     if [ ! -d RCS ]; then
  mkdir RCS
            fi

     # ファイルごとに ci を実行
            for file in *; do
  if [ -d "${file}" ]; then
      continue
  fi

  ci ${msg} -l "${file}" < /dev/null > /dev/null 2>&1
  if [ $? -ne 0 ]; then
      echo "backup FAIL: ${file}" 1>&2
  fi
     done
        done            

    # 最初いたディレクトリに戻る
    popd > /dev/null
}

make_rcs_backup

もしくは,rsyncを用いて差分バックアップを取る方法もある.
この場合,変更なきファイルはハードリンクとし,前回のバックアップから変更があったファイルのみ実際のコピーを行う為,バックアップの容量圧縮する事が可能となる.
rsync -av --delete --link-dest=../[過去] [現在]/ [保存名]

2010年11月25日木曜日

[SA-4-4] メール送信(Shell Script)

サーバは管理者の傍らではなく,遠隔地に置かれることが多い事から,ディスク使用量/プロセス死活監視/ネットワーク疎通確認等で問題が起きた際に,サーバの画面上にアラートを表示するだけでは不十分である.
そこで,アラートが発生した際にそのメッセージをメールとしてサーバから管理者に送信する事で,トラブルの見落としを防ぐ事が可能となる.

※下記サンプルをCentOS上で動かすために,
1.sendmailのインストール
yum install sendmail
service sendmail start
chkconfig sendmail on
2.スクリプト中のsendmailのパスを変更
/usr/local/sendmail → /usr/sbin/sendmail
3.MAIL_TOを自分のメールアドレスに変更
4.iconvの記述を変更
iconv -f EUC-JP -t ISO-2022-JP → iconv -f UTF-8 -t ISO-2022-JP


mail_plain.bash
#!/bin/bash
# メール設定
MAIL_FROM="foo@example.com"
MAIL_TO="bar@example.com"
MAIL_SUBJECT="テストメール"
MAIL_ID="<$(date +%Y%m%d%H%M%S).$(id -ru).$$@$(hostname)>"
SENDMAIL=/usr/lib/sendmail

# 共通関数の読み込み
FILE_UTIL=util_common.bash
. "${FILE_UTIL}" 2> /dev/null \
    || . "${0%/*}/${FILE_UTIL}" 2> /dev/null
if [ $? -ne 0 ]; then
    echo "Can't load ${FILE_UTIL}!" 1>&2
    exit 1
fi

# 文字コードを英語に
unset_linguas

# 作業ディレクトリの作成
tmpdir=$(make_tmp_dir 2>/dev/null)
if [ $? -ne 0 ]; then
    echo "Can't create temporary directory!" 1>&2
    exit 2
fi

# trap の設定
SIGNALS="HUP INT QUIT PIPE TERM"
trap "{ clean_tmp_dir; exit; }" ${SIGNALS}

# サブジェクトを Base64 エンコーディング
subject=$(echo -n "${MAIL_SUBJECT}" |
             iconv -f EUC-JP -t ISO-2022-JP |
             perl -MMIME::Base64 -ne 'print encode_base64($_)')

# メールの作成
mail_data="${tmpdir}/mail_data"
cat <<EOF > "${mail_data}"
Mime-Version: 1.0
Content-Type: Text/Plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
From: ${MAIL_FROM}
To:   ${MAIL_TO}
Subject: =?ISO-2022-JP?B?${subject}?=
Message-Id: ${MAIL_ID}
Date: $(date +"%a, %e %b %Y %H:%M:%S %z")

--------------------------------------------------------
UPTIME
--------------------------------------------------------
$(uptime)

--------------------------------------------------------
W
--------------------------------------------------------
$(w)

--------------------------------------------------------
FREE
--------------------------------------------------------
$(free)


EOF

# メールの送信
iconv -f EUC-JP -t ISO-2022-JP "${mail_data}" |
    "${SENDMAIL}" -oi "${MAIL_TO}" > /dev/null 2>&1

# 作業ディレクトリの削除と trap 解除
clean_tmp_dir
trap ${SIGNALS}

[SA-4-3] プロセスの死活監視(Shell Script)

サーバが稼働しているからと言って,特定のアプリケーション(プロセス)も正常に動作しているとは限らない.
そこで,プロセス一覧に指定したアプリケーションが表示されているか確認し,プロセスレベルで動作している事をもって正常とみなす.
ちなみに,アプリケーションレベルでの動作確認方法としては,例えばWEBサーバであれば特定のWEBページをHTTPを用いて表示させる,等がある.

check_proc_alive.bash
#!/bin/bash
# usage: check_proc_alive.bash

# 監視対象を記述したファイル
PROGLIST=/usr/local/etc/check_progs.conf

# util_common.bash(ucb_ps) を読み込む
# 1. PATH が通っているところから読み込む
# 2. このスクリプトがディレクトリ指定付で実行されていれば、
#    このスクリプトと同じ場所から読み込む
# 3. 1., 2. でダメならエラー
FILE_UTIL=util_common.bash
. "${FILE_UTIL}" 2> /dev/null \
    || . "${0%/*}/${FILE_UTIL}" 2> /dev/null
if [ $? -ne 0 ]; then
    echo "Can't load ${FILE_UTIL}!" 1>&2
    exit 1
fi

# 指定されたプログラムのプロセス ID を取得する
#
# 使い方
#   pidof [-s] 
#
# 引数:
#   -s
#     一つでもプロセスが見つかったら、そこで処理を終える
#   prog_name
#     探すプログラムの名前
#
# 出力
#   プロセスID_1 プロセスID_2  ...
#   (プロセスが見つからない場合は空行を 1 行出力する)
#
# 終了ステータス:
#   0: プロセスが見つかった
#   1: プロセスが存在しなかった
pidof () {
    local cmd_target            # 探すコマンド
    local is_single             # -s オプションが指定されたか

    # 引数の処理
    is_single=false

    case "$1" in
      -s)
        is_single=true
 shift
 ;;
    esac

    cmd_target="$1"

    # 以下のコマンド(パイプライン)の戻値が、関数の戻値になる
    ucb_ps ax | (
 # ここからサブシェルなので、変数の設定は呼び出し元には
 # 影響しません。よって local 定義もありません
 # ただし、変数の初期化は必要です。
 pids=""

 # へッダ行は捨てます
 read line

 # 2 行目以降の処理
 while read pid tty stat time cmd args; do
     # 対象行が求めるものであるか
     was_found="false"

     if [ "${cmd}" = "${cmd_target}" ]; then
  # そのまま一致
  was_found="true"
     elif [ "${cmd##*/}" = "${cmd_target}" ]; then
  # ベース名が一致
  was_found="true"
     fi

     if ${was_found} ; then
  pids="${pids} ${pid}"
  if ${is_single}; then
      # -s が指定されていればここで終わり。
      # 終了ステータス 0
      break
  fi
     fi
 done

 # 結果の表示
 echo ${pids}

 # 終了ステータスの設定
 [ "${pids}" != "" ]
    )
}

# プロセス生存監視
# 引数なし
check_alive_procs () {
    # PROGLIST 存在チェック
    if [ ! -r "${PROGLIST}" ]; then
 echo "Can't read ${PROGLIST}"
 return 1
    fi

    # PROGLIST の行ごとのループ
    cat "${PROGLIST}" | while read prog ; do
 case "${prog}" in
     "")   continue ;;
     "#"*) continue ;;
 esac
 pids=$(pidof ${prog})
 if [ $? -ne 0 ]; then
     pids="DOWN"
 fi
 echo "${prog}: ${pids}"
    done
}

check_alive_procs

2010年11月18日木曜日

[SA-4-2] ディスク容量の監視(Shell Script)

サーバの残りディスク容量が低下すると動作に支障があるため,ディスク容量が閾値(80%)を超えた際にメッセージを表示する.
管理者宛にメールを送信するスクリプトと組み合わせることにより,サーバの管理画面を確認することなく,サーバの残りディスク容量の低下に気がつくことが可能となる.

disk_usage.bash
#!/bin/bash

# ディスク使用量が THRESHOLD(%) を越えたら警告
#THRESHOLD="80"
THRESHOLD="10"

# 引数: なし
print_disk_usage () {
    # df コマンドのオプション
    local DF_OPTIONS="-k -l"
#    local DF_OPTIONS="-k -l /dev/sda1"
    local line used

    df ${DF_OPTIONS} |
    (
 # へッダ行をそのまま表示
        read line
#        echo "${line}"
        echo ${line}\c
        while read line; do
     # "デバイス" "総容量" "使用中" "空き容量" "使用率" ...
     set -- ${line}
     case "$1" in
              # 実存する(仮想でない)デバイスのみ対象
       /*)
  used=${5%%"%"*}
  if [ ${used} -ge ${THRESHOLD} ]; then
      echo "${line}"
  fi
  ;;
     esac
 done
    )
}

output=$(print_disk_usage)
lines=$(echo "${output}" | wc -l)

if [ ${lines} -gt 1 ]; then
    echo "${output}"
fi

[SA-4-1] PINGによる疎通確認(Shell Script)

PINGを用いてネットワークの向こう側にある機器との間の疎通確認を行うシェルスクリプト

/usr/local/etc/ping_hosts
192.168.147.1
192.168.147.2
192.168.147.3
192.168.147.4
192.168.147.5
192.168.147.6
192.168.147.7
192.168.147.8
192.168.147.9
192.168.147.10

util_common.bash
#
# 共通関数群(bash 用)
#

# BSD スタイルの ps コマンド
# 引数: ps コマンドの引数と同じ
ucb_ps () {
    local CMD_PS=/usr/ucb/ps

    if [ ! -x ${CMD_PS} ]; then
 CMD_PS=ps
    fi

    ${CMD_PS} "$@"
}

# ロケール(言語)設定をデフォルト(POSIX)にする
# 引数: なし
unset_linguas () {
    export LC_ALL=C
    export LC_MESSAGES=C
    export LANGUAGE=C
    export LANG=C
}

# 一時ディレクトリの作成
# 引数: 一時ディレクトリの親ディレクトリ
#       (省略時デフォルト: ${TMP_ROOT})
# 出力: 作成したディレクトリ名
# 終了ステータス: 0: 成功, 1: 失敗
# シェル変数:
#   TMP_ROOT(IN): 一時ディレクトリの親ディレクトリ
#                 (省略時デフォルト: ${HOME})
make_tmp_dir () {
    # 一時ディレクトリの親ディレクトリ
    local TMP_ROOT="${1:-${TMP_ROOT:-${HOME}}}"
    local tmpdir=$(basename "$0")$$

    tmpdir="${TMP_ROOT}/${tmpdir}"

    mkdir "${tmpdir}" > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
 echo "${tmpdir}"
 chmod 700 "${tmpdir}"
    else
 echo "Can't create directory: ${tmpdir}" 1>&2
 return 1
    fi
}

# 一時ディレクトリの削除
# 引数: 一時ディレクトリの親ディレクトリ
#       (省略時デフォルト: ${TMP_ROOT})
# 出力: なし
# 終了ステータス: 0: 成功, 1以上: 失敗
#   TMP_ROOT(IN): 一時ディレクトリの親ディレクトリ
#                 (省略時デフォルト: ${HOME})
clean_tmp_dir () {
    # 一時ディレクトリの親ディレクトリ
    local TMP_ROOT="${1:-${TMP_ROOT:-${HOME}}}"
    local tmpdir=$(basename "$0")$$

    tmpdir="${TMP_ROOT}/${tmpdir}"

    # ディレクトリが存在しなければエラーにします
    if [ ! -d "${tmpdir}" ]; then
 echo "No such directory: ${tmpdir}" 1>&2
 return 1
    fi
    # 対象がシンボリックの場合は、想定外のためエラーにします
    if [ -L "${tmpdir}" ]; then
 echo "Can't delete unexpected symlink: ${tmpdir}" 1>&2
 return 1
    fi
    # rm コマンドの終了ステータスをそのまま返します
    rm -rf "${tmpdir}" > /dev/null 2>&1
}


ping.bash
#!/bin/bash
# usage: ping.bash

# 監視対象ホストを記述したファイル
# (書式は 1 行に 1 ホスト)
PING_HOSTS="/usr/local/etc/ping_hosts"

# 汎用pingコマンドインターフェース
# 使い方:
#   ping_common  [  ]
# 引数:
#   hostname: ホスト名/IPアドレス
#   timeout: pingのタイムアウト(秒)
# 出力:
#   なし(エラー出力はあり)
# 終了ステータス:
#   0: 応答あり
#   1: 応答なし
#   2以上: エラー
ping_alive_common () {
    # システム(unameの結果)ごとに処理を分岐
    case $(uname -s) in
      Linux | NetBSD | OpenBSD)
        ping_alive_bsd $1 $2
        status=$?
        ;;
      SunOS)
 ping_alive_solaris $1 $2
        status=$?
 ;;
      FreeBSD)
        ping_alive_freebsd $1 $2
        status=$?
        ;;
      *)
 # 上記以外のシステムでは、自分で調べて修正してください
 echo "This system is not supported." 1>&2
 return 2
 ;;
    esac

    return ${status}
}

# Linux/NetBSD/OpenBSD用pingコマンドインタフェース
# 使い方:
#   ping_alive_bsd  [  ]
# 引数:
#   hostname: ホスト名/IPアドレス
#   timeout: pingのタイムアウト(秒)
# 出力:
#   なし(エラー出力はあり)
# 終了ステータス:
#   0: 応答あり
#   1: 応答なし(またはエラー)
#   2以上: エラー
ping_alive_bsd () {
    local timeout=${2:+"-w $2"}
    local status

    ping -c 1 ${timeout} $1 > /dev/null
    status=$?

    # 不正な引数の場合は終了ステータスは2以上(?)
    if [ $status -ge 2 ]; then
 # timeout オプションを削除して再試行
 ping -c 1 $1 > /dev/null
 status=$?
    fi

    return ${status}
}

# FreeBSD用pingコマンドインタフェース
# 使い方:
#   ping_alive_freebsd  [  ]
# 引数:
#   hostname: ホスト名/IPアドレス
#   timeout: pingのタイムアウト(秒)
# 出力:
#   なし(エラー出力はあり)
# 終了ステータス:
#   0: 応答あり
#   1: 応答なし
#   3以上: エラー
ping_alive_freebsd () {
    local timeout=${2:+"-t $2"}

    ping -c 1 ${timeout} $1 > /dev/null
    status=$?

    # 不正な引数の場合 = 古い実装は終了ステータスが2以上
    if [ $? -ge 2 -a "${timeout}" != "" ]; then
 # timeout オプションを削除して再試行
 ping -c 1 $1 > /dev/null
 status=$?
    fi

    case ${status} in
      0)
        return 0
        ;;
      1 | 2)
        return 1
        ;;
      *)
        return ${status}
        ;;
    esac
}

# Solaris(SunOS)用pingコマンドインタフェース
# 使い方:
#   ping_alive_solaris  [  ]
# 引数:
#   hostname: ホスト名/IPアドレス
#   timeout: pingのタイムアウト(秒)
# 出力:
#   なし(エラー出力はあり)
# 終了ステータス:
#   0: 応答あり
#   1: 応答なし
#   2以上: エラー
ping_alive_solaris () {
    ping $1 $2 > /dev/null
}

# 非同期 ping 実行
# 使い方:
#   ping_async  [  ] [  ]
# 引数:
#   hostname: ホスト名/IPアドレス
#   directory: ログ出力先ディレクトリ(デフォルトはカレントディレクトリ)
#   timeout: ping タイムアウト(秒)
# 出力:
#   なし
# 終了ステータス:
#   0: pingの実行に成功
#   1以上: エラー
ping_async () {
    local hostname=$1
    local resultfile="${2:+${2}/}${hostname}"
    local timeout=$3

    rm -f ${resultfile} > /dev/null 2>&1

    (
        ping_alive_common ${hostname} ${timeout} \
     > /dev/null 2> "${resultfile}"
 echo $? >> "${resultfile}"
    ) > /dev/null 2>&1 &
}

# 非同期 ping 実行結果取得
# 使い方:
#   ping_check_result  [  ]
# 引数:
#   hostname: ホスト名/IPアドレス
#   directory: ログ出力先ディレクトリ(デフォルトはカレントディレクトリ)
# 出力:
#   なし
# 終了ステータス:
#   0: 応答あり
#   1: 応答なし
#   2以上: エラー
#   70: 結果不明(結果ファイルが存在しない/読み込めない)
ping_check_result () {
    local hostname=$1
    local resultfile="${2:+${2}/}${hostname}"
    local num_line
    local status

    [ -r "${resultfile}" ] || return 70
    status=$(tail -1 "${resultfile}")

    # エラーの表示
    if [ ${status} -ge 2 ]; then
 num_line=$(wc -l "${resultfile}" | awk '{print $1}')
 if [ ${num_line} -gt 1 ]; then
     sed ${num_line}d "${resultfile}" 1>&2
 fi
    fi

    return ${status}
}

# 複数ホストへのping同時実行
# 使い方:
#   ping_from_file  [  ] [  ]
# 引数:
#   hostname: ホスト名/IPアドレス
#   directory: ログ出力先ディレクトリ(デフォルトはカレントディレクトリ)
#   timeout: ping タイムアウト(秒)
# 出力:
#   <ホスト名>: <ステータス>
#   ...
#
#   ステータスは 0:応答あり 1:応答なし 2以上:エラー
# 終了ステータス:
#   常に 0
ping_from_file () {
    local inputfile="$1"
    local hostname
    local dummy

    # 入力ファイルの読み込みチェック
    if [ ! -r "${inputfile}" ]; then
 echo "No such file/Can't read file: ${inputfile}" 1>&2
 return 1
    fi

    # 位置パラメータを以下のようにする
    # $1: result_dir(省略可), $2: timeout(省略可)
    shift

    # 第2要素以降は無視する。すなわち
    #   192.168.1.1 # ルーター
    # のような記述も OK である
    while read hostname dummy; do
 # 空行/コメント行は無視
 case "${hostname}" in
   "")   continue ;;
   "#"*) continue ;;
        esac

 ping_async ${hostname} "$@" > /dev/null
    done < "${inputfile}"

    # ping_async で実行した非同期コマンドの終了を待つ
    wait

    # 位置パラメータを以下のようにする
    # $1: result_dir(省略可)
    if [ $# -ge 2 ]; then
 set -- "$1"
    fi

    while read hostname dummy; do
 # 空行/コメント行は無視
 case "${hostname}" in
   "")   continue ;;
   "#"*) continue ;;
        esac

 ping_check_result ${hostname} "$@"
 echo "${hostname}: $?"
    done < "${inputfile}"

    return 0
}

# メイン処理

# util_common.bash を読み込む(make_tmp_dir/clean_tmp_dir)
FILE_UTIL=util_common.bash
. "${FILE_UTIL}" 2> /dev/null \
    || . "${0%/*}/${FILE_UTIL}" 2> /dev/null
if [ $? -ne 0 ]; then
    echo "Can't load ${FILE_UTIL}!" 1>&2
    exit 1
fi

# 作業ディレクトリの作成
tmpdir=$(make_tmp_dir 2>/dev/null)

if [ $? -ne 0 ]; then
    echo "Can't create temporary directory!" 1>&2
    exit 2
fi

# trap の設定
SIGNALS="HUP INT QUIT PIPE TERM"
trap "{ clean_tmp_dir; exit; }" ${SIGNALS}

# ping 監視の実行
ping_from_file "${PING_HOSTS}" "${tmpdir}"

# 作業ディレクトリの削除と trap 解除
clean_tmp_dir
trap ${SIGNALS}

2010年10月21日木曜日

[SA-3-12] JavascriptからMySQLに接続

fig. 1


1.index.html, xmlhttp.js, backend.phpを,/var/www/html/ajaxに配置
index.html : ベースファイル
xmlhttp.js : フォームに入力された文字列を,リアルタイムにbackend.phpに渡し,結果を受け取る
backend.php : DBに接続し,結果をXMLとして出力

2.backend.phpに実行権限を付与(chmod 755 backend.php)

3.以下のアドレスにアクセスし,表示される項目を確認
(A)AJAXを利用し,表示項目を動的に絞り込み
http://[サーバのアドレス]/ajax/index.html
(B)MySQLから受け取ったデータをXML形式で表示
http://[サーバのアドレス]/ajax/backend.php?host_name=sa01

index.html
<html>
<head>
    <meta http-equiv=content-type content="text/html; charset=UTF-8">
 <title>server_list search result</title>
 
 <STYLE TYPE="text/css">
 <!--
 .table1 {
  width: 400px;
  border-collapse: collapse;
  border: 1px #708090 solid;
 }
 .table1 TD {
  border: 1px #708090 solid;
 }
 -->
 </STYLE> 
 
    <script type="text/javascript" src="xmlhttp.js"></script>
    <script type="text/javascript">
    <!--
    findText = findTextOld = "";

    function loadXmlFile(fName){
        httpObj = createXMLHttpRequest(displayData);
        if (httpObj){
            httpObj.open("GET",fName,true);
            httpObj.send(null);
        }
    }

    function displayData(){
        if ((httpObj.readyState == 4) && (httpObj.status == 200)){
            xmlData = httpObj.responseXML;
            $("result").innerHTML = parseXmlData(httpObj.responseText);
        }else{
            $("result").innerHTML = "Loading ...";
        }
    }

    function parseXmlData(xmlData){
        $("result").innerHTML = xmlData;
        idListTags = document.getElementsByTagName("id");
        numListTags = document.getElementsByTagName("num");
        host_nameListTags = document.getElementsByTagName("host_name");
        ip_addressListTags = document.getElementsByTagName("ip_address");
        idLen = idListTags.length;

        resultText = "<table class='table1'><tr><th colspan=4>server_list search result</th></tr><tr><td><b>id</b></td><td><b>num</b></td><td><b>host_name</b></td><td><b>ip_address</b></td></tr>";
        for(i=0; i<idLen; i++){
            id = idListTags[i].childNodes[0].nodeValue;
            num = numListTags[i].childNodes[0].nodeValue;
            host_name = host_nameListTags[i].childNodes[0].nodeValue;
            ip_address = ip_addressListTags[i].childNodes[0].nodeValue;
            str = host_name.match(findText);
            if (str){
                resultText += "<tr><td>" + id + "</td><td>" + num + "</td><td>" + host_name + "</td><td><a href='http://" + ip_address + "' target='_blank'>" + ip_address + "</a></td></tr>";
            }
        }
        resultText += "</table>";
        return resultText;
    }

    function inputCheck(){
        findText = document.ajaxForm.requestText.value;
        if (findText != findTextOld) {
            str_search = "./backend.php?host_name=" + findText
            loadXmlFile(str_search);
            findTextOld = findText;
        }else{
//            $("result").innerHTML = "Loading ...";
        }
        setTimeout(" inputCheck()",500); // 0.5秒毎
    }

    window.onload = inputCheck;
    // -->
    </script>
</head>
<body>
<form name="ajaxForm" onSubmit="return false">
<input type="text" value="sa00" name="requestText">
</form>
<div id="result"></div>
</body>
</html>

xmlhttp.js
// HTTP通信用、共通関数
function createXMLHttpRequest(cbFunc){
 var XMLhttpObject = null;
 try{
  XMLhttpObject = new XMLHttpRequest();
 }catch(e){
  try{
   XMLhttpObject = new ActiveXObject("Msxml2.XMLHTTP");
  }catch(e){
   try{
    XMLhttpObject = new ActiveXObject("Microsoft.XMLHTTP");
   }catch(e){
    return null;
   }
  }
 }
 if (XMLhttpObject) XMLhttpObject.onreadystatechange = cbFunc;
 return XMLhttpObject;
}
 
// document.getElementById
function $(tagId){
 return document.getElementById(tagId);
}

backend.php
<?php
 $db_user  = "[user name]";
 $db_password = "[password]";
 $db_name = "[database name]";
 $db_host  = "localhost";

//create xml
    header('Content-type: text/xml; charset=utf-8');
    echo '<?xml version="1.0"?><sa>';

 $host_name = null;

 if(isset($_GET['host_name'])) {
  $host_name = $_GET['host_name'];

  $con = mysql_connect($db_host,$db_user,$db_password) or die("error!");
  mysql_select_db($db_name,$con) or die("DB is not exist");
  $strsql = "SET CHARACTER SET UTF8";
  mysql_query($strsql,$con);
  $strsql = "SELECT id, num, host_name, ip_address FROM server_list WHERE host_name LIKE '%".$host_name."%';";
  $res = mysql_query($strsql,$con);

  while ($item = mysql_fetch_array($res)) {
   print "<server_list><id>".$item[0]."</id><num>".$item[1]."</num><host_name>".$item[2]."</host_name><ip_address>".$item[3]."</ip_address></server_list>";
  }
  mysql_close($con);
    }

    echo '</sa>'; 
?>

2010年10月14日木曜日

[SA-3-11] PHP-MySQL連携

1.php-mysqlモジュールをインストール
$ su
# yum install php-mysql
# service httpd stop
# service httpd start
# service mysqld stop
# service mysqld start

2.MySQLにデータベース,テーブル作成
$ mysql -u root -p
create database sa;

$ vi server_list.csv
,1,sa000,10.2.3.100
,2,sa001,10.2.3.101
,3,sa002,10.2.3.102
,4,sa003,10.2.3.103
,5,sa004,10.2.3.104
,6,sa005,10.2.3.105
,7,sa006,10.2.3.106
,8,sa007,10.2.3.107
,9,sa008,10.2.3.108
,10,sa009,10.2.3.109
,11,sa010,10.2.3.110
,12,sa011,10.2.3.111

$ mysql -u root -p sa
create table server_list ( id integer NOT NULL AUTO_INCREMENT PRIMARY KEY, num char(4), host_name char(20), ip_address char(15) );

show tables;

load data local infile "~/server_list.csv" into table server_list fields terminated by ',' enclosed by '"' lines terminated by '\n';
select * from server_list;

3.Windows側でPHPファイルを作成
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>server_list</title>
</head>
<body>
<?php
 $db_user  = "[user name]";
 $db_password = "[password]";
 $db_name = "[database name]";
 $db_host  = "localhost";

 $db = mysql_connect($db_host,$db_user,$db_password);
 mysql_select_db($db_name,$db); 
 $str_sql = "select * from server_list";
 $rs = mysql_query($str_sql,$db);
 $num = mysql_num_fields($rs);

 print("<table><tr><th colspan=4>server_list</th></tr>");
 echo("
 ");
 print("<tr>");
 for ($i=0;$i<$num;$i++){
  print("<td><b>".mysql_field_name($rs,$i)."</b></td>");
 }
 print("</tr>");
 while($row=mysql_fetch_array($rs)){
  echo("
 ");
  print("<tr>");
  for($j=0;$j<$num;$j++){
   print("<td>".$row[$j]."</td>");
  }
  print("</tr>");
 }

 print("</table>");

 mysql_free_result($rs);
 mysql_close($db);
?>
</body>
</html>

4.FTP後にパーミッションを755に変更

[SA-3-10] httpd設定

selinuxの無効化
# getenforce
# setenforce 0
# vi /etc/sysconfig/selinux
#SELINUX=enforcing
SELINUX=disabled
httpdの設定ファイル修正
# vi /etc/httpd/conf/httpd.conf
エラーページ等でOS名を非表示
 #ServerTokens OS
 ServerTokens Prod

エラーページ等でApacheのバージョン非表示
 #ServerSignature On
 ServerSignature Off

不要モジュールの読み込み解除
 #LoadModule auth_anon_module 
 #LoadModule ldap_module modules/mod_ldap.so
 #LoadModule auth_ldap_module modules/mod_auth_ldap.so
 #LoadModule mime_magic_module 
 #LoadModule cern_meta_module 
 #LoadModule deflate_module modules/mod_deflate.so
 #LoadModule headers_module modules/mod_headers.so
 #LoadModule usertrack_module modules/mod_usertrack.so
 #LoadModule status_module modules/mod_status.so
 #LoadModule asis_module modules/mod_asis.so
 #LoadModule info_module modules/mod_info.so
 #LoadModule vhost_alias_module 
 #LoadModule imap_module modules/mod_imap.so
 #LoadModule speling_module modules/mod_speling.so
 #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
 #LoadModule cache_module modules/mod_cache.so
 #LoadModule disk_cache_module 
 #LoadModule file_cache_module modules/mod_file_cache.so
 #LoadModule mem_cache_module 

サーバ管理者のメールアドレス設定
 #ServerAdmin root@localhost

サーバ(FQDN)名設定
 #ServerName www.example.com:80

ドキュメントルート(/var/www/html)のCGI/SSIの実行権付与とインデックスリストの非表示
(Indexes : インデックスリスト表示, FollowSymLinks : Symlink許可, Includes : SSI許可, ExecCGI : CGI許可)
 # Options Indexes FollowSymLinks
 Options FollowSymLinks Includes ExecCGI

ディレクトリアクセス制御
(FileInfo : ファイル関係の制御, AuthConfig : 認証関係, Limit : .htaccessによるアクセス制御, or ALL : 全て許可)
 # AllowOverride None
 AllowOverride FileInfo AuthConfig Limit

ユーザディレクトリ(/home/[user]/public_htmlをhttp://localhost.localdomain/~[user]として表示)の有効化とCGI/SSIの実行権付与とインデックスリストの非表示
※各ディレクトリのパーミッションは,/home/[user] : 711, /home/[user]/public_html : 755です.
 #UserDir disable
 UserDir public_html
 <Directory /home/*/public_html>
  AllowOverride FileInfo AuthConfig Limit
  Options MultiViews SymLinksIfOwnerMatch 
  <LimitExcept GET POST OPTIONS>
   Order deny,allow
   Deny from all
  </LimitExcept>
 </Directory>
 <Directory /home/*/public_html>
  AllowOverride FileInfo AuthConfig Limit
  Options MultiViews SymLinksIfOwnerMatch IncludesNoExec ExecCGI
  <LimitExcept GET POST OPTIONS>
   Order deny,allow
   Deny from all
  </LimitExcept>
 </Directory>

iconsディレクトリのファイル一覧を非表示
<Directory "/var/www/icons">
 #Options Indexes MultiViews
 Options MultiViews
 AllowOverride None
 Order allow,deny
 Allow from all
</Directory>

Index.htmの許可
 DirectoryIndex index.html index.htm

CGIスクリプトとして.plを許可
#AddHandler cgi-script .cgi
AddHandler cgi-script .cgi .pl

アクセスログでのホストネーム使用
 #HostnameLookups Off
 HostnameLookups On

ログ分離設定
 #CustomLog logs/access_log combined
 SetEnvIf Remote_Addr 192.168.1 nolog
 SetEnvIf Remote_Addr 127.0.0.1 nolog
 SetEnvIf Request_URI "Admin.dll" wormlog nolog
 SetEnvIf Request_URI "cmd.exe" wormlog nolog
 SetEnvIf Request_URI "default.ida" wormlog nolog
 SetEnvIf Request_URI "null.ida" wormlog nolog
 SetEnvIf Request_URI "root.exe" wormlog nolog
 CustomLog logs/worm_log common env=wormlog
 CustomLog logs/access_log combined env=!nolog

/var/www以下のディレクトリを,ユーザー権限で操作可能(SFTPにてファイルのアップロードが可能)とする.
# chown -R [user name] /var/www/
# chmod -R g+w /var/www/

テスト用のhtmlファイル作成
# vi /var/www/html/index.html
もしくは
例) sftp://192.168.147.131

外部からWEBサーバへの接続確認
例) http://192.168.147.131

→[SA-1-5]

[SA-3-9] Firewall(iptables)設定

iptablesの自動起動確認
# chkconfig --list | grep tables

iptablesの自動起動停止
# chkconfig iptables off

iptablesの起動
# service iptables start

iptablesの停止
# service iptables stop
(/etc/rc.d/init.d/iptables stop)

※ip6tablesについても同様です.


iptablesの設定ファイル編集
# vi /etc/sysconfig/iptables
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT


※直接設定ファイルを編集する事は,危険が伴うため推奨されません.以下のコマンドを使用して,個別にルールを適用して下さい.

iptablesのルール初期化
# /sbin/iptables -F

外部からWEBサーバへの接続許可1(SYNフラグ,ACKフラグ)
クライアント→サーバ方向
# /sbin/iptables -A FORWARD -p TCP -s 0.0.0.0 --dport 80 -d 192.168.147.131 -j ACCEPT
-p プロトコル:tcp
--dport 送信先ポート:80
-d 送信先アドレス:192.168.147.131
-j ターゲット:ACCEPT(パケットの通過を許可)

外部からWEBサーバへの接続許可2(SYN/ACKフラグ)
サーバ→クライアント方向
# /sbin/iptables -A FORWARD -p TCP ! --syn -m state --state ESTABLISHED --sport 80 -s 192.168.147.131 -d 0.0.0.0 -j ACCEPT
-p プロトコル:tcp
--sport 送信元ポート:80
-s 送信元アドレス:192.168.147.131
! --syn フラグ:SYNフラグ以外
-m state --state ステータス:ESTABLISHED
-j ターゲット:ACCEPT(パケットの通過を許可)

2010年10月7日木曜日

[SA-3-8] CentOS5.5(最小インストール)でのcrontabの利用

今回最小構成でインストールした関係で,初期状態ではcronが使えない場合もあります.
その際はvixie-cronをインストールし,利用可能な状態にしてください.
# yum install vixie-cron


crontabへの登録
$ crontab -e

crontabに登録された内容の確認
$ crontab -l

[SA-3-7] VMWare Player 3.0のNAT設定変更方法

最新のVMWare Player 3.0から,標準ではNATの設定を変更できなくなったようです.
ただし,インストーラーの中にはexeファイルが含まれているので,それを取り出して利用する事とします.

1.ダウンロードしたVMWare Playerのインストールファイルを,Windowsのコマンドライン上で,オプションを付けて実行.
VMware-player-3.1.2-301548.exe /e temp

2.作成されたtempフォルダの中のnetwork.cabをWIndowsの解凍ソフトで展開する.

3.展開されたフォルダの中のvmnetcfg.exeをVMWare Playerがインストールされたフォルダ(C:\Program Files\VMware\VMware Player)に移動する.

4. vmnetcfg.exeを実行

[SA-3-6] 最低限必要となるアプリケーションをインストール

1.yum準備
#yum install yum-fastestmirror
#yum install yum-utils

2.NTPインストール
#yum install ntp
#chkconfig ntpd on
#chkconfig --list | grep ntp
#service ntpd start

3.PHPインストール
#yum install php
#vi /etc/php.ini
memory_limit = 16M ; Maximum amount of memory a script may consume

4.Webサーバ(httpd)インストール
#yum install httpd
#vi /etc/httpd/conf/httpd.conf
KeepAlive On
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
※ログや参考となるサイトを確認しながらパラメータの微調整を行います.
#service httpd start

5.MySQL(サーバ,クライアント)インストール
#yum install mysql mysql-server
#vi /etc/my.cnf
[mysql]
default_character_set=utf8

[mysqld]
character_set-server=utf8
innodb_log_file_size=64M
innodb_buffer_pool_size=128M
#mysql_secure_installation
#service mysqld start
#chkconfig mysqld on

6.MySQLの不要ユーザー削除/新規ユーザー追加
#mysql -u root

ユーザ情報表示
select user,host,password from mysql.user;

匿名ユーザー削除
delete from mysql.user where user='';

rootパスワード設定
set password for root@localhost=password('[任意のパスワード]');
set password for root@'[ホスト名]'=password('[任意のパスワード]');
set password for root@127.0.0.1=password('[任意のパスワード]');

新規ユーザーの追加
grant all privileges on *.* to [user name]@"%" identified by '[password]' with grant option;

ユーザ情報表示(確認)
select user,host,password from mysql.user;

7.viエディタのカラー化
# yum install vim-enhanced
# alias vi='vim'
# vi /etc/bashrc
alias vi='vim'

2010年9月30日木曜日

[SA-3-5] 不要なサービスの自動起動設定解除

1.サービスの自動起動設定一覧表示
#chkconfig --list

2.不要なサービスの自動起動設定解除
#chkconfig (サービス名) off

例)chkconfig avahi-daemon off