Skip to content
GitHub

Networking

Documentación de la configuración de red y comunicación entre componentes del ecosistema Nostromo.


Internet
[Nginx Proxy - Port 80/443]
[Sevastopol Frontend - Port 4321]
↓ API calls
[Orchestrator Backend - Port 8000]
↓ DB queries
[Mother (PostgreSQL) - Port 5432]

Diagrama Mermaid:

graph TB
    Internet([Internet])
    Nginx[Nginx Reverse Proxy<br/>:80, :443]
    Sevastopol[Sevastopol Frontend<br/>:4321]
    Orchestrator[Orchestrator Backend<br/>:8000]
    Mother[Mother PostgreSQL<br/>:5432]
    ETL[ETL Service Python<br/>N/A]

    Internet --> Nginx
    Nginx --> Sevastopol
    Sevastopol --> Orchestrator
    Orchestrator --> Mother
    ETL --> Mother

    style Internet fill:#e1f5ff
    style Nginx fill:#ff9999
    style Sevastopol fill:#99ccff
    style Orchestrator fill:#99ff99
    style Mother fill:#ffcc99
    style ETL fill:#cc99ff

ComponentInternal IPExternal IPHostname
Nginx Proxy<INTERNAL_IP_NGINX><EXTERNAL_IP>app.nostromo.cl
Sevastopol<INTERNAL_IP_SEVASTOPOL>N/Asevastopol.internal
Orchestrator<INTERNAL_IP_ORCHESTRATOR>N/Aorchestrator.internal
Mother (PostgreSQL)<INTERNAL_IP_MOTHER>N/Amother.internal
ETL Service<INTERNAL_IP_ETL>N/Aetl.internal
ComponentIPPort
Sevastopollocalhost4321
Orchestratorlocalhost8000
PostgreSQLlocalhost5432

PortProtocolServiceDescription
80HTTPNginxHTTP redirect a HTTPS
443HTTPSNginxFrontend (Sevastopol) público
PortProtocolServiceDescription
4321HTTPSevastopolAstro dev server (dev) / Nginx upstream (prod)
8000HTTPOrchestratorNode.js API backend
5432TCPPostgreSQLDatabase connections
22SSHServerAdmin access

SourceDestinationPortActionRule
0.0.0.0/0Nginx80ALLOWPublic HTTP
0.0.0.0/0Nginx443ALLOWPublic HTTPS
<ADMIN_IPS>Server22ALLOWSSH admin access
*Orchestrator8000DENYBackend NO público
*PostgreSQL5432DENYDB NO pública
SourceDestinationPortActionRule
OrchestratorMother (PostgreSQL)5432ALLOWDB queries
ETL ServiceMother (PostgreSQL)5432ALLOWData ingestion
SevastopolOrchestrator8000ALLOWAPI calls
ServerInternet80/443ALLOWPackage downloads, updates
OrchestratorSII Websites443ALLOWETL scraping (si aplicable)

Domain: nostromo.cl

Nameservers:

  • ns1.cloudflare.com
  • ns2.cloudflare.com
SubdomainTypeValueTTLDescription
appA<EXTERNAL_IP>300Frontend público
apiCNAMEapp.nostromo.cl300API endpoint (mismo servidor)
wwwCNAMEapp.nostromo.cl300Redirect a app

Cloudflare Settings:

  • ✅ Proxy enabled (orange cloud)
  • ✅ SSL/TLS: Full (strict)
  • ✅ Always Use HTTPS: ON

Provider: Let’s Encrypt (auto-renew via Certbot)

Certificate Path:

/etc/letsencrypt/live/app.nostromo.cl/fullchain.pem
/etc/letsencrypt/live/app.nostromo.cl/privkey.pem

Renewal:

Terminal window
# Auto-renewal via cron (runs daily)
0 0 * * * certbot renew --quiet

Verify cert:

Terminal window
openssl x509 -in /etc/letsencrypt/live/app.nostromo.cl/fullchain.pem \
-text -noout | grep "Not After"

Estado actual: NO implementado - single server setup.

Futuro (si escala):

  • Nginx como load balancer entre múltiples nodos Orchestrator
  • Sticky sessions para mantener tenant context
  • Health checks: GET /health endpoint

Status: Recomendado para producción, pero actualmente NO implementado.

Mejora futura: Mover servicios internos (Orchestrator, Mother) a VPC privada.


Key-based authentication ONLY (password auth disabled).

Authorized Keys: /home/user/.ssh/authorized_keys

Restrict SSH:

/etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Nginx rate limiting (previene DDoS):

/etc/nginx/nginx.conf
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://localhost:8000;
}
}

Limits:

  • 10 requests/second per IP
  • Burst up to 20 requests

Tool: Grafana + Prometheus

Métricas:

  • Request/second por endpoint
  • Response time (p50, p95, p99)
  • Error rate (4xx, 5xx)
  • Bandwidth usage

Configuración:

  • Alert si error rate > 5% por 5 minutos
  • Alert si response time p95 > 1000ms
  • Alert si Orchestrator unreachable (health check fails)

Síntoma: fetch('http://localhost:8000/api/...') fails with ECONNREFUSED

Debugging:

Terminal window
# Verify Orchestrator is running
pm2 status orchestrator
# Verify port 8000 is listening
lsof -i :8000
# Verify firewall allows internal traffic
sudo iptables -L -n | grep 8000

Síntoma: ERR_CERT_DATE_INVALID en browser.

Fix:

Terminal window
# Renew cert manually
sudo certbot renew
# Reload Nginx
sudo systemctl reload nginx


FechaVersionCambios
2026-01-181.0Documentación inicial creada