feat(miniooni): use a remote miniooni instance to measure#969
Draft
bassosimone wants to merge 5 commits intomasterfrom
Draft
feat(miniooni): use a remote miniooni instance to measure#969bassosimone wants to merge 5 commits intomasterfrom
bassosimone wants to merge 5 commits intomasterfrom
Conversation
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.
Contributor
Author
|
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.
This file contains hidden or 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
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
remotetcpandremotessh.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_SOCKis 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
netxliteprimitives: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.