pages tagged mozillaFeeding the Cloudhttps://feeding.cloud.geek.nz/tags/mozilla/Feeding the Cloudikiwiki2021-07-03T19:03:09ZZoom WebRTC linkshttps://feeding.cloud.geek.nz/posts/zoom-webrtc-links/
<a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>
2021-07-03T19:03:09Z2021-07-03T20:00:00Z
<p>Most people connect to Zoom via a <a href="https://zoom.us/download">proprietary
client</a> which has been on the receiving end of a
number of <a href="https://www.tomsguide.com/news/zoom-security-privacy-woes">security and privacy
issues</a> over the
past year, with some experts even describing it as
<a href="https://www.theguardian.com/technology/2020/apr/02/zoom-technology-security-coronavirus-video-conferencing">malware</a>.</p>
<p>It's not widely known however that Zoom offers a half-decent
<a href="https://webrtc.org/">WebRTC</a> client which means cross-platform one-click
access to a Zoom room or webinar without needing to install any software.</p>
<p><strong>Given a Zoom link such as
<code>https://companyname.zoom.us/j/123456789?pwd=letmein</code>, you can use
<code>https://zoom.us/wc/join/123456789?pwd=letmein</code> to connect in your browser.</strong></p>
<p>Notice that the pool of Zoom room IDs is global and you can just drop the
<code>companyname</code> from the URL.</p>
<p>In my experience however, <a href="https://meet.jit.si">Jitsi</a> has much better
performance than Zoom's WebRTC client. For instance, I've never been able to
use Zoom successfully on a <a href="https://www.raspberrypi.org/products/raspberry-pi-4-model-b/">Raspberry Pi
4</a> (8GB), but
Jitsi works quite well. If you have a say in the choice of conference
platform, go with Jitsi instead.</p>
How to get a direct WebRTC connections between two computershttps://feeding.cloud.geek.nz/posts/how-to-get-direct-webrtc-connection-between-computers/
<a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>
2021-06-11T20:43:57Z2020-03-28T23:55:00Z
<p><a href="https://webrtc.org/">WebRTC</a> is a standard real-time communication protocol
built directly into modern web browsers. It enables the creation of video
conferencing services which do not require participants to download
additional software. Many services make use of it and it almost always works
out of the box.</p>
<p>The reason it just works is that it uses a protocol called
<a href="https://en.wikipedia.org/wiki/Interactive_Connectivity_Establishment">ICE</a>
to establish a connection regardless of the network environment. What that
means however is that in some cases, your video/audio connection will need
to be relayed (using end-to-end encryption) to the other person via
third-party
<a href="https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT">TURN</a>
server. In addition to adding extra network latency to your call that relay
server might overloaded at some point and drop or delay packets coming
through.</p>
<p>Here's how to tell whether or not your WebRTC calls are being relayed, and
how to ensure you get a direct connection to the other host.</p>
<h1 id="Testing_basic_WebRTC_functionality">Testing basic WebRTC functionality</h1>
<p>Before you place a real call, I suggest using the official <a href="https://test.webrtc.org/">test
page</a> which will test your camera, microphone and
network connectivity.</p>
<p>Note that this test page makes use of a Google TURN server which is locked
to particular HTTP referrers and so you'll need to disable privacy features
that might interfere with this:</p>
<ul>
<li><a href="https://brave.com/">Brave</a>: Disable Shields entirely for that page
(Simple view) or <em>allow all cookies</em> for that page (Advanced view).</li>
</ul>
<p><img alt="" src="https://feeding.cloud.geek.nz/posts/how-to-get-direct-webrtc-connection-between-computers/brave-shields-cookies.png" /></p>
<ul>
<li><p>Firefox: Ensure that <code>http.network.referer.spoofSource</code> is set to <code>false</code>
in <code>about:config</code>, which it is by default.</p></li>
<li><p><a href="https://github.com/gorhill/uMatrix">uMatrix</a>: The "Spoof <code>Referer</code>
header" option needs to be turned off for that site.</p></li>
</ul>
<p><img alt="" src="https://feeding.cloud.geek.nz/posts/how-to-get-direct-webrtc-connection-between-computers/umatrix-settings.png" /></p>
<h1 id="Checking_the_type_of_peer_connection_you_have">Checking the type of peer connection you have</h1>
<p>Once you know that WebRTC is working in your browser, it's time to establish
a connection and look at the network configuration that the two peers agreed
on.</p>
<p>My favorite service at the moment is <a href="https://whereby.com">Whereby</a>
(formerly <em>Appear.in</em>), so I'm going to use that to connect from two
different computers:</p>
<ul>
<li><code>canada</code> is a laptop behind a regular home router without any port
forwarding.</li>
<li><code>siberia</code> is a desktop computer in a remote location that is also behind a
home router, but in this case its internal IP address (<code>192.168.1.2</code>) is
set as the <a href="https://en.wikipedia.org/wiki/DMZ_%28computing%29#DMZ_host">DMZ
host</a>.</li>
</ul>
<h2 id="Chromium">Chromium</h2>
<p>For all Chromium-based browsers, such as Brave, Chrome, Edge, Opera and
Vivaldi, the debugging page you'll need to open is called
<code>chrome://webrtc-internals</code>.</p>
<p>Look for <code>RTCIceCandidatePair</code> lines and expand them one at a time until you
find the one which says:</p>
<ul>
<li><code>state: succeeded</code> (or <code>state: in-progress</code>)</li>
<li><code>nominated: true</code></li>
<li><code>writable: true</code></li>
</ul>
<p><img alt="" src="https://feeding.cloud.geek.nz/posts/how-to-get-direct-webrtc-connection-between-computers/chromium-webrtc-internals-candidatepair.png" /></p>
<p>Then from the name of that pair (<code>N6cxxnrr_OEpeash</code> in the above example)
find the two matching <code>RTCIceCandidate</code> lines (one <code>local-candidate</code> and one
<code>remote-candidate</code>) and expand them.</p>
<p><img alt="" src="https://feeding.cloud.geek.nz/posts/how-to-get-direct-webrtc-connection-between-computers/chromium-webrtc-internals-candidates.png" /></p>
<p>In the case of a <strong>direct connection</strong>, I saw the following on the
<code>remote-candidate</code>:</p>
<ul>
<li><code>ip</code> shows the external IP address of <code>siberia</code></li>
<li><code>port</code> shows a random number between 1024 and 65535</li>
<li><code>candidateType: srflx</code></li>
</ul>
<p>and the following on <code>local-candidate</code>:</p>
<ul>
<li><code>ip</code> shows the external IP address of <code>canada</code></li>
<li><code>port</code> shows a random number between 1024 and 65535</li>
<li><code>candidateType: prflx</code></li>
</ul>
<p>These <a href="https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate/type">candidate
types</a>
indicate that a <a href="https://en.wikipedia.org/wiki/STUN">STUN</a> server was used
to determine the public-facing IP address and port for each computer, but
the actual connection between the peers is direct.</p>
<p>On the other hand, for a <strong>relayed/proxied connection</strong>, I saw the following
on the <code>remote-candidate</code> side:</p>
<ul>
<li><code>ip</code> shows an IP address belonging to the TURN server</li>
<li><code>candidateType: relay</code></li>
</ul>
<p>and the same information as before on the <code>local-candidate</code>.</p>
<h2 id="Firefox">Firefox</h2>
<p>If you are using Firefox, the debugging page you want to look at is
<code>about:webrtc</code>.</p>
<p>Expand the top entry under "Session Statistics" and look for the line
(should be the first one) which says the following in green:</p>
<ul>
<li><code>ICE State: succeeded</code></li>
<li><code>Nominated: true</code></li>
<li><code>Selected: true</code></li>
</ul>
<p>then look in the "Local Candidate" and "Remote Candidate" sections to find
the <a href="https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate/type">candidate
type</a>
in brackets.</p>
<p><img alt="" src="https://feeding.cloud.geek.nz/posts/how-to-get-direct-webrtc-connection-between-computers/firefox-about-webrtc.png" /></p>
<h1 id="Firewall_ports_to_open_to_avoid_using_a_relay">Firewall ports to open to avoid using a relay</h1>
<p>In order to get a direct connection to the other WebRTC peer, <strong>one</strong> of the
two computers (in my case, <code>siberia</code>) needs to <strong>open all inbound UDP
ports</strong> since there doesn't appear to be a way to restrict Chromium or
Firefox to a smaller port range for incoming WebRTC connections.</p>
<p>This isn't great and so I decided to tighten that up in two ways by:</p>
<ul>
<li>restricting incoming UDP traffic to the IP range of <code>siberia</code>'s ISP, and</li>
<li>explicitly denying incoming to the UDP ports I know are open on <code>siberia</code>.</li>
</ul>
<p>To get the IP range, start with the external IP address of the machine (I'll
use the IP address of my blog in this example: <code>66.228.46.55</code>) and pass it
to the <code>whois</code> command:</p>
<pre><code>$ whois 66.228.46.55 | grep CIDR
CIDR: 66.228.32.0/19
</code></pre>
<p>To get the list of open UDP ports on <code>siberia</code>, I <code>ssh</code>ed into it and ran
nmap:</p>
<pre><code>$ sudo nmap -sU localhost
Starting Nmap 7.60 ( https://nmap.org ) at 2020-03-28 15:55 PDT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000015s latency).
Not shown: 994 closed ports
PORT STATE SERVICE
631/udp open|filtered ipp
5060/udp open|filtered sip
5353/udp open zeroconf
Nmap done: 1 IP address (1 host up) scanned in 190.25 seconds
</code></pre>
<p>I ended up with the following in my <code>/etc/network/iptables.up.rules</code> (ports
below 1024 are denied by the default rule and don't need to be included
here):</p>
<pre><code># Deny all known-open high UDP ports before enabling WebRTC for canada
-A INPUT -p udp --dport 5060 -j DROP
-A INPUT -p udp --dport 5353 -j DROP
-A INPUT -s 66.228.32.0/19 -p udp --dport 1024:65535 -j ACCEPT
</code></pre>