@@ -15,8 +15,9 @@ use futures_util::{sink::SinkExt, stream::StreamExt, TryStreamExt};
15
15
use http:: { header:: HOST , HeaderMap } ;
16
16
use std:: sync:: Arc ;
17
17
use tokio_tungstenite:: {
18
- connect_async,
18
+ connect_async, connect_async_tls_with_config ,
19
19
tungstenite:: { protocol:: CloseFrame , Message as MsgTng } ,
20
+ Connector ,
20
21
} ;
21
22
use tower_http:: trace:: TraceLayer ;
22
23
@@ -144,6 +145,84 @@ fn make_outbound_request(
144
145
Ok ( request)
145
146
}
146
147
148
+ fn make_insecure_connector ( ) -> Option < Connector > {
149
+ #[ cfg( feature = "native-tls" ) ]
150
+ {
151
+ match native_tls:: TlsConnector :: builder ( )
152
+ . danger_accept_invalid_certs ( true )
153
+ . build ( )
154
+ {
155
+ Ok ( connector) => Some ( Connector :: NativeTls ( connector) ) ,
156
+ Err ( err) => {
157
+ tracing:: error!( error = ?err, "error building native TLS connector" ) ;
158
+ None
159
+ }
160
+ }
161
+ }
162
+ #[ cfg( feature = "rustls" ) ]
163
+ {
164
+ use rustls:: {
165
+ client:: danger:: { HandshakeSignatureValid , ServerCertVerified , ServerCertVerifier } ,
166
+ pki_types:: { CertificateDer , ServerName , UnixTime } ,
167
+ ClientConfig , DigitallySignedStruct , SignatureScheme ,
168
+ } ;
169
+
170
+ #[ derive( Debug ) ]
171
+ struct NoCertVerification ;
172
+
173
+ impl ServerCertVerifier for NoCertVerification {
174
+ fn verify_server_cert (
175
+ & self ,
176
+ _: & CertificateDer < ' _ > ,
177
+ _: & [ CertificateDer < ' _ > ] ,
178
+ _: & ServerName < ' _ > ,
179
+ _: & [ u8 ] ,
180
+ _: UnixTime ,
181
+ ) -> Result < ServerCertVerified , rustls:: Error > {
182
+ Ok ( ServerCertVerified :: assertion ( ) )
183
+ }
184
+
185
+ fn verify_tls12_signature (
186
+ & self ,
187
+ _: & [ u8 ] ,
188
+ _: & CertificateDer < ' _ > ,
189
+ _: & DigitallySignedStruct ,
190
+ ) -> Result < HandshakeSignatureValid , rustls:: Error > {
191
+ Ok ( HandshakeSignatureValid :: assertion ( ) )
192
+ }
193
+
194
+ fn verify_tls13_signature (
195
+ & self ,
196
+ _: & [ u8 ] ,
197
+ _: & CertificateDer < ' _ > ,
198
+ _: & DigitallySignedStruct ,
199
+ ) -> Result < HandshakeSignatureValid , rustls:: Error > {
200
+ Ok ( HandshakeSignatureValid :: assertion ( ) )
201
+ }
202
+
203
+ fn supported_verify_schemes ( & self ) -> Vec < SignatureScheme > {
204
+ vec ! [
205
+ SignatureScheme :: ED25519 ,
206
+ SignatureScheme :: ECDSA_NISTP256_SHA256 ,
207
+ SignatureScheme :: ECDSA_NISTP384_SHA384 ,
208
+ SignatureScheme :: ECDSA_NISTP521_SHA512 ,
209
+ SignatureScheme :: RSA_PSS_SHA256 ,
210
+ SignatureScheme :: RSA_PSS_SHA384 ,
211
+ SignatureScheme :: RSA_PSS_SHA512 ,
212
+ SignatureScheme :: ED448 ,
213
+ ]
214
+ }
215
+ }
216
+
217
+ Some ( Connector :: Rustls ( std:: sync:: Arc :: new (
218
+ ClientConfig :: builder ( )
219
+ . dangerous ( )
220
+ . with_custom_certificate_verifier ( Arc :: new ( NoCertVerification { } ) )
221
+ . with_no_client_auth ( ) ,
222
+ ) ) )
223
+ }
224
+ }
225
+
147
226
impl ProxyHandlerHttp {
148
227
/// Construct a new instance.
149
228
pub fn new (
@@ -243,6 +322,8 @@ pub struct ProxyHandlerWebSocket {
243
322
rewrite : Option < String > ,
244
323
/// The headers to inject with the request
245
324
request_headers : HeaderMap ,
325
+ /// Allow insecure TLS websocket connections.
326
+ insecure : bool ,
246
327
}
247
328
248
329
impl ProxyHandlerWebSocket {
@@ -252,12 +333,14 @@ impl ProxyHandlerWebSocket {
252
333
backend : Uri ,
253
334
headers : HeaderMap ,
254
335
rewrite : Option < String > ,
336
+ insecure : bool ,
255
337
) -> Arc < Self > {
256
338
Arc :: new ( Self {
257
339
proto,
258
340
backend,
259
341
rewrite,
260
342
request_headers : headers,
343
+ insecure,
261
344
} )
262
345
}
263
346
@@ -337,8 +420,15 @@ impl ProxyHandlerWebSocket {
337
420
}
338
421
} ;
339
422
423
+ let connect_result = if self . insecure {
424
+ connect_async_tls_with_config ( outbound_request, None , false , make_insecure_connector ( ) )
425
+ . await
426
+ } else {
427
+ connect_async ( outbound_request) . await
428
+ } ;
429
+
340
430
// Establish WS connection to backend.
341
- let ( backend, _res) = match connect_async ( outbound_request ) . await {
431
+ let ( backend, _res) = match connect_result {
342
432
Ok ( backend) => backend,
343
433
Err ( err) => {
344
434
tracing:: error!( error = ?err, "error establishing WebSocket connection to backend {:?} for proxy" , & outbound_uri) ;
0 commit comments