+2
cmd/hythlodaeus/main.go
+2
cmd/hythlodaeus/main.go
···
26
26
grpcKey = flag.String("grpc-key", "./var/tls.key", "the TLS key to serve grpc")
27
27
httpBind = flag.String("http-bind", ":80", "the host:port to bind plain HTTP")
28
28
httpsBind = flag.String("https-bind", ":443", "the host:port to bind secure HTTPS")
29
+
proxyProto = flag.Bool("proxy-proto", false, "if true, use haproxy proxy protocol")
29
30
telemetryEnable = flag.Bool("telemetry-enable", false, "if true, enable request telemetry bundling to object storage")
30
31
telemetryBucket = flag.String("telemetry-bucket", "relayd-logs", "object storage bucket to dump logs to")
31
32
telemetryPathStyle = flag.Bool("telemetry-path-style", false, "if true, use s3 path style")
···
60
61
server.WithGRPCKey(*grpcKey),
61
62
server.WithHTTPBind(*httpBind),
62
63
server.WithHTTPSBind(*httpsBind),
64
+
server.WithProxyProto(*proxyProto),
63
65
server.WithTelemetryConfig(telemetry.Config{
64
66
Bucket: *telemetryBucket,
65
67
PathStyle: *telemetryPathStyle,
+1
go.mod
+1
go.mod
+2
go.sum
+2
go.sum
···
259
259
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
260
260
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
261
261
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
262
+
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
263
+
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
262
264
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
263
265
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
264
266
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+8
server/config.go
+8
server/config.go
···
9
9
grpcInsecure bool
10
10
httpBind string
11
11
httpsBind string
12
+
proxyProto bool
12
13
telemetryConfig telemetry.Config
13
14
}
14
15
···
20
21
grpcKey: "",
21
22
httpBind: ":80",
22
23
httpsBind: ":443",
24
+
proxyProto: false,
23
25
}
24
26
}
25
27
···
59
61
func WithHTTPSBind(httpsBind string) Option {
60
62
return func(cfg *config) {
61
63
cfg.httpsBind = httpsBind
64
+
}
65
+
}
66
+
67
+
func WithProxyProto(proxyProto bool) Option {
68
+
return func(cfg *config) {
69
+
cfg.proxyProto = proxyProto
62
70
}
63
71
}
64
72
+35
-11
server/server.go
+35
-11
server/server.go
···
13
13
"git.xeserv.us/Techaro/hythlodaeus/telemetry"
14
14
"git.xeserv.us/Techaro/hythlodaeus/watcher"
15
15
"github.com/exaring/ja4plus"
16
+
"github.com/pires/go-proxyproto"
16
17
"golang.org/x/net/http2"
17
18
"golang.org/x/sync/errgroup"
18
19
"google.golang.org/grpc"
···
93
94
})
94
95
95
96
eg.Go(func() error {
97
+
tc := &tls.Config{
98
+
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
99
+
return s.routingTable.Load().(*RoutingTable).GetCertificate(hello.ServerName)
100
+
},
101
+
GetConfigForClient: func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
102
+
s.ja4m.StoreFingerprintFromClientHello(chi)
103
+
return nil, nil
104
+
},
105
+
}
106
+
96
107
srv := http.Server{
97
108
Addr: s.cfg.httpsBind,
98
109
Handler: s.ja4m.Wrap(s.sink.Middleware(s)),
99
110
ConnState: s.ja4m.ConnStateCallback,
100
-
TLSConfig: &tls.Config{
101
-
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
102
-
return s.routingTable.Load().(*RoutingTable).GetCertificate(hello.ServerName)
103
-
},
104
-
GetConfigForClient: func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
105
-
s.ja4m.StoreFingerprintFromClientHello(chi)
106
-
return nil, nil
107
-
},
108
-
},
111
+
TLSConfig: tc,
109
112
}
110
113
111
114
slog.Info("starting server", "protocol", "https", "addr", srv.Addr)
112
115
113
116
healthSrv.SetServingStatus("https", healthv1.HealthCheckResponse_SERVING)
114
117
115
-
err := srv.ListenAndServeTLS("", "")
118
+
lis, err := net.Listen("tcp", s.cfg.httpsBind)
119
+
if err != nil {
120
+
return fmt.Errorf("error listening on %s: %v", s.cfg.httpsBind, err)
121
+
}
122
+
defer lis.Close()
123
+
124
+
if s.cfg.proxyProto {
125
+
lis = &proxyproto.Listener{Listener: lis}
126
+
}
127
+
lis = tls.NewListener(lis, tc)
128
+
129
+
err = srv.Serve(lis)
116
130
if err != nil {
117
131
return fmt.Errorf("error serving tls: %w", err)
118
132
}
···
129
143
130
144
healthSrv.SetServingStatus("http", healthv1.HealthCheckResponse_SERVING)
131
145
132
-
err := srv.ListenAndServe()
146
+
lis, err := net.Listen("tcp", s.cfg.httpsBind)
147
+
if err != nil {
148
+
return fmt.Errorf("error listening on %s: %v", s.cfg.httpsBind, err)
149
+
}
150
+
defer lis.Close()
151
+
152
+
if s.cfg.proxyProto {
153
+
lis = &proxyproto.Listener{Listener: lis}
154
+
}
155
+
156
+
err = srv.Serve(lis)
133
157
if err != nil {
134
158
return fmt.Errorf("error serving non-tls: %w", err)
135
159
}