========================================
Guía de Despliegue Web: NGINX-Tailscale
========================================

Introducción
------------

Tradicionalmente, para publicar una aplicación web en Internet desde un
servidor en casa era necesario abrir puertos en nuestro router, configurar
reglas NAT y exponer directamente nuestro servidor al mundo. Este enfoque
presenta diversos problemas de seguridad y administración.

Actualmente existen alternativas más seguras y flexibles. Una de ellas consiste
en utilizar una red privada virtual (VPN) moderna como `Tailscale
<https://tailscale.com/>`_ para conectar nuestros servidores internos (homelab)
con un servidor virtual privado (VPS) que actúa como punto el punto de entrada público.
Los clientes se conectan al VPS e internamente enruta el tráfico por un túnel privado 
a nuestros servidores locales.

La arquitectura permite publicar aplicaciones Django, FastAPI, NodeJS, sitios
Sphinx, bases de datos o cualquier otro servicio sin exponer directamente la
infraestructura de nuestro **homelab** a Internet.

La siguiente figura  muestra la arquitectura propuesta:

:: 

   Internet 
       |
       v 
   Cloudflare 
       | 
       v
   VPS Público (Nginx) 
       | 
       v 
   Tailscale 
       | 
       v 
    Homelab 
       ├── Django 
       ├── FastAPI 
       ├── Sphinx 
       ├── PostgreSQL 
       └── Redis

El usuario únicamente tiene acceso al VPS. Los servidores del homelab
permanecen ocultos detrás de la red Tailscale. Para agregar otra capa 
de seguridad también nuesta máquina virtual pública está detrás de Cloudflare. 

Veamos cada uno de los componentes:

Cloudflare
~~~~~~~~~~

Cloudflare puede utilizarse como primera capa de protección. Para esto, vamos a
hospedar nuestro dominio en los servidores DNS de Cloudflare, de esta manera
las peticiones no verán directamente a nuestra IP, y aprovechamos la
funcionalidad que nos brinda:

* Protección contra ataques automatizados.
* Protección DDoS.
* Caché de contenido estático.
* Certificados TLS.
* Firewall de aplicaciones web (WAF).


VPS
~~~

El VPS actúa como punto de entrada público. Este puede 
ser un servidor de bajos recursos, hospedado en servicios como 
`OVHcloud <https://www.ovhcloud.com/>`_, `Digital Ocean <https://www.digitalocean.com/>`_
o alguna instancia gratuita de AWS.

Su función principal consiste en:

* Terminar las conexiones HTTPS.
* Gestionar certificados TLS.
* Reenviar peticiones mediante Nginx.
* Conectarse a los servicios internos mediante Tailscale.

Contrario a lo que suele pensarse, el VPS no necesita ser especialmente
potente. La mayor parte del procesamiento ocurre en los servidores del homelab.

Tailscale
~~~~~~~~~

Tailscale crea una red privada virtual entre todos los equipos.

Ejemplo:

::

     VPS
      |
      +---- Fedora
      |
      +---- Mac Mini
      |
      +---- Servidor IA
      |
      +---- Laptop

Cada nodo obtiene una dirección IP privada dentro de la red Tailscale.

Ejemplo:

::

    VPS      -> 100.81.91.82
    Fedora   -> 100.109.57.106
    MacMini  -> 100.116.196.76

También es posible utilizar nombres mediante MagicDNS:

::

    fedora
    macmini
    vps
    servidor
    laptop


Nginx como Reverse Proxy
------------------------

En el VPS se configura Nginx para reenviar peticiones al servidor
correspondiente. En este ejemplo ya se tienen certificados para 
utilizar peticiones **https**.

Para publicar un sitio web en nuestra máquina llamada `fedora` en 
la red de `Tailscale` podemos editar la configuración de Nginx en 
el VPS:

::

    server {
        listen 443 ssl;
        server_name python.midominio.com;

        location / {
            proxy_pass http://fedora:8080;

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
        }
    }

La parte importante de la configuración es `proxy_pass`, con esto 
pasamos la petición directamente a nuestra máquina `fedora`. El 
host de la petición es `python.midominio.com`, pero a `fedora` 
llegaría `http://fedora:8080`, por lo que agregamos la información 
original de la petición en los headres correspondiente con `proxy_set_header`. 

Así, cuando un usuario accede a:

::

    https://python.midominio.com

la petición sigue el siguiente recorrido:

::

     Usuario
       |
       v
   Cloudflare 
       | 
       v
  VPS (Nginx)
       |
       v
   Tailscale
       |
       v
    Fedora:8080

Ejemplo: Publicación de Sitios Sphinx
-------------------------------------

Un sitio generado con Sphinx (como este libro) puede publicarse directamente
mediante Nginx. En este caso en el servidor Nginx de `fedora` agregamos en 
`\etc\nginx\sites-enabled\python.midominio.com`:

Ejemplo:

::

    server {
        listen 8080;
        server_name python.midominio.com;

        root /var/www/python/html;
        index index.html;

        location / {
            try_files $uri $uri/ =404;
        }
    }

Permisos
~~~~~~~~



Múltiples Servicios
-------------------

Una de las principales ventajas de esta arquitectura es que permite distribuir
servicios entre varios equipos.

Por ejemplo:

::

    docs.midominio.com
        |
        +--> Fedora
              Sphinx

    api.midominio.com
        |
        +--> Dell
              FastAPI

    ai.midominio.com
        |
        +--> Threadripper
              LLM

    cloud.midominio.com
        |
        +--> Mac Mini
              Nextcloud

Cada servicio puede ejecutarse en un equipo diferente.

SSH Seguro con Tailscale
------------------------

Una práctica recomendada consiste en no exponer SSH a Internet.

Arquitectura recomendada:

::

    Internet
       |
       +---- HTTPS (443)
       |
       X SSH público

    Tailscale
       |
       +---- SSH

De esta forma sólo los miembros autorizados de la red Tailscale pueden administrar los servidores.

Diagnóstico de Problemas
------------------------

Algunas herramientas útiles:

Verificar estado de Tailscale:

::

    tailscale status

Probar conectividad:

::

    tailscale ping fedora

Probar servicio web desde la red Tailscale:

::

    curl -v --connect-timeout 5 -H "Host: python.mariosky.dev" http://fedora:8080/

Ver puertos abiertos:

::

    ss -ltnp

Ver tráfico de red tailscale0:

::

    sudo tcpdump -ni tailscale0

Verificar configuración de Nginx:

::

    sudo nginx -t

Mostrar configuración completa:

::

    sudo nginx -T

Ver logs de Nginx: 

:: 
    
    sudo tail -f /var/log/nginx/access.log




