Certificado SSL para conexión al servidor doméstico a través de socat

Certificado SSL para conexión al servidor doméstico a través de socat

Estoy ejecutando Nextcloud en una Raspberry Pi en casa. Actualiza su dirección IPv6 en un nombre de host en el proveedor DynDNS spDYN.de. Sin embargo, como mi proveedor solo ofrece conexiones IPv6 (usando DS-Lite para IPv4), solo puedo acceder directamente al nombre de host desde otras conexiones IPv6 y tengo que usar un postmapper IPv4-IPv6 para conectarme desde redes IPv4.

Esto no es gran cosa, ya que mi sitio web está alojado en un servidor que tiene conexiones IPv6 e IPv4, así que usé socat de acuerdo coneste tutorialpara configurar un mapeador de puertos en el servidor que aloja mi sitio web, enrutando un puerto específico desde el dominio de mi sitio web al puerto 443 en el nombre de host DNS dinámico. Esto funciona perfectamente, pero crea un problema con los certificados SSL:

En RasPi, utilicé certbot para crear un certificado "Cifremos" para el nombre de host DNS dinámico, que funciona perfectamente y la conexión se muestra como segura. Además, en mi servidor web, creé un certificado similar para el dominio que estoy usando para el mapeador de puertos, que en sí mismo funciona. Sin embargo, cuando accedo al dominio con el puerto reenviado específico para acceder a RasPi, el navegador continúa mostrando la URL que contiene mi dominio, pero recibe el certificado de RasPi que se emitió para el nombre de host DNS dinámico. Como consecuencia, por supuesto, la comprobación de seguridad falla ya que el certificado se emite para el dominio "incorrecto". Ya intenté emitir un certificado en mi RasPi para mi dominio, pero falla al decirme que no estoy "autorizado".

¿Como puedó resolver esté problema? ¿Dónde tengo que configurar qué tipo de certificado?

Respuesta1

Para evitar errores de certificado, necesita que pi envíe un certificado que coincida con el dominio utilizado.Hay dos enfoques para esto:

  1. Utilice un certificado para ambos dominios, instalado tanto en el pi como en el servidor principal. No importa qué dominio utilizó el cliente en su consulta, el certificado coincidirá.
  2. Elija un certificado que el cliente espera y envíelo.

La opción 1 es una práctica más fácil y común. ¡Mira el certificado de google.com! Tanto el pi como el servidor principal tendrán instalado el mismo certificado (para ambos dominios). Para obtener dicho certificado de Let's Encrypt, necesitará que el servidor principal ejecute también un sitio web para el dominio dinámico de pi y useunoComando certbot para verificar el control de ambos dominios a la vez. El sitio del servidor principal para el nombre dyndns no necesita alojar el contenido del pi; simplemente está ahí para que Let's Encrypt pueda verificar que usted tiene control de ese sitio (incluso puede desactivar ese sitio entre renovaciones).

Ejemplo de comando Certbot para esto (ejecutarlo en el servidor web principal):

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

Donde request.csrutiliza cualquiera de los dominios como CN y tiene ambos dominios en el campo SAN, /http/pisite/wwwse refiere a un directorio local que crearía para otro sitio web en el servidor actual vinculado al nombre dinámico de pi y /http/mainwebsite/wwwes el directorio existente de su sitio web principal.


La opción 2 es más complicada pero produce un resultado "más limpio": el cliente obtiene un certificado que coincide con el dominio que escribió. En Raspberry Pi, ejecute nginx con el módulo de transmisión (o equivalente) que, cuando se abre una conexión TLS: examina el campo SNI (sin aceptar la conexión TLS) y, según el dominio incluido allí, elige qué flujo ascendente reenviar el conexión a. Esto le permite elegir cómo desea manejar las solicitudes realizadas desde el dominio principal en el puerto externo reenviado a la Raspberry Pi. Puede enviarlos al servidor web principal como si se hubieran creado en el puerto correcto, puede enviarlos a algún otro puerto en el pi (es decir, Nextcloud o cualquier otro), puede terminarlos con la misma instancia de nginx y muestra la página que quieras o simplemente cierra la conexión. La decisión es tuya.

Aquí hay una configuración de muestra para este método:

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;
}

Y ennginx.conf

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

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

...

Para hacer esto con Apache, consulteeste. Una configuración de muestra que podría verse así:

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

información relacionada