サーバー構築: kanakofolio(③SSL化・ファイアウォール)

VPSサーバー構築の関連記事:

サーバー構築: Kanakofolio (①概要・ドメイン移行)

サーバー構築: kanakofolio(②ユーザー登録・SSH設定)

サーバー構築: kanakofolio(③SSL化・ファイアウォール)

サーバー構築: kanakofolio(④WordPress・データベース設定)

課題と目的

概要

Apache + Let’s EncryptでSSL化(https)を実施。

その過程でのファイアウォールの設定も含めて、サイト運用の上での必要最低限のセキュリティの設定を一通り行った。

実施内容(概要)

  1. インストール: certbotでLet’s Encryptをインストール。
  2. 権限設定: SSL化に関連するファイル・ディレクトリ(主に/etc/letsencrypt/・/etc/apache2/)の権限を設定。
  3. ファイアウォール設定: ufw statusコマンドで、80番(http)と443番(https)及び、22番(SSHでの操作)のポートが許可されてるかを確認。許可されていないポートがあれば追加。
  4. 証明書確認:
  5. 動作確認: サーバー内外でcurl -Iコマンド及び、外部ブラウザからでのhttps://・http://kanakofolio.netで開けるか確認。一時的にSSL Labsも用いてエラーの原因を探った。
//Let's Encryptインストールのコマンド
sudo apt install certbot python3-certbot-apache 
sudo certbot --apache

技術的試行錯誤

関連ディレクトリ・ファイルの権限設定

SSL化するには、サーバー内部だけではなく外部からのアクセスも可能にするためにLet’s Encrypt関連ディレクトリだけではなく、Apacheのそれらの権限も設定する必要がある。

/etc/letsencrypt/
/etc/apache2/ //これらのディレクトリ及びこの中のディレクトリ・ファイルを全て設定。

関連ディレクトリ・ファイルの権限は以下のコマンドで一括で設定可能。

※念の為設定後に、手動で「ls -l ディレクトリ名」を用いて問題が無いのを確認することをおすすめする。

sudo chown -R root:root /etc/letsencrypt/ /etc/apache2/ //ディレクトリ所有がrootの場合はスキップ可
sudo find /etc/letsencrypt/ /etc/apache2/ -type d -exec chmod 755 {} \;//ディレクトリ内の全てのディレクトリに一括で権限を設定。
sudo find /etc/letsencrypt/ /etc/apache2/ -type f -exec chmod 644 {} \; //ディレクトリ内部のファイルの権限を一括で設定。
sudo chmod 600 /etc/letsencrypt/archive/kanakofolio.net/privkey*.pem //秘密鍵ファイルのみピンポイントで600(所有者のみ読み書き可)指定。
sudo systemctl reload apache2 //リロードし、編集を反映。
  • ディレクトリは755:
    • 所有者(root)rwx(読み取り・編集・実行可)
    • グループ及びその他ユーザーr-xにし、Apacheプロセスからも読み取り可能に。
  • ファイルは644:
    • 所有者(root)rw-(読み取り・編集)
    • グループ及びその他ユーザーr–。Apacheからも証明書の読み込みが可能。
  • グループも所有者もrootに設定することで、セキュリティ的に最低限守られつつ、必要なユーザー(主にApache)がアクセス可能に。
  • 秘密鍵ファイルのみ600:
    • このファイルはSSL通信を復号するために必要で。漏洩するとHTTPS通信を盗聴・改竄のリスクに晒すため、所有者以外のユーザーのアクセスを不可にする必要がある。

補足: 所有者(or グループ)をwww-dataにするリスク

  • 外部からの不正アクセス・改ざんを防ぐために、root以外に書き込み権限を与えない→サーバー運用での安全性が高い
  • Webサーバーやプロセスが書き込み権限を持つ必要がある場合は、専用のディレクトリのみに限定
  • 権限付与の原則:
    • 所有者: root
    • グループ: root(もしくは必要最小限の管理者)
    • その他: 読み取りのみ or アクセス不要

ファイアウォールでのポート許可

sudo ufw status verbose //許可されているポート番号を詳細表示。
sudo ufw allow portnum/tcp //特定のポートを許可。
sudo systemctl reload apache2 //リロードし、編集を反映させる。 

ファイアウォールで許可されているポート番号を上記のコマンドで確認。

最低限SSL化・サイト運用に必要なのは、80番(HTTP)・443番(HTTPS)・22番(SSHでのサーバー操作)で、コマンドで表示されるリストに掲載されていないポート番号がある場合は追加し、リロード。

補足: sudo ufw statusとsudo ufw status verboseの違い

sudo ufw status

  • 簡易的なシンプル表示
  • 許可/拒否されたポートやサービスを一覧で出す。
$ sudo ufw status
Status: active

To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
//「ポート番号/サービス名」「許可/拒否」、「通信元(Anywhere)」だけが表示される。

sudo ufw status verbose

  • 詳細表示
  • statusの内容に加えて以下の情報も表示。
    • デフォルトポリシー(incoming/outcoming/forwardの既定動作)
    • ログレベル
    • IPv6が有効か否か
    • ルール詳細
  • デフォルトポリシーやログなども含めて全体の設定を把握したいときに使用。
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
//statusよりも全体のポリシーやルールの適用範囲がはっきりわかる。

※ファイアウォール全般のルールの詳細を表示するiptablesコマンドも存在するが、出力はかなり冗長。本当に細かいパケットルールを全て確認したい場合にのみ使用。

個人的には、ファイアウォール設定時には「sudo ufw status verbose」コマンドの使用をおすすめしたい。「sudo ufw status」では実際には「INかOUTか」や「IPv6も対象か」などは明示されず、それらの設定が不十分な場合にはこのコマンドのみでは確認出来ない場合があるため。(今回のSSL化の設定でも、これによりブラウザなど外部からのサーバー接続が出来ない原因の特定に時間を取られた)

また、SafariやGoogle Chromeなどの主要なブラウザはIPv4よりもIPv6を優先的に読み込むため、IPv6の設定も行わないとサイト読み込みの遅延に繋がる。IPv6の設定も把握できるverboseのコマンドを用いることで、これらの設定を確実に行うことが出来る。