Open felipedau opened 7 years ago
I took a look at the Mumble codecs - celt, speex, and vorbis have all been superceded by opus. So it's pretty clear that is the one to use.
I've got a simple audio chat client running over tor using the opus codec. Including symmetric encryption of the payloads (same key, not ephemeral), the latencies are ~200-300 ms. Not bad! Codec parameters are: 48000 samples/sec with 16 bit samples, 20msec packets (payload 128 bytes each, total encrypted packet size 168 bytes), single-channel.
The audio is very good. We could probably tune the codec params to reduce the bandwidth requirements (8.4 kbytes/sec encrypted) if we need to, although from my testing things seem to work fine with the above params. Obviously, that will be circuit-dependent to a certain extent.
I'm not aware of any other real-time audio chat clients running over tor. This could be a big enhancement for unMessage. It shouldn't be too hard to integrate ;)
Thats incredible :)
I also like Opus its modern and also seems to be coded with security in mind. That feature makes unMessage the first of its kind. Thank you!
cc/ @adrelanos
Sounds great!
You could also consider an option to enable push to talk walkie-talkie style. A voice messages one can sent. (Similar to WhatsApp.)
Not as a replacement for real phone calling. Just as an option for slow connections.
I mean, Tor already is slow. Phone calling might work for people having fast connections and Tor. For others on slow connections plus Tor, such a fallback mode could be neat.
We have some general advice on VoIP and anonymity in the Whonix wiki.
Can you please make sure Opus is only running in a constant bitrate? We know at least that ZRTP encryption cannot Protect VBR Streams as the pauses in a conversation produce fingerprints in the encrypted stream that allow the adversary to infer what words are being said.
http://zfoneproject.com/faq.html#vbr
EDIT:
Important part worth quoting that makes it clear:
It's not a problem if the codec adapts the bit rate to the available channel bandwidth. The dangerous codecs are the ones that change their bit rate depending on the type of sound being compressed.
Yep. That's the way I've got it implemented.
@felipedau and I are going to test a bit today. After that, if you'd like to give it a try, let me know and I can get you a tarball.
Tests yesterday went very well. We were able to have several ~hour-long audio conversations.
@felipedau is working on integration with unMessage now. We'll probably have a first commit to unMessage sometime tomorrow.
Sounds great! You could also consider an option to enable push to talk walkie-talkie style. A voice messages one can sent. (Similar to WhatsApp.) Not as a replacement for real phone calling. Just as an option for slow connections. I mean, Tor already is slow. Phone calling might work for people having fast connections and Tor. For others on slow connections plus Tor, such a fallback mode could be neat. We have some general advice on VoIP and anonymity in the Whonix wiki. https://www.whonix.org/wiki/VoIP
That's a great idea @adrelanos, we should be able to implement that!
@felipedau is working on integration with unMessage now. We'll probably have a first commit to unMessage sometime tomorrow.
Well, it took longer than expected but we finally finished the integration and tested it basically every day since @rxcomm developed the first version. Unfortunately we do not have many machines to test it with different devices, so if you can, run the unMessage code from the develop branch (which is now the primary branch).
Here are some instructions to use unTalk (that's what we are calling this feature) for a fresh installation:
sudo apt-get install build-essential gcc libffi-dev libopus0 libsodium-dev portaudio19-dev python-dev python-tk tor
git clone https://github.com/AnemoneLabs/unmessage
(It should clone the develop
branch by default)sudo pip install -e unmessage/
unmessage-cli -n your_peer
the_other_peer is online
(this will only work if either of the peers use /pres-on
to notify their presence) or /msg
them and wait for it to be delivered (A line like the_other_peer< the message you sent
is displayed right below the command's echo/untalk the_other_peer
/untalk your_peer
If no errors occur and you start listening to each other: awesome!
/untalk the_other_peer
to end the voice conversation or just /quit
However, if some error occur or someone/no one seems to listen/speak, then you probably have to adjust the devices you have available. This part can be a bit tricky and we still have to find a better way to do this.
/quit
unMessage and launch it again (now just unmessage
on the terminal should launch it using the same interface and peer)/untalk-devices
to display the devices unTalk can useLook for default
and pulse
. The former is (usually) an input device and the latter an output device. Let's say that their index numbers are respectively 2
and 1
:
/untalk the_other_peer 2 1
You should be able to talk. If it does not work, you will probably have to try different combinations until you find the right one. I would make sure to restart unMessage every time you repeat the process (sorry :/). I would hate to see you spending time to make it work, so if things go wrong, please let us know so we can try to find a solution.
Once we are able to test with more devices and we are sure this new version is a bit stable, then we will merge to master, make a new release, upload to PyPI, etc.
Thank you very much guys!
I would also like to clarify that this feature does not use ephemeral encryption. The requests do use the regular packets (ephemerally encrypted) to exchange handshake keys (short term, randomly generated every session) but each session uses a shared key to symmetrically encrypt the packets. The key is generated with Triple DH using the identity keys (longterm) and the handshake keys previously exchanged.
@felipedau - great job on the integration!
One additional point I could make is that if people have underrun audio errors or choppy audio, they might try starting by setting the PULSE_LATENCY_MSEC environment variable:
PULSE_LATENCY_MSEC=30 unmessage[-cli] ...
Choose a latency appropriate to your hardware. This helps with slow machines and other ideosyncracies.
I've created a docker image with the develop branch of unmessage. This image supports audio chat: https://github.com/rxcomm/unmessage-client/tree/master/src/unmessage-client-audio
To run the container, you first need to authenticate the docker daemon to your host's pulseaudio. To do that, run the dockerpulse.sh script: https://github.com/rxcomm/unmessage-client/blob/master/util/dockerpulse.sh
and then with the output of that script, start the container with the audio.sh script: https://github.com/rxcomm/unmessage-client/blob/master/util/audio.sh
./audio.sh <docker daemon ip> <pulseaudio port>
The dockerpulse.sh script will give you the parameters for the audio.sh script.
Example:
host_$ ./dockerpulse.sh
Configuring pulseaudio sound over tcp for docker container
Pulse port: 56272
Docker daemon: 172.17.0.1
Pulse module id: 25
Now run: ./audio.sh 172.17.0.1 56272
to start the container
To unload the pulseaudio module, run: pactl unload-module 25
host_$ ./audio.sh 172.17.0.1 56272
[sudo] password for <user>:
Starting with UID : 1000
useradd: warning: the home directory already exists.
Not copying any file from skel directory into it.
user@6d7b62174a2c:~$ unmessage
unMessage requires a mono microphone. If your microphone is stereo (like mine ;), pulseaudio will map it to mono for you:
pacmd list-sources | grep name:
pacmd load-module module-remap-source master=<name of your mic here> \
master_channel_map=front-left,front-right channels=2 channel_map=mono,mono
The name of your mic should not include the angle brackets.
To make this automatically load when pulseaudio starts, you can add the argument of the second pacmd command to either /etc/pulse/defaults.pa or ~/.config/pulse/defaults.pa.
Thanks @rxcomm! I'll add that to the docs once I start writing instructions for unTalk.
As requested by @rxcomm in previous discussions and @HulaHoopWhonix in #5, unMessage should allow users to do voice chat. This is related to #11 and some structure or a
VoiceElement
class should be used.@HulaHoopWhonix also suggested to use "TCP latency tolerant codecs like those in mumble".
It will be interesting to see how this feature behaves with Tor's latency.