SSL-сертификат для подключения к домашнему серверу через socat

724
iYassin

Я бегу Nextcloud на Raspberry Pi дома. Он обновляет свой IPv6-адрес на имени хоста у провайдера DynDNS spDYN.de. Однако, поскольку мой провайдер предлагает только соединения IPv6 (используя DS-Lite для IPv4), я могу напрямую получать доступ к имени хоста только из других подключений IPv6, и мне нужно использовать почтовый преобразователь IPv4-IPv6 для подключения к нему из сетей IPv4.

Это не имеет большого значения, так как мой веб-сайт размещен на сервере, который имеет соединения как IPv6, так и IPv4, поэтому я использовал socat в соответствии с этим руководством, чтобы настроить portmapper на сервере, на котором размещен мой сайт, маршрутизируя определенный порт с моего сайта. домен на порт 443 на динамическом DNS-имени хоста. Это работает отлично, но создает проблему с сертификатами SSL:

На RasPi я использовал certbot для создания сертификата «Let's encrypt» для динамического DNS-имени хоста, который отлично работает, и соединение отображается как защищенное. Кроме того, на своем веб-сервере я создал аналогичный сертификат для домена, который я использую для portmapper, который сам по себе работает. Однако, когда я получаю доступ к домену через определенный перенаправленный порт для доступа к RasPi, браузер продолжает отображать URL-адрес, содержащий мой домен, но он получает сертификат от RasPi, который был выдан для имени узла динамического DNS. Как следствие, конечно, проверка безопасности не проходит, так как сертификат выдан для «неправильного» домена. Я уже пытался выдать сертификат на своем RasPi для моего домена, но он не может сказать, что я "не авторизован".

Как я могу решить эту проблему? Где мне установить сертификат?

3

1 ответ на вопрос

2
Scruffy

Чтобы избежать ошибок сертификата, вам нужно пи для отправки сертификата, который соответствует используемому домену. Есть два подхода к этому:

  1. Используйте один сертификат для обоих доменов, установленных как на пи, так и на главном сервере. Не имеет значения, какой домен клиент использовал в своем запросе, сертификат будет совпадать.
  2. Выберите сертификат, который ожидает клиент, и отправьте его.

Вариант 1 является более простой и распространенной практикой. Посмотрите сертификат для google.com! Как на пи, так и на главном сервере будет установлен один и тот же сертификат (для обоих доменов). Чтобы получить такой сертификат от Let's Encrypt, вам потребуется главный сервер для запуска веб-сайта для динамического домена pi, а также одна команда certbot для проверки управления обоими доменами одновременно. На сайте главного сервера для имени dyndns не обязательно размещать контент от pi - он просто есть, поэтому Let's Encrypt может проверить, что вы контролируете этот сайт (вы даже можете отключить этот сайт между обновлениями).

Пример команды Certbot для этого (запустите на главном веб-сервере):

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, и /http/mainwebsite/wwwявляется существующим каталогом вашего основного веб-сайта.


Вариант 2 более сложен, но дает более «чистый» результат: клиент получает сертификат, соответствующий домену, который он ввел. На raspberry pi запустите nginx с потоковым модулем (или его эквивалентом), который при открытии соединения TLS: исследует поле SNI (без принятия соединения TLS) и, основываясь на включенном в него домене, выбирает, какой восходящий канал направить подключение к. Это позволяет вам выбирать, как вы хотите обрабатывать запросы, сделанные из основного домена на внешний порт, перенаправленные на RasPberry Pi. Вы можете отправить их на основной веб-сервер так же, как если бы они были сделаны на правильном порте, вы можете отправить их на другой порт 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-имени не проходит через веб-сервер, так что это значит, что я бы перенаправил свое динамическое DNS-имя хоста на свой веб-сервер, чтобы сгенерировать сертификат? Что касается варианта 2 - я использую Apache, я думаю, этот модуль будет служить той же цели? https://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI iYassin 6 лет назад 0
1- Это бы сработало, да. Вы должны быть готовы вносить это существенное изменение конфигурации каждые три месяца или около того. 2 - [сделать это так] (https://httpd.apache.org/docs/current/vhosts/examples.html#proxy) Scruffy 6 лет назад 0
Я понял это, используя опцию VirtualHost, и она работает отлично. Спасибо! iYassin 6 лет назад 0

Похожие вопросы