Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for custom OpenVPN socks5 bridge client in daemon #5587

Conversation

Jontified
Copy link
Contributor

@Jontified Jontified commented Dec 13, 2023

This PR is meant to make it easier for us to use a socks5 server as an obfuscation layer for OpenVPN connections.
It aims to make local socks5 servers work without having to use split tunneling, create a CLI UI to allow easily setting this up.
To set up for easy integration into the UI.


This change is Reviewable

Copy link

linear bot commented Dec 13, 2023

@Jontified Jontified marked this pull request as draft December 13, 2023 09:38
Copy link
Member

@dlon dlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 8 of 15 files at r1, 7 of 7 files at r2, all commit messages.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @Jontified)


dist-assets/binaries line 1 at r2 (raw file):

Subproject commit d9db5c930cb3eb1d3ee048e5546be6377dedf8ab

Accidentally committed?


talpid-core/src/firewall/mod.rs line 130 at r2 (raw file):

        /// TODO
        #[cfg(any(target_os = "linux", target_os = "macos"))]
        allow_all_traffic_to_peer: bool,

What do you think of replacing peer_endpoint with an AllowedEndpoint? It has the exact same purpose.

I'm not sure if the type's name would still make sense, but you'd be able to remove both relay_client and allow_all_traffic_to_peer


talpid-core/src/firewall/mod.rs line 146 at r2 (raw file):

        /// TODO
        #[cfg(any(target_os = "linux", target_os = "macos"))]
        allow_all_traffic_to_peer: bool,

This should probably be moved down so it's grouped with relay_client.


talpid-types/src/net/mod.rs line 100 at r2 (raw file):

    pub fn get_openvpn_local_proxy_settings(&self) -> Option<&LocalProxySettings> {
        match &self {

Nit: It's already borrowed

@faern faern changed the title Implement custom openvpn socks5 bridge client in daemon des 430 Implement support for custom OpenVPN socks5 bridge client in daemon Dec 15, 2023
Copy link
Contributor Author

@Jontified Jontified left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 6 of 36 files reviewed, 2 unresolved discussions (waiting on @dlon)


talpid-core/src/firewall/mod.rs line 130 at r2 (raw file):

Previously, dlon (David Lönnhager) wrote…

What do you think of replacing peer_endpoint with an AllowedEndpoint? It has the exact same purpose.

I'm not sure if the type's name would still make sense, but you'd be able to remove both relay_client and allow_all_traffic_to_peer

Done.


dist-assets/binaries line 1 at r2 (raw file):

Previously, dlon (David Lönnhager) wrote…

Accidentally committed?

Done. Why is the old submodule not set to main though?

@Jontified Jontified force-pushed the implement-custom-openvpn-socks5-bridge-client-in-daemon-des-430 branch 2 times, most recently from ab8c900 to d451c92 Compare December 24, 2023 07:46
Copy link
Member

@dlon dlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 30 files at r3.
Reviewable status: 7 of 36 files reviewed, 1 unresolved discussion


dist-assets/binaries line 1 at r2 (raw file):

Previously, Jontified wrote…

Done. Why is the old submodule not set to main though?

The most recent commit doesn't modify any artifacts, so there's no real reason to point to it.

Copy link
Member

@dlon dlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 30 files at r3, 3 of 4 files at r4, 8 of 8 files at r5, all commit messages.
Reviewable status: 14 of 37 files reviewed, 1 unresolved discussion (waiting on @Jontified)


talpid-core/src/firewall/windows.rs line 162 at r5 (raw file):

        let relay_client_wstr_ptrs: Vec<*const u16> = relay_client_wstrs.iter().map(|wstr| wstr.as_ptr()).collect();
        let relay_client_wstr_ptrs_len = relay_client_wstr_ptrs.len();
        //let relay_client_wstr_ptr: *const u16 = if let Some(ref wstr) = relay_client_wstr {

Comments


windows/winfw/src/winfw/winfw.cpp line 408 at r5 (raw file):

		}

		auto relayClientWstrings = std::vector<std::wstring>();

Nit: std::vector<std::wstring> relayClientWstrings;

@Jontified Jontified force-pushed the implement-custom-openvpn-socks5-bridge-client-in-daemon-des-430 branch from b1872fe to 6fb2f44 Compare December 28, 2023 11:13
@Jontified Jontified removed the WIP label Dec 28, 2023
@Jontified Jontified marked this pull request as ready for review December 28, 2023 12:42
Copy link
Member

@dlon dlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 30 files at r3, 15 of 23 files at r6.
Reviewable status: 26 of 38 files reviewed, 6 unresolved discussions (waiting on @Jontified)


mullvad-cli/src/cmds/api_access.rs line 343 at r6 (raw file):

    item: SelectItem,
    /// Name of the API access method in the Mullvad client [All]
    #[arg(long)]

Is it possible to specify a group here and for item? That would make the arguments mutually exclusive.


mullvad-cli/src/cmds/api_access.rs line 358 at r6 (raw file):

    edit_params: ProxyEditParams,
    ///// Username for authentication [Socks5 (Remote proxy)]
    //#[arg(long)]

The commented code should probably be removed.


mullvad-daemon/src/management_interface.rs line 709 at r6 (raw file):

    }

    async fn get_custom_bridge(&self, _: Request<()>) -> ServiceResult<CustomBridgeSettings> {

This probably does not require a special command. This is present in the settings already.


mullvad-daemon/src/management_interface.rs line 726 at r6 (raw file):

        log::debug!("update_custom_bridge");
        let (tx, rx) = oneshot::channel();
        self.send_command_to_daemon(DaemonCommand::UpdateCustomBridge(

For consistency, maybe the settings should be updated using GetSettings + SetCustomBridge if a bridge is already set.

However, I'm not sure why we can't use the existing function SetBridgeSettings for this.


mullvad-management-interface/proto/management_interface.proto line 86 at r6 (raw file):

  // Custom proxy
  rpc SetCustomBridge(google.protobuf.Empty) returns (google.protobuf.Empty) {}

Set confused me a lot at first. I think "enable" or something might be clearer.

But this also seems redundant given that we already have a bridge_state.


mullvad-types/src/settings/mod.rs line 85 at r6 (raw file):

    /// A potential custom bridge.
    #[cfg_attr(target_os = "android", jnix(skip))]
    pub custom_bridge: CustomBridgeSettings,

I found it pretty confusing to understand the purpose of having both BridgeSettings and CustomBridgeSettings. It's probably not ideal to have a duplicated "runtime-only" state in the settings.

Have you considered updating BridgeSettings to simply store all constraints/settings independently of the current "bridge type"?

Instead of

  pub enum BridgeSettings {
      Normal(BridgeConstraints),
      Custom(ProxySettings),
  }

use something like

  enum BridgeType {
      Builtin,
      Custom,
  }

  pub struct BridgeSettings {
      bridge_type: BridgeSettingsType,
      normal: BridgeConstraints,
      custom: ProxySettings,       
  }

Then you won't lose the custom bridge settings when you stop using the custom bridge.

@Jontified Jontified force-pushed the implement-custom-openvpn-socks5-bridge-client-in-daemon-des-430 branch from 8230600 to 96b5ea2 Compare January 2, 2024 10:04
Copy link
Contributor Author

@Jontified Jontified left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 9 of 58 files reviewed, 2 unresolved discussions (waiting on @dlon)


mullvad-cli/src/cmds/api_access.rs line 343 at r6 (raw file):

Previously, dlon (David Lönnhager) wrote…

Is it possible to specify a group here and for item? That would make the arguments mutually exclusive.

I think this is far enough away from the purpose of this PR that it should be fixed somewhere else.


mullvad-management-interface/proto/management_interface.proto line 86 at r6 (raw file):

Previously, dlon (David Lönnhager) wrote…

Set confused me a lot at first. I think "enable" or something might be clearer.

But this also seems redundant given that we already have a bridge_state.

This is improved in the new other PR


mullvad-types/src/settings/mod.rs line 85 at r6 (raw file):

Previously, dlon (David Lönnhager) wrote…

I found it pretty confusing to understand the purpose of having both BridgeSettings and CustomBridgeSettings. It's probably not ideal to have a duplicated "runtime-only" state in the settings.

Have you considered updating BridgeSettings to simply store all constraints independently of the current "bridge type"?

Instead of

  pub enum BridgeSettings {
      Normal(BridgeConstraints),
      Custom(ProxySettings),
  }

use something like

  enum BridgeType {
      Builtin,
      Custom,
  }

  pub struct BridgeSettings {
      bridge_type: BridgeSettingsType,
      normal: BridgeConstraints,
      custom: ProxySettings,       
  }

Then you won't lose the custom bridge settings when you stop using the custom bridge.

Done. This is fixed, among other things in the other PR.

@Jontified Jontified requested a review from dlon January 2, 2024 10:07
Copy link
Contributor

@MarkusPettersson98 MarkusPettersson98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 2 of 23 files at r6, 3 of 4 files at r7, 1 of 3 files at r9, 33 of 40 files at r10, 8 of 8 files at r11, 3 of 3 files at r12, 2 of 2 files at r13, 3 of 3 files at r14, all commit messages.
Reviewable status: all files reviewed, 4 unresolved discussions (waiting on @dlon and @Jontified)


talpid-openvpn/src/lib.rs line 763 at r11 (raw file):

    use talpid_types::ErrorExt;
    #[cfg(target_os = "macos")]
    use talpid_types::ErrorExt;

Nit: No conditional compilation is needed here. use can be merged as well:
use talpid_types::{net::proxy::CustomProxy, ErrorExt};

Code quote:

    use talpid_types::net::proxy::CustomProxy;
    #[cfg(any(target_os = "linux", windows))]
    use talpid_types::ErrorExt;
    #[cfg(target_os = "macos")]
    use talpid_types::ErrorExt;

talpid-openvpn/src/lib.rs line 846 at r11 (raw file):

            let mut routes = HashSet::new();
            #[cfg(not(target_os = "linux"))]
            if let Some(talpid_types::net::proxy::CustomProxy::Socks5Local(proxy_settings)) =

Nit: CustomProxy is already imported in this scope, might as well use it unqualified.

Code quote:

talpid_types::net::proxy::CustomProxy::Socks5Local(proxy_settings)

@Jontified Jontified force-pushed the implement-custom-openvpn-socks5-bridge-client-in-daemon-des-430 branch from 69481a6 to df75d96 Compare January 2, 2024 14:46
Copy link
Contributor

@MarkusPettersson98 MarkusPettersson98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 30 of 40 files at r16, 6 of 8 files at r17, 3 of 3 files at r18, 7 of 7 files at r19, 1 of 1 files at r20, 6 of 6 files at r21, all commit messages.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @dlon)

Copy link
Member

@dlon dlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 40 files at r16, 1 of 8 files at r17, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

Copy link
Member

@dlon dlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r22, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

@Jontified Jontified force-pushed the implement-custom-openvpn-socks5-bridge-client-in-daemon-des-430 branch from 3247076 to b96fb43 Compare January 3, 2024 13:05
This PR has a couple of different purposes
    - Allow users to use socks5 local proxies with the CLI without
      having to be root nor use split-tunneling. This only works for
      OpenVPN.
    - Unify the types used by different proxy parts of the codebase,
      such as the Access Methods as well as some already existing
      OpenVPN proxy code.

This PR changes the firewall on all desktop platforms as well as changes
the routing table slightly on MacOS and Windows.
On Linux the firewall code is modified to apply the appropriate firewall
marks to all packages that go to a remote endpoint corresponding to the
remote part of a local socks5 proxy. The firewall marks will allow the
routing to be done without having to modify the routing table.
On MacOS and Windows the routing table is modified to allow packages to
go to that same endpoint to pass outside the VPN tunnel, it will
additionally punch a hole in the firewall.

The PR also migrates the settings file from version 7 to version 8 in order
to properly and neatly unify Proxy related types.

Finally it provides some slight extensions to the gRPC interface in
order to allow for control over the custom proxy settings.
@Jontified Jontified force-pushed the implement-custom-openvpn-socks5-bridge-client-in-daemon-des-430 branch from b96fb43 to 4fdc34a Compare January 3, 2024 13:38
@Jontified Jontified merged commit 711d4e4 into main Jan 3, 2024
38 of 39 checks passed
@Jontified Jontified deleted the implement-custom-openvpn-socks5-bridge-client-in-daemon-des-430 branch January 3, 2024 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants