4
4
"context"
5
5
"crypto/rand"
6
6
"crypto/tls"
7
+ "crypto/x509"
7
8
"encoding/binary"
8
9
"errors"
9
10
"flag"
@@ -64,16 +65,18 @@ func main() {
64
65
65
66
func loop (l log.Logger , ctx context.Context ) error {
66
67
var (
67
- addr string
68
- tlsCert string
69
- tlsKey string
70
- backend string
68
+ addr string
69
+ tlsCert string
70
+ tlsKey string
71
+ backend string
72
+ mtlsCACerts string
71
73
)
72
74
73
75
flag .StringVar (& addr , "listen" , "127.0.0.1:853" , "UDP address to listen on." )
74
- flag .StringVar (& tlsCert , "cert" , "cert.pem " , "TLS certificate path ." )
75
- flag .StringVar (& tlsKey , "key" , "key.pem " , "TLS key path ." )
76
+ flag .StringVar (& tlsCert , "cert" , "server.crt " , "Path to server TLS certificate." )
77
+ flag .StringVar (& tlsKey , "key" , "server.key " , "Path to server TLS key." )
76
78
flag .StringVar (& backend , "backend" , "8.8.4.4:53" , "IP of backend server." )
79
+ flag .StringVar (& mtlsCACerts , "mtls_ca_certs" , "" , "Path to CA bundle for mTLS." )
77
80
78
81
flag .Parse ()
79
82
@@ -82,12 +85,27 @@ func loop(l log.Logger, ctx context.Context) error {
82
85
return fmt .Errorf ("load certificate: %w" , err )
83
86
}
84
87
85
- tls := tls.Config {
88
+ tlsConfig := tls.Config {
86
89
Certificates : []tls.Certificate {cert },
87
90
NextProtos : []string {"doq" },
88
91
}
89
92
90
- listener , err := quic .ListenAddr (addr , & tls , nil )
93
+ if mtlsCACerts != "" {
94
+ pems , err := os .ReadFile (mtlsCACerts )
95
+ if err != nil {
96
+ return fmt .Errorf ("load mTLS CA certificates: %w" , err )
97
+ }
98
+ pool := x509 .NewCertPool ()
99
+ if ok := pool .AppendCertsFromPEM (pems ); ! ok {
100
+ return fmt .Errorf ("load mTLS CA certificates: found no certificate" )
101
+ }
102
+
103
+ tlsConfig .ClientCAs = pool
104
+ tlsConfig .ClientAuth = tls .RequireAndVerifyClientCert
105
+
106
+ }
107
+
108
+ listener , err := quic .ListenAddr (addr , & tlsConfig , nil )
91
109
if err != nil {
92
110
return fmt .Errorf ("listen: %w" , err )
93
111
}
@@ -105,6 +123,12 @@ func loop(l log.Logger, ctx context.Context) error {
105
123
}
106
124
107
125
l := log .With (l , "client" , session .RemoteAddr ())
126
+
127
+ certs := session .ConnectionState ().TLS .PeerCertificates
128
+ if len (certs ) > 0 {
129
+ l = log .With (l , "client_cert_subject" , certs [0 ].Subject )
130
+ }
131
+
108
132
wg .Add (1 )
109
133
go func () {
110
134
handleClient (l , ctx , session , backend )
0 commit comments