mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
feat(docker): Add iperf3 testing, config templating, and test improvements
Docker testing infrastructure: - Add iperf3 bandwidth testing (10s duration, 8 parallel streams) - Install iperf3 in container, auto-start as daemon alongside FIPS - Support --live flag for real-time iperf3 output during tests - Aggregate [SUM] bandwidth reporting with correct units Configuration templating system: - Single node.template.yaml replacing per-node hand-written configs - Topology definitions in configs/topologies/ (mesh.yaml, chain.yaml) - generate-configs.sh script for automatic config generation - Integrated into build.sh for regeneration on build - Generated configs in generated-configs/ (gitignored) Ping test improvements: - Reduce to 1 ping per test for faster execution (~10s vs ~30s) - Show response times (RTT) for each test - Add Ctrl+C trap for clean exit - Reduce convergence wait from 5s to 3s
This commit is contained in:
committed by
Johnathan Corgan
parent
d46dc874ef
commit
68b9652aa9
@@ -1 +1,2 @@
|
||||
fips
|
||||
generated-configs
|
||||
@@ -2,7 +2,7 @@ FROM debian:bookworm-slim
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
iproute2 iputils-ping dnsutils openssh-client openssh-server && \
|
||||
iproute2 iputils-ping dnsutils openssh-client openssh-server iperf3 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Setup SSH server with no authentication (test only!)
|
||||
@@ -16,5 +16,5 @@ RUN mkdir -p /var/run/sshd && \
|
||||
COPY fips /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/fips
|
||||
|
||||
# Start SSH server in background, then run FIPS
|
||||
ENTRYPOINT ["/bin/bash", "-c", "/usr/sbin/sshd && exec fips --config /etc/fips/fips.yaml"]
|
||||
# Start SSH server and iperf3 server in background, then run FIPS
|
||||
ENTRYPOINT ["/bin/bash", "-c", "/usr/sbin/sshd && iperf3 -s -D && exec fips --config /etc/fips/fips.yaml"]
|
||||
|
||||
@@ -24,7 +24,8 @@ Build the binary and copy it to the docker context:
|
||||
```bash
|
||||
docker compose --profile mesh build
|
||||
docker compose --profile mesh up -d
|
||||
./scripts/ping-test.sh mesh # 20/20 expected
|
||||
./scripts/ping-test.sh mesh # 20/20 expected (with response times)
|
||||
./scripts/iperf-test.sh mesh # bandwidth test
|
||||
docker compose --profile mesh down
|
||||
```
|
||||
|
||||
@@ -33,7 +34,8 @@ docker compose --profile mesh down
|
||||
```bash
|
||||
docker compose --profile chain build
|
||||
docker compose --profile chain up -d
|
||||
./scripts/ping-test.sh chain # 6/6 expected
|
||||
./scripts/ping-test.sh chain # 6/6 expected (with response times)
|
||||
./scripts/iperf-test.sh chain # bandwidth test
|
||||
docker compose --profile chain down
|
||||
```
|
||||
|
||||
@@ -75,6 +77,68 @@ The ping test covers:
|
||||
- Multi-hop: A→C (2 hops), A→D (3 hops), A→E (4 hops)
|
||||
- Reverse: E→A (4 hops)
|
||||
|
||||
## Performance Testing
|
||||
|
||||
The `iperf-test.sh` script measures bandwidth between nodes using iperf3:
|
||||
|
||||
```bash
|
||||
./scripts/iperf-test.sh [mesh|chain]
|
||||
```
|
||||
|
||||
The test runs iperf3 with the following parameters:
|
||||
- Duration: 10 seconds (`-t 10`)
|
||||
- Parallel streams: 8 (`-P 8`)
|
||||
- Protocol: TCP over IPv6
|
||||
|
||||
This exercises the full FIPS stack including encryption, routing, and TUN device performance.
|
||||
|
||||
## Configuration Management
|
||||
|
||||
Node configurations are generated from templates to ensure consistency across all nodes:
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
configs/
|
||||
├── node.template.yaml # Single template for all node configs
|
||||
├── topologies/
|
||||
│ ├── mesh.yaml # Mesh topology definition (reference)
|
||||
│ └── chain.yaml # Chain topology definition (reference)
|
||||
└── [mesh|chain]/ # Original hand-written configs (deprecated)
|
||||
|
||||
generated-configs/ # Auto-generated configs (gitignored)
|
||||
├── mesh/
|
||||
│ ├── node-a.yaml
|
||||
│ ├── node-b.yaml
|
||||
│ └── ...
|
||||
└── chain/
|
||||
├── node-a.yaml
|
||||
└── ...
|
||||
```
|
||||
|
||||
### Topology Files
|
||||
|
||||
The `configs/topologies/` directory contains YAML files documenting each network topology:
|
||||
- Node identities (nsec, npub)
|
||||
- Docker IP addresses
|
||||
- Peer connections for each node
|
||||
|
||||
These files serve as reference documentation and make it easy to understand and modify network topologies.
|
||||
|
||||
### Generating Configs
|
||||
|
||||
The `scripts/generate-configs.sh` script reads the topology definitions (embedded in the script) and generates node configs into `generated-configs/`:
|
||||
|
||||
```bash
|
||||
./scripts/generate-configs.sh [mesh|chain|all]
|
||||
```
|
||||
|
||||
The build script (`scripts/build.sh`) automatically regenerates configs before building Docker images.
|
||||
|
||||
### Modifying Topologies
|
||||
|
||||
To change network topologies, edit the `get_mesh_peers()` or `get_chain_peers()` functions in `generate-configs.sh`, then update the corresponding YAML file in `configs/topologies/` for documentation.
|
||||
|
||||
## Node Identities
|
||||
|
||||
All nodes use deterministic test keys (not for production use).
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# FIPS Node A configuration (chain topology: A-B-C-D-E)
|
||||
#
|
||||
# Identity: npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m
|
||||
# FIPS address: fd69:e08d:65cc:3a6b:9c2c:2ac4:bd40:5e4b
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le"
|
||||
alias: "node-b"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.11:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,37 +0,0 @@
|
||||
# FIPS Node B configuration (chain topology: A-B-C-D-E)
|
||||
#
|
||||
# Identity: npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le
|
||||
# FIPS address: fd8e:302c:287e:b48d:6268:122f:da76:b77
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "b102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fb0"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m"
|
||||
alias: "node-a"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.10:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6"
|
||||
alias: "node-c"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.12:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,37 +0,0 @@
|
||||
# FIPS Node C configuration (chain topology: A-B-C-D-E)
|
||||
#
|
||||
# Identity: npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6
|
||||
# FIPS address: fdac:a221:4069:5044:c41:d550:280e:d15a
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "c102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fc0"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le"
|
||||
alias: "node-b"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.11:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl"
|
||||
alias: "node-d"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.13:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,37 +0,0 @@
|
||||
# FIPS Node D configuration (chain topology: A-B-C-D-E)
|
||||
#
|
||||
# Identity: npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl
|
||||
# FIPS address: fdb6:8411:a191:6d48:efc6:b8bd:63bb:1cd7
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "d102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fd0"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6"
|
||||
alias: "node-c"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.12:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4"
|
||||
alias: "node-e"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.14:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,31 +0,0 @@
|
||||
# FIPS Node E configuration (chain topology: A-B-C-D-E)
|
||||
#
|
||||
# Identity: npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4
|
||||
# FIPS address: fded:7dee:d386:a546:2a43:5103:16d8:4f3c
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "e102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fe0"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl"
|
||||
alias: "node-d"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.13:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,37 +0,0 @@
|
||||
# FIPS Node A configuration (mesh topology)
|
||||
#
|
||||
# Identity: npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m
|
||||
# FIPS address: fd69:e08d:65cc:3a6b:9c2c:2ac4:bd40:5e4b
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl"
|
||||
alias: "node-d"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.13:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4"
|
||||
alias: "node-e"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.14:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,31 +0,0 @@
|
||||
# FIPS Node B configuration (mesh topology)
|
||||
#
|
||||
# Identity: npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le
|
||||
# FIPS address: fd8e:302c:287e:b48d:6268:122f:da76:b77
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "b102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fb0"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6"
|
||||
alias: "node-c"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.12:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,43 +0,0 @@
|
||||
# FIPS Node C configuration (mesh topology)
|
||||
#
|
||||
# Identity: npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6
|
||||
# FIPS address: fdac:a221:4069:5044:c41:d550:280e:d15a
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "c102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fc0"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le"
|
||||
alias: "node-b"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.11:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl"
|
||||
alias: "node-d"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.13:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4"
|
||||
alias: "node-e"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.14:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,43 +0,0 @@
|
||||
# FIPS Node D configuration (mesh topology)
|
||||
#
|
||||
# Identity: npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl
|
||||
# FIPS address: fdb6:8411:a191:6d48:efc6:b8bd:63bb:1cd7
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "d102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fd0"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m"
|
||||
alias: "node-a"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.10:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6"
|
||||
alias: "node-c"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.12:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4"
|
||||
alias: "node-e"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.14:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -1,43 +0,0 @@
|
||||
# FIPS Node E configuration (mesh topology)
|
||||
#
|
||||
# Identity: npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4
|
||||
# FIPS address: fded:7dee:d386:a546:2a43:5103:16d8:4f3c
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "e102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fe0"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
- npub: "npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m"
|
||||
alias: "node-a"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.10:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6"
|
||||
alias: "node-c"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.12:4000"
|
||||
connect_policy: auto_connect
|
||||
- npub: "npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl"
|
||||
alias: "node-d"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "172.20.0.13:4000"
|
||||
connect_policy: auto_connect
|
||||
@@ -0,0 +1,25 @@
|
||||
# FIPS Node {{NODE_NAME}} configuration ({{TOPOLOGY}} topology)
|
||||
#
|
||||
# Identity: {{NPUB}}
|
||||
|
||||
node:
|
||||
identity:
|
||||
nsec: "{{NSEC}}"
|
||||
|
||||
tun:
|
||||
enabled: true
|
||||
name: fips0
|
||||
mtu: 1280
|
||||
|
||||
dns:
|
||||
enabled: true
|
||||
bind_addr: "127.0.0.1"
|
||||
port: 53
|
||||
|
||||
transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:4000"
|
||||
mtu: 1472
|
||||
|
||||
peers:
|
||||
{{PEERS}}
|
||||
@@ -0,0 +1,42 @@
|
||||
# Chain Topology Definition
|
||||
#
|
||||
# Five nodes in a linear chain: A — B — C — D — E
|
||||
# Each node peers only with its immediate neighbors. Multi-hop communication
|
||||
# (e.g., A to E) requires the discovery protocol to find routes through
|
||||
# intermediate nodes.
|
||||
|
||||
nodes:
|
||||
a:
|
||||
nsec: "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
|
||||
npub: "npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m"
|
||||
docker_ip: "172.20.0.10"
|
||||
peers: [b]
|
||||
|
||||
b:
|
||||
nsec: "b102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fb0"
|
||||
npub: "npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le"
|
||||
docker_ip: "172.20.0.11"
|
||||
peers: [a, c]
|
||||
|
||||
c:
|
||||
nsec: "c102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fc0"
|
||||
npub: "npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6"
|
||||
docker_ip: "172.20.0.12"
|
||||
peers: [b, d]
|
||||
|
||||
d:
|
||||
nsec: "d102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fd0"
|
||||
npub: "npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl"
|
||||
docker_ip: "172.20.0.13"
|
||||
peers: [c, e]
|
||||
|
||||
e:
|
||||
nsec: "e102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fe0"
|
||||
npub: "npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4"
|
||||
docker_ip: "172.20.0.14"
|
||||
peers: [d]
|
||||
|
||||
# Test Coverage:
|
||||
# - Adjacent hops: A→B, B→C (1 hop each)
|
||||
# - Multi-hop: A→C (2 hops), A→D (3 hops), A→E (4 hops)
|
||||
# - Reverse: E→A (4 hops)
|
||||
@@ -0,0 +1,44 @@
|
||||
# Mesh Topology Definition
|
||||
#
|
||||
# Five nodes with 6 bidirectional UDP links forming a sparse, fully connected
|
||||
# graph. Not all nodes are direct peers — non-adjacent pairs require
|
||||
# discovery-driven multi-hop routing to establish end-to-end sessions.
|
||||
|
||||
nodes:
|
||||
a:
|
||||
nsec: "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
|
||||
npub: "npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m"
|
||||
docker_ip: "172.20.0.10"
|
||||
peers: [d, e]
|
||||
|
||||
b:
|
||||
nsec: "b102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fb0"
|
||||
npub: "npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le"
|
||||
docker_ip: "172.20.0.11"
|
||||
peers: [c]
|
||||
|
||||
c:
|
||||
nsec: "c102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fc0"
|
||||
npub: "npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6"
|
||||
docker_ip: "172.20.0.12"
|
||||
peers: [b, d, e]
|
||||
|
||||
d:
|
||||
nsec: "d102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fd0"
|
||||
npub: "npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl"
|
||||
docker_ip: "172.20.0.13"
|
||||
peers: [a, c, e]
|
||||
|
||||
e:
|
||||
nsec: "e102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fe0"
|
||||
npub: "npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4"
|
||||
docker_ip: "172.20.0.14"
|
||||
peers: [a, c, d]
|
||||
|
||||
# Spanning Tree Structure (rooted at node A):
|
||||
# - A — D (tree edge, D's parent is A)
|
||||
# - A — E (tree edge, E's parent is A)
|
||||
# - C — D (tree edge, C's parent is D)
|
||||
# - B — C (tree edge, B's parent is C)
|
||||
# - D — E (non-tree link)
|
||||
# - C — E (non-tree link)
|
||||
@@ -27,7 +27,7 @@ services:
|
||||
hostname: node-a
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/mesh/node-a.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/mesh/node-a.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.10
|
||||
@@ -39,7 +39,7 @@ services:
|
||||
hostname: node-b
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/mesh/node-b.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/mesh/node-b.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.11
|
||||
@@ -51,7 +51,7 @@ services:
|
||||
hostname: node-c
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/mesh/node-c.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/mesh/node-c.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.12
|
||||
@@ -63,7 +63,7 @@ services:
|
||||
hostname: node-d
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/mesh/node-d.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/mesh/node-d.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.13
|
||||
@@ -75,7 +75,7 @@ services:
|
||||
hostname: node-e
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/mesh/node-e.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/mesh/node-e.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.14
|
||||
@@ -88,7 +88,7 @@ services:
|
||||
hostname: node-a
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/chain/node-a.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/chain/node-a.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.10
|
||||
@@ -100,7 +100,7 @@ services:
|
||||
hostname: node-b
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/chain/node-b.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/chain/node-b.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.11
|
||||
@@ -112,7 +112,7 @@ services:
|
||||
hostname: node-c
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/chain/node-c.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/chain/node-c.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.12
|
||||
@@ -124,7 +124,7 @@ services:
|
||||
hostname: node-d
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/chain/node-d.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/chain/node-d.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.13
|
||||
@@ -136,7 +136,7 @@ services:
|
||||
hostname: node-e
|
||||
volumes:
|
||||
- ./resolv.conf:/etc/resolv.conf:ro
|
||||
- ./configs/chain/node-e.yaml:/etc/fips/fips.yaml:ro
|
||||
- ./generated-configs/chain/node-e.yaml:/etc/fips/fips.yaml:ro
|
||||
networks:
|
||||
fips-net:
|
||||
ipv4_address: 172.20.0.14
|
||||
|
||||
@@ -53,4 +53,7 @@ fi
|
||||
|
||||
echo "Done. Binary at $DOCKER_DIR/fips"
|
||||
echo ""
|
||||
echo "Generating node configurations from templates..."
|
||||
"$SCRIPT_DIR/generate-configs.sh" all
|
||||
echo ""
|
||||
echo "Next: cd $DOCKER_DIR && docker compose --profile mesh build"
|
||||
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
#!/bin/bash
|
||||
# Generate FIPS node configuration files from template and topology definition.
|
||||
#
|
||||
# Usage: ./generate-configs.sh [mesh|chain|all]
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_DIR="$SCRIPT_DIR/../configs"
|
||||
GENERATED_DIR="$SCRIPT_DIR/../generated-configs"
|
||||
TEMPLATE_FILE="$CONFIG_DIR/node.template.yaml"
|
||||
|
||||
# Node data lookup functions
|
||||
get_nsec() {
|
||||
case "$1" in
|
||||
a) echo "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" ;;
|
||||
b) echo "b102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fb0" ;;
|
||||
c) echo "c102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fc0" ;;
|
||||
d) echo "d102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fd0" ;;
|
||||
e) echo "e102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fe0" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_npub() {
|
||||
case "$1" in
|
||||
a) echo "npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m" ;;
|
||||
b) echo "npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le" ;;
|
||||
c) echo "npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6" ;;
|
||||
d) echo "npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl" ;;
|
||||
e) echo "npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_docker_ip() {
|
||||
case "$1" in
|
||||
a) echo "172.20.0.10" ;;
|
||||
b) echo "172.20.0.11" ;;
|
||||
c) echo "172.20.0.12" ;;
|
||||
d) echo "172.20.0.13" ;;
|
||||
e) echo "172.20.0.14" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_mesh_peers() {
|
||||
case "$1" in
|
||||
a) echo "d e" ;;
|
||||
b) echo "c" ;;
|
||||
c) echo "b d e" ;;
|
||||
d) echo "a c e" ;;
|
||||
e) echo "a c d" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_chain_peers() {
|
||||
case "$1" in
|
||||
a) echo "b" ;;
|
||||
b) echo "a c" ;;
|
||||
c) echo "b d" ;;
|
||||
d) echo "c e" ;;
|
||||
e) echo "d" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
generate_peer_block() {
|
||||
local peer_id="$1"
|
||||
cat <<EOF
|
||||
- npub: "$(get_npub "$peer_id")"
|
||||
alias: "node-$peer_id"
|
||||
addresses:
|
||||
- transport: udp
|
||||
addr: "$(get_docker_ip "$peer_id"):4000"
|
||||
connect_policy: auto_connect
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_config() {
|
||||
local node_id="$1"
|
||||
local topology="$2"
|
||||
local peers="$3"
|
||||
|
||||
local node_name=$(echo "$node_id" | tr '[:lower:]' '[:upper:]')
|
||||
local template
|
||||
template=$(cat "$TEMPLATE_FILE")
|
||||
|
||||
# Generate peers section
|
||||
local peers_config=""
|
||||
if [ -n "$peers" ]; then
|
||||
for peer_id in $peers; do
|
||||
if [ -n "$peers_config" ]; then
|
||||
peers_config="$peers_config"$'\n'
|
||||
fi
|
||||
peers_config="$peers_config$(generate_peer_block "$peer_id")"
|
||||
done
|
||||
else
|
||||
peers_config=" []"
|
||||
fi
|
||||
|
||||
# Replace template variables
|
||||
local config="$template"
|
||||
config="${config//\{\{NODE_NAME\}\}/$node_name}"
|
||||
config="${config//\{\{TOPOLOGY\}\}/$topology}"
|
||||
config="${config//\{\{NPUB\}\}/$(get_npub "$node_id")}"
|
||||
config="${config//\{\{NSEC\}\}/$(get_nsec "$node_id")}"
|
||||
config="${config//\{\{PEERS\}\}/$peers_config}"
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
generate_topology() {
|
||||
local topology="$1"
|
||||
local output_dir="$GENERATED_DIR/$topology"
|
||||
|
||||
echo "Generating $topology topology configs..."
|
||||
mkdir -p "$output_dir"
|
||||
|
||||
for node_id in a b c d e; do
|
||||
local peers
|
||||
if [ "$topology" = "mesh" ]; then
|
||||
peers=$(get_mesh_peers "$node_id")
|
||||
else
|
||||
peers=$(get_chain_peers "$node_id")
|
||||
fi
|
||||
|
||||
local output_file="$output_dir/node-$node_id.yaml"
|
||||
generate_config "$node_id" "$topology" "$peers" > "$output_file"
|
||||
echo " ✓ Generated $output_file"
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
local requested="${1:-all}"
|
||||
|
||||
case "$requested" in
|
||||
mesh)
|
||||
generate_topology "mesh"
|
||||
;;
|
||||
chain)
|
||||
generate_topology "chain"
|
||||
;;
|
||||
all)
|
||||
generate_topology "mesh"
|
||||
generate_topology "chain"
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unknown topology '$requested'"
|
||||
echo "Usage: $0 [mesh|chain|all]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "✓ All configurations generated successfully!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
#!/bin/bash
|
||||
# End-to-end iperf3 bandwidth test between FIPS nodes via DNS resolution.
|
||||
# Usage: ./iperf-test.sh [mesh|chain] [--live]
|
||||
#
|
||||
# Requires containers to be running:
|
||||
# docker compose --profile mesh up -d
|
||||
# ./scripts/iperf-test.sh mesh
|
||||
# ./scripts/iperf-test.sh mesh --live # Show live iperf3 output
|
||||
set -e
|
||||
|
||||
# Exit entire script on Ctrl+C
|
||||
trap 'echo ""; echo "Test interrupted"; exit 130' INT
|
||||
|
||||
PROFILE="${1:-mesh}"
|
||||
LIVE_OUTPUT=false
|
||||
if [ "$2" = "--live" ] || [ "$1" = "--live" ]; then
|
||||
LIVE_OUTPUT=true
|
||||
[ "$1" = "--live" ] && PROFILE="mesh"
|
||||
fi
|
||||
|
||||
DURATION=10
|
||||
PARALLEL=8
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
|
||||
# Node identities
|
||||
NPUB_A="npub1sjlh2c3x9w7kjsqg2ay080n2lff2uvt325vpan33ke34rn8l5jcqawh57m"
|
||||
NPUB_B="npub1tdwa4vjrjl33pcjdpf2t4p027nl86xrx24g4d3avg4vwvayr3g8qhd84le"
|
||||
NPUB_C="npub1cld9yay0u24davpu6c35l4vldrhzvaq66pcqtg9a0j2cnjrn9rtsxx2pe6"
|
||||
NPUB_D="npub1n9lpnv0592cc2ps6nm0ca3qls642vx7yjsv35rkxqzj2vgds52sqgpverl"
|
||||
NPUB_E="npub1wf8akf8lu2zdkjkmwhl75pqvven654mpv4sz2x2tprl5265mgrzq8nhak4"
|
||||
|
||||
# FIPS IPv6 addresses (derived from npubs)
|
||||
ADDR_A="fd69:e08d:65cc:3a6b:9c2c:2ac4:bd40:5e4b"
|
||||
ADDR_B="fd8e:302c:287e:b48d:e5b7:6eee:e8a7:4f1e"
|
||||
ADDR_C="fdac:a221:4069:5044:e0e5:7a5f:5a0f:4d43"
|
||||
ADDR_D="fdb6:8411:a191:6d48:c5f7:e5f5:e5a5:2a50"
|
||||
ADDR_E="fded:7dee:d386:a546:e5f7:e5f5:e5a5:2a50"
|
||||
|
||||
iperf_test() {
|
||||
local server_node="$1"
|
||||
local client_node="$2"
|
||||
local dest_npub="$3"
|
||||
local label="$4"
|
||||
|
||||
echo ""
|
||||
echo "=== $label ==="
|
||||
|
||||
# iperf3 server is already running in daemon mode in each container
|
||||
|
||||
if [ "$LIVE_OUTPUT" = true ]; then
|
||||
# Show live output
|
||||
echo "Running iperf3 test (live output):"
|
||||
if docker exec "fips-$client_node" iperf3 -c "${dest_npub}.fips" -t "$DURATION" -P "$PARALLEL"; then
|
||||
PASSED=$((PASSED + 1))
|
||||
else
|
||||
echo "FAIL"
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
else
|
||||
# Capture and summarize output
|
||||
echo -n "Running iperf3 test... "
|
||||
local output
|
||||
if output=$(docker exec "fips-$client_node" iperf3 -c "${dest_npub}.fips" -t "$DURATION" -P "$PARALLEL" 2>&1); then
|
||||
# Check if we got valid results
|
||||
if echo "$output" | grep -q "sender"; then
|
||||
# Extract and display results (get SUM line for aggregate bandwidth)
|
||||
local bandwidth=$(echo "$output" | grep "\[SUM\].*sender" | tail -1 | awk '{print $(NF-2), $(NF-1)}')
|
||||
echo "OK"
|
||||
echo "Bandwidth: $bandwidth"
|
||||
PASSED=$((PASSED + 1))
|
||||
else
|
||||
echo "FAIL (no bandwidth data)"
|
||||
echo "Output: $output"
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
else
|
||||
echo "FAIL"
|
||||
echo "Error output:"
|
||||
echo "$output" | head -10
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
echo "=== FIPS iperf3 Bandwidth Test ($PROFILE topology) ==="
|
||||
echo ""
|
||||
|
||||
# Wait for nodes to converge
|
||||
echo "Waiting 3s for mesh convergence..."
|
||||
sleep 3
|
||||
|
||||
if [ "$PROFILE" = "mesh" ]; then
|
||||
# Test key paths in mesh topology
|
||||
echo ""
|
||||
echo "Testing mesh topology paths:"
|
||||
|
||||
# Direct peer links
|
||||
iperf_test node-a node-d "$NPUB_D" "A → D (direct peer)"
|
||||
iperf_test node-a node-e "$NPUB_E" "A → E (direct peer)"
|
||||
|
||||
# Multi-hop paths
|
||||
iperf_test node-a node-b "$NPUB_B" "A → B (multi-hop)"
|
||||
iperf_test node-a node-c "$NPUB_C" "A → C (multi-hop)"
|
||||
|
||||
# Reverse test
|
||||
iperf_test node-e node-a "$NPUB_A" "E → A (direct peer)"
|
||||
|
||||
elif [ "$PROFILE" = "chain" ]; then
|
||||
echo ""
|
||||
echo "Testing chain topology paths:"
|
||||
|
||||
# Adjacent hop
|
||||
iperf_test node-a node-b "$NPUB_B" "A → B (1 hop)"
|
||||
|
||||
# Multi-hop tests
|
||||
iperf_test node-a node-c "$NPUB_C" "A → C (2 hops)"
|
||||
iperf_test node-a node-d "$NPUB_D" "A → D (3 hops)"
|
||||
iperf_test node-a node-e "$NPUB_E" "A → E (4 hops)"
|
||||
|
||||
# Reverse multi-hop
|
||||
iperf_test node-e node-a "$NPUB_A" "E → A (4 hops)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Results: $PASSED passed, $FAILED failed ==="
|
||||
[ "$FAILED" -eq 0 ] && exit 0 || exit 1
|
||||
@@ -7,9 +7,12 @@
|
||||
# ./scripts/ping-test.sh mesh
|
||||
set -e
|
||||
|
||||
# Exit entire script on Ctrl+C
|
||||
trap 'echo ""; echo "Test interrupted"; exit 130' INT
|
||||
|
||||
PROFILE="${1:-mesh}"
|
||||
COUNT=3
|
||||
TIMEOUT=10
|
||||
COUNT=1
|
||||
TIMEOUT=5
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
|
||||
@@ -26,8 +29,15 @@ ping_test() {
|
||||
local label="$3"
|
||||
|
||||
echo -n " $label ... "
|
||||
if docker exec "fips-$from" ping6 -c "$COUNT" -W "$TIMEOUT" "${to_npub}.fips" > /dev/null 2>&1; then
|
||||
echo "OK"
|
||||
local output
|
||||
if output=$(docker exec "fips-$from" ping6 -c "$COUNT" -W "$TIMEOUT" "${to_npub}.fips" 2>&1); then
|
||||
# Extract round-trip time from ping output
|
||||
local rtt=$(echo "$output" | grep -oE 'time=[0-9.]+' | cut -d= -f2)
|
||||
if [ -n "$rtt" ]; then
|
||||
echo "OK (${rtt}ms)"
|
||||
else
|
||||
echo "OK"
|
||||
fi
|
||||
PASSED=$((PASSED + 1))
|
||||
else
|
||||
echo "FAIL"
|
||||
@@ -39,8 +49,8 @@ echo "=== FIPS Ping Test ($PROFILE topology) ==="
|
||||
echo ""
|
||||
|
||||
# Wait for nodes to converge
|
||||
echo "Waiting 5s for mesh convergence..."
|
||||
sleep 5
|
||||
echo "Waiting 3s for mesh convergence..."
|
||||
sleep 3
|
||||
|
||||
if [ "$PROFILE" = "mesh" ]; then
|
||||
# Sparse mesh topology: A-B, B-C, C-D, D-E, E-A, A-D
|
||||
|
||||
Reference in New Issue
Block a user