濁点(゛)と半濁点(゜)を含む日本語のメール文字化け対応

JIS(≒ISO-2022-JP)で定義されていない文字コードは、UTF8から変換しても、もちろん正常に表示されません。

しかし日本語のUTF8には、実は、濁点と半濁点をふくむ文字に2パターンの表示方法があります。

たとえば「が」というひらがなですが、普通は、

xE3x81x8C

となります。

しかし、UTF8の決まりでは、

xE3x81x8B + xE3x82x99 (「か」+「 ○゛」)

でもOKなのです。

 

うちでは日本語文字コードの変換にUnicode::Japaneseを使ってます。非常に多くの変換パターンが実現できるので便利なのですが、上記の後者の場合(「か」+「 ○゛」の場合)に、UTF8→JISなどの変換に失敗します。

失敗というか、厳密にはxE3x82x99( ○゛)とxE3x82x9A( ○゜)が未定義状態のようで、「が」は「が」のように変換されてしまいます。

エンコーダを変えればいいのかもしれませんが、やはりバグが怖いので、下記のようにJISへの変換前にコードを統一することで対応してます。

 

ご自由にコピペどうぞ。

 

 

参考サイト)

http://d.hatena.ne.jp/kamosawa/20151015

http://www.seiai.ed.jp/sys/text/java/utf8table.html

http://webmastertool.jp/other/utf.html

http://www.asahi-net.or.jp/~ax2s-kmtn/ref/unicode/u3040.html

Postfixで特定のクライアントからのアクセスをブロックするテスト

※本記事は過去に公開した記事の復刻記事です※

特定のホストからのSMTP要求を拒否するための設定。実務的には、主にメールが拒否された際に行いたい処理の確認などに使う。

 

■main.cfを編集

————————————————

# vi /etc/postfix.main.cf

(以下を追記)


smtpd_client_restrictions = check_client_access regexp:/etc/postfix/clients_test

————————————————

※正規表現を使わない場合は「regexp:」でなく、「hash:」や「cidr:」でも可。ただし「postmap /etc/postfix/clients_test」してdbファイルを作り必要あり。

 

■client_testファイル作成

————————————————

vi /etc/postfix/client_test

(以下の形式で記載)

/接続元/ 応答コード [バナーテキスト]

例:

/123.123.123.123/ REJECT

/test.smtp.hoge.jp/ REJECT

/123.123.123.123/ 550 This is test block.(Don’t send anymore.)

/123.123.123.123/ 421 This is test block.(Send one more later.)

————————————————

※書式の詳細はこちらを参照。

 

■Postfix 再起動

————————————————

# service postfix restart

————————————————

 

参考サイト)

http://www.postfix-jp.info/trans-2.1/jhtml/access.5.html

http://d.hatena.ne.jp/hidde/20081104/1225775861

http://kisekiit.seesaa.net/article/226142927.html

http://blog.negabaro.com/4496.html

 

超簡単なMySQL死活監視

マスター・スレーブ間でMySQLのレプリケーションを取っている場合のとても簡単な死活監視。
keepalivedなどを使えない(VIPによる自動フェイルオーバーが使えない)環境のため、負荷分散および接続不可時の接続IP切り替えはアプリ側で制御した。(LBかまそうにも、LB自体が前述の理由で冗長化できないので。)
なので、以下はマスター・スレーブをお互いに監視して、落ちたときにアラート通知をするだけ。

以下、基本はマスター・スレーブ共通

シェル設置用のディレクトリ作成
# mkdir /root/bin
# cd /root/bin

監視用シェル作成(マスター側)
# vi mysql_alive_chk.sh

—————————————————————-
#!/bin/sh

##################################
# /root/bin/mysql_alive_chk.sh
##################################

#監視先
MYSQL_NAME=”mysql2.hoge.jp”
MYSQL_IP=”192.168.100.102″
MYSQL_USER=”user”
MYSQL_PASS=”pass”

ALERT_FLG=”/root/bin/${MYSQL_NAME}.alert”

RES_STRING=mysqladmin ping -h $MYSQL_IP -u$MYSQL_USER -p$MYSQL_PASS
ALIVE_STRING=”mysqld is alive”
echo $RES_STRING

if [ “$RES_STRING” != “$ALIVE_STRING” ] ; then
if [ ! -e “$ALERT_FLG” ] ; then
touch $ALERT_FLG
echo “MySQL on $MYSQL_NAME might be down!! Please check and restore.” | mail -s “System Alert” alert@hoge.jp, alert@hoge.com
exit
fi
else
if [ -e “$ALERT_FLG” ] ; then
rm -f $ALERT_FLG
fi
fi

exit
—————————————————————-

監視用シェル作成(スレーブ側)
# vi mysql_alive_chk.sh

—————————————————————-
#!/bin/sh

##################################
# /root/bin/mysql_alive_chk.sh
##################################

#監視先
MYSQL_NAME=”mysql.hoge.jp”
MYSQL_IP=”192.168.100.101″
MYSQL_USER=”user”
MYSQL_PASS=”pass”

ALERT_FLG=”/root/bin/${MYSQL_NAME}.alert”

RES_STRING=mysqladmin ping -h $MYSQL_IP -u$MYSQL_USER -p$MYSQL_PASS
ALIVE_STRING=”mysqld is alive”
echo $RES_STRING

if [ “$RES_STRING” != “$ALIVE_STRING” ] ; then
if [ ! -e “$ALERT_FLG” ] ; then
touch $ALERT_FLG
echo “MySQL on $MYSQL_NAME might be down!! Please check and restore.” | mail -s “System Alert” alert@hoge.jp, alert@hoge.com
exit
fi
else
if [ -e “$ALERT_FLG” ] ; then
rm -f $ALERT_FLG
fi
fi

exit
—————————————————————-

実行権限付与
# chmod 755 mysql_alive_chk.sh

アラートメール配信のためにMTAを起動しておく
# service postfix start

自動起動ON
# chkconfig postfix on

今回はCRONに登録
# vi /etc/crontab
—————-
# 動作が確認できればメールがうっとうしいので止める
MAILTO=root
 ↓
MAILTO=””
 :
# monitering slave’s(master’s) mysql
*/5 * * * * root /root/bin/mysql_alive_chk.sh; >/dev/null 2>&1
—————-

以上。

試しにどちらかのmysqldを止めたりしてみて、ちゃんとアラートメールが来ればOK。

参考サイト)
http://d.hatena.ne.jp/bose999/20100925/1285408588
http://d.hatena.ne.jp/bose999/20100926/1285440284

CentOS5.5 keepalivedで負荷分散と冗長化

プライマリとスレーブのDB(MySQL)サーバを準備し、マスターがLVS(バランシング)も兼ねる。
通常はマスターに来たパケットを半分スレーブに流す。
またお互いに監視しあって、マスターがダウンした場合にスレーブがマスターに昇格するフェイルオーバ機能を作る。

2016-06-06_120846

※なおクラウドの場合、VIPが設定できなかったり、バケット転送ができないようになっている場合があるので、注意が必要。

以下、マスターのみの設定。

まずバランサのためipvsadm のインストール

いろいろ事前にインストールが必要らしい
# yum install -y kernel-devel

カーネルのIP_VSのバージョンを確認
# grep IP_VS_VERSION_CODE /usr/src/kernels/2.6.18-194.32.1.el5-i686/include/net/ip_vs.h
(32bitの場合は「2.6.18-194.32.1.el5-i686」を「2.6.18-194.32.1.el5-i386」に読み替える)
——————–
-> 0x010201
——————–
これはどうやらバージョン 1.2.1。

IP_VS_VERSION_CODE 1.2.1 に該当する ipvsadm は 1.24 である為、これをソースコードからインストール。

# cd /usr/local/src
# wget http://www.linux-vs.org/software/kernel-2.6/ipvsadm-1.24.tar.gz
# tar zxvf ipvsadm-1.24.tar.gz
# cd ipvsadm-1.24
# mkdir -p /usr/src/linux
# ln -s /usr/src/kernels/2.6.18-194.32.1.el5-i686/include /usr/src/linux/include# make
# make -e BUILD_ROOT=/usr/local install

パスを通す
# cd ~/
# vi .bash_profile
以下を追記
——————–
PATH=${PATH}:/usr/local/sbin
export PATH
——————–
# source ~/.bash_profile

バージョン確認
# ipvsadm -v
——————–
-> ipvsadm v1.24 2005/12/10 (compiled with popt and IPVS v1.2.1)
——————–
v1.2.1なので、OK。

バランシング設定

192.168.10.100のVIPに来たDBアクセスをラウンドロビンさせる場合
# ipvsadm -A -t 192.168.10.100:3306 -s rr

追加された事を確認する。
# ipvsadm -Ln
—————————–
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.10.100:3306 rr
—————————–

VIP(192.168.10.100)で接続されたものを、次のサーバーへ転送する設定

192.168.10.100からリアルサーバのIPアドレスの192.168.10.101を追加。
# ipvsadm -a -t 192.168.10.100:3306 -r 192.168.10.101 -g

192.168.10.100からリアルサーバのIPアドレスの192.168.10.102を追加。
# ipvsadm -a -t 192.168.10.100:3306 -r 192.168.10.132 -g

確認
# ipvsadm -Ln
—————————–
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.10.100:3306 rr
-> 192.168.10.101:3306 Route 1 0 0
-> 192.168.10.102:3306 Route 1 0 0
—————————–

OSが再起動されたときに消えないように保存。
# ipvsadm -S

IPフォワード(パケット転送)の設定とARP設定
# vi /etc/sysctl.conf
————–
 :
# Controls IP packet forwarding
#net.ipv4.ip_forward = 0
net.ipv4.ip_forward = 1
 :
————–

設定内容反映
# sysctl -p
# cat /proc/sys/net/ipv4/ip_forward
————–
->1
————–
1と表示されればOK

以下、マスターとスレーブ共通

ifcfg-eth0:0など、VIP用の設定ファイルを削除またはリネーム。当然ネットワークはrestart。
# cd /etc/sysconfig/network-scripts
# mv ifcfg-eth0:0 ifcfg-eth0:0.bak
  :
# /etc/init.d/network restart

ローカルループバックアドレスにVIPアドレスを設定する。
#vi /etc/sysconfig/network-scripts/ifcfg-lo:0
—————————–
DEVICE=lo:0
IPADDR=192.168.10.100
NETMASK=255.255.255.255
ONBOOT=yes
—————————–

ネットワーク再起動
# /etc/init.d/network restart

keepalivedインストール

残念ながらyumにkeepalivedは無い。

まず依存関係インストール
# yum -y install make kernel kernel-devel rpm-build openssl-devel

keepalivedソースコード取得
# cd /usr/local/src
# wget http://www.keepalived.org/software/keepalived-1.1.20.tar.gz
# tar zxvf keepalived-1.1.20.tar.gz
# cd ./keepalived-1.1.20
# chown -R root:root /root/keepalived-1.1.20
# ./configure

RPMからインストール
# cp /usr/local/src/keepalived-1.1.20.tar.gz /usr/src/redhat/SOURCES/
# rpmbuild -ba ./keepalived.spec
# cd /usr/src/redhat/RPMS/x86_64(32bitの場合はi386)
# rpm -ivh ./keepalived-1.1.20-5.x86_64.rpm(32bitの場合はkeepalived-1.1.20-5.i386.rpm)

# チェック
keepalived -version

keepalived.confの「notify_master」と「notify_backup」を使い下記を現在のLVS STATEにより切り替える

LVSとリアルサーバが同一筐体の場合、
・master機の時は、VIPに対するarp応答をする
・slave機の時は、VIPに対するarp応答をしない

このためのShellを作る。

MASTER時用
# touch /etc/keepalived/lvs_master.sh
————————————-
#!/bin/sh
#lvs master起動時にARP応答する

/bin/sed -i -e ‘s/net.ipv4.conf.all.arp_ignore = 1//g;s/net.ipv4.conf.all.arp_announce = 2//g’ /etc/sysctl.conf

/sbin/sysctl -p
————————————-

スレーブ時用
# touch /etc/keepalived/lvs_backup.sh
————————————-
#!/bin/sh
#lvs backup起動時にARP応答を無効化する

/bin/echo ‘net.ipv4.conf.all.arp_ignore = 1’|/usr/bin/tee -a /etc/sysctl.conf
/bin/echo ‘net.ipv4.conf.all.arp_announce = 2’|/usr/bin/tee -a /etc/sysctl.conf

/sbin/sysctl -p
————————————-

※net.ipv4.conf.all.arp_ignore = 1 および net.ipv4.conf.all.arp_announce = 2
は、MACアドレスを覚えさせないようにする為、arpに応答させないための設定。
arpに返答してしまうと、MACアドレスを覚えてしまい、ipとmacアドレスが関係付けられてしまい送りたい機器へ通信がいかなくなるため。

設定ファイル編集
# vi /etc/keepalived/keepalived.conf
マスター側
————————————-
global_defs {
notification_email {
# 通知を受けるメールアドレス
down_notice@fuga.com
}
notification_email_from mysql1@hoge.com
smtp_server localhost
smtp_connect_timeout 30
}

vrrp_instance VI_1 {
state MASTER
# バーチャルIPのインターフェイス
interface eth1
# VRRPのID(共通)
virtual_router_id 105
# 優先度。スレーブより高くしておく
priority 51
# Master から送信する死活情報の秒指定
advert_int 1
# Master が落ちて Slave に系切り替えし、再度 Master が起動した
# 場合に Slave -> Master へ系切り替えをしないようにしたい場合は
# この nopreempt(Option 不要) を有効にする
#nopreempt
authentication {
auth_type PASS
auth_pass secret
}
virtual_ipaddress {
# バーチャルIP(keepalived が起動時に有効化するIP)を指定。
# 必ずバーチャルで付与したIP(例えば ip addr show したとき、
#「eth1」ではなく「eth1:1」となっている方のIP)を指定。
192.168.10.100 dev eth1
}
notify_master “/bin/sh /etc/keepalived/lvs_master.sh”
notify_backup “/bin/sh /etc/keepalived/lvs_backup.sh”
}

virtual_server 192.168.10.100 3306 {

# ヘルスチェックの間隔(秒)
delay_loop 120

lvs_method DR
protocol TCP
real_server 172.16.10.101 3306 {
TCP_CHECK {
connect_port 3306
connect_timeout 30
}
}
real_server 172.16.10.102 3306 {
TCP_CHECK {
connect_port 3306
connect_timeout 30
}
}
}

————————————-

スレーブ側
————————————-
global_defs {
notification_email {
down_notice@fuga.com
}
notification_email_from mysql2@hoge.com
smtp_server localhost
smtp_connect_timeout 30
}

vrrp_instance VI_2 {
state BACKUP
interface eth1
virtual_router_id 105
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass secret
}
virtual_ipaddress {
192.168.10.100 dev eth1
}
notify_master “/bin/sh /etc/keepalived/lvs_master.sh”
notify_backup “/bin/sh /etc/keepalived/lvs_backup.sh”
}
————————————-

mysqlが落ちて、かつマシン(vrrp)が動いている場合、フェイルオーバが効かないので、mysqlが落ちた時に自身のkeepalivedを落とすスクリプト(PHP)を作成。
こちらからのまるパクリです。

# touch /etc/keeplalive/mysql_alivecheck.php
————————————-
hostname‘;

// 成功したときに実行したいコマンド
$SUCCESS_BIN = ”;

$result = db_connect_check($HOST, $USER, $PASS, $DB_NAME);

if (!$result) {
// 失敗
print “error\n”;
if ($FAIL_BIN) {
system($FAIL_BIN);
}
} else {
// OK
if ($SUCCESS_BIN) {
system($SUCCESS_BIN);
}
}
exit;

function db_connect_check($host, $user, $pass, $db_name) {
$con = mysql_connect($host, $user, $pass, true);
if (!$con) {
// エラー表示
print mysql_error();
return false;
}

if ($db_name) {
if (!mysql_select_db($db_name, $con)) {
// エラー表示
print mysql_error();
return false;
}
}
return true;
}
?>
————————————-
※これはPHPの例だが、”mysqladmin -ping”でチェックするshellスクリプトなどでもOK。
CRONに登録
# vi /etc/crontab
————————————-
*/1 * * * * root php /etc/keeplalive/mysql_alivecheck.php;
————————————-

CRONじゃなくループでまわしちゃいたいときなどは下記参照。
http://d.hatena.ne.jp/bose999/20100926/1285440284

ていうか、こういうスクリプト走らせなくても、keepalivedのvirtual_serverディレクティブで自分のリアルIPの3306ポート監視して、notify_downでkeepalived落とせばいいんじゃないの?って思った。
↓こんな風に。
http://d.hatena.ne.jp/interdb/20131219/1387380530
試してませんが。

最後にkeepalivedの自動起動設定
# chkconfig keepalived on

あとは必要に応じてiptablesで規制をするなどしてください。
今回許可が必要なのはtcp、以下MySQL、vrrp、icmpくらい。
必要に応じてHTTP,DNSなど。

# 参考サイト
http://sonarsrv.com/blog/server/server_debian/344.html
http://d.hatena.ne.jp/bose999/20100925/1285408588
http://d.hatena.ne.jp/bose999/20100926/1285440284
http://qiita.com/nagais/items/b9b1940cdaf9a17b4088
http://infra.makeall.net/archives/1475
http://infra.makeall.net/archives/1607
http://infra.makeall.net/archives/1665
http://knowledge.sakura.ad.jp/tech/274/3/
http://knowledge.sakura.ad.jp/tech/274/4/
http://tanyaolinux.blogspot.jp/2014/04/vip-permanent.html
http://k-1-ne-jp.blogspot.jp/2013/02/lvsipvsadm.html
http://q.hatena.ne.jp/1199870913
http://d.hatena.ne.jp/interdb/20131219/1387380530
http://rksz.hateblo.jp/entry/2013/03/19_keepalived_lvs_load_balancer_2013
http://oxynotes.com/?p=6361#2
http://techblog.raccoon.ne.jp/archives/47152095.html

G社のIaaS型クラウドサービスのネットワーク構成について

以下、2015-04-15のサポートへの問い合わせより判明したこと

——————————————–
御社で提供しているLBは冗長化構成なのか。
→違う。
(ん?ハイパーバイザー配下でHA校正とうたっているのでは?LBは対象外なの?)
じゃあLB自体に障害があった際にはどうなる?
→配下ノードへの負荷分散以前に接続できなくなる。(keepalivedなどが動いているわけではない)
じゃあなぜIPが2つ付与されるのか?1つはメイン用でもう1つはスタンバイ用ではないのか?
→仕様上そうなっていて(1つはバーチャル用でもう1つが実IP)、もう1つがスタンバイ用というわけではない
じゃあLBをもう1つ作ってスタンバイ用にできるのか。
→LBをもう1つ作ることはできるが、死活監視する機能がない(ユーザ側で設定もできない)ので、スタンバイとしては機能しない。

では話は変わるが、LBのIPは増減できないのか?
→できない。
LBにローカルのNICおよびローカルIPは付与できないのか
→できない。決められたパブリックの仮想NICとパブリックIPが自動的に2つ付与される。じゃあWEBなどからローカル経由で複数のDBに負荷分散できないということか?
→できない。
では御社のLBはWEBなどの外部公開用サーバの負荷分散が前提ということか。
→そういうこと。
じゃあLAN内DBに負荷分散したいときは?
→LB用のVMを独自に立てていただく必要がある。
——————————————–

その後判明したこと
・仕様変更により仮想サーバ間のip forwarding(パケット転送)ができなくなった。
 http://d.hatena.ne.jp/turkey_hate/20130416

・フェイルオーバー時、keepalivedによって、各サーバのネットワーク構成はスタンバイがプライマリに昇格となるが(ip add show で確認)、ブロードキャストが、切り替わった後の躯体のARPを返してくれない?もしくは返すがパケット転送規制によりMacアドレスを取得できない?
  ↓
・LAN内サーバから、スタンバイ機(この時プライマリ)のMacアドレスが取得できない?
※tcpdumpで確認。ずっと”who has ***.***.***.***? tell 接続元IP”を繰り返している。
※ちなみに接続元のサーバで、スタンバイ機のMacアドレスをARPコマンドで明示的に登録してもダメ。
  ↓
・よって独自のオートフェイルオーバー構成付きLAN内LBは立てられない?
・バランシングを目的としたLBだけ(冗長化構成無し)ならできる?←それなら理屈上オートフェイルオーバーもできるはずだが。。。
 http://blog.code4u.org/archives/444
 http://gmo1973.blogspot.jp/2013/01/blog-post_21.html
もしかしたら、ローカル側のパケット転送だけDROPしているのかも。
この件については引き続き調査中。

logrotateでsyslog肥大化防止

もともと小さなDisk容量が圧迫され、一部のサービスがダウンしたのでその対策。
※この方法の欠点:「元ファイルコピー」 ~ 「元ファイルの中身の消去」の間に発生したログは記録されない

ディスク・ドライブの使用量を確認
# df -h

どのフォルダが多いか特定する
# du -h /

ある程度見当がついたら、
# du -h “ディレクトリパス” | sort -n | tail -10
# du -h “ディレクトリパス” | sort -n | more
などで絞り込んでいく。

これで調べるとやはりログ関係のある/var/logが大きそう。

ディレクトリが特定できたら、ファイルを特定していく
(-aオプションでファイルも表示)
# du -ha /var/log | sort -n | more

syslog関係が肥大化している。

一般的には、メールサーバであればmaillog、WEBなど外部公開されているものであれば、不正ログイン失敗を記録するbtmpあたりが、おそらく大きくなってるのではないかと思われる。

# vi /etc/logrotate.d/syslog

/var/log/maillog /var/log/btmp をログローテートさせる場合は以下のように修正
※10MBを超えたらローテートし、4世代分まで残す場合
————————————————————————–
/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron {# sharedscripts
postrotate
/bin/kill -HUP cat /var/run/syslogd.pid 2> /dev/null 2> /dev/null || true
/bin/kill -HUP cat /var/run/rsyslogd.pid 2> /dev/null 2> /dev/null || true
endscript
}

   ↓

/var/log/messages /var/log/secure /var/log/spooler /var/log/boot.log /var/log/cron { sharedscripts
postrotate
/bin/kill -HUP cat /var/run/syslogd.pid 2> /dev/null 2> /dev/null || true
/bin/kill -HUP cat /var/run/rsyslogd.pid 2> /dev/null 2> /dev/null || true
endscript
}

/var/log/maillog /var/log/btmp {
rotate 4
size 10M
sharedscripts
postrotate /bin/kill -HUP cat /var/run/syslogd.pid 2> /dev/null 2> /dev/null || true /bin/kill -HUP cat /var/run/rsyslogd.pid 2> /dev/null 2> /dev/null || true
endscript
}
————————————————————————–

テスト実行
# logrotate -d /etc/logrotate.conf

ファイルが指定した世代数や要領でローテートされているのを確認

CRONへの登録確認
/etc/cron.daily内にlogrotateがあればOK
# ls -lat /etc/cron.daily

MySQLのレプリケーション設定

■マスター側

設定ファイル編集
vi /etc/my.cnf

 

MySQL再起動

 

データディレクトリがにバイナリデータが作成されているのを確認

 

MySQLユーザと権限付与

 

データダンプ

※特定のDBのみdumpする場合は–all-databasesを削除しdb名を追加
※MyISAMの場合は、–master-dataによって、自動的に–lock-all-tablesが有効になるので、すべてのテーブルがロックされてしまうので注意
※InnoDBであれば、–single-transactionを付与することで、ロックされることなくdumpを取得できる。

dumpファイルをスレーブ側へ転送しておく

 

■スレーブ側設定

設定ファイル編集

 

再起動

 

マスターDBのダンプの読み込み

 

ダンプした時点の、マスターのバイナリログファイル名(MASTER_LOG_FILE)と開始位置(MASTER_LOG_POS)を確認しておく

 

レプリケーション設定

 

レプリケーションの開始

 

レプリケーションの動作確認

※Slave_IO_Running と Slave_SQL_Running がどちらもYesになっていれば、レプリケーションが正常に動作しています。

参考サイト)

レプリケーションが動かなくなった時

基本は以下のサイトの手順で復旧可能。

MySQLのレプリケーション時エラー対処方法

https://qiita.com/soramugi/items/3c33200b5903007f3ead

 

もしそれでもだめなら、当記事の「データダンプ」のとこからやり直す。

2019/1/28レプリケーションが機能していないと気付いた(「Slave_IO_Running 」が「Yes」にならない)。

その際はダンプからもう一度行うことで復旧した。

ストレージ障害とか、IO系の障害とかあった後は、要注意。

OpenSSLでPKCS12ファイルの解凍

主にSSLサーバ証明書の設置や更新のための1手段。

まず、対象のPKCS12ファイルを、WinSCPなどのFTPクライアントやSSHクライアントを使い、サーバのユーザホームディレクトリ等に転送。

ここでは、
転送したPKCS12ファイルの場所を、
/home/userdir/PKCS12.pfx
サーバ証明書と中間証明書の展開先を、
/etc/httpd/conf/ssl.crt/
秘密鍵の展開先を、
/etc/httpd/conf/ssl.key/
とする。

展開時にファイルは上書きされるので、過去のものがあれば念のため各ファイルのバックアップ取得
# cp /etc/httpd/conf/ssl.crt/clcert.crt /etc/httpd/conf/ssl.crt/clcert.crt.bak
# cp /etc/httpd/conf/ssl.crt/cacert.cer /etc/httpd/conf/ssl.crt/cacert.cer.bak
# cp /etc/httpd/conf/ssl.key/privatekey.key /etc/httpd/conf/ssl.key/privatekey.key.bak

#サーバ証明書解凍
# openssl pkcs12 -in /home/userdir/PKCS12.pfx -clcerts -nokeys -out /etc/httpd/conf/ssl.crt/clcert.crt

#中間証明書解凍
# openssl pkcs12 -in /home/userdir/PKCS12.pfx -cacerts -nokeys -out /etc/httpd/conf/ssl.crt/cacert.cer

#秘密鍵解凍
# openssl pkcs12 -in /home/userdir/PKCS12.pfx -nocerts -nodes -out /etc/httpd/conf/ssl.key/privatekey.key

上記各々のコマンドで、解凍パスワードを求められるので入力すると、目的の場所にファイルが展開される。

後は、必要に応じて、ssl.conf内の各ファイルのパスを指定し、WEBサーバのリロードまたは再起動。

# リロードする前に文法チェック
# service httpd configtest

# リロード
# service httpd reload

 

MySQLのクエリログの出力方法

/etc/my.cnfを開く。

[mysqld]ディレクティブにログの種類と出力場所を指定。

代表的なものは下記。

(エラーログ)※これはたぶん最初から書いてある
log_error=”/var/log/mysqld.log”
log_warnings=1

(一般クエリログ)
log=”/var/log/sql.log”

(バイナリログ)
log_bin=”/var/log/mysqlbin.log”
log_bin_index=”/var/log/mysqlbin.list”
max_binlog_size=1M
expire_logs_days=1

(スロークエリログ)
slow_query_log=1
slow_query_log_file=”/var/log/slowquery.log”
log_queries_not_using_indexes
log_slow_admin_statements

設定を書いて保存したら、出力ファイルを作成し、所有者をmysqlに変更しておく。

(一般クエリログの場合)
# touch /var/log/sql.log
# chown mysql:mysql /var/log/sql.log

最後にmysqldを再起動。
# service mysqld restart

一般クエリログの出力例
——————————-
  :
18 Connect ****@localhost on dbname
18 Query set autocommit=1
18 Query SET NAMES utf8
18 Query SELECT * FROM tbl1
18 Query SELECT * FROM tbl2
WHERE id = ‘*****’
18 Query UPDATE tbl2
SET clm1 = UNIX_TIMESTAMP()
WHERE id = ‘*****’
18 Query SELECT * FROM tbl3 WHERE id=’****’
17 Quit
  :
——————————-

ちなみにSQLインジェクション攻撃を受けている場合のログの例
——————————-
  :
1019 Connect ****@localhost on dbname
1019 Query set autocommit=1
1019 Query SET NAMES utf8
1019 Query SELECT * FROM tbl1 WHERE id=’-2353′ OR ORD(MID((SELECT IFNULL(CAST(clm1 AS CHAR),0x20) FROM tbl2 LIMIT 1328,1),12,1))>112#’ AND clm2=’abcdefg’
1019 Query SELECT * FROM tbl3
1019 Quit
  :
——————————-

ちなみに、
# tail -f /var/log/sql.log
とすれば発行クエリがリアルタイムでチェック可能。

DBI使って開発段階で生のSQLをチェックしたい時かあると思いますが、DBIx::QueryLogとか使うよりこっちのほうがアナログで簡単そう。

sqlmapの使い方

いろいろ資料は散見されるが、、、

弊社なりにまとめてみました。

まず、sqlmapをインストールしたディレクトリに移動。

$ cd sqlmap

基本は、

$ ./sqlmap.py -u “http://hoge.jp/index.php?id=fuga”

とやるだけでOK。Getパラメタに対してインジェクションチェックを行ってくれる。

POSTもチェックしたいときは、

$ ./sqlmap.py -u “http://hoge.jp/index.php?id=fuga” –data “postparm1=123&postparam2=456”

 

DBMSの種類がすでに分かっているときは、明示的に指定すれば時間の省略になる。

$ ./sqlmap.py -u “http://hoge.jp/index.php?id=fuga” –dbms mysql

 

脆弱性が発見されたときに、同時にDB一覧の取得を試みる場合。

$ ./sqlmap.py -u “http://hoge.jp/index.php?id=fuga” –dbs

 

脆弱性が発見されたときに、同時にテーブル一覧の取得を試みる場合。

$ ./sqlmap.py -u “http://hoge.jp/index.php?id=fuga” –tables

 

脆弱性が発見されたときに、特定のテーブルのカラムデータ取得を試みる場合。

$ ./sqlmap.py -u “http://hoge.jp/index.php?id=fuga” -T “table name” –colum

※「column」ではなく「columns」と記載されているドキュメントも見かけたが、うちの環境の場合は「column」で通った。

 

脆弱性が発見されたときに、特定のテーブルの中身のダンプ取得を試みる場合。

$ ./sqlmap.py -u “http://hoge.jp/index.php?id=fuga” -T “table name” –dump

※実際表示されるとかなりショッキングです。。。。

 

基本は、上記の基本的なコマンドを発行し、デフォルトレベルのチェックで、

[CRITICAL] all tested parameters appear to be not injectable.

と判定されれば、とりあえずは脆弱性は無いということなので、あとは必要に応じてチェックレベルを上げてみてもよいかと思います。

レベルを指定する場合は下記のようにする。(0~5の範囲で指定可能)

$ ./sqlmap.py -u “http://hoge.jp/index.php?id=fuga” –level 3

 

その他、任意のヘッダを指定したりログレベルを調整したり、さまざまな使い方ができる模様。

詳細は下記の参考サイトをどうぞ。

 

参考サイト)

オープンソースの SQL インジェクション脆弱性診断ツールの sqlmap を Kali Linux で使ってみる