MySql の「unauthenticated user」。
サイトが激重になった調査と解決のログ。
とりあえずログインとプロセスの確認。
[server ~]# top top - 16:07:35 up 97 days, 14:55, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 37 total, 2 running, 35 sleeping, 0 stopped, 0 zombie Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 1998992k total, 577856k used, 1421136k free, 161764k buffers Swap: 0k total, 0k used, 0k free, 295652k cached
平和だ。
ネットワークを疑う。
[server]# netstat -an (略)
State "ESTABLISHED" が10個ほど。
そのうちの、全てが MySql のポート。
MySQL のプロセスを確認。
mysql> show processlist; | 1401878 | root | localhost | NULL | Query | 0 | NULL | show processlist | | 1401885 | unauthenticated user | xx.xx.xx.xx:pppp | NULL | Connect | NULL | login | NULL | | 1401886 | unauthenticated user | xx.xx.xx.xx:pppp | NULL | Connect | NULL | login | NULL | | 1401887 | unauthenticated user | xx.xx.xx.xx:pppp | NULL | Connect | NULL | login | NULL | | 1401888 | unauthenticated user | xx.xx.xx.xx:pppp | NULL | Connect | NULL | login | NULL | | 1401889 | unauthenticated user | xx.xx.xx.xx:pppp | NULL | Connect | NULL | login | NULL | | 1401890 | unauthenticated user | xx.xx.xx.xx:pppp | NULL | Connect | NULL | login | NULL |
調べたところ
MySQLがDNSの逆引きをする際に起こるらしい
参考) http://kennyqi.com/archives/70.html
対応もこのサイトの通りに
# vi /etc/my.cnf [mysqld] skip-name-resolve
で、すっきり解決しました。
だが何故突然、この現象が発生したのかは謎。
『「ESTABLISHED」10個、「unauthenticated user」が6個』は多いのか? 少ないのか?
MySQL のコネクションはデフォで100なのだから、この程度の量は問題ないと思ったのだが .....
謎は深まる。
ちなみに、MySQLのコネクション最大値。
( my.cnf に何も記述していない場合 )
mysql> show variables like 'max_connections' -> ; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 100 | +-----------------+-------+ 1 row in set (0.00 sec)
Web サーバーに繋がらないと思ったら iptables のせいでした。
RedHat Enterprise のネットワーク設定に詰まったのでメモ。
Apache 等のプロセスは立ち上げたのに、アクセスできない。
アクセスログも残ってない。
[ローカル]$ telnet xxx.xxx.xxx.xxx Trying xxx.xxx.xxx.xxx... telnet: connect to address xxx.xxx.xxx.xxx: Connection refused telnet: Unable to connect to remote host
サーバーにログインして、自分でアクセスしたらちゃんと応答が返る
[サーバー]$ telnet localhost 80 GET / HTTP/1.1 (略 ちゃんと応答が帰ってる)
なので Apache はちゃんと動いてるっぽい。
ネットワークに問題が?
パケットを監視してみる
[サーバー]# tcpdump port 80 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes xxxxxxxxx > xxxxxxxxx.http: S xxxxxx:xxxxxx(0) win xxxxx <mss xxxx,nop,wscale 3,nop,nop,timestamp 257328529 0,sackOK,eol>
一行だけでも出力はしているので、パケットはとりあえず到着していると判断。
ここでネットワーク途中のFWではなく、サーバー内のFWを疑う。
[サーバー]# 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 443 -j ACCEPT
[サーバー]# /etc/init.d/iptables restart [サーバー]# /sbin/iptables -L ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:https
http と https が ACCEPT になり、外からのアクセスも成功した。
たまにやる、慣れないディストリビューションの初期設定は地雷 orz
CentOS5.7 で rssh と chroot の設定をする。
CentOS 5.7 に rssh の設定をするログ。
目的
1.rssh のインストール
yum 等では配布していないので、rssh の最新版を確認する
http://sourceforge.net/projects/rssh/files/rssh/
以下、サーバーに root でログインしたところから。
今回は、rssh-2.3.3。
# cd /usr/local/src/ # wget http://jaist.dl.sourceforge.net/sourceforge/rssh/rssh-2.3.3-1.src.rpm # wget http://jaist.dl.sourceforge.net/sourceforge/rssh/rssh-2.3.3.tar.gz
ソースと rpm を両方ダウンロード。
( 後でソースが必要となるため。自分でconfigureとmakeをするならrpmはいらない )
# rpmbuild --rebuild rssh-2.3.3-1.src.rpm # rpm -ihv /usr/src/redhat/RPMS/i386/rssh-2.3.3-1.i386.rpm # which rssh /usr/bin/rssh
rpm のビルド
# vi /etc/shells (追記) /usr/bin/rssh # vi /etc/rssh.conf (以下のコメントを外す) allowscp allowsftp
2.ユーザーの追加
# adduser -s /usr/bin/rssh -d /home/scptest scptest # passwd scptest # cat /etc/passwd (略) scptest:x:501:501::/home/scptest:/usr/bin/rssh
3. chroot の設定
# tar zxvf rssh-2.3.3.tar.gz # cp rssh-2.3.3/mkchroot.sh ~ # cd # ./mkchroot.sh /home/scptest # cd /home/scptest/ # vi etc/passwd (対象のユーザー以外を削除)
ソース内に入っている mkchroot.sh を使い、 対象ディレクトリに chroot の設定をする。
[chrootdir] /etc/passwd 内の不要なユーザー情報を削除する
4.動作確認
別のマシンからアクセスのテスト
$ ssh scptest@192.168.0.100 scptest@192.168.0.100's password: This account is restricted by rssh. Allowed commands: scp sftp If you believe this is in error, please contact your system administrator. Connection to 192.168.0.100 closed. $ scp dummy.txt scptest@192.168.0.100:. scptest@192.168.0.100's password: dummy.txt $ sftp scptest@192.168.0.100:. Connecting to 192.168.0.100... scptest@192.168.0.100's password: Changing to: /home/scptest/. sftp>
SCP / SFTP のみでアクセスできる事を確認。
Apacheのバージョンが上がらない。
CentOS5.7 が出たらしいので ApacheKiller に対応した Apache2.2.20 をインストールしてみる。
# yum update httpd Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: www.ftp.ne.jp * extras: www.ftp.ne.jp * updates: www.ftp.ne.jp Setting up Update Process No Packages marked for Update
あれ?
# cat /etc/redhat-release CentOS release 5.6 (Final) # apachectl -v Server version: Apache/2.2.17 (Unix) Server built: Dec 17 2010 11:58:24 # yum update (略) # cat /etc/redhat-release CentOS release 5.7 (Final) # apachectl -v Server version: Apache/2.2.17 (Unix) Server built: Dec 17 2010 11:58:24
え? 何故に?
ApacheKiller のアドバイザイリをちゃんと解釈してみる。
ApacheKiller 対策をしていて、公式のセキュリティアドバイザリをそのまま貼付けるのもコピペプログラマみたいで芸がないので、ちゃんと解釈してみる。
# Drop the Range header when more than 5 ranges. # CVE-2011-3192 SetEnvIf Range (?:,.*?){5,5} bad-range=1
HTTPリクエストヘッダフィールド(Range) が正規表現にマッチした場合に環境変数 bad-range=1 をセット。
http://httpd.apache.org/docs/2.0/ja/mod/mod_setenvif.html#setenvif
※ 正規表現
『(?: ... )』 拡張正規表現 後方参照しない
『,.*?』の5回(以上)の繰り返しにマッチ
RequestHeader unset Range env=bad-range
RequestHeader リクエストヘッダディレクティブ
bad-range 環境変数がセットされている時に、RequestHeader から Range 属性を削除
http://httpd.apache.org/docs/2.2/ja/mod/mod_headers.html#requestheader
# We always drop Request-Range; as this is a legacy # dating back to MSIE3 and Netscape 2 and 3. RequestHeader unset Request-Range
Request-Range を削除。こちらは無条件に削除している。
# optional logging.
CustomLog logs/range-CVE-2011-3192.log common env=bad-range
CustomLog logs/range-CVE-2011-3192.log common env=bad-req-range
環境変数 bad-range、bad-req-range が指定されている時に、カスタムログ出力
ファイル指定(ServerRootからの相対パス)、ログのフォーマットは common(通常)
http://httpd.apache.org/docs/current/ja/mod/mod_log_config.html#customlog
まとめ。
- 「1. 攻撃っぽかったら 2. ヘッダーだけ捨てて 3. ログを取る」の流れ。
- 拡張正規表現とか、急に出てくると思い出せない。
- 「{5,5}」が地味に冗長
- ログの出力先を変更しているサーバーは、ちゃんと設定しよう。
- 最後の「env=bad-req-range」って不要なんじゃ ...
- アドバイザリにも書いてあるけれど、 Apache2.2 以上の設定です。
+Snippets Testing Tool 等。
Zend FrameWorkでCLIのスクリプトを実行するルーター
ZFでバッチ処理とかが、どうもすっきり書けないのでちゃんと考えてみた。
こちらの方の記事をかなり参考にさせて頂きました。
CLI(php コマンドライン) から Zend Framework アプリを実行するには - Enjoi Blog
この方のプログラムの Controlelr_Router と Console_Getopt をくっつけただけです。
<?php require_once 'Zend/Controller/Router/Abstract.php'; require_once 'Zend/Controller/Router/Interface.php'; class Zend_Controller_Router_Cli extends Zend_Controller_Router_Abstract implements Zend_Controller_Router_Interface { public function assemble($userParams, $name = null, $reset = false, $encode = true) {} public function route(Zend_Controller_Request_Abstract $dispatcher) { require_once 'Zend/Console/Getopt.php'; $opt = new Zend_Console_Getopt(array( 'action|a=s' => 'action', 'controller|c=s' => 'controller', 'module|m=s' => 'module', )); $dispatcher->setControllerName($opt->controller) ->setActionName($opt->action) ->setModuleName($opt->module); return $dispatcher; } }
あとは追加のパラメータをどう処理するかが課題。
ini ファイルからでも読み込ませるか?
そんな感じで。