@celilo/e2e 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +360 -0
  2. package/bin/cache-docker-images +46 -0
  3. package/bin/e2e-build +66 -0
  4. package/bin/e2e-down +67 -0
  5. package/bin/e2e-infra +92 -0
  6. package/bin/e2e-load +40 -0
  7. package/bin/e2e-run +354 -0
  8. package/bin/e2e-shell +27 -0
  9. package/bin/e2e-status +29 -0
  10. package/bin/e2e-up +160 -0
  11. package/config/dhcp/dnsmasq.conf +27 -0
  12. package/config/dns/com.zone +11 -0
  13. package/config/dns/iamtheinternet.org.zone +15 -0
  14. package/config/dns/knot-namecheap.conf +11 -0
  15. package/config/dns/knot-root.conf +7 -0
  16. package/config/dns/knot-tld.conf +11 -0
  17. package/config/dns/org.zone +14 -0
  18. package/config/dns/park-your-domain.com.zone +10 -0
  19. package/config/dns/root.zone +14 -0
  20. package/config/pebble/pebble-ca.crt +20 -0
  21. package/config/pebble/pebble-config.json +11 -0
  22. package/config/pebble/pebble-tls.crt +21 -0
  23. package/config/pebble/pebble-tls.key +28 -0
  24. package/config/proxy/generate-ca.sh +20 -0
  25. package/config/proxy/squid-ca.crt +22 -0
  26. package/config/proxy/squid-ca.pem +50 -0
  27. package/config/proxy/squid.conf +38 -0
  28. package/config/proxy/startup.sh +11 -0
  29. package/config/resolver/root.hints +2 -0
  30. package/config/resolver/unbound.conf +28 -0
  31. package/config/routing/apt-cache-routes.sh +21 -0
  32. package/config/routing/dhcp-client-setup.sh +17 -0
  33. package/config/routing/dns-routes.sh +12 -0
  34. package/config/routing/fw-ext-routes.sh +50 -0
  35. package/config/routing/fw-isp-routes.sh +37 -0
  36. package/config/routing/fw-main-routes.sh +31 -0
  37. package/config/routing/management-routes.sh +96 -0
  38. package/config/routing/namecheap-startup.sh +17 -0
  39. package/config/routing/pebble-startup.sh +9 -0
  40. package/config/routing/resolver-routes.sh +15 -0
  41. package/config/routing/target-routes.sh +23 -0
  42. package/config/routing/target-setup.service +13 -0
  43. package/config/routing/target-setup.sh +36 -0
  44. package/config/ssh/generate-keys.sh +17 -0
  45. package/docker/Dockerfile.apt-cache +16 -0
  46. package/docker/Dockerfile.authoritative-dns +15 -0
  47. package/docker/Dockerfile.dhcp-client +16 -0
  48. package/docker/Dockerfile.firewall +28 -0
  49. package/docker/Dockerfile.forward-proxy +28 -0
  50. package/docker/Dockerfile.greenwave-sim +29 -0
  51. package/docker/Dockerfile.management +30 -0
  52. package/docker/Dockerfile.namecheap-dns +25 -0
  53. package/docker/Dockerfile.pebble +18 -0
  54. package/docker/Dockerfile.resolver +20 -0
  55. package/docker/Dockerfile.router +33 -0
  56. package/docker/Dockerfile.target-machine +58 -0
  57. package/docker/Dockerfile.target-machine-docker +105 -0
  58. package/package.json +45 -0
  59. package/simulators/greenwave/server.ts +164 -0
  60. package/simulators/greenwave/state.ts +206 -0
  61. package/simulators/greenwave/types.ts +31 -0
  62. package/simulators/namecheap-ddns/server.ts +97 -0
  63. package/simulators/namecheap-ddns/types.ts +12 -0
  64. package/simulators/namecheap-ddns/zone-updater.ts +49 -0
  65. package/src/container-manager.ts +324 -0
  66. package/src/docker-compose-generator.ts +499 -0
  67. package/src/fixtures.ts +40 -0
  68. package/src/index.ts +59 -0
  69. package/src/network-builder.ts +91 -0
  70. package/src/shared-infra.ts +163 -0
  71. package/src/types.ts +74 -0
@@ -0,0 +1,10 @@
1
+ $ORIGIN park-your-domain.com.
2
+ $TTL 300
3
+
4
+ @ IN SOA ns1.park-your-domain.com. admin.park-your-domain.com. (
5
+ 2024010101 300 60 604800 300
6
+ )
7
+
8
+ @ IN NS ns1.park-your-domain.com.
9
+ ns1 IN A 100.64.0.55
10
+ dynamicdns IN A 100.64.0.55
@@ -0,0 +1,14 @@
1
+ $ORIGIN .
2
+ $TTL 86400
3
+
4
+ @ IN SOA root-dns.lab. admin.lab. (
5
+ 2024010101 1800 900 604800 86400
6
+ )
7
+
8
+ . IN NS root-dns.lab.
9
+ root-dns.lab. IN A 100.64.0.53
10
+
11
+ com. IN NS tld-dns.lab.
12
+ tld-dns.lab. IN A 100.64.0.54
13
+
14
+ org. IN NS tld-dns.lab.
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDMTCCAhmgAwIBAgIUaYCN3ZFMCmaVcENgKZ/xOGhglVowDQYJKoZIhvcNAQEL
3
+ BQAwIDEeMBwGA1UEAwwVQ29uZHVjdG9yIEUyRSBSb290IENBMB4XDTI2MDMzMDE5
4
+ NTMwNVoXDTM2MDMyNzE5NTMwNVowIDEeMBwGA1UEAwwVQ29uZHVjdG9yIEUyRSBS
5
+ b290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAupS6A0MRmHf3
6
+ kA6aSkY0He8U+wXZ2OMvHyOecL4UGAO3dmuoOiDVLqtrYkUxmIT8Xqb231ZmUPnV
7
+ YaCtumheP0R8Wk+8cI42yZHoCmTWSmBFFdre3OQeKx8JqW6pt0O3VaRIYZeaDGrU
8
+ 3BmJC7UQFBA3gv4HxX4MQxjG7/Uv3QC1rmhBh5P478B5ARc+rpXq/TaYFvvnhSNX
9
+ eS2dOAJmlCD6T4Z3YVb9agNN0I83SQjbowT6Hcnd0hG1qzjcGo6Hh17++tO5Rv48
10
+ a5daf89JXMzt5H5SLAszs0l8YbBENyHGf9ODhTA9rsOPfb16cui/lPWoyK6ZVV1E
11
+ 6abbDrau5wIDAQABo2MwYTAdBgNVHQ4EFgQUm0hU9Poa7Jt4/rknHfwM357i5e0w
12
+ HwYDVR0jBBgwFoAUm0hU9Poa7Jt4/rknHfwM357i5e0wDwYDVR0TAQH/BAUwAwEB
13
+ /zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHNPUe7vyCWii1Oz
14
+ 2zQDo14/Hj83eIwUTiFL/ri/KnSgIHDz7yTqlTMONMFB7x22WmJ52akr7B46Fz7F
15
+ LB/c28oaGAP2g6+ACrsicmk3MUPnNWAzkyL6qIJnejkWk3bUJ9QDJ+mUi5OwhFnY
16
+ 9s++J5dPDzJzsJxEFwbt2VXh9DA5+FgDl/hULzmr048HT4TStYZth1+cIaZebB9w
17
+ nTYYQAVqXxmkxwtpNTQPjGysAwV4XyYdGFwQBFt2DnsnrdZDSobNSvVqfvnyy6mV
18
+ uXMHYLKgdE9uUgfP5kwIJ6Qo8P+RN4JcGDSWOswLm48YZFThQxH9Yft5+b7CLb+K
19
+ 8AA+0IM=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,11 @@
1
+ {
2
+ "pebble": {
3
+ "listenAddress": "0.0.0.0:443",
4
+ "managementListenAddress": "0.0.0.0:15000",
5
+ "certificate": "/config/pebble-tls.crt",
6
+ "privateKey": "/config/pebble-tls.key",
7
+ "httpPort": 80,
8
+ "tlsPort": 443,
9
+ "ocspResponderURL": ""
10
+ }
11
+ }
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDZTCCAk2gAwIBAgIUbphe84IVhcS25gLcekwSZYM6zcAwDQYJKoZIhvcNAQEL
3
+ BQAwIDEeMBwGA1UEAwwVQ29uZHVjdG9yIEUyRSBSb290IENBMB4XDTI2MDMzMDE5
4
+ NTMyMloXDTM2MDMyNzE5NTMyMlowETEPMA0GA1UEAwwGcGViYmxlMIIBIjANBgkq
5
+ hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtX72hIsegPpLkhUa02GTOSowtl8N6jJ9
6
+ f9IH98WDH5yDwKbZPic7pRIhSespmbFdLMt+Hs/fEr/hBQiOSR4hkezb3F8bkv0T
7
+ S0VvSK/Ao9hSbm5H7pFZRucJno5s/g0KIwe/rqI90c/bpIVP8izwXFyGr+D1Aw4R
8
+ RPle4viILZ1MRnshOF5uX2MkZlyMaW/uxFRzHDiN4cAE7nl1nBRGzwI//tA7Ag2h
9
+ XKRZaBJ9180pTcZobWaqxNgw3pAzXqsZbmW+eDOqMdgS/9srX+AHY2kiX+Qg3ozX
10
+ 4WgTwebqLf0qw2zsMY10lfn/kiwYC42ukol/r2rp4Ub7EzIgrWA8AwIDAQABo4Gl
11
+ MIGiMGAGA1UdEQRZMFeCCWxvY2FsaG9zdIIGcGViYmxlghxhY21lLXYwMi5hcGku
12
+ bGV0c2VuY3J5cHQub3JngiRhY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlw
13
+ dC5vcmcwHQYDVR0OBBYEFDGYCywDhGO3KTo1PwCyojJIEGC/MB8GA1UdIwQYMBaA
14
+ FJtIVPT6GuybeP65Jx38DN+e4uXtMA0GCSqGSIb3DQEBCwUAA4IBAQB/ftFFJTww
15
+ 7vUcinY7oeeKHDMUUGKIijAshr9F8p8nwIvMpBurrdTCoYSTrXNOxWg7m6eHpjo/
16
+ GYH459Uk9UDF5tp6+WfElTCBEvL0xaOprBFURuy9cbFC1byPtwdht/5o2BijTjEU
17
+ WLmMkth5SkRrXJe1whruT/cxJEf7h/pgzMOiKjil7km933x7bNjMOdjZmUrPT6jd
18
+ 8+EJugopzHqkFHZ+uFQmhtQ2F3liyS+FB+9i28dy2vrVylUlPsOZicSzi9RcPwKx
19
+ 1Jc+t4gENUInePA5floWZHwvRp9zgWWLNS4XdD2vawUnb7KiIXMLzCg4ETiPHfG0
20
+ Dhqj9k8SflJx
21
+ -----END CERTIFICATE-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQC1fvaEix6A+kuS
3
+ FRrTYZM5KjC2Xw3qMn1/0gf3xYMfnIPAptk+JzulEiFJ6ymZsV0sy34ez98Sv+EF
4
+ CI5JHiGR7NvcXxuS/RNLRW9Ir8Cj2FJubkfukVlG5wmejmz+DQojB7+uoj3Rz9uk
5
+ hU/yLPBcXIav4PUDDhFE+V7i+IgtnUxGeyE4Xm5fYyRmXIxpb+7EVHMcOI3hwATu
6
+ eXWcFEbPAj/+0DsCDaFcpFloEn3XzSlNxmhtZqrE2DDekDNeqxluZb54M6ox2BL/
7
+ 2ytf4AdjaSJf5CDejNfhaBPB5uot/SrDbOwxjXSV+f+SLBgLja6SiX+vaunhRvsT
8
+ MiCtYDwDAgMBAAECgf5791pOB+uEzhpc9Dg97oW5A0YKhvc8xfDAPrXJG2KtTUer
9
+ vLMmIYLfab/46DEl2ENoQIMtEXE/ZfkvngtJH1xu0rQjvpqT24vtgqzB68D8X4zP
10
+ +Pp1klyTNbN6aDoLFC0QGYHBMt7qfM9NwDbs5qK+hO+Joqc6QvLbaVIuPg2pY/Vu
11
+ 7l5nslOr3WDnX4u9TfGVGR6uIq9Hi+K/4S9pf26PSE1+c4I7qCDAqAlfVLcGJ5HJ
12
+ T65hjwA+XR5rPG8x04LYGjCFFflcZoEvC3FBTOXbRJXvjBjoqVFqFU78YY8WbIy9
13
+ bUX+BuNvB72Ff5lzcV+c5QICuRAMe0LYVfs8NQKBgQD1c9gNR9OmyU3pF71q2mW5
14
+ 9+DWIf/qn12PVmaLoiMCAKjcVKTY7JOmHHZNKeWJMHJIXw33TXerv7MYxa7lJALG
15
+ Si1qaeQ6ci1u7Buzd3KHjmQtgwbYmXRPNc8sVaOy2boC+j+OFBf7hSN7U6s7J3f5
16
+ DueEyCTYx1XvyhByPtdXnQKBgQC9S4zgVTF399CseQ/iC+2n+ThIngOFYZJZGnmE
17
+ mHF1v9GPxiidtZji7bDxpX/oEwBP9WTNGPXXAMFPYLkhYvH82SFwH2cZqxXWo2Je
18
+ nMhKnvaHwn/umRDJbXGlqsBcXHQiC1dzwHo7g195O3I6UHKI9UNCWK6FPlKMlaon
19
+ Eu0gHwKBgBlx+vHVgmGF+OezKFXNckJHKi3ItIkUIFTdth+/nTV18At3UueSDvRn
20
+ evQg5cTFGvPZts7uXvuVEfH9fFYQ16DKy85+T8SnVYJsQ6rlNSBMaKI3NRx7PA2C
21
+ HIoSDrhZzejFHJWUC7BtavI8CEJHoy5Ulzeyr+8xKv2CyxWs4hIZAoGATl9/Xkon
22
+ hyIlVaNx/gcuSIOY2AgEMS8qppWdhlaPc08N9tb2bgWH3TzIK+R3xqBHWtOg/oG9
23
+ F12Kq9DCFZ6fzi4f+AooZ6o8Cnfu/HkxPCQAskjHKwRYvO0BRrQhnJvywT2s4ZHp
24
+ icZkuw7vxlEUerwBMvEAoM4i42372t2tK8UCgYEAhahQmoHy83JeXKIh7U6Dkllz
25
+ 0cmIu0/mH3lzWm1I19We197hBTBX8c+LDV1dGb9O6Kd7K9GHUMR2/5T09ZKcxa7o
26
+ opR4Mj9gQ7s7ySIAYItmtIRljzKDsh+z65PVdMQfvHaqqtTNALeFLsaAQJBNq06z
27
+ 1mKt/BA6j/jpJej7SLM=
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+ # Generate a Squid CA certificate for SSL bumping.
3
+ # Called during Docker image build to create a deterministic CA.
4
+ set -e
5
+
6
+ CERT_DIR=/etc/squid/ssl
7
+ mkdir -p "$CERT_DIR"
8
+
9
+ openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \
10
+ -subj "/C=US/ST=Test/L=E2E/O=Celilo E2E/CN=E2E Forward Proxy CA" \
11
+ -keyout "$CERT_DIR/squid-ca.pem" \
12
+ -out "$CERT_DIR/squid-ca.pem" 2>/dev/null
13
+
14
+ # Export just the certificate (no private key) for distribution to clients
15
+ openssl x509 -in "$CERT_DIR/squid-ca.pem" -out "$CERT_DIR/squid-ca.crt"
16
+
17
+ # Initialize Squid SSL certificate database
18
+ /usr/lib/squid/security_file_certgen -c -s /var/spool/squid/ssl_db -M 4MB 2>/dev/null || true
19
+
20
+ echo "Squid CA generated at $CERT_DIR/squid-ca.pem"
@@ -0,0 +1,22 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDozCCAougAwIBAgIUNd9blKIHJAKDmqm52oe1zQEf9PowDQYJKoZIhvcNAQEL
3
+ BQAwYTELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDDAKBgNVBAcMA0UyRTEW
4
+ MBQGA1UECgwNQ29uZHVjdG9yIEUyRTEdMBsGA1UEAwwURTJFIEZvcndhcmQgUHJv
5
+ eHkgQ0EwHhcNMjYwMzMwMDI0OTAxWhcNMzYwMzI3MDI0OTAxWjBhMQswCQYDVQQG
6
+ EwJVUzENMAsGA1UECAwEVGVzdDEMMAoGA1UEBwwDRTJFMRYwFAYDVQQKDA1Db25k
7
+ dWN0b3IgRTJFMR0wGwYDVQQDDBRFMkUgRm9yd2FyZCBQcm94eSBDQTCCASIwDQYJ
8
+ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXyuY1L9PAJxj4sTLp1qbIFHgKh+oRX
9
+ sZqyhSLJl8dcn8ulf6Xi9ESyOacN99K6z0WQHRSCPOcrDjqqfuTpysK7noZgRu7w
10
+ 85xxGGviERbaS7/cCLczVVbVWJznz0z5aTV6gNG0fZjhCNeubq8jWBlRHwruWXDR
11
+ PxsJMwq7HBfhvraM9soh43L5ZFW+6Rg2mf8Ka0i+j+wJsqimmHUpfLuU3Uv12sb+
12
+ 7px6EK9jaa7NL6DFZgEtnmpHYLcCJmfrmWLsx58xlUQC2mr3nrR7xLnuyd5iWt5s
13
+ q8ggnerAbw3xqFXrvaVbwNrzgRwszsu/2Sg46Jd2Ymks5XGHpY2tz/UCAwEAAaNT
14
+ MFEwHQYDVR0OBBYEFNPJkgXvVsG2f4o4KfYIhGM42bRKMB8GA1UdIwQYMBaAFNPJ
15
+ kgXvVsG2f4o4KfYIhGM42bRKMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
16
+ BQADggEBABoZdGSVrwMScAebd+zHsvq8uexmKqhU2T6XKjuIHy+OzEZfalPzv+Gm
17
+ U7aZfulpLfwqfsiAq2aSTv3+CFRBgTzQJUaY4URt8S7WoQ1fSPF9ZHYFyOV+eEvK
18
+ biTixKSyH++dW3Z4Xn4vELf1mzZQM1mUaUs34hf0lxVjRs+zXzzG8W5MeIFMXKle
19
+ yamqnud5L8oS0l9l45n0R2yBHenWkRZ1yF6EtPxBSGXitLRN0Ge3AMKyRzTbqcnD
20
+ BbSXk41Offknn9StmLkDUnX3/xbv99sDcbUyj7FDC0VNEqgZfd/6jSsAdyBdaiIa
21
+ AHTY/mSRaUZ9otjpKFpxjrHfdZNPWQM=
22
+ -----END CERTIFICATE-----
@@ -0,0 +1,50 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD18rmNS/TwCcY+
3
+ LEy6damyBR4CofqEV7GasoUiyZfHXJ/LpX+l4vREsjmnDffSus9FkB0UgjznKw46
4
+ qn7k6crCu56GYEbu8POccRhr4hEW2ku/3Ai3M1VW1Vic589M+Wk1eoDRtH2Y4QjX
5
+ rm6vI1gZUR8K7llw0T8bCTMKuxwX4b62jPbKIeNy+WRVvukYNpn/CmtIvo/sCbKo
6
+ pph1KXy7lN1L9drG/u6cehCvY2muzS+gxWYBLZ5qR2C3AiZn65li7MefMZVEAtpq
7
+ 9560e8S57sneYlrebKvIIJ3qwG8N8ahV672lW8Da84EcLM7Lv9koOOiXdmJpLOVx
8
+ h6WNrc/1AgMBAAECggEAH1E18Vj/qmUEOjx31LJQ1lsydBFeDeYAtnsO2twimH8h
9
+ 1dOQCnZ4thqfnrb3nHyvEeOE4GypBqKD4FJ/b/SZHey4BdJSlfBWhNAd1PbnSCqp
10
+ xJdnALTno/PsoaYezmVf0TB1IL7D02isMJKEg4aTnD2pH0I0X1o1l+K2/iHPNPcI
11
+ 4xDYlINdqmdGNkmaDpgAjrrSSDQCWHa2FcskNKu8+K+Fif7AHKM4rSFwCxzdDN9D
12
+ iAkG4cRdMBTjxMZRS/w82ggBFtKiAz0qYp1i4PxmSTuNQjjfdFm3qv2JrVxjLVNe
13
+ 7re/gTHCwbMx57aDGX5cGrOKG5+By0Xcri+AEYwfDQKBgQD9Knus/7GHeZF50BLX
14
+ bakDwFHlxCHGSJKP+R3I0BuxGpFa6dh3TFbvKqYAOpNuV281S1svDgfQp3W6ea6V
15
+ 5WRzKhpaYOLrFrgKb4Pxt6Ymzhs4/A7vMzQ9xA6hufK7/9ld4E/+tpLl1NgTQ9Y7
16
+ zrOZSwVzJ3hy/P7I72/8cLqrvwKBgQD4s46dZ8h9LIQHMB6bRwjvRy0QNU2nmmn1
17
+ TIB/ZjqgJYYAqjJuBSclA2MytKd7q+dGpiPIXYc0bGY5EfojgUjRi4gfizFH+83/
18
+ wM3pmBUcKyYaUv+mxtMSfAq5kC0uO3MOa/R1ALj3YtCO+qcrJX8tlCOinqneCRK3
19
+ 2vVTPx5BSwKBgQCFCjZEC3q3vuL8KKQ+IZqYJhDjtdYp5SlgD4Hfbb2frF6GcC0Z
20
+ RDzLIpZpuF6RtdDzKM6aQ71HoTj07c0ZaJsJCi8fH5sf/6hnk4K7G89sxRL5NzyB
21
+ 516ktssZoiY1NZZ9BswDBt7beKa0OQn0FAO9ovcSNMPPabRa07j96B+w8QKBgB9g
22
+ J8Hb8gM4tn9hprrYP1xQknLVBrL6XBvCRwPLleHWWg2Da1FN/R5CSyV+fRKxIUBc
23
+ fW8tvXzzoAHbLr+D8/fbrpSsLs9yCQ8W9+NceG1RVEFF71LPCpnuZDv84HZQsbdE
24
+ D1cjfDJZmQ4wuR5MYLsTUVuWwL9uTZo8WW7jK6H5AoGBALxPBXNtLjvGHOMooA0I
25
+ 5LwdyzJxSLlA6cLU8P5NSfUWEZAEH9fnD3q+tiYeGzf62ptxXOOrzEe/q91HVtwW
26
+ ugvVmbdJ8IMrtz+uVt5f5XrlHEa4sTfS+Kk+pZJMwTkGpGSav91u6ND0+/r+IgR2
27
+ I0OZRbgFU0YofZgI88DIH35e
28
+ -----END PRIVATE KEY-----
29
+ -----BEGIN CERTIFICATE-----
30
+ MIIDozCCAougAwIBAgIUNd9blKIHJAKDmqm52oe1zQEf9PowDQYJKoZIhvcNAQEL
31
+ BQAwYTELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDDAKBgNVBAcMA0UyRTEW
32
+ MBQGA1UECgwNQ29uZHVjdG9yIEUyRTEdMBsGA1UEAwwURTJFIEZvcndhcmQgUHJv
33
+ eHkgQ0EwHhcNMjYwMzMwMDI0OTAxWhcNMzYwMzI3MDI0OTAxWjBhMQswCQYDVQQG
34
+ EwJVUzENMAsGA1UECAwEVGVzdDEMMAoGA1UEBwwDRTJFMRYwFAYDVQQKDA1Db25k
35
+ dWN0b3IgRTJFMR0wGwYDVQQDDBRFMkUgRm9yd2FyZCBQcm94eSBDQTCCASIwDQYJ
36
+ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXyuY1L9PAJxj4sTLp1qbIFHgKh+oRX
37
+ sZqyhSLJl8dcn8ulf6Xi9ESyOacN99K6z0WQHRSCPOcrDjqqfuTpysK7noZgRu7w
38
+ 85xxGGviERbaS7/cCLczVVbVWJznz0z5aTV6gNG0fZjhCNeubq8jWBlRHwruWXDR
39
+ PxsJMwq7HBfhvraM9soh43L5ZFW+6Rg2mf8Ka0i+j+wJsqimmHUpfLuU3Uv12sb+
40
+ 7px6EK9jaa7NL6DFZgEtnmpHYLcCJmfrmWLsx58xlUQC2mr3nrR7xLnuyd5iWt5s
41
+ q8ggnerAbw3xqFXrvaVbwNrzgRwszsu/2Sg46Jd2Ymks5XGHpY2tz/UCAwEAAaNT
42
+ MFEwHQYDVR0OBBYEFNPJkgXvVsG2f4o4KfYIhGM42bRKMB8GA1UdIwQYMBaAFNPJ
43
+ kgXvVsG2f4o4KfYIhGM42bRKMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
44
+ BQADggEBABoZdGSVrwMScAebd+zHsvq8uexmKqhU2T6XKjuIHy+OzEZfalPzv+Gm
45
+ U7aZfulpLfwqfsiAq2aSTv3+CFRBgTzQJUaY4URt8S7WoQ1fSPF9ZHYFyOV+eEvK
46
+ biTixKSyH++dW3Z4Xn4vELf1mzZQM1mUaUs34hf0lxVjRs+zXzzG8W5MeIFMXKle
47
+ yamqnud5L8oS0l9l45n0R2yBHenWkRZ1yF6EtPxBSGXitLRN0Ge3AMKyRzTbqcnD
48
+ BbSXk41Offknn9StmLkDUnX3/xbv99sDcbUyj7FDC0VNEqgZfd/6jSsAdyBdaiIa
49
+ AHTY/mSRaUZ9otjpKFpxjrHfdZNPWQM=
50
+ -----END CERTIFICATE-----
@@ -0,0 +1,38 @@
1
+ # Squid transparent MITM proxy for E2E test network
2
+ # Intercepts HTTP/HTTPS from simulated machines and proxies to real internet
3
+
4
+ # Regular forward proxy port (required by Squid even in intercept mode)
5
+ http_port 3127
6
+
7
+ # Transparent interception ports
8
+ http_port 3128 intercept
9
+ https_port 3129 intercept ssl-bump \
10
+ cert=/etc/squid/ssl/squid-ca.pem \
11
+ generate-host-certificates=on \
12
+ dynamic_cert_mem_cache_size=4MB
13
+
14
+ # SSL bump: peek at SNI, then bump (MITM) all connections
15
+ acl step1 at_step SslBump1
16
+ ssl_bump peek step1
17
+ ssl_bump bump all
18
+
19
+ # Allow all traffic (the E2E network is fully trusted)
20
+ http_access allow all
21
+
22
+ # Cache settings (speeds up repeated package downloads)
23
+ cache_dir ufs /var/spool/squid 200 16 256
24
+ maximum_object_size 512 MB
25
+
26
+ # SSL certificate database
27
+ sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/spool/squid/ssl_db -M 4MB
28
+
29
+ # Logging
30
+ access_log stdio:/var/log/squid/access.log
31
+ cache_log /var/log/squid/cache.log
32
+
33
+ # Resolve via real public DNS (reachable from real-internet bridge)
34
+ dns_nameservers 8.8.8.8 1.1.1.1
35
+
36
+ # Timeouts
37
+ connect_timeout 30 seconds
38
+ read_timeout 60 seconds
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Route outbound traffic via real-internet bridge
5
+ ip route del default 2>/dev/null || true
6
+ ip route add default via 172.30.0.1
7
+
8
+ rm -f /run/squid.pid
9
+
10
+ echo "forward-proxy ready on ports 3128 (HTTP) / 3129 (HTTPS)"
11
+ exec squid -N -f /etc/squid/squid.conf
@@ -0,0 +1,2 @@
1
+ . 3600000 NS root-dns.lab.
2
+ root-dns.lab. 3600000 A 100.64.0.53
@@ -0,0 +1,28 @@
1
+ server:
2
+ interface: 0.0.0.0
3
+ access-control: 0.0.0.0/0 allow
4
+ cache-min-ttl: 0
5
+ cache-max-ttl: 60
6
+ verbosity: 1
7
+ do-daemonize: no
8
+ do-not-query-localhost: no
9
+
10
+ # Simulated DNS overrides (served directly by unbound)
11
+ # Let's Encrypt ACME endpoints → Pebble
12
+ local-data: "acme-v02.api.letsencrypt.org. IN A 100.64.0.100"
13
+ local-data: "acme-staging-v02.api.letsencrypt.org. IN A 100.64.0.100"
14
+
15
+ # Simulated domains → namecheap-dns (authoritative)
16
+ stub-zone:
17
+ name: "iamtheinternet.org."
18
+ stub-addr: 100.64.0.55
19
+
20
+ stub-zone:
21
+ name: "park-your-domain.com."
22
+ stub-addr: 100.64.0.55
23
+
24
+ # Everything else → real public DNS (reachable via real-internet bridge)
25
+ forward-zone:
26
+ name: "."
27
+ forward-addr: 8.8.8.8
28
+ forward-addr: 1.1.1.1
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # The apt-cache container has two interfaces:
5
+ # - internet-external (100.64.0.x): reachable by simulated machines
6
+ # - real-internet: has masquerade enabled for actual internet access
7
+ #
8
+ # Default route must go via the real-internet bridge (for package downloads).
9
+ # Simulated machines reach us on 100.64.0.2:3142.
10
+
11
+ # Fix default route: use real-internet bridge for outbound traffic
12
+ # Docker defaults to the first network's gateway, but we need the
13
+ # real-internet network which has masquerade enabled.
14
+ ip route del default 2>/dev/null || true
15
+ ip route add default via 172.30.0.1
16
+
17
+ # Start apt-cacher-ng
18
+ /usr/sbin/apt-cacher-ng -c /etc/apt-cacher-ng
19
+
20
+ echo "apt-cache ready on port 3142"
21
+ sleep infinity
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ # DHCP client container startup
3
+ # Gets network config (DNS server, search domain) from DHCP
4
+ set -e
5
+
6
+ echo "DHCP client starting..."
7
+
8
+ # Run dhclient - it will get a lease from dnsmasq on the greenwave sim
9
+ # The lease file at /var/lib/dhcp/dhclient.leases records what was offered
10
+ mkdir -p /var/lib/dhcp
11
+ dhclient -v eth0 2>&1 || true
12
+
13
+ echo "DHCP client ready: $(hostname)"
14
+ echo "Lease info:"
15
+ cat /var/lib/dhcp/dhclient.leases 2>/dev/null | head -20
16
+
17
+ sleep infinity
@@ -0,0 +1,12 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Routing — all DNS servers are on internet-external
5
+ ip route del default 2>/dev/null || true
6
+ ip route add default via 100.64.0.1 # Everything via fw-ext
7
+
8
+ # Start knot DNS
9
+ /usr/sbin/knotd --config /config/knot.conf --daemonize
10
+
11
+ echo "DNS server ready: $(hostname)"
12
+ sleep infinity
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Routing
5
+ ip route del default 2>/dev/null || true
6
+ # Default route via real-internet bridge (for Squid outbound to real internet)
7
+ ip route add default via 172.30.0.1
8
+ # Internal subnets via fw-isp
9
+ ip route add 192.168.0.0/24 via 100.100.0.100 # Internal via fw-isp
10
+ ip route add 10.0.10.0/24 via 100.100.0.100 # dmz via fw-isp
11
+ ip route add 10.0.20.0/24 via 100.100.0.100 # app via fw-isp
12
+ ip route add 10.0.30.0/24 via 100.100.0.100 # secure via fw-isp
13
+
14
+ # IP forwarding is set via sysctls in docker-compose
15
+
16
+ # NAT/forward between isp-external and internet-external
17
+ iptables -t nat -A POSTROUTING -j MASQUERADE
18
+ iptables -P FORWARD ACCEPT
19
+
20
+ # Start Squid transparent proxy (runs on fw-ext itself)
21
+ rm -f /run/squid.pid
22
+ squid -N -f /etc/squid/squid.conf &
23
+
24
+ # Transparent proxy: REDIRECT HTTP/HTTPS from isp-external to local Squid
25
+ # Exception: traffic to simulated services (100.64.0.0/24) passes through directly
26
+ ISP_IFACE=$(ip -o addr show | grep '100.100.0.101' | awk '{print $2}')
27
+ iptables -t nat -A PREROUTING -i "$ISP_IFACE" -p tcp --dport 80 ! -d 100.64.0.0/24 -j REDIRECT --to-port 3128
28
+ iptables -t nat -A PREROUTING -i "$ISP_IFACE" -p tcp --dport 443 ! -d 100.64.0.0/24 -j REDIRECT --to-port 3129
29
+
30
+ # DNS
31
+ echo "nameserver 100.100.0.1" > /etc/resolv.conf
32
+
33
+ # Fetch Pebble's runtime ACME root CA (Pebble generates a fresh root at each startup)
34
+ # Retry until Pebble is up and responding
35
+ echo "Waiting for Pebble ACME root CA..."
36
+ (
37
+ for i in $(seq 1 60); do
38
+ if curl -sk https://100.64.0.100:15000/roots/0 -o /usr/local/share/ca-certificates/pebble-acme-root.crt 2>/dev/null; then
39
+ if [ -s /usr/local/share/ca-certificates/pebble-acme-root.crt ]; then
40
+ update-ca-certificates 2>/dev/null
41
+ echo "Pebble ACME root CA installed"
42
+ break
43
+ fi
44
+ fi
45
+ sleep 2
46
+ done
47
+ ) &
48
+
49
+ echo "fw-ext ready (with transparent HTTPS proxy)"
50
+ sleep infinity
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # SSH setup
5
+ mkdir -p /root/.ssh
6
+ cp /ssh-keys/authorized_keys /root/.ssh/authorized_keys
7
+ chmod 700 /root/.ssh
8
+ chmod 600 /root/.ssh/authorized_keys
9
+ /usr/sbin/sshd
10
+
11
+ # Routing
12
+ ip route del default 2>/dev/null || true
13
+ ip route add default via 100.100.0.101 # Internet via fw-ext
14
+ ip route add 10.0.10.0/24 via 192.168.0.254 # dmz via fw-main
15
+ ip route add 10.0.20.0/24 via 192.168.0.254 # app via fw-main
16
+ ip route add 10.0.30.0/24 via 192.168.0.254 # secure via fw-main
17
+
18
+ # IP forwarding is set via sysctls in docker-compose
19
+
20
+ # NAT all outbound traffic
21
+ iptables -t nat -A POSTROUTING -j MASQUERADE
22
+ iptables -P FORWARD ACCEPT
23
+
24
+ # DNS
25
+ echo "nameserver 100.100.0.1" > /etc/resolv.conf
26
+
27
+ # Start dnsmasq DHCP server on internal network
28
+ dnsmasq --conf-dir=/etc/dnsmasq.d --keep-in-foreground --log-facility=- &
29
+ echo "dnsmasq DHCP server started"
30
+
31
+ # Start greenwave simulator
32
+ if [ -f /simulator/server.ts ]; then
33
+ cd /simulator && bun run server.ts &
34
+ fi
35
+
36
+ echo "fw-isp ready"
37
+ sleep infinity
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # SSH setup
5
+ mkdir -p /root/.ssh
6
+ cp /ssh-keys/authorized_keys /root/.ssh/authorized_keys
7
+ chmod 700 /root/.ssh
8
+ chmod 600 /root/.ssh/authorized_keys
9
+ /usr/sbin/sshd
10
+
11
+ # Routing — detect if we have an isp-external interface (direct-internet topology)
12
+ ip route del default 2>/dev/null || true
13
+ if ip -o addr show | grep -q '100.100.0'; then
14
+ # Direct internet: route via fw-ext on isp-external
15
+ ip route add default via 100.100.0.101
16
+ else
17
+ # Default: route via fw-isp on internal
18
+ ip route add default via 192.168.0.1
19
+ fi
20
+
21
+ # IP forwarding is set via sysctls in docker-compose
22
+
23
+ # NAT all outbound traffic from dmz/app/secure
24
+ iptables -t nat -A POSTROUTING -j MASQUERADE
25
+ iptables -P FORWARD ACCEPT
26
+
27
+ # DNS
28
+ echo "nameserver 100.100.0.1" > /etc/resolv.conf
29
+
30
+ echo "fw-main ready"
31
+ sleep infinity
@@ -0,0 +1,96 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # System-wide environment for all processes (hooks, ansible, etc.)
5
+ echo 'DDNS_ENDPOINT=http://100.64.0.55:8080/update' >> /etc/environment
6
+ export DDNS_ENDPOINT="http://100.64.0.55:8080/update"
7
+
8
+ # Generate SSH keys if needed
9
+ /config/ssh/generate-keys.sh /ssh-keys
10
+
11
+ # Set up SSH
12
+ mkdir -p /root/.ssh
13
+ cp /ssh-keys/id_ed25519 /root/.ssh/id_ed25519
14
+ cp /ssh-keys/id_ed25519.pub /root/.ssh/id_ed25519.pub
15
+ chmod 700 /root/.ssh
16
+ chmod 600 /root/.ssh/id_ed25519
17
+ # Accept all host keys automatically
18
+ echo "StrictHostKeyChecking no" > /root/.ssh/config
19
+ echo "UserKnownHostsFile /dev/null" >> /root/.ssh/config
20
+ chmod 600 /root/.ssh/config
21
+
22
+ # Routing — DEFAULT_GATEWAY comes from docker-compose environment
23
+ # default: 192.168.0.1 (fw-isp), direct-internet: 192.168.0.254 (fw-main)
24
+ GATEWAY="${DEFAULT_GATEWAY:-192.168.0.1}"
25
+ ip route del default 2>/dev/null || true
26
+ ip route add default via "$GATEWAY"
27
+ ip route add 10.0.10.0/24 via 192.168.0.254 # dmz via fw-main
28
+ ip route add 10.0.20.0/24 via 192.168.0.254 # app via fw-main
29
+ ip route add 10.0.30.0/24 via 192.168.0.254 # secure via fw-main
30
+
31
+ # DNS — use the simulated resolver
32
+ echo "nameserver 100.100.0.1" > /etc/resolv.conf
33
+
34
+ # Create celilo data directory (Linux default: /var/lib/celilo/)
35
+ mkdir -p /var/lib/celilo/modules
36
+
37
+ # Dependencies come from the host bind mount (node_modules/)
38
+ # If missing, run 'cd apps/celilo && bun install' on the host first.
39
+ cd /celilo/apps/celilo
40
+ if [ ! -d node_modules/@clack ]; then
41
+ echo "WARNING: node_modules not found. Run 'cd apps/celilo && bun install' on the host."
42
+ fi
43
+
44
+ # Generate zsh completion script from celilo
45
+ mkdir -p /root/.zsh/completions
46
+ bun run /celilo/apps/celilo/src/cli/index.ts completion zsh > /root/.zsh/completions/_celilo 2>/dev/null || true
47
+
48
+ # Shell setup: aliases and completion for zsh
49
+ cat > /root/.zshrc << 'ZSHRC'
50
+ export PATH="/root/.bun/bin:$PATH"
51
+
52
+ # Simulated network overrides
53
+ export DDNS_ENDPOINT="http://100.64.0.55:8080/update"
54
+
55
+ # History
56
+ HISTFILE=/root/.zsh_history
57
+ HISTSIZE=10000
58
+ SAVEHIST=10000
59
+ setopt SHARE_HISTORY
60
+ setopt HIST_IGNORE_DUPS
61
+ setopt HIST_IGNORE_SPACE
62
+
63
+ # Key bindings — emacs mode (ctrl-p/n for history, ctrl-a/e, etc.)
64
+ bindkey -e
65
+ bindkey '^P' up-history
66
+ bindkey '^N' down-history
67
+ bindkey '^R' history-incremental-search-backward
68
+
69
+ # Prompt
70
+ PROMPT='%F{cyan}celilo%f:%F{yellow}%~%f# '
71
+
72
+ # Commands
73
+ celilo() { bun run /celilo/apps/celilo/src/cli/index.ts "$@"; }
74
+ c() { celilo "$@"; }
75
+ alias ll='ls -la'
76
+
77
+ # Tab completion — use celilo's built-in zsh completion generator
78
+ fpath=(~/.zsh/completions $fpath)
79
+ autoload -Uz compinit && compinit -u
80
+
81
+ # Also bind `c` to the same completion
82
+ compdef _celilo c
83
+
84
+ cd /celilo/apps/celilo
85
+ ZSHRC
86
+
87
+ # Also set up bash aliases (for non-zsh shells)
88
+ cat > /root/.bashrc << 'BASHRC'
89
+ export PATH="/root/.bun/bin:$PATH"
90
+ alias celilo='bun run /celilo/apps/celilo/src/cli/index.ts'
91
+ alias c='celilo'
92
+ cd /celilo/apps/celilo
93
+ BASHRC
94
+
95
+ echo "Management machine ready"
96
+ sleep infinity
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Routing
5
+ ip route del default 2>/dev/null || true
6
+ ip route add default via 100.64.0.1
7
+
8
+ # Start knot DNS
9
+ /usr/sbin/knotd --config /config/knot.conf --daemonize
10
+
11
+ # Start DDNS simulator (will be added in Phase 3)
12
+ if [ -f /simulator/server.ts ]; then
13
+ cd /simulator && bun run server.ts &
14
+ fi
15
+
16
+ echo "namecheap-dns ready"
17
+ sleep infinity
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Route through fw-ext to reach isp-external (where comcast-resolver lives)
5
+ ip route del default 2>/dev/null || true
6
+ ip route add default via 100.64.0.1
7
+
8
+ echo "pebble starting"
9
+ exec pebble "$@"
@@ -0,0 +1,15 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Routing: default via real-internet bridge for DNS forwarding to real upstream
5
+ ip route del default 2>/dev/null || true
6
+ ip route add default via 172.30.0.1
7
+
8
+ # Keep route to simulated internet services via fw-ext
9
+ ip route add 100.64.0.0/24 via 100.100.0.101
10
+
11
+ # Start unbound
12
+ /usr/sbin/unbound -d &
13
+
14
+ echo "comcast-resolver ready"
15
+ sleep infinity
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+ # Generic startup for target machines (dmz/app/secure).
3
+ # The default gateway is passed as $1 (e.g., 10.0.10.1 for dmz).
4
+ set -e
5
+
6
+ GATEWAY="${1:?Usage: target-routes.sh <gateway-ip>}"
7
+
8
+ # SSH setup
9
+ mkdir -p /root/.ssh
10
+ cp /ssh-keys/authorized_keys /root/.ssh/authorized_keys
11
+ chmod 700 /root/.ssh
12
+ chmod 600 /root/.ssh/authorized_keys
13
+ /usr/sbin/sshd
14
+
15
+ # Routing
16
+ ip route del default 2>/dev/null || true
17
+ ip route add default via "$GATEWAY"
18
+
19
+ # DNS
20
+ echo "nameserver 100.100.0.1" > /etc/resolv.conf
21
+
22
+ echo "Target machine ready: $(hostname)"
23
+ sleep infinity
@@ -0,0 +1,13 @@
1
+ [Unit]
2
+ Description=E2E target machine network setup
3
+ After=network.target
4
+ Before=ssh.service
5
+
6
+ [Service]
7
+ Type=oneshot
8
+ ExecStart=/usr/local/bin/target-setup.sh
9
+ RemainAfterExit=yes
10
+ PassEnvironment=GATEWAY
11
+
12
+ [Install]
13
+ WantedBy=multi-user.target