Tengo un sistema de dispositivos IoT detrás de una NAT, por lo que no se puede acceder a ellos desde la Internet pública (aunque es deseable). Para superar esto, los vinculé a una VPN, con un miembro expuesto a la Internet pública para actuar como puerta de enlace. La VPN tiene un dominio interno configurado y cada miembro de la red tiene un subdominio basado en una ID única (vamos con la dirección MAC), así:12a4f81ead4e.vpn.example.com
Deseo crear un proxy inverso en las Gatway
solicitudes de proxy, ejecutando nginx.
El plan es crear un registro DNS para la puerta de enlace *.gateway.com
y enrutar (ejem, proxy) el tráfico que va hacia/ 12a4f81ead4e.gateway.com
desde 12a4f81ead4e.vpn.example.com
. Y así, el usuario final sólo tendría que escribir 12a4f81ead4e.gateway.com
en su navegador para acceder a su dispositivo. Me gustaría usar nginx, ya que la puerta de enlace ya ejecuta nginx para otros fines.
Espero que las solicitudes HTTP sean fáciles y se puedan realizar con una proxy_pass
directiva nginx cuidadosamente diseñada.
Pero ¿qué pasa con las solicitudes HTTPS? Hasta donde tengo entendido, nginx ahora implementa el paso de TLS basado en SNI, pero todos los ejemplos que he visto hasta ahora crean un mapa estático para... bueno, mapean el SNI entrante a un objetivo ascendente:
stream {
map $ssl_preread_server_name $selected_upstream {
example.org upstream_1;
example.net upstream_2;
example.com upstream_3;
default upstream_4;
}
upstream upstream_1 { server 10.0.0.1:443; }
upstream upstream_2 { server 10.0.0.2:443; }
upstream upstream_3 { server 10.0.0.3:443; }
upstream upstream_4 { server 10.0.0.4:443; }
server {
listen 10.0.0.5:443;
proxy_pass $selected_upstream;
ssl_preread on;
}
}
El problema es que los dispositivos se agregan/eliminan dinámicamente de la VPN y no quiero reescribir los archivos de configuración de nginx todo el tiempo. Si es posible leer el mapa desde un archivo, es un paso en la dirección correcta, aunque creo que nginx debería recargarse cada vez que cambie, lo que plantea problemas de permisos, que podrían evitarse con reglas sudo, por supuesto, pero no con la mejor solución.
Además, solo quiero enviar por proxy las solicitudes que llegan *.gateway.com
y enviar otras solicitudes https normalmente a los vhosts existentes. Si es posible, me gustaría evitar cancelar la conexión SSL. Realmente no es un requisito difícil, pero me gustaría implementarlo de esa manera si es técnicamente factible. También sólo por diversión.
Estoy bien escuchando internamente en un puerto alternativo para los otros vhosts, hice algo similar para HTTP cuando quería establecer una ubicación "global", moví todos los vhosts HTTP al puerto 81 e implementé un vhost general en el puerto. 80 que sirvió a la ubicación "global" y envió todo lo demás al puerto 81. :)
Entonces... Lo que necesitaría sería algo como esto (obviamente no funciona):
stream {
map $ssl_preread_server_name $selected_upstream {
(.*).gateway.com $1.vpn.example.com;
default normal_serve;
}
upstream normal_serve { server 127.0.0.1:8443; }
server {
listen 0.0.0.0:443;
proxy_pass $selected_upstream;
ssl_preread on;
}
server {
listen 127.0.0.1:8443;
server_name other.website.com;
(...)
}
}
Respuesta1
Esto funciona:
stream {
resolver 8.8.8.8;
map $ssl_preread_server_name $selected_upstream {
~(.*).gateway.example.com $1.vpn.example.com:443;
default 127.0.0.1:8443;
}
server {
listen 0.0.0.0;
proxy_pass $selected_upstream;
ssl_preread on;
}
}
http {
resolver 8.8.8.8;
server {
listen 127.0.0.1:8443 ssl;
(...)
}
}