socatを介してホームサーバーに接続するためのSSL証明書


3

私は自宅でRaspberry PiでNextcloudを実行しています。DynDNSプロバイダーspDYN.deでホスト名のIPv6アドレスを更新します。ただし、私のプロバイダーはIPv6接続のみを提供しているため(DS-Lite for IPv4を使用)、他のIPv6接続からのみホスト名に直接アクセスでき、IPv4ネットワークから接続するにはIPv4-IPv6ポストマッパーを使用する必要があります。

私のウェブサイトはIPv6接続とIPv4接続の両方を備えたサーバーでホストされているため、これは大した問題ではないので、このチュートリアルに従ってsocatを使用して、ウェブサイトをホストするサーバーにポートマッパーをセットアップし、特定のポートを私のウェブサイトからルーティングダイナミックDNSホスト名のポート443にドメイン。これは完全に機能しますが、SSL証明書に問題が発生します。

RasPiでは、certbotを使用して、ダイナミックDNSホスト名の「暗号化」証明書を作成しました。これは完全に機能し、接続は保護されていると表示されます。また、私のWebサーバーで、ポートマッパーに使用しているドメイン用の同様の証明書を作成しましたが、それ自体は機能します。ただし、特定の転送されたポートでドメインにアクセスしてRasPiにアクセスすると、ブラウザーはドメインを含むURLを表示し続けますが、動的DNSホスト名に対して発行されたRasPiから証明書を受け取ります。結果として、もちろん、証明書が「間違った」ドメインに対して発行されるため、セキュリティチェックは失敗します。私はすでに自分のドメインのRasPiで証明書を発行しようとしましたが、「無許可」であると言って失敗します。

この問題を解決するにはどうすればよいですか?どの種類の証明書をどこで設定する必要がありますか?

回答:


2

証明書のエラーを回避するには、使用するドメインに一致する証明書を送信するためにpiが必要です。これには2つのアプローチがあります。

  1. piサーバーとメインサーバーの両方にインストールされた両方のドメインに1つの証明書を使用します。クライアントがクエリでどのドメインを使用したかは関係ありません。証明書は一致します。
  2. クライアントが期待する証明書を選択して送信します。

オプション1はより簡単で一般的な方法です。google.comの証明書を見てください!piとメインサーバーの両方に同じ証明書がインストールされます(両方のドメイン用)。Let's Encryptからこのような証明書を取得するには、メインサーバーでpiの動的ドメインのWebサイトを実行し、1つの certbotコマンドを使用して両方のドメインの制御を一度に確認する必要があります。メインサーバーのdyndns名のサイトは、piからのコンテンツをホストする必要はありません。Let's Encryptがそのサイトの制御権があることを確認できるようにします(更新の間にそのサイトをオフにすることもできます)。

このためのサンプルCertbotコマンド(メインWebサーバーで実行):

letsencrypt certonly --webroot --csr request.csr -w /http/pisite/www -d mypi.spdyn.de -w /http/mainwebsite/www -d maindomain.de

どこrequest.csrCNとしてドメインのいずれかを使用して、SANのフィールドに両方のドメインを持っている、/http/pisite/wwwあなたはパイの動的な名前にバインドされた現行のサーバー上の別のウェブサイトのために作成したローカルディレクトリを参照し、/http/mainwebsite/wwwあなたのメインのウェブサイトの既存のディレクトリです。


オプション2はより複雑ですが、「よりクリーンな」結果が生成されます。クライアントは、入力したドメインに一致する証明書を取得します。raspberry piで、TLS接続が開かれたときに(TLS接続を受け入れずに)SNIフィールドを調べ、そこに含まれるドメインに基づいて、転送するアップストリームを選択するストリームモジュール(または同等のもの)でnginxを実行しますへの接続。これにより、raspberry piに転送される外部ポート上のメインドメインからの要求を処理する方法を選択できます。それらが正しいポートで作成されたかのようにメインWebサーバーに送信できます。pi上の他のポート(Nextcloudなど)に送信でき、同じnginxインスタンスで終了できます。好きなページを表示するか、単に接続を閉じます。選択はあなた次第です。

このメソッドのサンプル設定は次のとおりです。

stream/sni-switch.conf

# Listen on 443, and on new connection:
#   if the SNI is mapped herein, handle it on this Nginx
#   else, forward the whole session to 192.168.1.80:443 (TCP passthrough, no decryption)

upstream mainwebserver {
    server 192.168.1.80:443;
}

upstream local_https {
    server 127.0.0.1:1443;
}

map $ssl_preread_server_name $name {
    default mainwebserver;

    pisite.spdyn.de     local_https;
}

server {
    listen 443;

    ssl_preread on;
    proxy_pass $name;
}

そして nginx.conf

load_module /usr/lib/nginx/modules/ngx_stream_module.so;

stream {
    include /etc/nginx/stream/sni-switch.conf;
}

...

Apacheでこれを行うには、参照これを。次のようなサンプル構成:

<VirtualHost *:*>
    ProxyPreserveHost On
    ProxyPass        "/" "http://192.168.1.80/"
    ProxyPassReverse "/" "http://192.168.1.80/"
    ServerName maindomain.de
</VirtualHost>

ご回答どうもありがとうございました!オプション1について-現時点では、動的DNS名へのトラフィックはWebサーバーを通過しないため、証明書を生成するために動的DNSホスト名もWebサーバーにリダイレクトしますか?オプション2について-私はApacheを使用していますが、このモジュールは同じ目的を果たすと思いますか?wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI
iYassin

1-それは機能します、はい。ただし、この重要な構成の変更は3か月ごとに行う必要があります。2- このようにします
-Scruffy

VirtualHostオプションを使用してそれを実現し、完全に機能するようになりました。ありがとうございました!
-iYassin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.