このブログを検索

2011年2月24日木曜日

[PHP]バージョンを見えないようにする

PHPの場合、Apacheのバージョンを見えなくするをした上で、さらにPHPの設定を変更します。

php.iniを次のように変更します。
expose_php = Off

●変更前
$ telnet sssdev1 80
Trying 192.xxx.xxx.xxx...
Connected to sssdev1.sss.indexweb.co.jp (192.xxx.xxx.xxx).
Escape character is '^]'.
GET /pinfo.php HTTP/1.1
Host: ssssfuka.indexweb.co.jp

HTTP/1.1 200 OK
Date: Thu, 24 Feb 2011 03:09:46 GMT
Server: Apache
ココ→★X-Powered-By: PHP/5.2.17
Transfer-Encoding: chunked
Content-Type: text/html
        :
●設定後
$ telnet sssdev1 80
Trying 192.xxx.xxx.xxx...
Connected to sssdev1.sss.indexweb.co.jp (192.xxx.xxx.xxx).
Escape character is '^]'.
GET /pinfo.php HTTP/1.1
Host: ssssfuka.indexweb.co.jp

HTTP/1.1 200 OK
Date: Thu, 24 Feb 2011 03:11:17 GMT
Server: Apache
★(表示されない)
Transfer-Encoding: chunked
Content-Type: text/html
        :

[Apache]バージョンを見えないようにする

Apacheのバージョンが見えるとセキュリティ上、問題があります。
例えば、そのバージョンにあるセキュリティホールを使われてしまうリスクがあるためです。
詳細はこちら。
http://httpd.apache.org/docs/2.2/ja/mod/core.html#servertokens

httpd.confに次のように記述します。
ServerTokens ProductOnly
●変更前
$ telnet sssdev1 80
Trying 172.xxx.xxx.xxx...
Connected to sssdev1.sss.indexweb.co.jp (172.xxx.xxx.xxx).
Escape character is '^]'.
GET / HTTP/1.1

HTTP/1.1 400 Bad Request
Date: Thu, 24 Feb 2011 01:08:00 GMT
ココ→★Server: Apache/2.2.1x (Unix) DAV/2 PHP/5.2.1x
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1
       :
●設定後
$ telnet sssdev1 80
Trying 172.xxx.xxx.xxx...
Connected to sssdev1.sss.indexweb.co.jp (172.xxx.xxx.xxx).
Escape character is '^]'.
GET / HTTP/1.1

HTTP/1.1 400 Bad Request
Date: Thu, 24 Feb 2011 01:08:57 GMT
ココ→★Server: Apache
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1
       :

2011年2月23日水曜日

SSL証明書をopensslコマンドで確認する

opensslコマンドで接続先の証明書を取得することができます。
$ openssl s_client -connect xx.xx.xxx.xxx:443 -showcerts

-showcertsは、ベリサインなどの中間証明書も取得したい場合に使います。
ベリサインだけではないでしょうが、CAはときどき証明書の構成や暗号ロジックを変更することがあります。
実行例は次の通り。
CONNECTED(00000003)
depth=2 /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network
verify return:1
depth=1 /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server 1024-bit CA - G2
verify return:1
depth=0 /C=JP/ST=Tokyo/L=Taishido, Setagaya-ku/O=Index Corporation/OU=Technical Support Dept./CN=ssl-ssss.indexweb.co.jp
verify return:1
---
Certificate chain
 0 s:/C=JP/ST=Tokyo/L=Taishido, Setagaya-ku/O=Index Corporation/OU=Technical Support Dept./CN=ssl-ssss.indexweb.co.jp
   i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server 1024-bit CA - G2
-----BEGIN CERTIFICATE-----   ★接続先の証明書
MIIeWZccbcYGaWibaGiqywYoY9B7krqf1Jf92VXf4danbGKQHKIg9W0baqUFADCB
             :
+zcHSBcs/TAf0SUFoYTaaYS/pzeJUhO=
-----END CERTIFICATE-----
 1 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server 1024-bit CA - G2
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network
-----BEGIN CERTIFICATE-----   ★ベリサインの中間証明書
MIIfRdccbrwGaWibaGiqzwzyZf3KeK/Wf+X7KrvLGdanbGKQHKIg9W0baqufadCB
             :
54aOnkweIl2+DoyLE39vHw==
-----END CERTIFICATE-----
---
Server certificate
subject=/C=JP/ST=Tokyo/L=Taishido, Setagaya-ku/O=Index Corporation/OU=Technical Support Dept./CN=ssl-ssss.indexweb.co.jp
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)09/CN=VeriSign Class 3 Secure Server 1024-bit CA - G2
---
No client certificate CA names sent
---
SSL handshake has read 2844 bytes and written 316 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 1024 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Session-ID-ctx: 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXX
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1298440296
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
取得した証明書の内容を確認するのもopensslコマンドを使います。
コモンネームだけ知りたければgrepすると簡単です。
$ openssl asn1parse -i -in test.crt | grep -A1 commonName
  185:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
  190:d=5  hl=2 l=  47 prim:      PRINTABLESTRING   :VeriSign Class 3 Secure Server 1024-bit CA - G2
--
  401:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
  406:d=5  hl=2 l=  23 prim:      T61STRING         :ssl-ssss.indexweb.co.jp

2011年2月15日火曜日

[CloudForecast]RRDファイルへDSを追加する

RRDファイルへのData Sourceを追加する
基本的にRRDファイルはDS(Data Source)の追加ができません。
※そのため、CactiではRRD管理をグラフ単位にしています。
追加は、RRDファイルからdumpしたXMLファイルを修正してRRDにrestoreします。

1.RRDファイルのXML出力
$ rrdtool dump MONSSS_perfstat-xxxxxx.rrd xml/new.xml
2.XMLへDS追加
このperlスクリプトが便利です。
http://osdir.com/ml/db.rrdtool.user/2003-08/msg00116.html
perl rrdaddds.pl xml/new.xml DS名 > xml/new2.xml
3.DSタイプの修正
前述のスクリプトは強制的にDSタイプをGAUGEに設定します。
それ以外のDSタイプにする場合は、viなどエディタで修正します。
4.RRDファイルにリストア
$ rrdtool restore xml/new2.xml MONSSS_perfstat-xxxxxx.rrd

[MySQL]InnoDBのステータスを確認する

InnoDBのステータスを確認します。
この例では、InnoDB Pluginを使っているので、I/Oスレッド(read/write)をそれぞれ4に増やしてます。
$ grep _io_threads /etc/my.cnf
innodb_read_io_threads=4
innodb_write_io_threads=4

$ mysql -u root -p
mysql> SHOW ENGINE INNODB STATUS;
| Type   | Name | Status| InnoDB |      | 
=====================================
110215 22:32:10 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 8 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 20844 1_second, 20844 sleeps, 1732 10_second, 3540 background, 3540 flush
srv_master_thread log flush and writes: 20914
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 832, signal count 830
Mutex spin waits 234, rounds 6018, OS waits 63
RW-shared spins 763, OS waits 763; RW-excl spins 0, OS waits 6
Spin rounds per wait: 25.72 mutex, 30.00 RW-shared, 180.00 RW-excl
------------
TRANSACTIONS
------------
Trx id counter 417D3
Purge done for trx's n:o < 417C3 undo n:o < 0
History list length 7
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started, process no 3139, OS thread id 1242859840
MySQL thread id 5425, query id 65466 localhost root
SHOW ENGINE INNODB STATUS
---TRANSACTION 417D2, not started, process no 3139, OS thread id 1103010112
MySQL thread id 5422, query id 65451 Has read all relay log; waiting for the slave I/O thread to update it
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (read thread)
I/O thread 4 state: waiting for i/o request (read thread)
I/O thread 5 state: waiting for i/o request (read thread)
I/O thread 6 state: waiting for i/o request (write thread)
I/O thread 7 state: waiting for i/o request (write thread)
I/O thread 8 state: waiting for i/o request (write thread)
I/O thread 9 state: waiting for i/o request (write thread)
Pending normal aio reads: 0, aio writes: 0,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
523 OS file reads, 9909 OS file writes, 8774 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2,
0 inserts, 0 merged recs, 0 merges
Hash table size 6375023, node heap has 4 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
---
LOG
---
Log sequence number 177701418
Log flushed up to   177701418
Last checkpoint at  177701418
0 pending log writes, 0 pending chkp writes
5225 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 3293577216; in additional pool allocated 0
Dictionary memory allocated 607926
Buffer pool size   196607
Free buffers       194357
Database pages     2246
Old database pages 832
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 486, created 4563, written 7861
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s
LRU len: 2246, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread process no. 3139, id 1211124032, state: waiting for server activity
Number of rows inserted 514325, updated 8978, deleted 109, read 9934992
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

2011年2月10日木曜日

[MySQL]Maatkitによりレプリケーションの整合性をチェックする

何かしらの事情でマスタとスレーブに差異が出ることがあります。
マスタ、スレーブともにテーブルロックして比較するのが正攻法ですが、サービスに必ず影響が出ます。
そこで、Maatkitでチェックします。

1.しくみ
テーブルのチェックサム情報をマスタにinsertします。
ステートメントベースでスレーブに転送されるので、スレーブ側に差異があればマスタと異なるチェックサムが記録されます。

2.チェックサム記録用テーブルの作成
SQL> use mysql;
SQL> CREATE TABLE checksum (
     db         char(64)     NOT NULL,
     tbl        char(64)     NOT NULL,
     chunk      int          NOT NULL,
     boundaries char(100)    NOT NULL,
     this_crc   char(40)     NOT NULL,
     this_cnt   int          NOT NULL,
     master_crc char(40)         NULL,
     master_cnt int              NULL,
     ts         timestamp    NOT NULL,
     PRIMARY KEY (db, tbl, chunk)
  );

3.スレーブ→マスタ権限追加

4.チェックサムの記録
スレーブから実行します。
$ mk-table-checksum --replicate=mysql.checksum <マスタ名> -uroot -pxxxxxxxxxxxx -S/usr/local/db_data/mysql/mysql.sock 

DATABASE TABLE                     CHUNK HOST    ENGINE      COUNT         CHECKSUM TIME WAIT STAT  LAG
mysql    columns_priv                  0 sssdb12 MyISAM          0             NULL    0 NULL NULL NULL
mysql    db                            0 sssdb12 MyISAM         24         7bed06ed    0 NULL NULL NULL
                                        (略)
DATABASE  TABLE                 CHUNK HOST    ENGINE      COUNT         CHECKSUM TIME WAIT STAT  LAG
quest001i tbl_quest_item_hist1      0 sssdb12 InnoDB        298         61b07870    0 NULL NULL NULL
quest001i tbl_quest_user1           0 sssdb12 InnoDB     250027         333f3110    1 NULL NULL NULL
quest001i tbl_quest_user_area1      0 sssdb12 InnoDB          5         29fa5071    0 NULL NULL NULL

5.マスタとスレーブの比較
スレーブから実行します。
$ mk-table-checksum --replicate-check=1 --replicate=mysql.checksum <マスタ名> -uroot -pxxxxxxxxxxxx -S/usr/local/db_data/mysql/mysql.sock 

Differences on P=3306,h=sssdb13.smc.indexweb.co.jp
DB        TBL                   CHUNK CNT_DIFF CRC_DIFF BOUNDARIES
quest001i tbl_quest_item_hist1      0        0        1 1=1
quest001i tbl_quest_user1           0       -2        1 1=1
quest001i tbl_quest_user_area1      0        0        1 1=1

[MySQL]readonlyスレーブなのにduplicateエラーが出る

readonlyスレーブなのにDuplicateエラーが発生する時の暫定的な対処。
本来は根本原因を探るべき。
例えば次のようなエラーが発生し、SQLスレッドが停止したとします。
110209 21:08:45 [ERROR] Slave SQL: Error 'Duplicate entry '49-2147483647-49' for key 'PRIMARY'' on query. Default database: 'quest001i'. Query: 'INSERT INTO
        tbl_quest_user_stage1 
        (quest_id, user_id, stage_id, finish_flg, last_access_dt, finish_dt, delete_flg, regist_dt, update_dt)
VALUES
        (0x31, 0x3139323831393731, 0x31, 0x30, str_to_date(NULL,'%Y/%m/%d %T'), str_to_date(NULL,'%Y/%m/%d %T'), 0x30, str_to_date(0x323031312F30322F30392032313A30383A3233,'%Y/%m/%d %T'), str_to_date(0x323031312F30322F30392032313A30383A3233,'%Y/%m/%d %T'))', Error_code: 1062
110209 21:08:45 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000021' position 935073

手動でエラーをスキップしてSQLスレッドを再開するのは次の通り。
SQL> set global SQL_SLAVE_SKIP_COUNTER=1;
SQL> start slave sql thread;

スキップすべきエラーが大量にある場合はMaatkitが便利です。
mk-slave-restartをバックグラウンド実行すると、特定のエラーをスキップしスレーブを再開します。
mk-slave-restart -uroot -pxxxxxxxxxxxx -S/usr/local/db_data/mysql/mysql.sock --error-numbers=1062 --verbose > skipslave.err 2>&1 &


追記 2011/02/10
こんなことしなくても、my.cnfに書けばいいようです。
当然、MySQL再起動は必要ですが。
slave-skip-errors=1062
すべてスキップしたければ
slave-skip-errors=all

2011年2月9日水曜日

[MySQL]マスタをほぼ止めずにスレーブにまるごとコピーする

0.前提
単純なマスタ-スレーブ構成の場合。
マスタはreadonlyになります。

1.マスタをreadonlyにし、最新バイナリログのpositionを確認する
$ mysql -u root -p
master> flush tables with read lock;
master> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000016 |  72777285 |
| mysql-bin.000017 |    220724 |
| mysql-bin.000018 |    792503 |
| mysql-bin.000019 |       149 |
| mysql-bin.000020 |   4768160 |
| mysql-bin.000021 |       106 |★
+------------------+-----------+

2.マスタからdumpし、スレーブにコピーする
$ mysqldump -uroot -pxxxxxxxxxxxx -hsssdb12 --master-data=2 --flush-logs --single-transaction --a
ll-databases --default-character-set=sjis > dump-m_sssdb12_20110209.sql
$ scp dump-m_sssdb12_20110209.sql sssdb13:/tmp

3.マスタをロックを解放する
master> unlock tables;

4.マスタのデータをスレーブにコピーする
$ mysql -uroot -pxxxxxxxxxxxx < dump-m_sssdb12_20110209.sql
5.スレーブ設定を再設定する MASTER_LOG_FILEおよびMASTER_LOG_POSは確認した最新positionを設定する
slave> reset slave;
slave> CHANGE MASTER TO
  MASTER_HOST='sssdb12',
  MASTER_USER='rep1user',
  MASTER_PASSWORD='rep1xxxxxxx',
  MASTER_LOG_FILE='mysql-bin.000021',
  MASTER_LOG_POS=106;
slave> start slave;
6.スレーブのステータスを確認する
slave> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: sssdb12
                  Master_User: rep1user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000021
          Read_Master_Log_Pos: 66865
               Relay_Log_File: apsssdev01-relay-bin.000430
                Relay_Log_Pos: 67010
        Relay_Master_Log_File: mysql-bin.000021
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 66865
              Relay_Log_Space: 67170
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 

2011年2月6日日曜日

[CloudForecast]監視項目を追加する

担当案件にてCloudForecastというCactiのようなツールを仮運用中です。
http://blog.nomadscafe.jp/2010/05/cloudforecast.html

担当案件のOracle(RAC)は、Sybaseからの移行、開発体制などの事情によりセグメントレベルの負荷情報が必要になります。
負荷も高く、STATSPACKをレベル7実行するとサービス障害になるため、CloudForecastを導入しました。
Cactiの閲覧性能よりも監視項目の追加を重視したため、Cactiプラグインは選びませんでした。

ここでは同じ案件のサブシステムで使っているMySQLサーバの追加手順を紹介します。

0.インストール
省略します。
長野さんのサイト参照。

1.監視サーバの追加
1-1.監視対象サーバに監視アカウントを作成
grant select,process
on *.* to 'monitor'@'devdev.testtest.co.jp'
identified by 'monitor';

※process権限はInnoDBのために必要

1-2.監視アカウントの設定
$ vi /usr/local/src/compiles/cloudforecast/cloudforecast.yaml
config:以降に追記

# MySQLを監視する場合のuser名とパスワード
 MySQL:
   user: monitor
   password: "monitor"

1-3.サーバリストへの追加
$ vi/usr/local/src/compiles/cloudforecast/server_list.yaml
servers:以降に追記
   label: MySQL Servers
   hosts:
     - 172.99.99.156 snwdbmra1 mysql master
     - 172.99.99.157 snwdbmra2 mysql slave

2.CloudForecast再起動
再起動するrcスクリプトを作っておくと楽です。
ps auxw | grep cloudを実行し、cloudforecast_radarおよびcloudforecast_webをkill

# ./cloudforecast_radar -c cloudforecast.yaml -i server_list.yaml > radar.log 2>&1 &O
# ./cloudforecast_web -p 80 -c cloudforecast.yaml -l server_list.yaml > web.log 2>&1 &

3.例