Linux 上の Nginx で自己署名証明書を使用した HTTPS

CompTIABeginner
オンラインで実践に進む

はじめに

この実験では、自己署名証明書を使用して HTTPS を実装することにより、Linux 上の Nginx Web サーバーを保護する方法を学びます。まず、Nginx Web サーバーをインストールし、正しく実行されていることを確認して、安全な構成の基盤を確立します。初期設定の後、OpenSSL ツールキットを使用して自己署名 SSL 証明書を生成します。これは、暗号化された通信を有効にするための重要なコンポーネントです。

証明書が作成されたら、Nginx の設定を変更して、安全な HTTPS プロトコルで Web コンテンツを提供するように進めます。実験の最終段階は、検証とテストに焦点を当てます。新しい設定をアクティブにし、curlopensslなどのコマンドラインツールを使用して HTTPS 接続をテストし、新しく作成した自己署名証明書の詳細を検査して、サーバーが適切に保護されていることを確認します。

Nginx Web サーバーのインストールと起動

このステップでは、Nginx Web サーバーをインストールします。Nginx は、Web コンテンツの提供に広く使用されている高性能な Web サーバーです。まず Nginx をインストールし、正しく実行されていることを確認します。この実行中の Nginx インスタンスが、後続の HTTPS 構成の基盤となります。

まず、システムが最新バージョンのソフトウェアを取得できるように、システムのパッケージリストを更新することがベストプラクティスです。

ターミナルで以下のコマンドを実行してください。

sudo apt update

システムが設定されたソースからパッケージ情報を取得する様子が表示されます。出力は以下のようになります。

Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
...
Fetched 1,585 kB in 2s (924 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.

次に、Nginx をインストールできます。apt installコマンドを使用します。-yフラグを追加することで、インストールを自動的に確認し、対話的なプロンプトを回避します。

sudo apt install nginx -y

インストールプロセスでは、Nginx とその依存関係がダウンロードされ、セットアップされます。完了すると、nginxパッケージがセットアップされたことを示す出力が表示されるはずです。

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  nginx-common nginx-core
...
Setting up nginx-common (1.18.0-6ubuntu14.4) ...
Setting up nginx-core (1.18.0-6ubuntu14.4) ...
Setting up nginx (1.18.0-6ubuntu14.4) ...
Processing triggers for ufw (0.36.1-4ubuntu0.1) ...
Processing triggers for man-db (2.10.2-1) ...

インストールプロセスでは多くの場合サービスが開始されますが、明示的に管理することが良い習慣です。ここでは、最新の Linux システムでサービスを制御するための標準ユーティリティであるsystemctlを使用します。

このコマンドで Nginx サービスを開始します。

sudo systemctl start nginx

このコマンドは、正常に実行された場合、何も出力しません。サービスが実行されていることを確認するには、そのステータスを確認します。

sudo systemctl status nginx

出力にはサービスに関する詳細情報が表示されます。Active: active (running)という行を探してください。これにより、Nginx が起動して実行中であることが確認できます。

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2023-10-30 08:30:00 UTC; 5s ago
       Docs: man:nginx(8)
   Main PID: 1234 (nginx)
      Tasks: 2 (limit: 4617)
     Memory: 4.8M
        CPU: 43ms
     CGroup: /system.slice/nginx.service
             ├─1234 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─1235 "nginx: worker process"

これで、Nginx Web サーバーのインストールと起動が成功しました。次のステップでは、HTTPS を有効にするための前提条件となるデジタル証明書を生成します。

OpenSSL で自己署名 SSL 証明書を生成する

このステップでは、自己署名デジタル証明書とその対応する秘密鍵を作成します。HTTPS を有効にするには、Web サーバーはクライアントにその ID を証明するためのデジタル証明書と、安全で暗号化された接続を確立するための秘密鍵が必要です。ここでは、SSL/TLS を扱うための堅牢なユーティリティである openssl コマンドラインツールを使用します。

デジタル証明書は、公開鍵を ID(ウェブサイトのドメイン名など)にバインドします。通常、証明書は信頼された 認証局 (CA) によって発行および署名されます。しかし、テストや開発目的では、作成者自身によって署名された 自己署名証明書 を作成できます。このような証明書に対してブラウザはセキュリティ警告を表示しますが、この実験のような環境では完全に機能します。

まず、Nginx の設定フォルダ内に、SSL 証明書と鍵を保存するための専用ディレクトリを作成します。これにより、ファイルを整理して安全に保つことができます。

sudo mkdir -p /etc/nginx/ssl

次に、単一の openssl コマンドを使用して、2048 ビットの RSA 秘密鍵と自己署名証明書の両方を生成します。証明書は 365 日間有効です。これらは /etc/nginx/ssl/ ディレクトリに直接配置します。

コマンドオプションの内訳は以下のとおりです。

  • req -x509: 自己署名証明書を作成します。
  • -nodes: 秘密鍵がパスフレーズで暗号化されるのを防ぎます。これにより、Nginx は手動介入なしで開始できます。
  • -days 365: 証明書の有効期間を 1 年に設定します。
  • -newkey rsa:2048: 新しい 2048 ビットの RSA 秘密鍵を生成します。
  • -keyout: 秘密鍵の出力ファイル(/etc/nginx/ssl/nginx.key)を指定します。
  • -out: 証明書の出力ファイル(/etc/nginx/ssl/nginx.crt)を指定します。
  • -subj: 証明書のサブジェクト情報を非対話的に提供します。CN=localhost はコモンネームであり、サイトにアクセスするために使用するアドレスと一致する必要があります。

以下のコマンドを実行してください。

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/nginx.key \
  -out /etc/nginx/ssl/nginx.crt \
  -subj "/C=US/ST=State/L=City/O=LabOrg/OU=IT/CN=localhost"

コマンドを実行すると、鍵生成を確認する出力が表示されます。

Generating a RSA private key
writing new private key to '/etc/nginx/ssl/nginx.key'
-----

秘密鍵(/etc/nginx/ssl/nginx.key)は非常に機密性が高いものです。漏洩した場合、攻撃者はあなたのサーバーになりすますことができます。したがって、root ユーザーのみが読み取れるように、そのファイル権限を制限することが重要です。

sudo chmod 600 /etc/nginx/ssl/nginx.key

このコマンドは、所有者(root)のみに読み取りおよび書き込み権限を設定し、他のユーザーには権限を与えません。これは重要なセキュリティ対策です。

素晴らしい!これで自己署名証明書(nginx.crt)と安全な秘密鍵(nginx.key)が作成されました。次のステップでは、Nginx を設定してこれらの 2 つのファイルを使用して HTTPS を有効にします。

Nginx で HTTPS 経由のコンテンツ提供を設定する

このステップでは、Nginx の設定を変更して HTTPS を有効にします。前のステップで証明書と秘密鍵の準備ができたので、Nginx にそれらを使用するように指示する必要があります。これには、Nginx のサイト設定ファイルを編集してポート 443(HTTPS の標準ポート)でリッスンし、証明書と鍵ファイルのパスを指定することが含まれます。

設定ファイルを編集する前に、バックアップを作成することが賢明な習慣です。これにより、問題が発生した場合に元の状態に簡単に戻すことができます。デフォルトの Nginx サイト設定ファイルをバックアップしましょう。

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak

次に、nano テキストエディタを使用してメインの設定ファイルを編集します。このファイルには、Nginx が着信リクエストをどのように処理するかを定義するサーバーブロックが含まれています。

sudo nano /etc/nginx/sites-available/default

nano エディタ内では、ポート 80 で HTTP 用に設定されたデフォルトのサーバーブロックが表示されます。SSL 設定のセクションが見つかるまでスクロールしてください。通常、これはコメントアウトされています。このセクションのコメントを解除し、以下の設定と一致するようにする必要があります。このブロックは、Nginx にポート 443 でセキュアな接続をリッスンするように指示し、TLS ハンドシェイクに使用する証明書と鍵を指定します。

既存のコメントアウトされた SSL サーバーブロックを削除するか、コメントを解除して一致するように編集してください。

## --- CONTENT TO ADD/UNCOMMENT IN /etc/nginx/sites-available/default ---
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    server_name localhost;

    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;

    location / {
        try_files $uri $uri/ =404;
    }
}
## --- END CONTENT ---

これらのディレクティブの意味は次のとおりです。

  • listen 443 ssl: Nginx にポート 443 で着信接続をリッスンし、SSL/TLS プロトコルを使用してそれらを処理するように指示します。
  • server_name localhost: localhost へのリクエストに使用するサーバーブロックを定義します。
  • ssl_certificate: 公開証明書ファイル(nginx.crt)へのパスを指定します。
  • ssl_certificate_key: 秘密鍵ファイル(nginx.key)へのパスを指定します。

コンテンツを追加した後、ファイルを保存し、Ctrl+X、次に Y、最後に Enter を押して nano を終了します。

変更を適用する前に、Nginx の設定に構文エラーがないかテストすることが重要です。これにより、壊れた設定が Web サーバーを停止させるのを防ぎます。

sudo nginx -t

設定が正しい場合、成功メッセージが表示されます。

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

エラーが表示された場合は、設定ファイルを再度開き、タイプミスやセミコロンの欠落がないか慎重に確認してください。

これで、Nginx を HTTPS でコンテンツを提供するように正常に設定できました。次のステップは、サービスを再起動して接続をテストすることで、これらの変更を適用することです。

curl で HTTPS 設定を有効化しテストする

このステップでは、新しい Nginx 設定を適用し、Web サーバーが HTTPS で正しくコンテンツを提供していることを確認します。ディスク上の設定ファイルを変更しましたが、実行中の Nginx プロセスはまだ古い設定を使用しています。変更を有効にするには、サービスを再起動する必要があります。

新しい設定を適用するには、systemctl を使用して Nginx サービスを再起動します。

sudo systemctl restart nginx

このコマンドは、成功した場合、何も出力しません。Nginx はポート 443 でリッスンし、提供した証明書と鍵を使用して HTTPS リクエストを処理する準備ができました。

次に、HTTPS エンドポイントをテストしましょう。URL を使用したデータ転送のためのコマンドラインツールである curl を使用します。https:// プロトコルを使用して、サーバーからホームページを取得しようとします。

HTTPS を使用してサーバーに接続すると、クライアント(この場合は curl)は、サーバーの証明書が信頼された認証局(CA)によって署名されているかどうかを確認します。自己署名証明書を作成したため、デフォルトでは信頼されず、curl は接続を拒否し、証明書検証エラーを表示します。

テストのためにこれを回避するには、-k または --insecure フラグを使用します。このフラグは、curl に証明書検証をスキップするように指示します。これは安全ではなく、本番環境では使用すべきではありませんが、実験環境で自己署名証明書をテストするには必要です。

HTTPS サーバーをテストするには、次のコマンドを実行します。

curl -k https://localhost

設定が正しい場合、curl はサーバーに正常に接続し、デフォルトの Nginx ウェルカムページの HTML コンテンツを表示します。

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

この HTML 出力は、Nginx サーバーが正常に設定され、暗号化された HTTPS 接続でコンテンツを提供していることを確認します。最後のステップでは、サーバーが提示している証明書を検査する方法を学びます。

OpenSSL でサーバーの SSL 証明書を検査する

この最終ステップでは、Nginx サーバーがクライアントに提示しているデジタル証明書の詳細を調べます。これは、TLS/HTTPS の問題をトラブルシューティングし、サーバーの ID を検証するための重要なスキルです。再び openssl ツールを使用しますが、今回はクライアントとして自身のサーバーに接続し、提供される証明書を検査します。

パイプ (|) で接続された 2 つの openssl コマンドの組み合わせを使用します。

  • openssl s_client -connect localhost:443: このコマンドは汎用 SSL/TLS クライアントとして機能し、指定されたサーバーとポートに接続します。セッションの詳細とともにサーバーの証明書を出力します。
  • openssl x509 -text -noout: このコマンドは、X.509 証明書の内容を人間が読める形式で解析および表示するために使用されます。

s_client の出力を直接 x509 にパイプして、証明書をオンザフライで解析します。先頭の echo |s_client がユーザー入力を待つのを防ぎ、2>/dev/null は接続ステータスメッセージを非表示にします。明確にするために、出力をファイルに保存します。

次のコマンドを実行してサーバーに接続し、証明書を抽出し、解析して、詳細を /tmp/server_certificate_details.txt という名前のファイルに保存します。

echo | openssl s_client -connect localhost:443 2> /dev/null | openssl x509 -text -noout > /tmp/server_certificate_details.txt

次に、作成したばかりのファイルのコンテンツを表示して、証明書の詳細を確認します。

cat /tmp/server_certificate_details.txt

証明書のプロパティの詳細な内訳が表示されます。

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = State, L = City, O = LabOrg, OU = IT, CN = localhost
        Validity
            Not Before: Oct 30 09:00:00 2023 GMT
            Not After : Oct 29 09:00:00 2024 GMT
        Subject: C = US, ST = State, L = City, O = LabOrg, OU = IT, CN = localhost
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
                    ...
                Exponent: 65537 (0x10001)
...

出力に目を通してみてください。これらの重要なフィールドに注目してください。

  • Issuer: 証明書に署名したエンティティ。
  • Subject: 証明書が発行されたエンティティ。
  • CN (Common Name): 証明書が対象とする特定のドメイン (localhost)。

これは自己署名証明書であるため、IssuerSubject のフィールドは同一です。これが自己署名証明書の定義的な特徴です。有効期間と公開鍵の詳細も確認できます。

おめでとうございます!自己署名 SSL 証明書を使用して Nginx Web サーバーを正常にセットアップし、HTTPS 用に設定し、接続をテストし、証明書の詳細を検査しました。これで、TLS/HTTPS で Web トラフィックを保護するために含まれるコンポーネントの基本的な理解が得られました。

まとめ

この実験では、Linux 環境で Nginx Web サーバーに自己署名証明書を使用して HTTPS を実装するエンドツーエンドのプロセスを学びました。まず、システムのパッケージリストを更新し、apt パッケージマネージャーを使用して Nginx Web サーバーをインストールするという基盤をセットアップしました。実験の中心はセキュリティに焦点を当て、OpenSSL ツールキットを使用して秘密鍵とそれに対応する自己署名 SSL 証明書を生成しました。これらは、暗号化された接続を有効にするための不可欠なコンポーネントです。

証明書を作成した後、Nginx サーバーの設定に進みました。これには、HTTPS トラフィックのためにポート 443 でリッスンするサーバーブロックを作成し、新しい証明書と秘密鍵のパスを指定するように設定ファイルを変更することが含まれていました。プロセスを完了するために、新しい設定を有効にし、重要な検証ステップを実行しました。curl コマンドを使用してコマンドラインから HTTPS 接続をテストし、サーバーが安全に応答していることを確認しました。最後に、OpenSSL をクライアントツールとして使用してサーバーの証明書を検査し、正しい証明書が提供されていることを検証しました。