Skip to content

feat: streamline support of obfs4 dialer#31

Open
ainghazal wants to merge 15 commits into
ooni:mainfrom
ainghazal:feat/obfs4-dialer-support
Open

feat: streamline support of obfs4 dialer#31
ainghazal wants to merge 15 commits into
ooni:mainfrom
ainghazal:feat/obfs4-dialer-support

Conversation

@ainghazal

Copy link
Copy Markdown
Collaborator

Before, there was a separate entry point for the obfs4 dialer. This commit will create the right dialer if a line with proxy-obfs4 is added to the openvpn config file (or the equivalent fields are set in Options).

We also allow to pass any arbitrary dialer to the obfs4 base dialer.

While doing this, some attention is given to the thought that we might want to support an arbitrary number of similar obfuscation proxies -that's why we're trying to reuse the abstractions from the gost project.

@ainghazal

Copy link
Copy Markdown
Collaborator Author

this PR is missing tests - but let me know if you think there are possible improvements in the design.

@ainghazal
ainghazal force-pushed the feat/obfs4-dialer-support branch 2 times, most recently from 448280e to ed19197 Compare September 22, 2022 17:34

@bassosimone bassosimone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems a good approach 👍

I've provided suggestions

Comment thread vpn/client.go Outdated
Comment thread vpn/client.go Outdated
Comment thread vpn/client.go Outdated
Comment thread vpn/client.go Outdated

@bassosimone bassosimone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this PR still needs some extra tests. In the meanwhile, I provided an interim review.

Comment thread .gitignore Outdated
@@ -1,5 +1,5 @@
minivpn
./obfs4vpn
obfs4vpn

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why did this change? Could we have the binary at arbitrary directories?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

it actually should be removed, the cmd/obfs4vpn endpoint was deleted.

Comment thread obfs4/common.go Outdated
// NewProxyNodeFromURI returns a configured proxy node. It accepts a string
// with all the parameters needed to establish a connection to the obfs4
// proxy, in the form "obfs4://<ip>:<port>?cert=<deadbeef>&iat-mode=<int>"
func NewProxyNodeFromURI(uri string) (ProxyNode, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would return a *ProxyNode here

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done

Comment thread obfs4/common.go
return Node{
return ProxyNode{
Protocol: u.Scheme,
Addr: net.JoinHostPort(u.Hostname(), u.Port()),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You do not seem to be checking whether a port is defined here, so what happens if you pass a URL that does not have any port? Also, u.Host is equivalent to u.Hostname() when there is a port.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good question, and good catch. It should fail if no port is specified, there's no way to assign a default port.

@ainghazal ainghazal Mar 15, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

added test for the constructor, and checked for missing port, hostname

Comment thread obfs4/obfs4.go Outdated
"golang.org/x/net/proxy"
)

type DialFunc func(string, string) (net.Conn, error)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please, document new public types. Are not using a context-enabled dialer because other projects with which you want to be compatible do not define a context-enabled dialer as well?

@ainghazal ainghazal Mar 16, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

no, I think this was mostly because obfs4 passes a DialFunc. when integrating in OONI probably reusing OBFS4Dialer (with a DialContext method) would be the right thing to do...

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I've been looking at this again, and I think the reason I avoided going that way is that it entails quite a bit of code duplication (obfs4 transport).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Did another take, I was wrong about the code duplication (probe-cli does, but I don't seem to need it here). I think I've addressed the context-enabled dialer problem now.

Comment thread vpn/client.go Outdated

const (
// dialTimeoutInSeconds tells how long to wait on Dial
dialTimeoutInSeconds = 10

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe this is a little too low; I'd use ~15 seconds here

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

sounds good

Comment thread vpn/dialer.go Outdated
Comment thread vpn/events.go
const (
// Be very careful when altering the order of these event; other libraries
// might be trusting their values, so please release a new version and
// document the changes in that case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

Comment thread vpn/options.go

// protoUDP is used for vpn in UDP mode.
protoUDP = proto("udp")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

please, create a new const ( ) block for constants using a different type.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done

Before, there was a separate entry point for the obfs4 dialer. This
commit will create the right dialer if a line with proxy-obfs4 is added
to the openvpn config file (or the equivalent fields are set in
Options).

We also allow to pass any arbitrary dialer to the obfs4 base dialer.

While doing this, some attention is given to the thought that we might
want to support an arbitrary number of similar obfuscation proxies
-that's why we're trying to reuse the abstractions from the gost
project.
this is needed so that we can pass vpn.Dialer to HTTPConfig as part of
the urlgetter experiment in OONI probe-cli.
@ainghazal
ainghazal force-pushed the feat/obfs4-dialer-support branch from d927246 to 028dca7 Compare March 16, 2023 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants