カテゴリー別アーカイブ: LAMP[Linux, Apache, MySQL, PHP]

SSL設定

物販サイトとか、最近の商用サイトではSSL(HTTPS)の設置はほぼ常識だろう。
未だに、一般ユーザにはHTTPSの効果がわからない人もいるようだけど、少しでも知識があれば秘密情報を送るのにHTTPSが必須なのがわかるだろう。
単純に言えば、HTTPSは電子証明書を使って、接続先のサーバ名が証明書発行先の名前と一致することを保証し、かつ、ブラウザからサーバまでの通信が暗号化される。
電子証明書は、最初から端末にいくらかの物が保存されている。 これらの証明書の発行元を信頼された証明書発行機関として、その機関が発行した証明書を信頼できると判断する。
新たに接続したサイトの証明書が、信頼された証明書発行機関から発行された証明書であれば、接続したサイトも信頼できる(電子証明書にはサーバのアドレスが記述されている)
従って、携帯電話等では端末によって初期の証明書が異なり、あまり有名ではない発行機関が発行した証明書が信頼できない証明書と判断されることがある。
また、外部の証明書発行機関に依存せず、最初から自分で証明書を発行することも出来る(いわゆるオレオレ証明書) この場合、サイトの確認に利用するためには、信頼された方法で証明書を端末に登録しておく必要がある(例えば、USBメモリなどに保存してPCに登録する等だが、一度目に接続したサイトを信頼するなら、初回接続時に証明書を登録しても良い)
しかしながら、特定のクライアントに向けたサイト(契約業者向けサイトであるとか)でもない限り、信頼された機関から発行されていない証明書の使用は、逆に信頼度を下げる結果になるだろう(最近のIEやFirefox等のブラウザは、証明書が信頼できませんとでかでかと表示してクライアントに警告する)
それでもオレオレ証明書を使用するのは、通信経路の暗号化が可能であると言うポイントにある。 個人情報をHTTPで送信すれば、ネットワーク上にパケット盗聴器を配置したり、無線LANの電波を盗聴する等することで簡単に情報を盗まれてしまう。 しかし、HTTPSでは、ブラウザの内部からサイト内までの区間は暗号化されているので、無線LAN電波を盗聴されても、情報を入手することは困難である。
そんなわけで、個人サイト等で出先からのアクセスを保護する目的などでオレオレ証明書が使われることがある。
まぁ、有料の信頼された証明書を取得するのがベストであるのは確かだが。

実際にSSLを使用する設定。
基本的に、ServersManに入っているApacheは最初からSSLが使えるので、証明書の準備と設定ファイルを記述するだけで良い。

証明書の準備
A,オレオレ証明書を使う
B,信頼された証明書を使う
どちらのパターンでも、秘密鍵ファイルの作成は共通で

openssl genrsa -des3 2048 -out /etc/pki/tls/private/hoge.pem

DES3(従来のDES暗号を3回かける方式)で2048ビット長の鍵を作る設定 ※古いサイトでは1024ビットを示しているところもあるが、現在は1024ビットでは強度不足とされている。
このとき、秘密鍵を保護するパスフレーズの入力を促されるので、適当なものを設定する。

Aパターンの場合、この秘密鍵を元にサイト証明書(CRT)を作成する。

openssl req -new -x509 -days 365 -key /etc/pki/tls/private/hoge.pem -out /etc/pki/tls/certs/hoge.crt

この場合は、365日間有効なX509証明書を先ほどの秘密鍵を使って作成する。 有効期間は長くても良いが、パスワードのように定期的に更新するのが一般的。
(後記共通項へ)

Bパターンの場合、この秘密鍵を使って証明書要求(CSR)を作成する。

openssl req -new -key /etc/pki/tls/private/hoge.pem -out hoge.csr

先ほどの秘密鍵を使って証明書要求を作成する。 A/Bともコマンドは似ているが、Aは証明書自体を作り、Bは証明書を要求するための中間情報を作成している。

<共通項>
先ほどのパスフレーズや、サイト情報などの入力を促されるので入力していく。 項目名はビルドにより多少異なるので環境毎に読み替え

Enter pass phrase for /etc/pki/tls/private/hoge.pem:先ほどのパスフレーズ
Country Name (2 letter code)[GB]:JP
#2文字の国コードで、日本ならJP
State or Province Name (full name) [Berkshire]:Kanagawa
#都道府県
Locality Name (eg, city) [Newbury]:Yokohama
#市区町村
Organization Name (eg, company) [My Company Ltd]:hogehoge Corp
#団体名(個人の場合はフルネーム等)
Organizational Unit Name (eg, section) []:online sales div
#部署名だが、団体名までが同じ複数の証明書を取得する場合に、この項目を変更して取得する。
Common Name (eg, your name or your server’s hostname) []:ssl.hoge.net
#サイトの完全名を入力する。 サイト確認する為に使われるアドレスになる(異なるアドレスのサイトで証明書を使うと警告が出るので、運用アドレスにしっかりあわせる)
これ以降のEmail Address等の項目は任意でOK

これで証明書ファイルか、証明書要求ファイルが出来る。
Aならこれで証明書準備完了。 Bの場合は、作成されたhoge.csrの中身をSSL証明書発行機関の発行要求Webフォームやメールに添付したりして証明書を要求すると、証明書ファイルが送られてくるので、Aの/etc/pki/tls/certs/hoge.crt等のように配置する。
証明書と間違えて証明書要求ファイルを配置するとApacheがエラーで起動できなくなるし、証明機関に証明書を送っても証明書が作成できないので注意。

Apacheの設定を行う。
ApacheのSSL設定ファイルは↓がデフォルト
/etc/httpd/conf.d/ssl.conf

#HTTPSを受け入れるためにバーチャルホスト設定を使う。
<VirtualHost 210.170.xxx.yyy:443>
#ServerNameディレクティブで完全なホスト名を設定して、証明書のCommon Nameと一致させる。
ServerName ssl.hoge.net
#サイト証明書ファイルを設定する
SSLCertificateFile /etc/pki/tls/certs/hoge.crt
#秘密鍵ファイルを設定する
SSLCertificateKeyFile /etc/pki/tls/private/hoge.pem

この状態でApacheを起動しようとすると、秘密鍵のパスフレーズを要求されるようになるので、自動起動したい場合には
ssl.conf

SSLPassPhraseDialog exec:/root/sslkey.sh

コマンドの標準出力をパスフレーズとして利用しようとするので、echo ‘passphrase’等とシェルに記述して実行権限をつけておけば自動起動できるようになる。

(436)

カテゴリー: サーバ設定 | コメントをどうぞ

PHPとMySQLと文字コードと

 最近の流れとして、文字コードと言えばUTF8って感じが強い(携帯などではSJISもあるけど)
 しかしながら、CentOSや海外から拾ったコンパイル済みPHPの従来型MySQL関数って、コネクト時のクライアントエンコーディングがlatin1になっている。
 この値は、mbstringとか色々変えても変わらず、自前でビルドしないとダメっぽい。
 他方、MySQLサーバではmy.cnfに

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

等と入れてやるとUTF8で回るし、個別にデータベースやテーブルを作るときに指定してやることも出来る(現在のMySQLではdefault-character-setは推奨外) コマンドラインのmysqlもmy.cnfに

[mysql]
default-character-set=utf8

とかすれば、UTF8で繋がる。
 それでも、PHPクライアントでmysql_connectして、mysql_client_encodingで引っ張るとlatin1になるし、SHOW VARIABLESクエリの戻り値もクライアントやリザルトはlatin1になってしまう。
 このため、最近のMySQLとPHP(5.2.3以降)の組み合わせではmysql_set_charsetと言う関数を使ってクライアントのエンコーディングを設定してやることが出来る(古いバージョンでは、SET NAMESクエリを発行して変更できるが、サニタイズ関連の動作が期待と異なる事になったり、タイムアウトしたDB接続を自動再接続したときにエンコーディングが元に戻る様だ)
 しかし、実際の所は、このあたりの設定をせずともPHPから処理する限りは、UTF8の文字列を普通にDBに格納して取得も出来てしまう。 これは、エンコーディング設定が同じなら同じ方法で文字列を化けさせているから、化けた文字列を格納しても、取り出し時に逆処理で戻してしまい、外見上は問題なく動作してしまっているのだ。
これをデータベースマネージャなどでテーブル表示すると化け化けの文字列であるから、管理コマンドや、別のアプリケーションからDBを参照したときに問題が起きるし、検索処理や関数などで予想外の動作をする可能性もあるので、エンコーディング設定はしっかり行っておかなければならない。

 my.cnfの[mysqld]でskip-character-set-client-handshakeを設定してやると、サーバの標準キャラクタセットをクライアント値と同期しないので、mbstring.internal_encodingをutf8にしたPHPとutf8設定のMySQLの組み合わせでutf8で格納されて、データベースマネージャなどでもちゃんと表示できるので、この方法を示しているページもあるが、この状態でもmysql_client_encodingはlatin1で、SHOW VARIABLES結果はutf8設定というおかしな状態になるので、これも予想外の動作をする可能性があるわけで、正しく動作させたければ、毎回mysql_set_charsetを実行するか、ソースからPHPをビルドして、標準エンコーディングをutf8にするなどした方が良いと思う。
 また、skip-character-set-client-handshake設定してしまうと、[mysql]のdefault-character-setと整合を取らなくなるので注意が必要(例えば、mysqlをdefault-character-set=ujisで動かしてると、mysqlコマンドで接続した段階ではクライアントがujisで、サーバはutf8クライアントと認識しているのでキャラクタセットの齟齬で文字化けが生じる)

(471)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], PHP | コメントをどうぞ

PHP設定2

  • PHPのセッション時間設定とか
    php.iniの設定ディレクティブ

    session.cookie_lifetime=秒数

    で、デフォルトのセッションクッキークライアント生存時間を設定している。
    初期値は0で、ブラウザが終了するまで有効。
    しかし、この設定でも長時間放置しておくとセッションが切れることがあるが、これは、サーバ側でセッションファイルが処分されるのが原因で、こちらは

    session.gc_maxlifetime=秒数

    と言うディレクティブで設定されていて、デフォルトが24分なので、これを1日とかに延ばしてしまえばOK。
    上の設定をしてもphpMyAdminが切れるのは、phpMyAdminのconfig.inc.phpの設定

    $cfg[‘LoginCookieValidity’] = ‘秒数‘;

    この値を設定する必要がある。

(178)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], PHP | コメントをどうぞ

応用コマンド1・PHP設定1

  • 現在のディレクトリ以下で探索語を含むファイルを探す。

find . -type f -print | xargs grep 探索語 /dev/null

  • PHP:DocumentRootより上のファイルのfopenに失敗する。

ウェブアプリがDocumentRootより上にあるファイルを読む場合に、php.iniの設定ディレクティブopen_base_dirに追記しておかないと、fopenがI/O errorになる。 .htaccessでphp_admin_valueで設定しても良い。

open_base_dir = 参照したいディレクトリ
(:区切りで列挙)

(45)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], PHP | コメントをどうぞ

基本コマンド

cat ファイル名 ファイルの中身を表示する
tail ファイル名 ファイルの末尾を表示する
rm ファイル名 ファイルを削除する
touch ファイル名 ファイルを作成する
mkdir ディレクトリ名 ディレクトリを作成する
rmdir ディレクトリ名 ディレクトリを削除する
chown ユーザ名:グループ名 ファイル・ディレクトリ名 ファイル・ディレクトリの所有者を変更する
chmod パーミッション ファイル・ディレクトリ名 ファイル・ディレクトリのアクセス許可を変更する

・所有者について
アクセス許可(パーミッション)と連携することになる情報で、アクセス許可は所有者・同グループ・その他のユーザの3種類に分けて設定するので、この許可設定に関連して設定することになる。
例えば、一般ユーザグループusersに所属するユーザに読み取りを許可し、所有者ayuには書き換えと読み取りを許可したいファイルは、chown ayu:users ~とする。

・アクセス許可(パーミッション)について
アクセス許可は3桁の数字(内部的にビット表現)で表現されて、上位の桁から順に所有者・グループ所属者・その他の許可を示し、各桁は読み込み許可が4、書き込み許可が2、実行許可が1の数字で、読み込みと実行を許可するなら4+1の5、読み込みと書き込みを許可するなら4+2の6と言った具合に設定する(全てのユーザに全ての許可をする場合はchmod 777 ~となる)
4,2,1と言うのは、2進数の表現で0b100、0b010、0b001に該当するので、全て許可されていれば0b111であり、OS内部では特定のアクセス許可があるか調べるときには パーミッションと許可ビットパターンとのビットAND命令を実行することで判別できる。 また、既存のパーミッションに追加許可するなら許可ビットパターンとのビットORを求めれば良いし、逆に禁止するなら許可ビットパターンのビットNOTとビットANDすれば良いので処理が高速。

(156)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

cron

cronは簡単な設定ファイルを書くだけで、コマンドを定時実行をしてくれるスケジュール機能。
UNIX系OSで定期的に何かさせたい時には必ず出てくる。

メイン設定ファイルの/etc/crontabや、1日1回実行する/etc/cron.dailyディレクトリ、1時間に1回実行する/etc/cron.hourlyディレクトリ等色々設定できる場所がある。 今回は、/var/spool/cronディレクトリ以下にファイル名=ユーザ名として記述すると、そのユーザの権限で実行してくれるパターンを使う。

設定ファイル:/var/spool/cron/root

00 04 * * * /root/remotebackup.sh >> /var/log/backup.log

cron設定ファイルの書式は
分 時 日 月 曜日 コマンド
先の設定ファイルだと、毎日4時ちょうどに/root/remotebackup.shをキックすると言うことになる(>>は該当コマンドの標準出力を右のファイルに追記すると言う表現で、>だと上書きになる。 コマンドラインから cat > crontabなんて打ち込むと、入力モードになるんで適当に打ち込んでctrl+dで閉じると、入力した内容がcrontabファイルに書き込まれるんで、何かの拍子にエディタが消失してしまったり、ごくごく短い設定を書きたいときなどに使ったりする)
毎週月曜にだけ走らせたければ00 04 * * 1 ~の様に記述する(曜日は日曜が0で土曜日が6)
カンマ区切りで複数の値も設定できるので、00 09,17 * * ~と書けば9時5時に走るし、/を使って間隔指定もできるので*/15 * * * ~とすると15分ごとに走らせることが出来る。 更に、-を使って範囲指定も出来るので、就業時間中10分ごとにしたいとか言った場合、*/10 9-16 * 1-5 ~なんてしておけば、月曜日から金曜日の9時から5時の間、10分ごとに実行なんていう複雑な動作も出来る。
これを使えば、サーバの多くの機能を自動化したり(前回作ったバックアップや、再起動、ログ管理等々)出来るし、ディレクトリやメールを監視するようなサーバプログラムを簡単に作ることが出来る。

(514)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

GMailを使ってサーバのバックアップを取る

サーバのバックアップ置き場としてGMailを使うと、サーバやローカルPCがクラッシュしたときに便利なので、これをシェルスクリプトにする。

#バックアップシェル
#コンテンツ等のあるhome、設定ファイルのetc、及びMySQLのデータをバックアップする
MAILTO=アドレス@gmail.com
TODAY=date '+%Y%m%d'
/bin/tar czf /tmp/$TODAY.home.tgz /home
/bin/tar czf /tmp/$TODAY.etc.tgz /etc
/usr/bin/mysqldump -h localhost -uroot -pパスワード –skip-lock-table –all-databases|/usr/bin/gzip>/tmp/$TODAY.mysqldump.gz
cat /tmp/$TODAY.etc.tgz|/usr/bin/uuencode $TODAY.etc.tgz.uue|/bin/mail -s $TODAY-backup-etc $MAILTO
/bin/rm -f /tmp/$TODAY.etc.tgz
/usr/bin/split -b15m /tmp/$TODAY.mysqldump.gz /tmp/split/
/bin/rm -f /tmp/$TODAY.mysqldump.gz
/bin/ls -1 /tmp/split/|while read filename; do
cat /tmp/split/$filename|/usr/bin/uuencode mysqldump-$filename.uue|/bin/mail -s $TODAY-backup-mysqldump-$filename $MAILTO
/bin/sleep 30
/bin/rm -f /tmp/split/$filename
done
/usr/bin/split -b15m /tmp/$TODAY.home.tgz /tmp/split/
/bin/rm -f /tmp/$TODAY.home.tgz
/bin/ls -1 /tmp/split/|while read filename; do
cat /tmp/split/$filename|/usr/bin/uuencode home-$filename.uue|/bin/mail -s $TODAY-backup-home-$filename $MAILTO
/bin/sleep 30
/bin/rm -f /tmp/split/$filename
done

MAILTO変数の宛先に/etcと/homeのtar+gzファイル、MySQLダンプのgzファイルを送りつける。
etcは1メールで送れるが、homeとMySQLはサイズが大きくGMailに弾かれるので、15MBに切り分けて送信している。 また、一気に送ろうとするとサーバのリソース消費が大きいので、sendmailがGMailに転送する待機時間として30秒のスリープを挟んでいる。

(148)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ