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

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

Я запускаю 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 для моего домена, но он не срабатывает, сообщая мне, что я «не авторизован».

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

решение1

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

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

Вариант 1 проще и является общепринятой практикой. Посмотрите на сертификат для google.com! И pi, и основной сервер будут иметь один и тот же сертификат (для обоих доменов). Чтобы получить такой сертификат от 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 с модулем stream (или эквивалентом), который при открытии 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>

Связанный контент