-
Notifications
You must be signed in to change notification settings - Fork 54
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
feat(miniooni): use a remote miniooni instance to measure #969
Draft
bassosimone
wants to merge
5
commits into
master
Choose a base branch
from
remotessh
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This commit extends miniooni to be able to use a remote instance of miniooni for performing OONI measurements. The main use case for this functionality is to run measurements inside another network that has censorship for QA purposes. We currently support two transports for implementing remoting: 1. "tcp", which uses a cleartext TCP connection 2. "ssh", which uses SSH The tcp transport is useful when you trust the network that transports packets from and to the two miniooni instances. The ssh transport covers the case where you want a secure channel to transport packets between the two miniooni instances. To start the remotetcp server, run this command as `root`: ``` ./miniooni remotetcp ``` To start the remotessh server, run this command as `root`: ``` ./miniooni remotessh ``` On the local side, you need to create `$HOME/.miniooni/remote/config.yaml`, which must look like the following: ```YAML remotes: foobar_tcp: address: "1.2.3.4:5555" transport: "tcp" foobar_ssh: address: "1.2.3.4:2222" transport: "ssh" ssh: user: "root" ``` The ports in the above example are the default ones used by `remotetcp` and `remotessh`. On the command line, you can enable remoting by adding `--remote=NAME`, where NAME is the remote name. For example: ``` ./miniooni -n --remote foobar_ssh example ``` Note that this command will only work if you have an active instance of the ssh-agent (i.e., `SSH_AGENT_SOCK` is defined). Having described the functionality, let us explain how we implemented all of this. We have reintroduced the possibility of completely taking over the basic `netxlite` primitives: 1. dialing a TCP or UDP conn 2. looking up a domain name using getaddrinfo 3. creating a listening UDP socket When you use `--remote NAME`, the code will do the following: 1. read the config file 2. figure out the right remote 3. establish a connection with the remote 4. create a TCP/IP stack in userspace 5. create a TUN device in userspace that gets all the packets generated by the TCP/IP stack in userspace 6. overwrite netxlite primitives so they use the TCP/IP stack in userspace instead of the Go standard library 7. setup routing between the connection with the remote and the TUN device in userspace so we route packets 8. run the desired experiments as usual On the server side, we do something similar, except that we use a real TUN device as implemented by Linux. (We only support Linux servers at the moment.) Once the real TUN device has been created we setup masquerading for it, and then we we route between the connection with the miniooni client and the real TUN device. We don't currently implement censorship, but the real TUN device is clearly the right place where to do that.
I tested this code for ~30 minutes and it eventually crashed like this:
I suspect using a SSH channel in the middle exposed issues of the implementation. The crash, in fact, does not seem related to new code I added today but rather to previously existing code. |
Conflicts: internal/cmd/miniooni/main.go
bassosimone
added a commit
that referenced
this pull request
Oct 12, 2022
This functionality has slightly changed since when we removed it in ooni/probe#2224. Nevertheless, in #969, we determined that something like the previous TProxy, with small changes, was required to support ooni/probe#2340.
bassosimone
added a commit
that referenced
this pull request
Oct 12, 2022
We originally removed the TProxy in ooni/probe#2224. Nevertheless, in #969, we determined that something like the previous TProxy, with small changes, was required to support ooni/probe#2340. So, this pull request reintroduces a slightly-modified TProxy functionality that better adapts to the `--remote=REMOTE` use case.
bassosimone
added a commit
that referenced
this pull request
Oct 12, 2022
This change ensures that, in turn, we're able to remote all the traffic generated by geolocate, rather than missing some bits of it that were still using the standard library. Extracted from #969. Closes ooni/probe#1383. Part of ooni/probe#2340.
bassosimone
added a commit
that referenced
this pull request
Oct 12, 2022
This change ensures that, in turn, we're able to "remote" all the traffic generated by the `geolocate` package, rather than missing some bits of it that were still using the standard library and caused _some_ geolocations to geolocate as the local host rather than as the remote host. Extracted from #969, where we tested this functionality. Closes ooni/probe#1383 (which was long overdue). Part of ooni/probe#2340, because it allows us to make progress with that.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This commit extends miniooni to be able to use a remote instance of miniooni for performing OONI measurements.
The main use case for this functionality is to run measurements inside another network that has censorship for QA purposes.
We currently support two transports for implementing remoting:
"tcp", which uses a cleartext TCP connection
"ssh", which uses SSH
The tcp transport is useful when you trust the network that transports packets from and to the two miniooni instances.
The ssh transport covers the case where you want a secure channel to transport packets between the two miniooni instances.
To start the remotetcp server, run this command as
root
:To start the remotessh server, run this command as
root
:On the local side, you need to create
$HOME/.miniooni/remote/config.yaml
, which must look like the following:The ports in the above example are the default ones used by
remotetcp
andremotessh
.On the command line, you can enable remoting by adding
--remote=NAME
, where NAME is the remote name. For example:Note that this command will only work if you have an active instance of the ssh-agent (i.e.,
SSH_AGENT_SOCK
is defined).Having described the functionality, let us explain how we implemented all of this.
We have reintroduced the possibility of completely taking over the basic
netxlite
primitives:dialing a TCP or UDP conn
looking up a domain name using getaddrinfo
creating a listening UDP socket
When you use
--remote NAME
, the code will do the following:read the config file
figure out the right remote
establish a connection with the remote
create a TCP/IP stack in userspace
create a TUN device in userspace that gets all the packets generated by the TCP/IP stack in userspace
overwrite netxlite primitives so they use the TCP/IP stack in userspace instead of the Go standard library
setup routing between the connection with the remote and the TUN device in userspace so we route packets
run the desired experiments as usual
On the server side, we do something similar, except that we use a real TUN device as implemented by Linux. (We only support Linux servers at the moment.)
Once the real TUN device has been created we setup masquerading for it, and then we we route between the connection with the miniooni client and the real TUN device.
We don't currently implement censorship, but the real TUN device is clearly the right place where to do that.
See ooni/probe#2340.