mirror of
https://github.com/TrustTunnel/TrustTunnel.git
synced 2026-07-09 17:18:36 +00:00
Pull request 139: Fix bypassing allow_private_network_connections when numeric address is used
Squashed commit of the following:
commit 8f2431214f4cab93aaf042fd5c27955d302edd95
Author: Sergey Fionov <sfionov@adguard.com>
Date: Fri Jan 23 19:02:46 2026 +0200
Add CHANGELOG.md
commit 4b6a09216a6bb724fa0ff58a24fdeb91a55b6c59
Author: Sergey Fionov <sfionov@adguard.com>
Date: Fri Jan 23 17:44:27 2026 +0200
tcp_forwarder fix
This commit is contained in:
parent
1a853af415
commit
734bb5cf10
2 changed files with 75 additions and 1 deletions
|
|
@ -1,5 +1,8 @@
|
|||
# CHANGELOG
|
||||
|
||||
- Fixed an issue where allow_private_network_connections set to false could be bypassed
|
||||
when a numeric address was used.
|
||||
|
||||
## 0.9.87
|
||||
|
||||
- Added automatic Let's Encrypt certificate generation to `setup_wizard`
|
||||
|
|
|
|||
|
|
@ -66,7 +66,19 @@ impl TcpConnector for TcpForwarder {
|
|||
meta: forwarder::TcpConnectionMeta,
|
||||
) -> Result<(Box<dyn pipe::Source>, Box<dyn pipe::Sink>), tunnel::ConnectionError> {
|
||||
let peer = match meta.destination {
|
||||
TcpDestination::Address(peer) => peer,
|
||||
TcpDestination::Address(peer) => {
|
||||
let peer_ip = peer.ip();
|
||||
if !self.context.settings.allow_private_network_connections
|
||||
&& !net_utils::is_global_ip(&peer_ip)
|
||||
{
|
||||
if peer_ip.is_loopback() {
|
||||
return Err(tunnel::ConnectionError::DnsLoopback);
|
||||
}
|
||||
return Err(tunnel::ConnectionError::DnsNonroutable);
|
||||
}
|
||||
|
||||
peer
|
||||
}
|
||||
TcpDestination::HostName(peer) => {
|
||||
log_id!(trace, id, "Resolving peer: {:?}", peer);
|
||||
|
||||
|
|
@ -238,3 +250,62 @@ fn io_to_connection_error(error: io::Error) -> tunnel::ConnectionError {
|
|||
|
||||
tunnel::ConnectionError::Io(error)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
|
||||
fn make_test_context_disallow_private_network() -> Arc<core::Context> {
|
||||
let mut ctx = core::Context::default();
|
||||
Arc::get_mut(&mut ctx.settings)
|
||||
.unwrap()
|
||||
.allow_private_network_connections = false;
|
||||
Arc::new(ctx)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_connect_denies_loopback_address_when_private_network_disallowed() {
|
||||
let context = make_test_context_disallow_private_network();
|
||||
let connector: Box<dyn TcpConnector> = Box::new(TcpForwarder::new(context));
|
||||
|
||||
let meta = forwarder::TcpConnectionMeta {
|
||||
client_address: IpAddr::V4(Ipv4Addr::new(203, 0, 113, 1)),
|
||||
destination: TcpDestination::Address(SocketAddr::from((Ipv4Addr::LOCALHOST, 22))),
|
||||
auth: None,
|
||||
tls_domain: String::new(),
|
||||
user_agent: None,
|
||||
};
|
||||
|
||||
let err = match connector.connect(log_utils::IdChain::empty(), meta).await {
|
||||
Ok(_) => panic!("Expected connection to be denied"),
|
||||
Err(e) => e,
|
||||
};
|
||||
|
||||
assert!(matches!(err, tunnel::ConnectionError::DnsLoopback));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_connect_denies_private_address_when_private_network_disallowed() {
|
||||
let context = make_test_context_disallow_private_network();
|
||||
let connector: Box<dyn TcpConnector> = Box::new(TcpForwarder::new(context));
|
||||
|
||||
let meta = forwarder::TcpConnectionMeta {
|
||||
client_address: IpAddr::V4(Ipv4Addr::new(203, 0, 113, 1)),
|
||||
destination: TcpDestination::Address(SocketAddr::from((
|
||||
Ipv4Addr::new(192, 168, 0, 1),
|
||||
80,
|
||||
))),
|
||||
auth: None,
|
||||
tls_domain: String::new(),
|
||||
user_agent: None,
|
||||
};
|
||||
|
||||
let err = match connector.connect(log_utils::IdChain::empty(), meta).await {
|
||||
Ok(_) => panic!("Expected connection to be denied"),
|
||||
Err(e) => e,
|
||||
};
|
||||
|
||||
assert!(matches!(err, tunnel::ConnectionError::DnsNonroutable));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue