2010年11月26日金曜日

[MA-10-3] フリーの画像制作環境

Adobe IllustratorやCorel DRAWと同種の,Windows向けベクター形式のグラフィックエディタとして,Inkscapeがリリースされている.

また,Adobe Photoshopと同種の,Windows向けビットマップ形式のグラフィックエディタとしては,GIMPが有名である.

どちらもフリーソフトウェアな為,気軽に導入できるメリットがある.
ただし,業務用途においてはやはりAdobeの製品が一般的であるため,あくまでも補佐的な役割となるであろう.


ここで,Suzukaで使用される画像形式にPDRが存在するが,同じ作者がSVG形式をPDR形式に変換するSVG2PDRというツールをリリースしている.

こちらを利用すれば,フリーのソフトウェアのみで
  1. InkscapeでSVG形式のファイル作成
  2. SVG2PDRでPDR形式にコンバート
  3. PDRをsuzukaに読み込み,SWF出力
を行う事が可能となる.

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月24日水曜日

[memo] 安全なウェブサイトの作り方 (IPA)

情報処理推進機構(IPA)が公開している,サイト開発者・運営者が適切なセキュリティを考慮したサイトを作成するための資料をベースに,SQLインジェクションやOSコマンドインジェクション、クロスサイトスクリプティング(XSS)など、IPAへの届け出の多かった脆弱性や、攻撃による影響が大きい脆弱性を取り上げ、生じうる脅威や対策について解説する.

ダウンロード(PDF)

[MA-10-2] フリーの制作環境を使った作例 (Suzuka)

  1. Suzukaをここからダウンロードし,インストールする.
  2. サンプルをダウンロードする.
  3. Photoshop Elements,もしくはParaDrawを使って画像を作成.
  4. 作成した画像を使って,2のサンプルの画像を差し替え

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年11月8日月曜日

[memo] docomo2010年冬/2011年春モデル発表

docomoから2010年冬/2011年春モデルの発表がありました.

注目は,既に発売が開始されているAndroidスマートフォンのGALAXY SGALAXY Tabと,3D液晶が特徴の SHARP LYNX 3D SH-03C(SoftbankのGALAPAGOS 003SHと同等?),東芝 REGZA Phone T01-C(SoftbankのREGZA Phone IS04と同等?),LGエレクトロニクス Optimus chat L-04Cあたりでしょうか?

また,次世代無線技術であるLTE(Long Term Evolution,3.9G)に対応したデータ通信対応端末も発表されています.現時点ではエリアが限定的であるため,積極的に選択する理由がありませんが,料金プラン等今後の動向には注意が必要です.

#個人的には,SHARP SH-06Cとか面白そうですが,
#小型プロジェクタと携帯電話が一体になっている必然性が薄いんだよなぁ...
#また,残念ながら,Windows Phone 7の発表はありませんでした...

2010年11月5日金曜日

[memo] レンタルサーバ/VPSの選び方

インターネット上にはレンタルサーバを提供している会社がいくつもありますが,何を選択基準とすればよいか迷う事と思います.
そこで,レンタルサーバを用いて何をしたいかに注目し,レンタルサーバ選びの際の参考となる資料を纏めてみました.

テキスト中心のサイトであったり,自身で作成した作品を公開する場としてのサイトであれば,下記特記事項を気にする必要はありませんが,少し特殊な事を行いたい場合は,以下の項目を参考にして必要となる機能を把握してもらえればと思います.


目的別必要機能

独自ドメイン利用可能ディスク容量追加DB管理者権限CRON
自分で管理できるメールアドレスが欲しい


自分で決めたURLを使いたい


ファイルの配布



DBを使いたい



独自アプリケーション



定時作業の自動化


商用サイトの構築
(企業広報)



商用サイトの構築
(ショッピングサイト)



代表的なレンタルサーバとしては,paperboy&co.(ぺぱぼ)のロリポップや,さくらインターネットのさくらのレンタルサーバがあります.


またレンタルサーバとは少し異なりますが,VPS(Virtual Private Server)サービスを利用する方法も考えられます.
レンタルサーバは,あくまでも既に構築されているOSやアプリケーションの環境を,複数人で利用する事を前提とする事で低価格を実現したサービスですので,ユーザーによっては必要な機能を満たせない事もあり得ます.
それに対しVPSサービスは,仮想環境の範囲内でユーザーが全てをコントロール可能ですので,アプリケーションの追加やユーザー独自の作り込みといった,一般的なサーバ構築で行える事のほぼ全てが可能です.場合によっては,OSの入れ替えといった事も可能となっています.
(VPSで出来ないことは...サーバのロケーション選択とハードウェアの仕様選定といったところでしょうか)

というわけで,VPSを利用すれば,環境・仕様が画一的なレンタルサーバ以上に柔軟な運用が可能になります.

低価格なVPSサービスとしては,DTIのServerMan@VPSや,さくらインターネットのさくらのVPSがあります.

2010年11月4日木曜日

[memo] ソフトバンク2010年冬/2011年春モデル発表

ソフトバンクの2010年冬/2011年春モデルが発表されました.
予想通り,スマートフォンのラインアップが充実し(しかも全モデルAndroid 2.2!),ソフトバンクのスマートフォンにかける意気込みが伝わってきます.

注目は,DELLのStreakや,SHARPのGALAPAGOS 003SHGALAPAGOS 005SHあたりでしょうか?

また,キャリアメール(S!メール)にも最初から対応している事から,iPhoneで培ったスマートフォンの運用に関するノウハウが生かされていると思われます.

ちなみに,11/8(月)にはdocomoの発表会が控えています.
Windows Phone 7とか出てくるのかな?