summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-02-08 13:22:30 +0100
committerDavid Lönnhager <david.l@mullvad.net>2024-02-08 13:22:30 +0100
commitbc51bf6295f0c7fca273d720c624fbfee305e910 (patch)
treeca55c740372e146d9db789e1d3b657651ec0a656
parent7ab32cfb085c06460e9f7a0a886e9301c586db38 (diff)
parente1a194cd62a199e195481f937300af083e44c8fe (diff)
downloadmullvadvpn-bc51bf6295f0c7fca273d720c624fbfee305e910.tar.xz
mullvadvpn-bc51bf6295f0c7fca273d720c624fbfee305e910.zip
Merge branch 'testing-add-socks-bridge-tests'
-rw-r--r--test/test-manager/src/tests/tunnel.rs205
1 files changed, 202 insertions, 3 deletions
diff --git a/test/test-manager/src/tests/tunnel.rs b/test/test-manager/src/tests/tunnel.rs
index a66b7f7b88..3bbb832443 100644
--- a/test/test-manager/src/tests/tunnel.rs
+++ b/test/test-manager/src/tests/tunnel.rs
@@ -6,11 +6,16 @@ use crate::network_monitor::{start_packet_monitor, MonitorOptions};
use mullvad_management_interface::MullvadProxyClient;
use mullvad_types::relay_constraints::{
- self, BridgeSettings, Constraint, OpenVpnConstraints, RelayConstraints, RelaySettings,
- SelectedObfuscation, TransportPort, Udp2TcpObfuscationSettings, WireguardConstraints,
+ self, BridgeConstraints, BridgeSettings, BridgeType, Constraint, OpenVpnConstraints,
+ RelayConstraints, RelaySettings, SelectedObfuscation, TransportPort,
+ Udp2TcpObfuscationSettings, WireguardConstraints,
};
use mullvad_types::wireguard;
-use talpid_types::net::{TransportProtocol, TunnelType};
+use std::net::SocketAddr;
+use talpid_types::net::{
+ proxy::{CustomProxy, Socks5Local, Socks5Remote},
+ TransportProtocol, TunnelType,
+};
use test_macro::test_function;
use test_rpc::meta::Os;
use test_rpc::mullvad_daemon::ServiceStatus;
@@ -571,3 +576,197 @@ pub async fn test_quantum_resistant_multihop_udp2tcp_tunnel(
Ok(())
}
+
+/// Try to connect to an OpenVPN relay via a remote, passwordless SOCKS5 server.
+/// * No outgoing traffic to the bridge/entry relay is observed from the SUT.
+/// * The conncheck reports an unexpected exit relay.
+#[test_function]
+pub async fn test_remote_socks_bridge(
+ _: TestContext,
+ rpc: ServiceClient,
+ mut mullvad_client: MullvadProxyClient,
+) -> Result<(), Error> {
+ mullvad_client
+ .set_bridge_state(relay_constraints::BridgeState::On)
+ .await
+ .expect("failed to enable bridge mode");
+
+ mullvad_client
+ .set_bridge_settings(BridgeSettings {
+ bridge_type: BridgeType::Custom,
+ normal: BridgeConstraints::default(),
+ custom: Some(CustomProxy::Socks5Remote(Socks5Remote::new((
+ crate::vm::network::NON_TUN_GATEWAY,
+ crate::vm::network::SOCKS5_PORT,
+ )))),
+ })
+ .await
+ .expect("failed to update bridge settings");
+
+ set_relay_settings(
+ &mut mullvad_client,
+ RelaySettings::Normal(RelayConstraints {
+ tunnel_protocol: Constraint::Only(TunnelType::OpenVpn),
+ ..Default::default()
+ }),
+ )
+ .await
+ .expect("failed to update relay settings");
+
+ //
+ // Connect to VPN
+ //
+
+ connect_and_wait(&mut mullvad_client).await?;
+
+ let (entry, exit) = match mullvad_client.get_tunnel_state().await? {
+ mullvad_types::states::TunnelState::Connected { endpoint, .. } => {
+ (endpoint.proxy.unwrap().endpoint, endpoint.endpoint)
+ }
+ actual => {
+ panic!("unexpected tunnel state. Expected `TunnelState::Connected` but got {actual:?}")
+ }
+ };
+
+ log::info!(
+ "Selected entry bridge {entry_addr} & exit relay {exit_addr}",
+ entry_addr = entry.address,
+ exit_addr = exit.address
+ );
+
+ // Start recording outgoing packets. Their destination will be verified
+ // against the bridge's IP address later.
+ let monitor = start_packet_monitor(
+ move |packet| packet.destination.ip() == entry.address.ip(),
+ MonitorOptions::default(),
+ )
+ .await;
+
+ //
+ // Verify exit IP
+ //
+
+ log::info!("Verifying exit server");
+
+ assert!(
+ helpers::using_mullvad_exit(&rpc).await,
+ "expected Mullvad exit IP"
+ );
+
+ //
+ // Verify entry IP
+ //
+
+ log::info!("Verifying entry server");
+
+ let monitor_result = monitor.into_result().await.unwrap();
+ assert!(
+ !monitor_result.packets.is_empty(),
+ "detected no traffic to entry server",
+ );
+
+ Ok(())
+}
+
+/// Try to connect to an OpenVPN relay via a local, passwordless SOCKS5 server.
+/// * No outgoing traffic to the bridge/entry relay is observed from the SUT.
+/// * The conncheck reports an unexpected exit relay.
+#[test_function]
+pub async fn test_local_socks_bridge(
+ _: TestContext,
+ rpc: ServiceClient,
+ mut mullvad_client: MullvadProxyClient,
+) -> Result<(), Error> {
+ let remote_addr = SocketAddr::from((
+ crate::vm::network::NON_TUN_GATEWAY,
+ crate::vm::network::SOCKS5_PORT,
+ ));
+ let socks_server = rpc
+ .start_tcp_forward("127.0.0.1:0".parse().unwrap(), remote_addr)
+ .await
+ .expect("failed to start TCP forward");
+
+ mullvad_client
+ .set_bridge_state(relay_constraints::BridgeState::On)
+ .await
+ .expect("failed to enable bridge mode");
+
+ mullvad_client
+ .set_bridge_settings(BridgeSettings {
+ bridge_type: BridgeType::Custom,
+ normal: BridgeConstraints::default(),
+ custom: Some(CustomProxy::Socks5Local(
+ Socks5Local::new_with_transport_protocol(
+ remote_addr,
+ socks_server.bind_addr().port(),
+ TransportProtocol::Tcp,
+ ),
+ )),
+ })
+ .await
+ .expect("failed to update bridge settings");
+
+ set_relay_settings(
+ &mut mullvad_client,
+ RelaySettings::Normal(RelayConstraints {
+ tunnel_protocol: Constraint::Only(TunnelType::OpenVpn),
+ ..Default::default()
+ }),
+ )
+ .await
+ .expect("failed to update relay settings");
+
+ //
+ // Connect to VPN
+ //
+
+ connect_and_wait(&mut mullvad_client).await?;
+
+ let (entry, exit) = match mullvad_client.get_tunnel_state().await? {
+ mullvad_types::states::TunnelState::Connected { endpoint, .. } => {
+ (endpoint.proxy.unwrap().endpoint, endpoint.endpoint)
+ }
+ actual => {
+ panic!("unexpected tunnel state. Expected `TunnelState::Connected` but got {actual:?}")
+ }
+ };
+
+ log::info!(
+ "Selected entry bridge {entry_addr} & exit relay {exit_addr}",
+ entry_addr = entry.address,
+ exit_addr = exit.address
+ );
+
+ // Start recording outgoing packets. Their destination will be verified
+ // against the bridge's IP address later.
+ let monitor = start_packet_monitor(
+ move |packet| packet.destination.ip() == entry.address.ip(),
+ MonitorOptions::default(),
+ )
+ .await;
+
+ //
+ // Verify exit IP
+ //
+
+ log::info!("Verifying exit server");
+
+ assert!(
+ helpers::using_mullvad_exit(&rpc).await,
+ "expected Mullvad exit IP"
+ );
+
+ //
+ // Verify entry IP
+ //
+
+ log::info!("Verifying entry server");
+
+ let monitor_result = monitor.into_result().await.unwrap();
+ assert!(
+ !monitor_result.packets.is_empty(),
+ "detected no traffic to entry server",
+ );
+
+ Ok(())
+}