outbound/tls: added an option to disable certificate verification
This commit is contained in:
@@ -172,7 +172,7 @@ chrono = "0.4"
|
||||
colored = "2.0"
|
||||
|
||||
# TLS/rustls/QUIC
|
||||
tokio-rustls = { version = "0.23", optional = true }
|
||||
tokio-rustls = { version = "0.23", features = ["dangerous_configuration"], optional = true }
|
||||
webpki-roots = { version = "0.22", optional = true }
|
||||
rustls-pemfile = { version = "1.0.2", optional = true }
|
||||
|
||||
|
||||
@@ -267,6 +267,7 @@ impl OutboundManager {
|
||||
settings.server_name.clone(),
|
||||
settings.alpn.clone(),
|
||||
certificate,
|
||||
settings.insecure,
|
||||
)?);
|
||||
HandlerBuilder::default()
|
||||
.tag(tag.clone())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is generated by rust-protobuf 3.2.0. Do not edit
|
||||
// .proto file is parsed by protoc 22.2
|
||||
// .proto file is parsed by protoc 3.21.12
|
||||
// @generated
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/702
|
||||
|
||||
@@ -63,6 +63,7 @@ pub struct Proxy {
|
||||
pub ws: Option<bool>,
|
||||
pub tls: Option<bool>,
|
||||
pub tls_cert: Option<String>,
|
||||
pub tls_insecure: Option<bool>,
|
||||
pub ws_path: Option<String>,
|
||||
pub ws_host: Option<String>,
|
||||
|
||||
@@ -95,6 +96,7 @@ impl Default for Proxy {
|
||||
ws: Some(false),
|
||||
tls: Some(false),
|
||||
tls_cert: None,
|
||||
tls_insecure: Some(false),
|
||||
ws_path: None,
|
||||
ws_host: None,
|
||||
sni: None,
|
||||
@@ -391,6 +393,9 @@ pub fn from_lines(lines: Vec<io::Result<String>>) -> Result<Config> {
|
||||
"tls-cert" => {
|
||||
proxy.tls_cert = Some(v.to_string());
|
||||
}
|
||||
"tls-insecure" => {
|
||||
proxy.tls_insecure = if v == "true" { Some(true) } else { Some(false) }
|
||||
}
|
||||
"ws-path" => {
|
||||
proxy.ws_path = Some(v.to_string());
|
||||
}
|
||||
@@ -923,6 +928,7 @@ pub fn to_internal(conf: &mut Config) -> Result<internal::Config> {
|
||||
tls_settings.certificate = path;
|
||||
}
|
||||
}
|
||||
tls_settings.insecure = ext_proxy.tls_insecure.unwrap_or_default();
|
||||
let tls_settings = tls_settings.write_to_bytes().unwrap();
|
||||
tls_outbound.settings = tls_settings;
|
||||
tls_outbound.tag = format!("{}_tls_xxx", ext_proxy.tag.clone());
|
||||
@@ -1068,6 +1074,7 @@ pub fn to_internal(conf: &mut Config) -> Result<internal::Config> {
|
||||
tls_settings.certificate = path;
|
||||
}
|
||||
}
|
||||
tls_settings.insecure = ext_proxy.tls_insecure.unwrap_or_default();
|
||||
let tls_settings = tls_settings.write_to_bytes().unwrap();
|
||||
tls_outbound.settings = tls_settings;
|
||||
tls_outbound.tag = format!("{}_tls_xxx", ext_proxy.tag.clone());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is generated by rust-protobuf 3.2.0. Do not edit
|
||||
// .proto file is parsed by protoc 22.2
|
||||
// .proto file is parsed by protoc 3.21.12
|
||||
// @generated
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/702
|
||||
|
||||
@@ -123,6 +123,7 @@ message TlsOutboundSettings {
|
||||
string server_name = 1;
|
||||
repeated string alpn = 2;
|
||||
string certificate = 3;
|
||||
bool insecure = 4;
|
||||
}
|
||||
|
||||
message WebSocketOutboundSettings {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is generated by rust-protobuf 3.2.0. Do not edit
|
||||
// .proto file is parsed by protoc 22.2
|
||||
// .proto file is parsed by protoc 3.21.12
|
||||
// @generated
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/702
|
||||
@@ -2183,6 +2183,8 @@ pub struct TlsOutboundSettings {
|
||||
pub alpn: ::std::vec::Vec<::std::string::String>,
|
||||
// @@protoc_insertion_point(field:TlsOutboundSettings.certificate)
|
||||
pub certificate: ::std::string::String,
|
||||
// @@protoc_insertion_point(field:TlsOutboundSettings.insecure)
|
||||
pub insecure: bool,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:TlsOutboundSettings.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
@@ -2219,6 +2221,9 @@ impl ::protobuf::Message for TlsOutboundSettings {
|
||||
26 => {
|
||||
self.certificate = is.read_string()?;
|
||||
},
|
||||
32 => {
|
||||
self.insecure = is.read_bool()?;
|
||||
},
|
||||
tag => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||
},
|
||||
@@ -2240,6 +2245,9 @@ impl ::protobuf::Message for TlsOutboundSettings {
|
||||
if !self.certificate.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(3, &self.certificate);
|
||||
}
|
||||
if self.insecure != false {
|
||||
my_size += 1 + 1;
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||
self.special_fields.cached_size().set(my_size as u32);
|
||||
my_size
|
||||
@@ -2255,6 +2263,9 @@ impl ::protobuf::Message for TlsOutboundSettings {
|
||||
if !self.certificate.is_empty() {
|
||||
os.write_string(3, &self.certificate)?;
|
||||
}
|
||||
if self.insecure != false {
|
||||
os.write_bool(4, self.insecure)?;
|
||||
}
|
||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
@@ -2275,6 +2286,7 @@ impl ::protobuf::Message for TlsOutboundSettings {
|
||||
self.server_name.clear();
|
||||
self.alpn.clear();
|
||||
self.certificate.clear();
|
||||
self.insecure = false;
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
@@ -2283,6 +2295,7 @@ impl ::protobuf::Message for TlsOutboundSettings {
|
||||
server_name: ::std::string::String::new(),
|
||||
alpn: ::std::vec::Vec::new(),
|
||||
certificate: ::std::string::String::new(),
|
||||
insecure: false,
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
|
||||
@@ -148,6 +148,7 @@ pub struct TlsOutboundSettings {
|
||||
pub server_name: Option<String>,
|
||||
pub alpn: Option<Vec<String>>,
|
||||
pub certificate: Option<String>,
|
||||
pub insecure: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@@ -610,7 +611,8 @@ pub fn to_internal(json: &mut Config) -> Result<internal::Config> {
|
||||
let ext_settings: ObfsOutboundSettings =
|
||||
serde_json::from_str(ext_outbound.settings.as_ref().unwrap().get())
|
||||
.unwrap();
|
||||
if let Some(ext_method) = ext_settings.method { // TODO checks
|
||||
if let Some(ext_method) = ext_settings.method {
|
||||
// TODO checks
|
||||
settings.method = ext_method;
|
||||
} else {
|
||||
settings.method = "http".to_string();
|
||||
@@ -674,6 +676,7 @@ pub fn to_internal(json: &mut Config) -> Result<internal::Config> {
|
||||
settings.certificate = path;
|
||||
}
|
||||
}
|
||||
settings.insecure = ext_settings.insecure.unwrap_or_default();
|
||||
}
|
||||
let settings = settings.write_to_bytes().unwrap();
|
||||
outbound.settings = settings;
|
||||
|
||||
@@ -26,6 +26,32 @@ use {
|
||||
|
||||
use crate::{proxy::*, session::Session};
|
||||
|
||||
#[cfg(feature = "rustls-tls")]
|
||||
mod dangerous {
|
||||
use std::time::SystemTime;
|
||||
use tokio_rustls::rustls::{
|
||||
client::{ServerCertVerified, ServerCertVerifier},
|
||||
Certificate, ServerName,
|
||||
};
|
||||
|
||||
pub(super) struct NotVerified;
|
||||
|
||||
impl ServerCertVerifier for NotVerified {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
_end_entity: &Certificate,
|
||||
_intermediates: &[Certificate],
|
||||
server_name: &ServerName,
|
||||
_scts: &mut dyn Iterator<Item = &[u8]>,
|
||||
_ocsp_response: &[u8],
|
||||
_now: SystemTime,
|
||||
) -> core::result::Result<ServerCertVerified, rustls::Error> {
|
||||
log::debug!("TLS cert for {:?} not verified", server_name);
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Handler {
|
||||
server_name: String,
|
||||
#[cfg(feature = "rustls-tls")]
|
||||
@@ -39,6 +65,7 @@ impl Handler {
|
||||
server_name: String,
|
||||
alpns: Vec<String>,
|
||||
certificate: Option<String>,
|
||||
insecure: bool,
|
||||
) -> Result<Self> {
|
||||
#[cfg(feature = "rustls-tls")]
|
||||
{
|
||||
@@ -66,12 +93,14 @@ impl Handler {
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
let mut config = ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(root_cert_store)
|
||||
.with_no_client_auth();
|
||||
|
||||
if insecure {
|
||||
let mut dangerous_config = config.dangerous();
|
||||
dangerous_config.set_certificate_verifier(Arc::new(dangerous::NotVerified));
|
||||
}
|
||||
for alpn in alpns {
|
||||
config.alpn_protocols.push(alpn.as_bytes().to_vec());
|
||||
}
|
||||
@@ -96,6 +125,9 @@ impl Handler {
|
||||
.concat();
|
||||
builder.set_alpn_protos(&wire).expect("set alpn failed");
|
||||
}
|
||||
if insecure {
|
||||
builder.set_verify(openssl::ssl::SslVerifyMode::NONE);
|
||||
}
|
||||
let ssl_connector = builder.build();
|
||||
Ok(Handler {
|
||||
server_name,
|
||||
|
||||
Reference in New Issue
Block a user