Skip to content

feat: egress.mode (open/observe/enforce) + NetworkPolicy — firewall de egress (it.2)#85

Merged
az-adhoc merged 10 commits into
mainfrom
feat/egress-mode-iteration2
Jun 25, 2026
Merged

feat: egress.mode (open/observe/enforce) + NetworkPolicy — firewall de egress (it.2)#85
az-adhoc merged 10 commits into
mainfrom
feat/egress-mode-iteration2

Conversation

@az-adhoc

Copy link
Copy Markdown
Contributor

Qué

Implementa la iteración 2 del egress (spec ingadhoc/devops-project it.2, PR #17). Enum ingress.istio.egress.mode resuelto por el helper adhoc-odoo.egressMode.

Modo Sidecar Recursos
open ALLOW_ANY nada
observe (default con istio) ALLOW_ANY tls_inspector EnvoyFilter + Telemetry egress (logging con SNI)
enforce REGISTRY_ONLY allowedHosts/bannedHosts (ServiceEntry+VS+AuthorizationPolicy ALLOW/DENY) + NetworkPolicy de egress + logging heredado

Validado: render de los 3 modos correcto (NetworkPolicy solo en enforce, sidecar policy según modo, listas solo en enforce).

Compatibilidad

Helper de precedencia: egress.mode explícito > blockOutboundTraffic→enforce > logEgress→observe > istio.enabledobserve > open. Tenants con flags legacy no cambian.

⚠️ Cambios de comportamiento a revisar

  • Default observe con istio habilitado: los tenants Istio sin flags empiezan a loguear egress en el próximo deploy (no bloquean; suma volumen a Cloud Logging — ver medición pendiente spec 0007).
  • adhoc.dnsBannedHost eliminado (template /etc/hosts borrado) → reemplazado por bannedHosts (DENY Istio, modo enforce). Si algún tenant lo usaba, migrar a bannedHosts.
  • Sin bump de versión (decisión vigente del chart). Si preferís bump por estos cambios de comportamiento, avisá.

"Istio única salida" + no-TLS

  • REGISTRY_ONLY bloquea el no-TLS en el sidecar (protocol-agnostic; solo declaramos 443).
  • La NetworkPolicy deniega salida directa a Internet desde TODOS los pods (incluido PG, que no tiene sidecar) salvo kube-dns / istio-system / intra-ns / metadata server (169.254.169.254) + CIDRs configurables (egress.networkPolicy.allow). Defensa en profundidad.

Supersede #84

Incluye las listas blanca/negra + el fix de la regla ALLOW (from+to) de #84#84 queda superseded (cerrar).

Pendiente (no en este PR)

Validar enforce en un tenant de test (bloqueo no-TLS, host no permitido, PG sin Internet directo); afinar la allow-list de la NetworkPolicy con deps reales (redis cluster-level, etc.).

Spec it.2: ingadhoc/devops-project#17.

az-adhoc added 3 commits June 25, 2026 09:18
…gEgress y dnsBannedHost

Implementa la iteración 2 del egress (spec devops-project it.2). Enum
ingress.istio.egress.mode resuelto por helper egressMode con compatibilidad:
egress.mode explícito > blockOutboundTraffic→enforce > logEgress→observe >
istio.enabled→observe (default) > open.

- open: ALLOW_ANY, sin logging ni bloqueo.
- observe (default con istio): ALLOW_ANY + tls_inspector + Telemetry egress.
- enforce: REGISTRY_ONLY + allowedHosts/bannedHosts (AuthorizationPolicy) +
  NetworkPolicy de egress (deniega Internet directo salvo kube-dns/istio-system/
  intra-ns/metadata server + CIDRs de values) → Istio única salida, no-TLS bloqueado.
  Hereda el logging de observe.

Incluye y supersede #84 (listas blanca/negra + fix regla ALLOW from+to).
Deprecados (compat): logEgress, blockOutboundTraffic. Eliminado adhoc.dnsBannedHost
(/etc/hosts) → reemplazado por bannedHosts (DENY Istio). Sin bump de versión.
…erver

Validado en test-grittiagrimensura-23-06-2 (cluster01) con un pod no-meshed:
- En GKE el pod resuelve vía NodeLocal DNSCache (169.254.20.10, link-local), no el
  ClusterIP de kube-dns → el namespaceSelector de kube-system no lo cubre y enforce
  rompía TODO el DNS. Se agrega 169.254.20.10/32:53 a los baked-in.
- El API server (control plane) lo necesita el instance manager de CNPG (pod PG);
  su IP es por-cluster → va en egress.networkPolicy.allow (documentado). Con él,
  CNPG quedó sano bajo la policy.
Confirmado: el pod no-meshed no sale a Internet directo (TCP timeout) pero DNS y
API server OK → Istio única salida.
Tras validar enforce en un tenant de test:
- Quita el ruteo por el egress gateway (VirtualService + AuthorizationPolicy):
  el patrón TLS-passthrough no funcionaba (sidecar iba directo / hop se reseteaba).
  El allow-list ahora es solo ServiceEntry + REGISTRY_ONLY (sidecar sale directo).
- Sidecar scope (enforce) suma los namespaces cluster-level que Odoo usa
  cross-namespace (adhoc-redis, adhoc-aeroo-docs, kwkhtmltopdf), configurables
  en egress.meshExternalNamespaces; sin esto REGISTRY_ONLY los bloqueaba.
- NetworkPolicy: allow-private (RFC1918 + link-local, cubre API server/NodeLocal
  DNS/metadata/in-cluster), deny público; aplica SOLO a pods no-meshed (PG/jobs)
  vía podSelector security.istio.io/tlsMode DoesNotExist. Odoo lo controla el sidecar.
- bannedHosts diferido (su mecanismo era el AuthorizationPolicy DENY del gateway);
  el whitelist es deny-by-default. Follow-up: blacklist por sidecar EnvoyFilter.
El egress gateway queda sin uso para egress → removible (Pulumi, follow-up).
az-adhoc added 7 commits June 25, 2026 12:02
…iew Codex P1)

Al borrar dnsBannedHost.yaml + el value, el Deployment seguía montando el ConfigMap
{{fullname}}-hosts gateado en adhoc.dnsBannedHost. Con helm upgrade --reuse-values
(el default era una lista no vacía) el pod referenciaba un ConfigMap inexistente y el
rollout fallaba. Se remueve el volumeMount (/etc/hosts) y el volume → deprecación limpia.
… $extra

El `{{- $extra -}}` entre el comentario y apiVersion comía los newlines →
'apiVersion not set' al aplicar. Se mueve la asignación arriba del bloque (una sola
vez, tras el if). Detectado en la validación con helm sobre cluster01.
…ustom

Las instancias con odoo.entrypoint.repos clonan addons por PR en el boot; bajo
REGISTRY_ONLY github quedaba bloqueado y el arranque fallaba. Ahora
ingress.istio.egress.repoHosts (default trío github, sobreescribible) se agrega a la
whitelist solo cuando entrypoint.repos no está vacío. El default vive en el template
para que aplique también con helm upgrade --reuse-values. Aditivo/opt-in, sin bump.
…s templates

El rationale (modos, capas de bloqueo, logging, gotchas: NodeLocal DNS, CNPG,
reuse-values) pasa a charts/adhoc-odoo/doc/egress.md, linkeado desde el readme. Los
templates de in-istio y values.yaml quedan con comentarios mínimos (mecánica no obvia)
y apuntan al doc. Sin cambios de comportamiento.
…e-values

Un tenant Istio existente actualizado con helm upgrade --reuse-values no tiene la
subclave ingress.istio.egress, y el range directo abortaba con nil pointer. Se guarda
con default dict + el default de namespaces baked-in en el template (redis, aeroo,
kwkhtmltopdf), igual que repoHosts.
…erve

questions.yml ofrecía solo open/observe/enforce con default ''. Un select sin opción
vacía puede mandar un valor explícito (open) aunque el usuario no lo toque y, como el
helper da precedencia al modo explícito, anularía el default observe / el flag legacy.
Se agrega '' como primera opción.
Quita el doc/egress.md mal ubicado dentro del chart. La referencia de config de egress
(modos, values, repoHosts, NetworkPolicy) pasa a doc/adhoc-odoo.md: se actualiza la
sección Istio del values, se agrega 'Egress control' y se saca el dnsBannedHost stale.
Los comentarios de los templates apuntan a doc/adhoc-odoo.md.
@az-adhoc az-adhoc merged commit 25e0468 into main Jun 25, 2026
3 checks passed
@az-adhoc az-adhoc deleted the feat/egress-mode-iteration2 branch June 25, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant