feat: expose port 4017 in Dockerfile for relayserver
- Added EXPOSE directive to allow external access to the relayserver application on port 4017 - Ensures the container can receive incoming connections as expected by the application
lemon-mint committed
Oct 29, 2025 at 15:38 UTC
65c306d6ec1d76ba38a8a8cd73129434da143b70
3 files changed
+2
-484
DOCKER_BUILD_VERIFICATION.md
deleted
-229
@@ -1,229 +0,0 @@
1
-# Docker Build Verification
2
-
3
-## Build Process Flow
4
-
5
-```
6
-┌─────────────────────────────────────────────────────────┐
7
-│ Stage 1: WASM Builder (rust:1-bullseye) │
8
-│ │
9
-│ 1. Install wasm-pack │
10
-│ 2. Run: make build-wasm │
11
-│ ├─ wasm-pack build --target web │
12
-│ ├─ cp pkg/* → cmd/relay-server/wasm/ │
13
-│ ├─ cp sw-proxy.js → cmd/relay-server/wasm/ │
14
-│ └─ cp sw.js → cmd/relay-server/wasm/ │
15
-│ │
16
-│ Output: cmd/relay-server/wasm/ │
17
-│ ├── relaydns_wasm.js │
18
-│ ├── relaydns_wasm_bg.wasm │
19
-│ ├── relaydns_wasm_sw.js │
20
-│ ├── sw-proxy.js ← E2EE Proxy │
21
-│ └── sw.js ← Caching │
22
-└─────────────────────────────────────────────────────────┘
23
- │ COPY --from=wasm-builder
24
- ▼
25
-┌─────────────────────────────────────────────────────────┐
26
-│ Stage 2: Go Builder (golang:1) │
27
-│ │
28
-│ 1. Copy go.mod, go.sum │
29
-│ 2. go mod download │
30
-│ 3. Copy source code │
31
-│ 4. COPY WASM files from Stage 1 │
32
-│ 5. Run: make build-server │
33
-│ └─ go build (embeds wasm/ via //go:embed) │
34
-│ │
35
-│ Output: bin/relayserver (18MB with embedded WASM) │
36
-└─────────────────────────────────────────────────────────┘
37
- │ COPY --from=builder
38
- ▼
39
-┌─────────────────────────────────────────────────────────┐
40
-│ Stage 3: Runtime (distroless/static-debian12) │
41
-│ │
42
-│ Final binary: /usr/bin/relayserver │
43
-│ ├─ Contains all WASM files │
44
-│ ├─ Contains service workers │
45
-│ └─ Ready to serve E2EE proxy │
46
-└─────────────────────────────────────────────────────────┘
47
-```
48
-
49
-## Files Embedded in Binary
50
-
51
-```go
52
-// view.go line 28-29
53
-//go:embed wasm
54
-var wasmFS embed.FS
55
-```
56
-
57
-**Embedded files:**
58
-- `/pkg/relaydns_wasm.js` (47KB)
59
-- `/pkg/relaydns_wasm_bg.wasm` (465KB)
60
-- `/pkg/relaydns_wasm_sw.js` (52KB)
61
-- `/sw-proxy.js` (5KB) ← **E2EE Proxy Service Worker**
62
-- `/sw.js` (4KB) ← **Caching Service Worker**
63
-
64
-## Verification Commands
65
-
66
-### Local Build Test
67
-
68
-```bash
69
-# Test Makefile
70
-make clean
71
-make build-wasm
72
-
73
-# Verify files copied
74
-ls -lh cmd/relay-server/wasm/
75
-# Should show: sw-proxy.js, sw.js
76
-
77
-# Build server
78
-make build-server
79
-
80
-# Run
81
-./bin/relayserver
82
-```
83
-
84
-### Docker Build Test
85
-
86
-```bash
87
-# Build Docker image
88
-docker build -t relaydns-server .
89
-
90
-# Run container
91
-docker run -p 4017:4017 relaydns-server
92
-
93
-# Test endpoints
94
-curl http://localhost:4017/ # Admin UI
95
-curl http://localhost:4017/sw-proxy.js # Service Worker
96
-curl http://localhost:4017/pkg/relaydns_wasm.js # WASM
97
-```
98
-
99
-### Verify Embedded Files
100
-
101
-```bash
102
-# Check if files are embedded
103
-docker run relaydns-server strings /usr/bin/relayserver | grep -E "sw-proxy"
104
-
105
-# Should output:
106
-# sw-proxy.js
107
-```
108
-
109
-## Expected HTTP Endpoints
110
-
111
-| Endpoint | File | Description |
112
-|----------|------|-------------|
113
-| `/` | Admin template | Server admin UI |
114
-| `/sw-proxy.js` | `sw-proxy.js` | E2EE proxy service worker |
115
-| `/sw.js` | `sw.js` | WASM caching service worker |
116
-| `/pkg/relaydns_wasm.js` | `relaydns_wasm.js` | WASM binding |
117
-| `/pkg/relaydns_wasm_bg.wasm` | `relaydns_wasm_bg.wasm` | WASM binary |
118
-| `/pkg/relaydns_wasm_sw.js` | `relaydns_wasm_sw.js` | SW WASM binding |
119
-| `/relay` | WebSocket handler | E2EE tunnel |
120
-| `/peer/{id}/*` | Reverse proxy | Server-side proxy |
121
-
122
-## Troubleshooting
123
-
124
-### Issue: Service Worker 404
125
-
126
-**Symptom:**
127
-```bash
128
-curl http://localhost:4017/sw-proxy.js
129
-# 404 Not Found
130
-```
131
-
132
-**Cause:** Files not copied in Makefile
133
-
134
-**Fix:**
135
-```bash
136
-# Check Makefile has these lines:
137
-make build-wasm
138
-# [wasm] copying service workers and E2EE proxy files...
139
-# cp relaydns/wasm/sw-proxy.js cmd/relay-server/wasm/
140
-# cp relaydns/wasm/sw.js cmd/relay-server/wasm/
141
-```
142
-
143
-### Issue: Files Not Embedded
144
-
145
-**Cause:** `//go:embed wasm` not working
146
-
147
-**Fix:**
148
-1. Check `view.go` has `//go:embed wasm`
149
-2. Verify files exist in `cmd/relay-server/wasm/`
150
-3. Rebuild: `go build`
151
-
152
-### Issue: Docker Build Fails
153
-
154
-**Symptom:**
155
-```
156
-Step X: cp: cannot stat 'relaydns/wasm/sw-proxy.js': No such file or directory
157
-```
158
-
159
-**Cause:** Files not committed to git
160
-
161
-**Fix:**
162
-```bash
163
-# These files MUST be committed:
164
-git add -f relaydns/wasm/sw-proxy.js
165
-git add -f relaydns/wasm/sw.js
166
-git commit -m "feat: add E2EE proxy service workers"
167
-```
168
-
169
-## Success Criteria
170
-
171
-✅ **All checks must pass:**
172
-
173
-1. **Local Build**
174
- ```bash
175
- make build
176
- ./bin/relayserver
177
- curl http://localhost:4017/sw-proxy.js | head -5
178
- # Output: // Service Worker for RelayDNS Network Proxy
179
- ```
180
-
181
-2. **Docker Build**
182
- ```bash
183
- docker build -t test .
184
- # No errors
185
- ```
186
-
187
-3. **File Size**
188
- ```bash
189
- ls -lh bin/relayserver
190
- # Should be ~18MB (includes embedded WASM)
191
- ```
192
-
193
-4. **Service Worker Registration**
194
- - Open browser: `http://localhost:4017/`
195
- - DevTools → Application → Service Workers
196
- - Should show: `sw-proxy.js` registered
197
-
198
-## Deployment Checklist
199
-
200
-- [x] Makefile updated with SW file copying
201
-- [x] `sw-proxy.js` exists in `relaydns/wasm/`
202
-- [x] `sw.js` exists in `relaydns/wasm/`
203
-- [x] `.gitignore` allows SW files to be committed
204
-- [x] `view.go` serves SW files from embed
205
-- [x] Dockerfile uses `make build-wasm`
206
-- [ ] All files committed to git
207
-- [ ] Docker image built and tested
208
-- [ ] E2EE proxy verified working
209
-
210
-## Next Steps
211
-
212
-1. **Commit Changes**
213
- ```bash
214
- git add Makefile
215
- git add relaydns/wasm/{sw-proxy.js,sw.js}
216
- git commit -m "feat: add E2EE proxy with Docker support"
217
- ```
218
-
219
-2. **Test Docker Build**
220
- ```bash
221
- docker build -t relaydns-server:latest .
222
- docker run -p 4017:4017 relaydns-server:latest
223
- ```
224
-
225
-3. **Push Image**
226
- ```bash
227
- docker tag relaydns-server:latest ghcr.io/gosuda/relaydns:latest
228
- docker push ghcr.io/gosuda/relaydns:latest
229
- ```
Dockerfile
+2
@@ -36,4 +36,6 @@ FROM gcr.io/distroless/static-debian12:nonroot
36
37
COPY --from=builder /out/relayserver /usr/bin/relayserver
38
39
+EXPOSE 4017
40
+
41
ENTRYPOINT ["/usr/bin/relayserver"]
E2EE_VERIFICATION_GUIDE.md
deleted
-255
@@ -1,255 +0,0 @@
1
-# E2EE Encryption Verification Guide
2
-
3
-This guide demonstrates how to verify that the RelayDNS server acts as a **blind relay** and cannot decrypt E2EE (End-to-End Encrypted) traffic.
4
-
5
-## Overview
6
-
7
-The E2EE architecture ensures:
8
-- **Client-side encryption**: All data is encrypted in the browser using WASM
9
-- **Blind relay**: Server only forwards encrypted packets without decryption capability
10
-- **Content-Type detection**: Happens at Service Worker level before encryption
11
-
12
-## Server Logging
13
-
14
-The relay server now includes enhanced logging to show encrypted packet data as it flows through the relay. The server logs:
15
-
16
-1. **Direction**: `Client→Lease` or `Lease→Client`
17
-2. **Lease ID**: The target service identifier
18
-3. **Bytes transferred**: Size of each encrypted chunk
19
-4. **Packet count**: Number of encrypted packets relayed
20
-5. **Encrypted preview**: First 32 bytes of encrypted data in hexadecimal
21
-
22
-### Log Format
23
-
24
-```json
25
-{
26
- "level": "info",
27
- "direction": "Client→Lease",
28
- "lease_id": "ABC123XYZ",
29
- "bytes": 1024,
30
- "total_bytes": 4096,
31
- "packet_count": 4,
32
- "encrypted_preview": "a3f2e1d4c5b6a7890f1e2d3c4b5a6978...",
33
- "message": "[E2EE-RELAY] Forwarding encrypted packet (server cannot decrypt)"
34
-}
35
-```
36
-
37
-## Verification Steps
38
-
39
-### Step 1: Start the Relay Server
40
-
41
-```bash
42
-cd cmd/relay-server
43
-./relay-server
44
-
45
-# Server should start on :4017
46
-# [server] http: :4017
47
-```
48
-### Step 2: Make Test Requests
49
-
50
-In the browser console, run:
51
-
52
-```javascript
53
-// Simple text request
54
-fetch('https://api.github.com/zen')
55
- .then(r => r.text())
56
- .then(console.log);
57
-
58
-// JSON API request
59
-fetch('https://jsonplaceholder.typicode.com/posts/1')
60
- .then(r => r.json())
61
- .then(console.log);
62
-
63
-// Binary data request
64
-fetch('https://via.placeholder.com/150')
65
- .then(r => r.blob())
66
- .then(blob => console.log('Received image:', blob.size, 'bytes'));
67
-```
68
-
69
-### Step 3: Check Server Logs
70
-
71
-Watch the server console for E2EE relay logs:
72
-
73
-```bash
74
-# You should see logs like:
75
-
76
-[E2EE-RELAY] Starting E2EE tunnel relay (server acts as blind relay)
77
- lease_id=ABC123XYZ
78
-
79
-[E2EE-RELAY] Forwarding encrypted packet (server cannot decrypt)
80
- direction=Client→Lease
81
- lease_id=ABC123XYZ
82
- bytes=512
83
- total_bytes=512
84
- packet_count=1
85
- encrypted_preview=3a7f2e1d8c4b9a650f3e8d1c5b2a9746e3d8f1a4c7b2e5d9f0a3c6b8e1d4f7a2
86
-
87
-[E2EE-RELAY] Forwarding encrypted packet (server cannot decrypt)
88
- direction=Lease→Client
89
- lease_id=ABC123XYZ
90
- bytes=1024
91
- total_bytes=1536
92
- packet_count=2
93
- encrypted_preview=f9e4d3c2b1a0987654321fedcba09876543210fedcba0987654321fedcba098
94
-
95
-[E2EE-RELAY] E2EE tunnel relay completed
96
- lease_id=ABC123XYZ
97
-```
98
-
99
-## What the Logs Prove
100
-
101
-### 1. Server Cannot Decrypt
102
-
103
-The `encrypted_preview` field shows **hexadecimal gibberish**:
104
-```
105
-3a7f2e1d8c4b9a650f3e8d1c5b2a9746e3d8f1a4c7b2e5d9f0a3c6b8e1d4f7a2
106
-```
107
-
108
-This is **ChaCha20-Poly1305** encrypted data. The server:
109
-- ❌ Cannot see the HTTP headers (Host, User-Agent, etc.)
110
-- ❌ Cannot see the request method (GET, POST, etc.)
111
-- ❌ Cannot see the URL path
112
-- ❌ Cannot see the request/response body
113
-- ❌ Cannot determine if it's JSON, HTML, or binary
114
-- ✅ Can only see encrypted byte streams
115
-
116
-### 2. Blind Relay Operation
117
-
118
-The server only knows:
119
-- **Source**: Which client sent the data
120
-- **Destination**: Which lease holder should receive it
121
-- **Size**: How many bytes were transferred
122
-- **Direction**: Client→Lease or Lease→Client
123
-
124
-The server does NOT know:
125
-- What protocol is being used (HTTP, WebSocket, etc.)
126
-- What data is being transmitted
127
-- What the response contains
128
-
129
-### 3. Content-Type Detection Happens Before Encryption
130
-
131
-The Service Worker (`sw-proxy.js`) inspects `Content-Type` headers **before** passing data to WASM for encryption:
132
-
133
-```javascript
134
-// In sw-proxy.js (before encryption)
135
-const contentType = request.headers.get('content-type');
136
-if (contentType.includes('application/json')) {
137
- type = 'Text'; // or 'API'
138
-} else if (contentType.includes('multipart/form-data')) {
139
- type = 'File';
140
-}
141
-// THEN encrypt with WASM ProxyEngine
142
-```
143
-
144
-This means:
145
-- Type detection: **Client-side (unencrypted)**
146
-- Encryption: **Client-side (WASM)**
147
-- Server relay: **Blind (encrypted only)**
148
-
149
-## Comparison: Without E2EE vs With E2EE
150
-
151
-### Without E2EE (Traditional Proxy)
152
-
153
-Server log would show:
154
-```json
155
-{
156
- "method": "GET",
157
- "url": "https://api.github.com/zen",
158
- "headers": {
159
- "User-Agent": "Mozilla/5.0...",
160
- "Accept": "application/json"
161
- },
162
- "body": "...",
163
- "response_body": "Design for failure."
164
-}
165
-```
166
-
167
-### With E2EE (RelayDNS)
168
-
169
-Server log shows:
170
-```json
171
-{
172
- "direction": "Client→Lease",
173
- "encrypted_preview": "3a7f2e1d8c4b9a65...",
174
- "message": "server cannot decrypt"
175
-}
176
-```
177
-
178
-## Security Analysis
179
-
180
-### What Server CAN Do
181
-
182
-1. ✅ Count total bytes transferred
183
-2. ✅ Track connection timing (when started/ended)
184
-3. ✅ See source and destination identities (lease IDs)
185
-4. ✅ Monitor connection patterns (frequency, duration)
186
-
187
-### What Server CANNOT Do
188
-
189
-1. ❌ Decrypt any application data
190
-2. ❌ Read HTTP headers or bodies
191
-3. ❌ Modify encrypted data without detection (Poly1305 MAC)
192
-4. ❌ Perform man-in-the-middle attacks (no private keys)
193
-5. ❌ Log sensitive information (URLs, credentials, etc.)
194
-
195
-## Cryptographic Verification
196
-
197
-### Encryption Algorithm
198
-
199
-**ChaCha20-Poly1305** AEAD:
200
-- **Encryption**: ChaCha20 stream cipher (256-bit key)
201
-- **Authentication**: Poly1305 MAC (128-bit tag)
202
-- **Nonce**: 12 bytes random per message
203
-
204
-### Key Exchange
205
-
206
-**X25519** ephemeral key exchange:
207
-- Fresh keys per connection
208
-- No long-term keys stored on server
209
-- Perfect forward secrecy
210
-
211
-### Signature Verification
212
-
213
-**Ed25519** signatures:
214
-- Identity authentication
215
-- Cannot forge without private key
216
-- Server only verifies signatures, cannot decrypt
217
-
218
-## Testing Encrypted Data
219
-
220
-You can verify encryption by:
221
-
222
-1. **Inspect Network Tab** (browser):
223
- - Open DevTools → Network
224
- - Filter: WS (WebSocket)
225
- - Click on `/relay` connection
226
- - View Messages tab
227
- - You'll see binary frames (encrypted)
228
-
229
-2. **Server Logs**:
230
- - Look for `[E2EE-RELAY]` messages
231
- - `encrypted_preview` should be random hex
232
- - No plaintext should appear
233
-
234
-3. **Wireshark/tcpdump** (advanced):
235
- - Capture WebSocket traffic
236
- - All application data appears as binary blobs
237
- - No HTTP headers/bodies visible in relay tunnel
238
-
239
-## Conclusion
240
-
241
-The server logs **prove** that:
242
-
243
-1. ✅ All data is encrypted before reaching the server
244
-2. ✅ Server acts as a blind relay (cannot decrypt)
245
-3. ✅ Content-Type detection happens client-side before encryption
246
-4. ✅ E2EE architecture is working as designed
247
-
248
-The relay server is **zero-knowledge** about application content, ensuring maximum privacy and security for all relayed communications.
249
-
250
-## Further Reading
251
-
252
-- [E2EE_PROXY_INTEGRATION.md](relaydns/wasm/E2EE_PROXY_INTEGRATION.md) - Integration guide
253
-- [E2EE_PROXY_DEPLOYMENT.md](E2EE_PROXY_DEPLOYMENT.md) - Deployment guide (Korean)
254
-- [relaydns/core/cryptoops/README.md](relaydns/core/cryptoops/README.md) - Cryptographic details
255
-- [SERVICE_WORKER.md](relaydns/wasm/SERVICE_WORKER.md) - Service Worker implementation