Documentación Oficial de Ingeniería

MetaProxy v2
Manual Técnico y de Arquitectura

Especificación Integral, Motor de Reescritura, Egress Isolation y Guía de Despliegue
Versión del Sistema:2.0.0 (MVP para Demostración y Producción)
Plataforma:Go 1.27.1 / Ubuntu 26.04 LXC / Valkey 9 / PostgreSQL 18
Organización:Metabiblioteca
Fecha de Emisión:Octubre 2026
Estado:Verificado y Operativo

1. Visión General y Objetivos del Proyecto

MetaProxy v2 es una plataforma proxy inversa multitenant de alto rendimiento diseñada por Metabiblioteca para reemplazar la infraestructura existente basada en MuseProxy y BunkerWeb. Su propósito primordial es facultar el acceso remoto y seguro a recursos de investigación científica (Elsevier ScienceDirect, EBSCOhost, SpringerLink, JSTOR, ProQuest, vLex, eLibro) asegurando que el tráfico de cada institución salga a Internet exclusivamente por su dirección IP pública autorizada (Egress Isolation) y que la navegación del usuario permanezca confinada bajo el dominio institucional.

Objetivo Crítico (RNF-001): Ningún paquete transmitido por el usuario de una universidad puede salir a Internet por la dirección IP de otra universidad. El aislamiento físico de sockets y las guardias a nivel de kernel garantizan la seguridad de las suscripciones editoriales.

2. Arquitectura de Alto Nivel y Componentes

El sistema se organiza en tres componentes ejecutables independientes:

INTERNET / USUARIOS REMOTOS │ ▼ ┌────────────────────────────────────────────────────────┐ │ Firewall perimetral nftables (tmpproxy-04) │ │ Puertos públicos: 2828 (SSH VPN), 80/443 (HTTP/TLS) │ └────────────────────────────────────────────────────────┘ │ ┌────────────────────────┴────────────────────────┐ ▼ ▼ ┌───────────────────────────────┐ ┌───────────────────────────────┐ │ metaproxy-runtime (t07) │ │ metaproxy-runtime (t08) │ │ Dominio: *.temp-proxy07 │ │ Dominio: *.temp-proxy08 │ │ Bind: eth0 (54.36.18.254) │ │ Bind: eth1 (54.36.18.253) │ │ cgroup: mp-t07.slice │ │ cgroup: mp-t08.slice │ └───────────────────────────────┘ └───────────────────────────────┘ │ │ │ SO_BINDTODEVICE │ SO_BINDTODEVICE ▼ ▼ ┌───────────────────────────────┐ ┌───────────────────────────────┐ │ eth0 (54.36.18.254) │ │ eth1 (54.36.18.253 - tabla 1008) └───────────────────────────────┘ └───────────────────────────────┘ │ │ ▼ ▼ [ScienceDirect] [EBSCOhost] (Reconoce IP .254) (Reconoce IP .253)

3. Aislamiento de Red y Egress Isolation (RNF-001)

El servidor tmpproxy-04 dispone de dos interfaces de red físicas independientes:

TenantDominio BaseInterfaz FísicaIP EgressTabla de Ruteo
t07temp-proxy07.metaproxy.orgeth054.36.18.254main (default)
t08temp-proxy08.metaproxy.orgeth154.36.18.2531008 (RoutingPolicyRule)

Enlace de Socket en Go:

func BindToInterface(fd uintptr, iface string) error {
    return unix.SetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_BINDTODEVICE, iface)
}

Guardia en nftables por cgroupv2:

socket cgroupv2 level 1 "mp-t07.slice" oifname != "lo" ip saddr != 54.36.18.254 counter drop
socket cgroupv2 level 1 "mp-t08.slice" oifname != "lo" ip saddr != 54.36.18.253 counter drop

4. Motor de Reescritura Determinista

El motor de reescritura en Go garantiza que ninguna petición se fugue a la editorial original sin pasar por el proxy:

[ Flujo de Login Institucional y Canje de Ticket (Cookie Vault) ]
+---------------------------------------------------------------------------------------+ | FLUJO DE LOGIN INSTITUCIONAL Y CANJE DE TICKET (COOKIE VAULT) | | | | [Navegador] [Apex Portal] [Auth Engine] [Valkey :6379] [Sub] | | | | | | | | | 1. |-- GET /login ----->| | | | | | 2. |<- Formulario HTML -| | | | | | 3. |-- POST /login ---->| | | | | | | (user, pass) |-- Verificar ------->| | | | | 4. | |<- Argon2id OK ------| | | | | 5. | |-- Crear sess:t07: (TTL 8h) --------->| | | | 6. |<- 302 Found (Set-Cookie: mp_sid=; HttpOnly; Secure)-------| | | | | | | | | | | 7. |-- GET /go/ebsco -->| | | | | | | (con mp_sid) |-- Validar sesión ------------------>| | | | 8. | |-- Crear ticket:t07: (TTL 60s) ------>| | | | 9. |<- 302 a subdominio: search-ebscohost-com.temp-proxy07...?ticket= | | | | | | | | | | 10. |-- GET /login.aspx?ticket= ------------------------------------------>| | | 11. | | | Consumir y borrar ticket --->| | | 12. | | |<- Retorna session_id ----------| | | 13. |<- Set-Cookie: mp_hs=; HttpOnly; Secure; Path=/ --------------| | | 14. |<- 200 OK HTML Reescrito (Enlaces dentro de *.temp-proxy07.metaproxy.org) -| | +---------------------------------------------------------------------------------------+
[ Motor de Reescritura Determinista en Streaming ]
+---------------------------------------------------------------------------------------+ | MOTOR DE REESCRITURA DETERMINISTA EN STREAMING Y NAVEGACION PERSISTENTE | | | | [Navegador] [Apache 2.4 :443] [Runtime Go :8087] [Upstream Ed] | | | | | | | | 1. |-- GET https://www-sciencedirect-com.temp-proxy07.../science/article/123 -->| | | 2. | (Cookie: mp_hs) |-- ProxyPass http://127.0.0.1:8087 --------> | | | | | (ProxyPreserveHost On)| | | | 3. | | |-- Resolver | | | | | | Host: sciencedirect.com | | | | | Acción: PROXY | | | 4. | | |-- GET article --> | | | | | | (SO_BINDTODEVICE="eth0") | | | | | (Egress: 54.36.18.254) | | 5. | | |<- 200 OK (gzip original) ---| | 6. | | |-- Streaming Tokenizer | | | | | - Descomprimir gzip | | | | | - Reescribir href/src | | | | | - Inyectar Shim JS | | | | | - Recomprimir gzip | | 7. | | |-- Logpipe Asíncrono | | | | | (TipoAccion 2 - Metadatos)| | 8. | |<- 200 OK Stream --------| | | | 9. |<- 200 OK (HTML Reescrito servido al usuario) ---| | | +---------------------------------------------------------------------------------------+

5. API REST del Plano de Control

MétodoRutaDescripción
GET/healthzVerificación de salud del servidor (200 OK).
GET/api/statusMétricas generales, conteo de tenants y perfiles activos.
GET/api/tenantsListado de instituciones y configuraciones de red.
GET/api/profilesCatálogo de perfiles declarativos cargados.
POST/api/profiles/validateCompilación y ejecución de tests unitarios de perfiles.
POST/api/profiles/test-matchEvaluación de enrutamiento y reescritura sobre una URL dada.
GET/api/sessionsInspección de sesiones de usuario activas en Valkey.
GET/api/analyticsEstadísticas de uso por TipoAccion (MuseProxy 0..13).
GET/docs/*Manuales HTML, Markdown y descarga directa de archivos Word (.docx).

6. Infraestructura de Red, DNS y Terminación TLS (Apache + Certbot)

MetaProxy requiere resolver cualquier subdominio codificado (*.temp-proxy07.metaproxy.org y *.temp-proxy08.metaproxy.org) hacia la IP del servidor y terminar TLS con certificados comodín válidos.

[ Infraestructura de Red, DNS Wildcard y Terminación TLS ]
+---------------------------------------------------------------------------------------+ | INFRAESTRUCTURA DE RED, DNS WILDCARD Y TERMINACION TLS (APACHE + CERTBOT) | | | | [ Cliente / Navegador ] | | | | | | 1. Consulta DNS: *.temp-proxy07.metaproxy.org | | v | | +-------------------------------------------------------------------------------+ | | | GoDaddy DNS Autoritativo (Zona metaproxy.org) | | | | temp-proxy07.metaproxy.org A 54.36.18.254 | | | | *.temp-proxy07.metaproxy.org A 54.36.18.254 (Wildcard) | | | | temp-proxy08.metaproxy.org A 54.36.18.253 | | | | *.temp-proxy08.metaproxy.org A 54.36.18.253 (Wildcard) | | | +-------------------------------------------------------------------------------+ | | | | | | 2. Petición HTTPS entrante (TCP :443) | | v | | +-------------------------------------------------------------------------------+ | | | Apache 2.4 Reverse Proxy (tmpproxy-04) | | | | VirtualHost 54.36.18.254:443 (Tenant 07) -> Certificado Let's Encrypt / ECDSA| | | | VirtualHost 54.36.18.253:443 (Tenant 08) -> Certificado Let's Encrypt / ECDSA| | | | ProxyPreserveHost On | WebSocket WSS Tunnel | Cabeceras X-Forwarded-* | | | +-------------------------------------------------------------------------------+ | | | ^ | | | ProxyPass http://127.0.0.1:8087 | Recarga en caliente | | v | (systemctl reload apache2) | | +------------------------------------+ +--------------------------------------+ | | | metaproxy-runtime@t07 (:8087) | | Certbot DNS-01 (obtain-wildcard.sh) | | | | Data Plane Go | | Desafío TXT vía GoDaddy API / Manual | | | +------------------------------------+ +--------------------------------------+ | +---------------------------------------------------------------------------------------+

6.1 Configuración de Nombres de Dominio (DNS Wildcard)

Nombre de HostTipoDestino (IP Pública)Tenant AsignadoInterfaz
temp-proxy07.metaproxy.orgA54.36.18.254t07 (Apex)eth0
*.temp-proxy07.metaproxy.orgA54.36.18.254t07 (Wildcard)eth0
temp-proxy08.metaproxy.orgA54.36.18.253t08 (Apex)eth1
*.temp-proxy08.metaproxy.orgA54.36.18.253t08 (Wildcard)eth1

6.2 Apache VirtualHost con SSL Reverse Proxy

Implementado en deploy/apache/metaproxy-wildcard.conf:

6.3 Automatización de Certificados con Certbot (DNS-01 GoDaddy)

Para certificados comodín, MetaProxy utiliza el desafío DNS-01 mediante deploy/certbot/obtain-wildcard.sh:

certbot certonly \
  --dns-godaddy \
  --dns-godaddy-credentials /etc/letsencrypt/godaddy.ini \
  --dns-godaddy-propagation-seconds 60 \
  -d "$DOM" -d "*.$DOM" \
  --non-interactive --agree-tos -m "soporte@metabiblioteca.com.co" \
  --deploy-hook "/bin/systemctl reload metaproxy-runtime@$TENANT.service"

Los certificados emitidos se sincronizan en /var/lib/metaproxy/<tenant>/tls/ con permisos 0640/0600.

6.4 Estrategia de Fallback TLS On-Demand y Autofirmado

Para entornos de staging, pruebas de laboratorio o contingencias en la API de DNS:

7. Comandos de Operación y Administración

# Iniciar servicio de runtime para un tenant
systemctl start metaproxy-runtime@t07.service

# Recargar configuración y certificados en caliente (sin corte)
systemctl reload metaproxy-runtime@t07.service

# Recargar servidor Apache
systemctl reload apache2

# Validar catálogo de perfiles offline con mpctl
./bin/mpctl validate -d profiles ebsco sciencedirect springer jstor proquest

# Iniciar servidor de administración y panel web
./bin/metaproxy-admin -listen 0.0.0.0:9443 -profiles profiles -tenants deploy/tenants