web-dev-qa-db-ja.com

nginxリバースプロキシで暗号化できます

はじめに

私は開発サーバー(現在Ubuntu 14.04 LTSを実行しています)を使用しています。これは、さまざまなポートでさまざまな開発ツールをホストするためにしばらく使用しています。ポートは覚えにくい場合があるため、すべてのサービスにポート80を使用し、ホスト名に基づいて内部でポート転送を行うことにしました。

Domain.com:5432を記述する代わりに、sub.domain.comを介してそれにアクセスできます。

たとえば、ポート7547を使用し、sub.domain.comで実行されているアプリケーションXには、次のnginx構成があります。

upstream sub {
    server 127.0.0.1:7547;
}

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    access_log /var/log/nginx/sub.log combined;
    location / {
            proxy_set_header Host $Host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:7547;
            proxy_set_header Authorization "";
    }
}

質問

私が選択した現在の構成構造を考えると、letsencryptを使用してhttpsでさまざまなサービスを実行することは可能ですか?

46
0x450

はい、HTTPサーバーへのnginxプロキシリクエストを行い、それ自体がHTTPS経由でクライアントに応答することができます。これを行うときは、nginx <-> proxy接続が、予想される攻撃者である誰かによって傍受される可能性が低いことを確認する必要があります。安全なアプローチmightには以下が含まれます:

  • 同じホストへのプロキシ(あなたがするように)
  • ファイアウォールの背後にある他のホストへのプロキシ

公衆インターネット上の別のホストへのプロキシは十分に安全である可能性は低いです。

ここでは、プロキシとして使用しているのと同じWebサーバーを使用してLet's Encrypt証明書を取得する手順を示します。

Let's Encryptに初期証明書を要求する

server句を変更して、サブディレクトリ.well-knownがローカルディレクトリから提供されるようにします。例:

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    […]
    location /.well-known {
            alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here
        […]
    }
}

http://sub.domain.com/.well-knownは、Let's Encryptサーバーが発行する課題への回答を探す場所です。

次に certbot クライアントを使用して、 webroot プラグイン(ルートとして)を使用してLet's Encryptに証明書を要求できます。

certbot certonly --webroot -w /var/www/sub.domain.com/ -d sub.domain.com -d www.sub.domain.com

キー、証明書、証明書チェーンが/etc/letsencrypt/live/sub.domain.com/にインストールされます

証明書を使用するためのnginxの構成

まず、次のような新しいサーバー句を作成します。

server {
    listen 443 ssl;

    # if you wish, you can use the below line for listen instead
    # which enables HTTP/2
    # requires nginx version >= 1.9.5
    # listen 443 ssl http2;

    server_name sub.domain.com www.sub.domain.com;

    ssl_certificate /etc/letsencrypt/live/sub.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sub.domain.com/privkey.pem;

    # Turn on OCSP stapling as recommended at 
    # https://community.letsencrypt.org/t/integration-guide/13123 
    # requires nginx version >= 1.3.7
    ssl_stapling on;
    ssl_stapling_verify on;

    # Uncomment this line only after testing in browsers,
    # as it commits you to continuing to serve your site over HTTPS
    # in future
    # add_header Strict-Transport-Security "max-age=31536000";

    access_log /var/log/nginx/sub.log combined;

    # maintain the .well-known directory alias for renewals
    location /.well-known {
        alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here as in your port 80 configuration
        […]
    }
}

Nginxをリロードします。

service nginx reload

ブラウザ(およびサポートしたいその他のブラウザ)でhttps://sub.domain.comおよびhttps://www.sub.domain.comにアクセスし、証明書エラーが報告されていないことを確認して、HTTPSが機能することを確認します。

推奨: raymii.org:強力なSSLセキュリティon nginx も確認し、設定を SSL Labs でテストしてください。

(推奨)HTTPリクエストをHTTPSにリダイレクトする

サイトがhttps://バージョンのURLで動作していることを確認したら、http://sub.domain.comにアクセスしたために安全でないコンテンツを配信するユーザーがいるのではなく、サイトのHTTPSバージョンにリダイレクトします。

ポート80のserver句全体を次のものに置き換えます。

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    rewrite     ^   https://$Host$request_uri? permanent;
}

また、ポート443構成のこの行のコメントを外して、ブラウザーがサイトのHTTPバージョンを試しさえしないことを覚えておく必要があります。

add_header Strict-Transport-Security "max-age=31536000";

証明書を自動的に更新する

このコマンドを(ルートとして)使用して、certbotが認識しているすべての証明書を更新し、新しい証明書(既存の証明書と同じパスを持つ)を使用してnginxをリロードします。

certbot renew --renew-hook "service nginx reload"

certbotは60日以上経過した証明書のみを更新しようとするため、このコマンド 非常に定期的に を実行し、可能な場合は自動的に実行することが安全です(推奨されます)。たとえば、次のコマンドを/etc/crontabに入れることができます。

# at 4:47am/pm, renew all Let's Encrypt certificates over 60 days old
47 4,16   * * *   root   certbot renew --quiet --renew-hook "service nginx reload"

Let's Encryptステージングサーバーに接続してドメインへの接続の実際のテストを実行するいずれかの予行演習で更新をテストできますが、できない結果の証明書を保存します。

certbot --dry-run renew

または、次のようにして早期更新を強制できます。

certbot renew --force-renew --renew-hook "service nginx reload"

注:ドライランは何度でも実行できますが、実際の更新は Let's Encryptのレート制限 の影響を受けます。

82
puzzlement

はい、nginxをhttpsのエンドポイントとして使用し、http経由でバックエンドと連携できます。たとえば私の設定:

server {
        server_name Host;
        listen 443 ssl;
...
 location /svn/ {
            auth_ldap off;

            proxy_set_header Host $Host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            proxy_pass http://localhost:1080/svn/;
            proxy_redirect http://localhost:1080/ https://Host/;
        }
...
}

しかし、私が知っているように、暗号化では、証明書を取得するときにすべてのサブドメインをポイントする必要があります。これが問題である場合は、https://Host/serviceではなくhttps://service.Hostを選択します。

2
fghj