WIP-0001: Whitebox Network Configuration Specification¶
Introduction¶
This document proposes a standardized network configuration for whitebox development and production environments. The goal is to establish a consistent and predictable network configuration for all running services so that it is easily discoverable regardless of the environment.
Network Topology¶
The network is split into two parts:
- Host Network: This is the network that the client devices would connect to. We will only configure this when we are setting up a dedicated machine for whitebox. While configuring the network, subnet will be set to
10.38.0.0/24
and the DNS server will be set to10.38.128.2
, which will be running on the same machine under the docker network with the subnet being10.38.128.0/17
. More on this later.
When running Whitebox on your local development machine, only the client device IPs will differ from this schema. The internal Docker network structure - including the DNS server (10.38.128.2)
and web-proxy (10.38.128.3)
- will maintain the same IP addresses as defined in this document regardless of your local network configuration. This ensures consistency across all development environments. The only difference will be that your local machine would be updated to point to the DNS server running on the docker network.
- Docker Network: This is the network that all the services will run on. It will have it's own subnet
(10.38.128.0/17)
and DNS server. Each service will be assigned a static IP address within this subnet.
To ensure IP addresses are assigned in a predictable manner, we will reserve a range of IP addresses for each type of service. Example:
Service Type | IP Range |
---|---|
Router | 10.38.128.0/24 |
DB Apps | 10.38.129.0/24 |
Core Apps | 10.38.130.0/24 |
Other Apps | 10.38.131.0/24 |
Besides these IP ranges, other devices like remote cameras might have their own separate IPs and network configurations.
Above, the /24
subnet is for representation purposes only. They are represented as /24
to show that the first 3 octets are fixed and the last octet is variable based on the service type. Other apps may go beyond the /24
range if needed to accommodate more services.
To remember the IP subnet 10.38
, you can think of 38
being the WhiteBox acronym WB
, where 3
represents W
rotated 90 degrees and 8
represents B
.
When configuring a dedicated machine, we will also add a routing rule to the host's routing table to ensure traffic flows between the host and containers.
Note: 10.38.128.1
is assumed to be the default gateway for the docker network. Hence, it was reserved and could not be used for any services as docker will complain that the IP is already in use. DNS service was moved to 10.38.128.2
to avoid this issue. Investigate if 10.38.128.1
could somehow be used for the DNS server.
Docker Network Configuration¶
The docker network will be configured as follows:
networks:
whitebox-net:
name: whitebox-net
driver: bridge
ipam:
config:
- subnet: 10.38.128.0/17
services:
backend:
networks:
whitebox-net:
ipv4_address: 10.38.130.1
dns:
- 10.38.128.2
# ...
# ...
Domain Name Scheme¶
- Domain:
whitebox.local
- Service Subdomains:
- Backend:
backend.whitebox.local
- Frontend:
frontend.whitebox.local
DNS Server¶
For DNS & IP allocation, we use dnsmasq
, which has good ARM support:
dnsmasq.Dockerfile
FROM whitebox-base:latest
COPY packaging/dnsmasq/dnsmasq.conf /etc/dnsmasq.conf
COPY packaging/dnsmasq/dnsmasq.hosts /etc/dnsmasq.hosts
compose.yml
services:
dnsmasq:
build:
context: .
dockerfile: packaging/docker/dnsmasq.Dockerfile
container_name: dnsmasq
restart: unless-stopped
networks:
whitebox-dev-net:
ipv4_address: 10.38.128.2
cap_add:
- NET_ADMIN
dnsmasq.conf
# Listen on all interfaces
interface=*
# Don't use /etc/resolv.conf
no-resolv
# Set default domain
domain=whitebox.local
# Forward non-local queries to Quad9 DNS servers
server=9.9.9.9
server=9.9.9.10
# Don't forward reverse lookups for private IPs
bogus-priv
# Don't forward queries for plain names
domain-needed
# Add hosts from the hosts file
addn-hosts=/etc/dnsmasq.hosts
# Cache settings
cache-size=1000
local-ttl=3600
# Listen on all available addresses
listen-address=0.0.0.0
# Log to stdout for debugging
log-queries
log-facility=/var/log/dnsmasq.log
# CNAME Records
cname=whitebox.local,web-proxy.whitebox.local
cname=api.whitebox.local,web-proxy.whitebox.local
dnsmasq.hosts
10.38.128.2 router.whitebox.local
10.38.128.3 web-proxy.whitebox.local
; ... other services to expose via the web proxy
10.38.130.1 backend.whitebox.local
10.38.130.2 frontend.whitebox.local
; ... each service will have its own entry for internal usage within the docker network
Routing¶
The DNS server (dnsmasq) will resolve domain names like whitebox.local
and api.whitebox.local
to the web proxy's IP address (10.38.128.3). When client devices make requests to these domains, they'll be directed to the web proxy (nginx).
The nginx web proxy will then act as a reverse proxy, forwarding these requests to the appropriate internal services based on the domain name used. For example:
- Requests to
whitebox.local
will be forwarded to the frontend app running at 10.38.130.2:80 - Requests to
api.whitebox.local
will be forwarded to the API service running at 10.38.130.1:80
Note: Services like frontend and backend will be exposed on port 80 within the container and will only be accessible via the web proxy as a standard practice.
nginx.Dockerfile
FROM whitebox-base:latest
COPY packaging/nginx/nginx.conf /etc/nginx/nginx.conf
COPY packaging/nginx/conf.d /etc/nginx/conf.d
compose.yml
services:
nginx:
build:
context: .
dockerfile: packaging/docker/nginx.Dockerfile
container_name: nginx-proxy
restart: unless-stopped
networks:
whitebox-dev-net:
ipv4_address: 10.38.128.3
depends_on:
- dnsmasq
default.conf
# Default server that will just close the connection for unmatched hosts
server {
listen 80 default_server;
server_name _;
return 444;
}
# api.whitebox.local
server {
listen 80;
server_name api.whitebox.local api;
location / {
proxy_pass http://10.38.130.1:80;
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 $scheme;
}
}
# whitebox.local
server {
listen 80;
server_name whitebox.local;
location / {
proxy_pass http://10.38.130.2:80;
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 $scheme;
}
}
# ...
Additionally, each whitebox unit will have its own unique subdomain, e.g. john.whitebox.aero
, which will be resolved to different locations based on the context:
- Locally:
john.whitebox.aero
will resolve to10.38.128.3
(web-proxy.whitebox.local) and proxy requests to the frontend app. - Remotely:
john.whitebox.aero
will resolve to the web server hosted on the internet, which would proxy to the frontend app running on the whitebox unit when connected to the internet. Or maybe to cached backup version in the cloud when the whitebox unit is offline.