Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
S
Snowflake
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 45
    • Issues 45
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 4
    • Merge Requests 4
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards

GitLab is used only for code review, issue tracking and project management. Canonical locations for source code are still https://gitweb.torproject.org/ https://git.torproject.org/ and git-rw.torproject.org.

  • The Tor Project
    • A
      Anti-censorship
  • Pluggable Transports
  • Snowflake
  • Issues
  • #33157

Closed
Open
Opened Feb 05, 2020 by David Fifield@dcfOwner

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 legacy/trac#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.

Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: tpo/anti-censorship/pluggable-transports/snowflake#33157