chore: fix keyles dir config
rabbitprincess committed
Mar 7, 2026 at 22:18 UTC
62c34c1204efb952c8b54997282bed28be2fc140
4 files changed
+96
-96
cmd/relay-server/main.go
+1
-1
@@ -15,7 +15,7 @@ const (
15
defaultAPIPort = 4017
16
defaultSNIPort = 443
17
defaultPortalURL = "https://localhost:4017"
18
- defaultKeylessDir = ".portal-certs"
18
+ defaultKeylessDir = "./.portal-certs"
19
)
20
21
type relayServerConfig struct {
docker-compose.yml
+2
-2
@@ -19,7 +19,7 @@ services:
19
TRUSTED_PROXY_CIDRS: ${TRUSTED_PROXY_CIDRS:-}
20
21
# TLS/ACME and keyless materials
22
- KEYLESS_DIR: ${KEYLESS_DIR:-.portal-certs}
22
+ KEYLESS_DIR: /.portal-certs
23
ACME_DNS_PROVIDER: ${ACME_DNS_PROVIDER:-cloudflare}
24
CLOUDFLARE_TOKEN: ${CLOUDFLARE_TOKEN:-}
25
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
@@ -32,5 +32,5 @@ services:
32
- "${API_PORT:-4017}:${API_PORT:-4017}"
33
- "443:443"
34
volumes:
35
- - ./.portal-certs:/.portal-certs
35
+ - ${KEYLESS_DIR:-./.portal-certs}:/.portal-certs
36
restart: unless-stopped
docs/deployment.md
+2
-2
@@ -129,7 +129,7 @@ PORTAL_URL=https://example.com
129
BOOTSTRAP_URIS=https://example.com
130
SNI_PORT=443
131
ADMIN_SECRET_KEY=your-admin-secret
132
-KEYLESS_DIR=.portal-certs
132
+KEYLESS_DIR=./.portal-certs
133
ACME_DNS_PROVIDER=cloudflare
134
CLOUDFLARE_TOKEN=cf_xxxxxxxxxxxxxxxxx
135
```
@@ -137,7 +137,7 @@ CLOUDFLARE_TOKEN=cf_xxxxxxxxxxxxxxxxx
137
Route53 example:
138
139
```bash
140
-KEYLESS_DIR=.portal-certs
140
+KEYLESS_DIR=./.portal-certs
141
ACME_DNS_PROVIDER=route53
142
AWS_ACCESS_KEY_ID=AKIA...
143
AWS_SECRET_ACCESS_KEY=...
sdk/helper_test.go
+91
-91
@@ -11,6 +11,97 @@ import (
11
"time"
12
)
13
14
+func TestRunHTTPAppRelayOnly(t *testing.T) {
15
+ t.Parallel()
16
+
17
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
18
+ if err != nil {
19
+ t.Fatalf("Listen() error = %v", err)
20
+ }
21
+ defer listener.Close()
22
+
23
+ ctx, cancel := context.WithCancel(context.Background())
24
+ defer cancel()
25
+
26
+ errCh := make(chan error, 1)
27
+ go func() {
28
+ errCh <- RunHTTP(ctx, listener, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
29
+ _, _ = io.WriteString(w, "ok")
30
+ }), "")
31
+ }()
32
+
33
+ waitForHTTP(t, "http://"+listener.Addr().String())
34
+ cancel()
35
+
36
+ select {
37
+ case err := <-errCh:
38
+ if err != nil {
39
+ t.Fatalf("RunHTTPApp() error = %v", err)
40
+ }
41
+ case <-time.After(3 * time.Second):
42
+ t.Fatal("RunHTTPApp() did not exit after context cancellation")
43
+ }
44
+}
45
+
46
+func TestRunHTTPAppLocalAndRelay(t *testing.T) {
47
+ t.Parallel()
48
+
49
+ relayListener, err := net.Listen("tcp", "127.0.0.1:0")
50
+ if err != nil {
51
+ t.Fatalf("Listen() error = %v", err)
52
+ }
53
+ defer relayListener.Close()
54
+
55
+ localListener, err := net.Listen("tcp", "127.0.0.1:0")
56
+ if err != nil {
57
+ t.Fatalf("Listen() error = %v", err)
58
+ }
59
+ localAddr := localListener.Addr().String()
60
+ _ = localListener.Close()
61
+
62
+ ctx, cancel := context.WithCancel(context.Background())
63
+ defer cancel()
64
+
65
+ errCh := make(chan error, 1)
66
+ go func() {
67
+ errCh <- RunHTTP(ctx, relayListener, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
68
+ _, _ = io.WriteString(w, "ok")
69
+ }), localAddr)
70
+ }()
71
+
72
+ waitForHTTP(t, "http://"+relayListener.Addr().String())
73
+ waitForHTTP(t, "http://"+localAddr)
74
+ cancel()
75
+
76
+ select {
77
+ case err := <-errCh:
78
+ if err != nil {
79
+ t.Fatalf("RunHTTPApp() error = %v", err)
80
+ }
81
+ case <-time.After(3 * time.Second):
82
+ t.Fatal("RunHTTPApp() did not exit after context cancellation")
83
+ }
84
+}
85
+
86
+func waitForHTTP(t *testing.T, rawURL string) {
87
+ t.Helper()
88
+
89
+ client := &http.Client{Timeout: 200 * time.Millisecond}
90
+ deadline := time.Now().Add(3 * time.Second)
91
+ for time.Now().Before(deadline) {
92
+ resp, err := client.Get(rawURL)
93
+ if err == nil {
94
+ _ = resp.Body.Close()
95
+ if resp.StatusCode == http.StatusOK {
96
+ return
97
+ }
98
+ }
99
+ time.Sleep(50 * time.Millisecond)
100
+ }
101
+
102
+ t.Fatalf("timed out waiting for %s", rawURL)
103
+}
104
+
105
func TestMergeListenersRequiresInput(t *testing.T) {
106
t.Parallel()
107
@@ -162,94 +253,3 @@ func TestMergeListenersCloseUnblocksAccept(t *testing.T) {
253
t.Fatal("Accept() did not unblock after Close()")
254
}
255
}
165
-
166
-func TestRunHTTPAppRelayOnly(t *testing.T) {
167
- t.Parallel()
168
-
169
- listener, err := net.Listen("tcp", "127.0.0.1:0")
170
- if err != nil {
171
- t.Fatalf("Listen() error = %v", err)
172
- }
173
- defer listener.Close()
174
-
175
- ctx, cancel := context.WithCancel(context.Background())
176
- defer cancel()
177
-
178
- errCh := make(chan error, 1)
179
- go func() {
180
- errCh <- RunHTTP(ctx, listener, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
181
- _, _ = io.WriteString(w, "ok")
182
- }), "")
183
- }()
184
-
185
- waitForHTTP(t, "http://"+listener.Addr().String())
186
- cancel()
187
-
188
- select {
189
- case err := <-errCh:
190
- if err != nil {
191
- t.Fatalf("RunHTTPApp() error = %v", err)
192
- }
193
- case <-time.After(3 * time.Second):
194
- t.Fatal("RunHTTPApp() did not exit after context cancellation")
195
- }
196
-}
197
-
198
-func TestRunHTTPAppLocalAndRelay(t *testing.T) {
199
- t.Parallel()
200
-
201
- relayListener, err := net.Listen("tcp", "127.0.0.1:0")
202
- if err != nil {
203
- t.Fatalf("Listen() error = %v", err)
204
- }
205
- defer relayListener.Close()
206
-
207
- localListener, err := net.Listen("tcp", "127.0.0.1:0")
208
- if err != nil {
209
- t.Fatalf("Listen() error = %v", err)
210
- }
211
- localAddr := localListener.Addr().String()
212
- _ = localListener.Close()
213
-
214
- ctx, cancel := context.WithCancel(context.Background())
215
- defer cancel()
216
-
217
- errCh := make(chan error, 1)
218
- go func() {
219
- errCh <- RunHTTP(ctx, relayListener, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
220
- _, _ = io.WriteString(w, "ok")
221
- }), localAddr)
222
- }()
223
-
224
- waitForHTTP(t, "http://"+relayListener.Addr().String())
225
- waitForHTTP(t, "http://"+localAddr)
226
- cancel()
227
-
228
- select {
229
- case err := <-errCh:
230
- if err != nil {
231
- t.Fatalf("RunHTTPApp() error = %v", err)
232
- }
233
- case <-time.After(3 * time.Second):
234
- t.Fatal("RunHTTPApp() did not exit after context cancellation")
235
- }
236
-}
237
-
238
-func waitForHTTP(t *testing.T, rawURL string) {
239
- t.Helper()
240
-
241
- client := &http.Client{Timeout: 200 * time.Millisecond}
242
- deadline := time.Now().Add(3 * time.Second)
243
- for time.Now().Before(deadline) {
244
- resp, err := client.Get(rawURL)
245
- if err == nil {
246
- _ = resp.Body.Close()
247
- if resp.StatusCode == http.StatusOK {
248
- return
249
- }
250
- }
251
- time.Sleep(50 * time.Millisecond)
252
- }
253
-
254
- t.Fatalf("timed out waiting for %s", rawURL)
255
-}