Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • Trac Trac
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Issues 246
    • Issues 246
    • List
    • Boards
    • Service Desk
    • Milestones
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Analytics
    • Analytics
    • Value stream
  • Wiki
    • Wiki
  • Activity
  • Create a new issue
  • Issue Boards
Collapse sidebar
  • Legacy
  • TracTrac
  • Issues
  • #33157

Closed (moved)
(moved)
Open
Created Feb 05, 2020 by David Fifield@dcf

Client generates SDP with "IN IP4 0.0.0.0", causing proxy to send "client_ip=0.0.0.0" and bridge to send "USERADDR 0.0.0.0:1"

There is a pipeline of relaying the client IP address:

  • The proxy infers the client's IP address by grepping it out of the SDP during ICE negotiation (proxy, proxy-go) and attaches it to the WebSocket connection as a URL query parameter ?client_ip=A.B.C.D.
  • The bridge parses the client_ip query parameter and passes it on to tor with a USERADDR A.B.C.D:1 command on the ExtORPort.
  • tor does geoip lookups and aggregates statistics and ultimately sends them to Tor Metrics for country-specific graphs.

It looks like the pion SDP code puts 0.0.0.0 in the place where proxy and proxy-go look for the remote IP address. This causes the proxy to send ?client_ip=0.0.0.0 to the bridge, and the bridge to send USERADDR 0.0.0.0:1 to tor. I'm not sure that this happens every time; see below for bridge-extra-infos output.

I found it while testing proxy-go with a localhost client and a patch like:

--- a/proxy-go/snowflake.go
+++ b/proxy-go/snowflake.go
@@ -22,3 +22,3 @@ import (
        "git.torproject.org/pluggable-transports/snowflake.git/common/messages"
-       "git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
+       _ "git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
        "git.torproject.org/pluggable-transports/snowflake.git/common/websocketconn"
@@ -93,3 +93,3 @@ func (c *webRTCConn) Write(b []byte) (int, error) {
        // log.Printf("webrtc Write %d %+q", len(b), string(b))
-       log.Printf("Write %d bytes --> WebRTC", len(b))
+       // log.Printf("Write %d bytes --> WebRTC", len(b))
        if c.dc != nil {
@@ -114,2 +114,3 @@ func (c *webRTCConn) RemoteAddr() net.Addr {
        clientIP := remoteIPFromSDP(c.pc.RemoteDescription().SDP)
+       log.Printf("RemoteAddr %+q", c.pc.RemoteDescription().SDP)
        if clientIP == nil {
@@ -322,3 +323,3 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config webrtc.C
                dc.OnMessage(func(msg webrtc.DataChannelMessage) {
-                       log.Printf("OnMessage <--- %d bytes", len(msg.Data))
+                       // log.Printf("OnMessage <--- %d bytes", len(msg.Data))
                        var n int
@@ -432,3 +433,4 @@ func main() {
        //We want to send the log output through our scrubber first
-       log.SetOutput(&safelog.LogScrubber{Output: logOutput})
+       // log.SetOutput(&safelog.LogScrubber{Output: logOutput})
+       log.SetOutput(logOutput)

For example, the beginning of an SDP string for me is

v=0
o=- 34318359 1580881353 IN IP4 0.0.0.0
s=-
t=0 0
a=fingerprint:sha-256 80:EE:E6:8D:55:07:CB:52:58:7A:CC:61:70:F9:F3:65:DB:4B:D3:69:CB:F9:68:C8:5F:E3:06:3D:D3:90:C1:E6
a=group:BUNDLE 0
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0

The client IP address inference, implemented in #18628 (moved), was always a bit of a hack, but it was effective enough, as evidenced by country counts in comment:4:ticket:29734. I just now looked at bridge-extra-infos-2020-02.tar.xz and it seems that we are still sometimes getting identified countries, but the largest count belongs to ??.

$ tar -O -xf bridge-extra-infos-2020-02.tar.xz | grep -A 24 '^extra-info flakey 5481936581E23D2D178105D44DB6915AB06BFB7F$' | grep -E '^dirreq-v3-reqs '
dirreq-v3-reqs ??=16,tr=16,cn=8,de=8,eg=8,in=8,ir=8,ph=8,us=8
dirreq-v3-reqs ??=16,tr=16,cn=8,de=8,eg=8,in=8,ir=8,ph=8,us=8
dirreq-v3-reqs ??=24,cn=8,es=8,fr=8,ir=8,tr=8
dirreq-v3-reqs ??=48,tr=16,ar=8,ca=8,eg=8,gb=8,ir=8,us=8
dirreq-v3-reqs ??=16,tr=16,cn=8,de=8,eg=8,in=8,ir=8,ph=8,us=8
dirreq-v3-reqs ??=24,cn=8,es=8,fr=8,ir=8,tr=8
dirreq-v3-reqs ??=48,tr=16,ar=8,ca=8,eg=8,gb=8,ir=8,us=8
dirreq-v3-reqs ??=24,cn=8,es=8,fr=8,ir=8,tr=8
dirreq-v3-reqs ??=24,cn=8,es=8,fr=8,ir=8,tr=8
dirreq-v3-reqs ??=24,cn=8,es=8,fr=8,ir=8,tr=8
dirreq-v3-reqs ??=48,tr=16,ar=8,ca=8,eg=8,gb=8,ir=8,us=8
dirreq-v3-reqs ??=16,tr=16,cn=8,de=8,eg=8,in=8,ir=8,ph=8,us=8
dirreq-v3-reqs ??=24,cn=8,es=8,fr=8,ir=8,tr=8
dirreq-v3-reqs ??=48,tr=16,ar=8,ca=8,eg=8,gb=8,ir=8,us=8
dirreq-v3-reqs ??=16,tr=16,cn=8,de=8,eg=8,in=8,ir=8,ph=8,us=8
dirreq-v3-reqs ??=16,tr=16,cn=8,de=8,eg=8,in=8,ir=8,ph=8,us=8
dirreq-v3-reqs ??=24,cn=8,es=8,fr=8,ir=8,tr=8
dirreq-v3-reqs ??=16,tr=16,cn=8,de=8,eg=8,in=8,ir=8,ph=8,us=8
dirreq-v3-reqs ??=24,cn=8,es=8,fr=8,ir=8,tr=8
dirreq-v3-reqs ??=24,tr=16,fr=8,om=8,ru=8,us=8
dirreq-v3-reqs ??=16,tr=16,cn=8,de=8,eg=8,in=8,ir=8,ph=8,us=8
dirreq-v3-reqs ??=48,tr=16,ar=8,ca=8,eg=8,gb=8,ir=8,us=8

Maybe it happens only intermittently. pion/sdp sets UnicastAddress: "0.0.0.0" unconditionally and I don't see where it is ever modified. Maybe the others are older non-pion clients?

A little searching indicates that IN IP4 0.0.0.0 has something to do with trickle ICE:

  • https://bugzilla.mozilla.org/show_bug.cgi?id=1192813#c14

It seems that ultimately, we need a more reliable way for the proxy to infer the client's external IP address.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking