web-dev-qa-db-ja.com

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

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

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

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

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

3
iYassin

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

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

オプション1は、より簡単で一般的な方法です。 google.comの証明書を見てください! piとメインサーバーの両方に(両方のドメインに対して)同じ証明書がインストールされます。 Let's Encryptからこのような証明書を取得するには、メインサーバーでpiの動的ドメインのWebサイトも実行し、onecertbotコマンドを使用して両方のドメインの制御を確認する必要があります。すぐに。 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.csrはいずれかのドメインをCNとして使用し、SANフィールドに両方のドメインがあります。/http/pisite/wwwは、piの動的名にバインドされた現在のサーバー上の別のWebサイト用に作成するローカルディレクトリを指し、/http/mainwebsite/wwwは、メインWebサイトの既存のディレクトリです。


オプション2はより複雑ですが、「よりクリーンな」結果を生成します。クライアントは、入力したドメインに一致する証明書を取得します。 Raspberry Piで、ストリームモジュール(または同等のもの)を使用してnginxを実行します。これは、TLS接続が開かれると、(TLS接続を受け入れずに)SNIフィールドを調べ、そこに含まれるドメインに基づいて、転送するアップストリームを選択します。への接続。これにより、RaspberryPiに転送される外部ポートのメインドメインからのリクエストをどのように処理するかを選択できます。それらを正しいポートで作成されたかのようにメイン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でこれを行うには、 this を参照してください。次のような構成例:

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