makoto_fujimotoのblog

株式会社進角
代表 藤本信のブログです
どうぞよろしくお願いします

カテゴリ: 技術メモ

VPSとは、GMOグループやさくらインターネット社が提供している仮想専用サーバの事で、クラウドと称されることもあります。値段が安くて契約が簡単なので、ちょっとしたスタートアップサイトや開発サーバ用として、さくっと構築するのに便利です。また昨今は構築手順やノウハウもインターネット上や書籍にたくさん出回っているので、サーバやネットワーク技術者以外の方が果敢に構築・運用にチャレンジされる事も多いようです。ただしVPSとはいえ、OSやミドルウェアの仕様は通常のRedhat LinuxやCentOSと全く一緒ですから、セキュリティ対策は万全に行っておきたいものです。
そこで以下にVPSを借りたら真っ先にやったほうがよいセキュリティ対策を挙げてみました。

【固定IPアドレスの確認】
これはVPSを借りる以前の問題ですが、インターネット関連を生業としている会社や個人の方でも、固定IPアドレスを持たないプロバイダ契約をしていることがたまにあります。これは私の感覚ではネット上の住所不定という状態であり、アクセス制限や許可も曖昧にしか出来ないので、機密度の高い仕事を任せてもらえない可能性もあります。したがって固定IPアドレス程度の微々たる投資は惜しみなく行うべきだと思います。

【sshのrootログインを禁止する】
Linux系OSはデフォルトでリモートからのrootログインが許可されている場合が多いので、これを真っ先に禁止しましょう。
$ su
# cd /etc/ssh
# vi sshd_config

  PermitRootLogin yes ------> no

# /etc/init.d/sshd restart

【sshとftpのアクセス制限を行う】
主にサーバ管理に使用するSSHやコンテンツを更新する際に良く用いられるFTPは、ハッカーから攻撃される事が多いので、安全なパスワードや鍵を運用する以前に固定IPアドレス制限をかけておくべきです。アクセス制限方法はいくつか手法があるのですが、TCP Wrapperを用いた以下の設定が簡単です。
# cd /etc
# vi hosts.allow
  
  vsftpd: 123.45.67.89  (追記)
  sshd: 123.45.67.89 (追記)

#vi hosts.deny

  vsftpd: ALL  (追記)
  sshd: ALL  (追記)

ちなみにこれらの設定をミスるとサーバにアクセスできなくなる可能性が有ります。必ずallow側(許可)から設定を行うことと、SSHを制限する前にFTPで不通・通過の確認を行ってください。

【不要なサービスを停止する】
これはサーバ運用の一般的なセオリーですが、メールサーバ(sendmail/qmail/postfix)、メールクライアント(dovecot/qpoper/pop3d)、DNS(named)、Web(httpd)、FTP(vsftpd/proftpd)、データベース(mysql/postgresql)等を明確に使用する要件が無い場合は不用意にサービスを立ち上げておかない方が安全です。

# /etc/init.d/sendmail stop
# cd /etc/rc3.d
# mv S80sendmail K80sendmail

【iptablesによるファイアウォール構築】
Linuxにはiptabesという簡易ファイアウォール機能が備わっていますが、設定が少し専門的ですので素人が触るのはおススメしません(設定を誤るとサーバにアクセスできなくなる場合があります)。こちらの設定方法については別の機会で触れたいと思います。

フレッツ光をベースとしたインターネット回線をiDCなどで使用する場合、企業向けで高品質な"ビジネス"では実質100Mbpsが上限だったのですが、ここ数年の間にギガ帯域が使用できる"光ネクストビジネス"をベースとしたサービスが出てきたようなので調査してみました。

OCN光アクセス
http://www.ocn.ne.jp/business/ftth/flets/charge.html

bit-driveファイバーリンク
http://www.bit-drive.ne.jp/internet/flets/ftth/pricelist.html

InfoSphere
http://www.sphere.ne.jp/services/internet/flets/hikari/price.html


フレッツの競合にあたるUSEN参考
http://www.gate02.ne.jp/networkservice/ba

IP16までなら抜群に安い

  1. 設計パラメータ
    ・最大発行数
    ・桁数→多くとることでいたずらによるマッチ確率が減る
    ・認証方式
      DB照合※
      チェックデジット

  2. 設計例
    発行数1万、桁数10ケタ、チェックデジットあり
    チェックデジット方式*****
    [ランダム通し番号部5桁]+[ランダム数字4桁]+[チェックデジット1桁]
    00000 RRRR C
    99999 RRRR C
    実際の並びは機密事項

※発行したシリアルNoをあらかじめDBに保持して照合する方式。

grepコマンドは検索対象にパーティションデバイスを指定できるので、消してしまったファイルに含まれるキーワードをヒントとして部分的なデータのサルベージに利用できることがあります。

<コマンド例>
grep -a -B1 -A100000 "CREATE DATABASE faceback" /dev/sda13 > o &

この例は誤って消してしまったデータベースのダンプデータからデータを復元するコマンドになります(ただしテキストファイルに限ります)。

つまり単純にファイルを削除しただけでは、この様に簡単なコマンドでデータを復元できる可能性が残っているのです。

だから、逆に個人情報などを記録していたHDDを完全に削除するには再物理フォーマットくらいしないと心配です。ちなみに僕の運用チームではサーバ廃棄を行う際には必ずルーチーンとして実施させていました。

DM配信プログラム設計の考察メモ

  1. ロックファイルを使用して二重起動をチェック
    →ロックされていれば終了
    →ロックされていなければロックする

  2. タスクテーブルのステータスに"配信中"があるか?
    →あれば終了

  3. タスクテーブルのステータスが予約済かつ予約時間が範囲内のタスクがあるか?
    →無ければ終了
    →複数あった場合は最も古い一件のタスクを配信対象とする

  4. タスクテーブルの配信情報(From、件名、本文等)チェック
    →問題があれば終了
     管理者に異常通知メールを送信
     ステータスを異常終了に更新

  5. 配信リストのフォーマットチェック
    →問題があれば終了
     管理者に異常通知メールを送信
     ステータスを異常終了に更新

  6. タスクテーブルのステータスを配信中に更新

  7. 管理者に配信開始メールを送信

  8. 配信リストを読む
    メール文を組み立てる
    配信ログを記録する(No,日時,メアド)
    メールを送信する
    繰り返し

  9. 管理者に配信終了メールを送信

  10. タスクテーブルのステータスを配信済に更新

  11. ロックを解除

「○○を見ている人は○○も見ています」のようなレコメンドシステムの要件があった場合のデータ処理プロセスを考えてみました。

  1. ロギング
    商品の閲覧ログを記録するテーブルを作成しユニークユーザを識別するcookie値を記録する。

    商品ID   | 日時                           | Cookie
    --------+-----------------------+--------------
    000001 | 2012-12-15 12:00:05 | AA0000012326
    000002 | 2012-12-15 12:10:05 | AB7890987001
    000001 | 2012-12-15 12:11:05 | AB7890987001
    000003 | 2012-12-15 12:12:05 | AA0000012326
    000001 | 2012-12-15 14:12:05 | AA0000012326
    000004 | 2012-12-15 15:45:09 | AB7890987001

  2. バッチ処理1
    閲覧ログから商品ID毎にユーザ(Cookie)リストを抽出し更にそのユーザが見た他の全商品IDを抽出して別テーブルに書き出し。

    商品ID1 | Cookie               |商品ID2| 日時
    --------+-----------------+--------+---------------------
    000001 | AA0000012326 | 000003 | 2012-12-15 12:12:05
    000001 | AB7890987001 | 000002 | 2012-12-15 12:10:05
    000001 | AB7890987001 | 000004 | 2012-12-15 15:45:09
    000002 | AB7890987001 | 000001 | 2012-12-15 12:11:05
    000002 | AB7890987001 | 000004 | 2012-12-15 12:45:09
    000003 | AA0000012326 | 000001 | 2012-12-15 12:00:05
    000003 | AA0000012326 | 000001 | 2012-12-15 14:12:05
    000004 | AB7890987001 | 000002 | 2012-12-15 12:10:05
    000004 | AB7890987001 | 000001 | 2012-12-15 12:10:05

  3. バッチ処理2
    2.で生成したテーブルから同一ユーザが同一商品を見たレコードの重複を排除し閲覧数統計を行って別テーブルに書き出す(最大レコード数は"総商品数の二乗-総商品数"になる)。

    商品ID1 |商品ID2| 閲覧数
    --------+-------+--------
    000001 | 000002 |   999
    000001 | 000003 |   999
    000001 | 000004 |   999
     ・
     ・
     ・
    000002 | 000001 |   999
    000002 | 000003 |   999
    000002 | 000004 |   999
     ・
     ・
     ・

  4. レコメンド情報の表示
    3.で生成したテーブルから現在見ている商品に関連する閲覧数の多い商品を抽出してページに出力する。

わりと大変な処理の様です。。。
あとこの設計だとリアルタイムには分析できないという欠点があります


メール配信システムを設計する際のメモ

[基本原則]

  • 配信プログラムのチェック機能は配信情報入力系とは分けて考える(配信データを信用しない)。
  • 少しでも問題があったら安全側に振れるようなロジックにする。
  • 考えられる最悪の事故とは本文やヘッダから他人のメアドが流出すること。

[課題]

  • 配信ログを残す(異常終了時の状況確認等)。
  • エンベロープFromを設定する。
  • httpdの子プロセスとして起動しない(Apacheが終了すると配信が止まる)。
  • 重複配信を避けるために件名および本文が過去と同一のメールは送らない。
  • 配信リストにメアドの重複があれば除外する(sort|uniq)。
  • できれば全メアドの形式を再チェックして異常があればアベンドさせる。
  • PHPを使用する場合、スクリプト実行時間の制限設定を確認(php.ini)。
  • タスクのステータスは配信開始と配信終了時の2回更新する。
  • 配信プログラムが二重起動することが無いよう一件一件タスク処理する。
  • 配信リストはWebからGETできるところに保存しない。
  • 配信開始と終了時に管理者にメールを送る。

[例外処理の対応]

 以下の事故例を想定した例外処理を織り込む

  • テストメール送信事故
  • 管理系操作ミス事故
  • 空白メール事故
  • 本文へのアドレスリスト記載事故
  • ウィルス添付事故
  • BCCとCCを間違えてリストを流出してしまう事故
  • 改行文字事故
  • エスケープ文字事故
  • 文字コード事故
  • 重複送信事故
  • URLリンク切れ事故

Webサイトを運用してると図らずもPVの多いサイトから、アクセスが大量に流入してしまって運用に支障が生じることがありますよね?

そんな場合はApacheの.htaccessファイルに以下のような記述をすれば特定のリンク元からのアクセスをブロックすることができます。

<files ~ "\.(php|html)>
SetEnvIf Referer "^http://リンク元URL" ref_block
order allow,deny
allow from all
deny from env=ref_block
</files>

こちらのサイトに国別に発行されているIPアドレス(ipv4)が公開されています。
http://ftp.apnic.net/pub/stats/apnic/delegated-apnic-extended-latest
http://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest
http://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest
http://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-extended-latest
http://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-extended-latest
(それぞれ大量のリストが表示されます)

例えば日本国に発行されているIPアドレスを知りたい場合、2ケタの国識別IDの"JP"で検索すると以下のような行が見つかります。
"apnic|JP|ipv4|121.58.176.0|2048|"

ここの4列目の121.58.176.0がネットワークアドレスで5列目の2048がネットマスク値に相当します。ちなみにこの定義では121.58.176.0~121.58.183.255の範囲となります。

このサイトに公開されている、各国割り当てブロックをすべてデータベース化し、Webサービス等にアクセスしてきたリモートIPと比較することで IPアドレスによる制限が可能です(いちおう公的サイトの様なので定期的にデータを取得してパース&DB化を行っても問題は無いと思います)


Linux系OSではiptablesというファイアウォールが利用できる場合がありますのでIPブロックの一例を示します。拒否設定例(58.221.55.0~58.221.55.255)

# /sbin/iptables -I INPUT -s 58.221.55.0/24 -j DROP
 (設定を間違えるとサーバにアクセスできなくなる可能性があります)

設定確認方法
# /sbin/iptables -L

ちなみにブラウザの使用言語属性によって国を判別する方法もありますが、ユーザが任意に変更できるのでかなり緩い方式となります。

個人情報の漏えい事件やアカウントの乗っ取りなどの被害が後をたちません。

何らかの不正手段によってWebサイトがハッキングされて個人情報が漏えいした場合、パスワードデータが平文(非暗号)で保存される仕様になっていると、他のサービスで不正利用されるなど二次被害も予想されます。ユーザIDをメールアドレスとしているサイトが多数ありますので、使いまわしているパスワードとの組合せがあれば他のサイトでもそのまま使用できてしまいます。

日々さまざまなハッキング手法が生み出されるWebの世界では、常に完璧にセキュリティ対策を執り続けるのは不可能に近いので、「最悪盗まれても致命的なダメージとならない」という安全策も必要だと思います。

以下に既存サイトのパスワード保存形式を暗号化する改修ステップを整理してみました。

  1. 暗号化したパスワードが保管できるようにテーブルのフィールド長を拡張する
    MD5を使用する場合は最低32桁必要※
  2. ログインプログラムを改修
    パスワードを照合する際に入力値を一旦MD5ハッシュ値に変換して比較する
  3. 会員登録プログラムを改修
    入力したパスワードをMD5ハッシュ値に変換して保存する
  4. 会員情報変更プログラムを改修
    パスワードの変更があった場合に入力したパスワードをMD5ハッシュ値に変換して保存する
  5. バッチプログラムで平文パスワードを元にMD5ハッシュ変換した値に一括更新
  6. パスワードリマインダなどの機能は再発行のプロセスを仕様変更する必要あり

サービスレベルではパスワードの通知機能が使えなくなるなどのデメリットがありますが、セキュリティとのトレードオフで諦めるしかありません。

※ただしMD5やSHA1では、脆弱性が指摘されているので注意してほしい。現時点で最も手軽に使えて安全性の高いハッシュ・アルゴリズムはSHA256である。

(2014.8.19追記)
これらの暗号化方式では外部で不正流出した大量の情報によって暗号化データが解読されて出回っていることも考えられ安全とは言えないので、さらに独自の秘密キー設定も必要ですね。

↑このページのトップヘ