Environment_Infrastructure/setup/01-private-network-port-matrix.md
Murat ÖZDEMİR 67dc2986dd docs(infra): restructure and update infrastructure setup documentation
- Anglicized setup and facts markdown file names for better consistency.

- Updated 01-swarm-init-multinode.md to highlight Ansible automation of Swarm initialization and labeling.

- Overhauled 03-infra-stack-changes.md to describe the single monolithic file strategy and reflect current Redis, RabbitMQ, and etcd cluster configurations.

- Fixed minor overrides and typos in Patroni templates and Ansible bootstrap documents.

- Restructured README and roadmap mapping to align with the renamed setup documents.
2026-06-15 16:42:18 +03:00

8.0 KiB

01 - Private Network Port Matrix

This file defines the ports that must be opened inside the Hetzner private network for test and prod environments. Public ingress is limited to 22/tcp, 80/tcp, and 443/tcp, with one current test-only exception: 51820/udp is public on the test DB node for WireGuard. Vault 8200/tcp will not be opened publicly.

This matrix must be treated as the source for Terraform Hetzner firewall and Ansible firewalld rules.

Network Plan

Test

Subnet CIDR Purpose
App/Swarm 10.10.10.0/24 iklim-app-01
DB 10.10.20.0/24 iklim-db-01

Prod

Subnet CIDR Purpose
App/Swarm 10.20.10.0/24 iklim-app-01/02/03
DB 10.20.20.0/24 iklim-db-01/02/03

Public Ingress Standard

Public ingress:

Port Protocol Source Target Requirement
22 TCP Admin IP/CIDR All nodes SSH management
80 TCP Internet iklim-app-01 (gateway) HTTP / ACME redirect
443 TCP Internet iklim-app-01 (gateway) HTTPS
51820 UDP 0.0.0.0/0, ::/0 iklim-db-01 in test only WireGuard VPN — authentication with cryptographic key

Critical ports that will not be opened publicly:

Port Service
8200/tcp Vault
5432/tcp PostgreSQL
27017/tcp MongoDB
6379/tcp Redis
5672/tcp, 15672/tcp, 61613/tcp, 15674/tcp RabbitMQ
2377/tcp, 7946/tcp, 7946/udp, 4789/udp Docker Swarm
9180/tcp APISIX Admin API
9090/tcp Prometheus
3000/tcp Grafana

Docker Swarm Private Ports

Required ports between Docker Swarm nodes:

Port Protocol Source Target Description
2377 TCP Swarm nodes Swarm manager nodes Swarm control plane / join
7946 TCP All Swarm nodes All Swarm nodes Node discovery / gossip
7946 UDP All Swarm nodes All Swarm nodes Node discovery / gossip
4789 UDP All Swarm nodes All Swarm nodes Overlay VXLAN data path

In test, these ports are effectively required for a single Swarm node, but they can be defined inside the app subnet to make adding workers easier later.

In prod, these ports must be open between all iklim-app-* nodes inside the 10.20.10.0/24 app/swarm subnet.

Source: Docker overlay network documentation, https://docs.docker.com/engine/network/drivers/overlay/

Application and Infra Service Private Ports

These ports will not be opened publicly. Access will be allowed only from required sources inside the private network or Docker overlay.

Port Protocol Service Source Target Note
8200 TCP Vault API/UI Swarm app nodes / runner Vault service/node Public closed. Runtime services must reach Vault through private/overlay
6379 TCP Redis Swarm app nodes Redis service/node Public closed
5672 TCP RabbitMQ AMQP Swarm app nodes RabbitMQ service/node Public closed
15672 TCP RabbitMQ Management Admin CIDR or private ops RabbitMQ service/node Public closed; preferably VPN/bastion
61613 TCP RabbitMQ STOMP Required app nodes RabbitMQ service/node Public closed
15674 TCP RabbitMQ Web STOMP Required app/gateway nodes RabbitMQ service/node Public closed
2379 TCP etcd client APISIX service/node etcd service/node Public closed
2380 TCP etcd peer etcd cluster nodes etcd cluster nodes May not be needed for a single replica; required if clustered
9180 TCP APISIX Admin API Admin CIDR or private ops APISIX service/node Public closed
9090 TCP Prometheus UI/API Admin CIDR or private ops Prometheus service/node Public closed
3000 TCP Grafana UI Admin CIDR or private ops Grafana service/node Public closed

The current prod root stack is docker-stack-infra_db-prod.yml; Vault is deployed separately with docker-stack-vault.yml through vault-bootstrap.sh. Public traffic is expected to enter through SWAG on 80/443. Private service reachability is provided by the iklimco-net overlay and by the explicit host-mode DB/cluster ports listed below.

DB Node Ports

DB runtime services are deployed as Docker Swarm services. Prod currently uses Patroni/PostgreSQL, etcd, and a MongoDB replica set in docker-stack-infra_db-prod.yml; the required firewall ports are below.

PostgreSQL / PostGIS (Patroni + etcd)

The prod environment uses PostgreSQL managed with Patroni + etcd. In the test environment, replication and HA ports are not required because there is a single node.

Port Protocol Source Target Note
5432 TCP App/Swarm subnet PostgreSQL nodes (Patroni-managed) Application JDBC — connects to all nodes, driver finds the primary
5432 TCP DB subnet PostgreSQL nodes Patroni replication (pg_basebackup and WAL streaming)
8008 TCP DB subnet PostgreSQL nodes Patroni REST API — leader election, health check
2379 TCP DB subnet etcd nodes etcd client — Patroni -> etcd access
2380 TCP DB subnet etcd nodes etcd peer — raft protocol inside the etcd cluster

MongoDB

Port Protocol Source Target Note
27017 TCP App/Swarm subnet MongoDB node/replica set endpoint Application DB connection
27017 TCP DB subnet MongoDB replica set nodes Replica set internal traffic

If sharding is added later, additional MongoDB roles such as 27018/27019 may come up; they will not be opened at this stage.

Test Private Rules

Minimum for the test environment:

Source Target Ports
10.10.10.0/24 10.10.10.0/24 2377/tcp, 7946/tcp, 7946/udp, 4789/udp
10.10.10.0/24 10.10.20.0/24 5432/tcp, 27017/tcp
10.10.10.0/24 10.10.10.0/24 8200/tcp, 6379/tcp, 5672/tcp, 61613/tcp, 15674/tcp
Admin CIDR or VPN 10.10.10.0/24 9000/tcp, 15672/tcp, 9180/tcp, 9090/tcp, 3000/tcp

Because the DB node is single-node in test, PostgreSQL/MongoDB replication ports inside the DB subnet may not be actively used.

Prod Private Rules

Minimum for the prod environment, including Patroni + etcd:

App subnet (swarm firewall) — traffic inside itself:

Source Target Ports
10.20.10.0/24 10.20.10.0/24 2377/tcp, 7946/tcp, 7946/udp, 4789/udp (Swarm)
10.20.10.0/24 10.20.10.0/24 8200/tcp, 5672/tcp, 61613/tcp, 15674/tcp (application services)
Admin CIDR or VPN 10.20.10.0/24 15672/tcp, 9180/tcp, 9090/tcp, 3000/tcp

App -> DB traffic (there is no related rule in the swarm firewall; it is allowed in the db firewall):

Source Target Ports
10.20.10.0/24 10.20.20.0/24 5432/tcp, 27017/tcp (DB access)
10.20.10.0/24 10.20.20.0/24 2377/tcp, 7946/tcp, 7946/udp, 4789/udp (Swarm — DB worker join)

DB subnet (db firewall) — traffic between DB nodes:

Source Target Ports
10.20.20.0/24 10.20.20.0/24 5432/tcp, 27017/tcp (DB replication)
10.20.20.0/24 10.20.20.0/24 2379/tcp, 2380/tcp (etcd client/peer)
10.20.20.0/24 10.20.20.0/24 8008/tcp (Patroni REST API)

DB -> App traffic (allowed in the swarm firewall):

Source Target Ports
10.20.20.0/24 10.20.10.0/24 2377/tcp, 7946/tcp, 7946/udp, 4789/udp (Swarm — manager ports)

Acceptance Criteria

  • The public firewall does not open 8200/tcp.
  • DB ports are not open publicly.
  • Swarm ports are open only between Swarm app and DB subnets.
  • The App/Swarm subnet reaches the DB subnet only through required DB ports.
  • The DB subnet is not opened to the app subnet with broad permissions.
  • Admin UI ports are restricted through admin CIDR/VPN/private ops instead of public access.