From owner-freebsd-net@freebsd.org Sun Jun 11 07:51:17 2017 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1AD88C3107C for ; Sun, 11 Jun 2017 07:51:17 +0000 (UTC) (envelope-from damjan.jov@gmail.com) Received: from mail-lf0-x231.google.com (mail-lf0-x231.google.com [IPv6:2a00:1450:4010:c07::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 9502E7E576 for ; Sun, 11 Jun 2017 07:51:16 +0000 (UTC) (envelope-from damjan.jov@gmail.com) Received: by mail-lf0-x231.google.com with SMTP id v20so41567606lfa.1 for ; Sun, 11 Jun 2017 00:51:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=y5g3fBEUNwXvlk/Z3ciVZk4q5wc7+fqLaTKBv5+IjH4=; b=SR1fMPUY32HzZGW5yuktNE5I3SzMfD6X+7prj4nkjh/6aep+fum4trobETsrzoHiOR /7Zng4XFtRrX0OZ+tqvFclhz+1UVeebbJMWc1SRzTGMcRLjDfqd4PTEOnL+zjpCpl9xF OPoAMneGFmIJN+Ci8A0KFUWIJKvmoh2on2dLohgUYzyqv2wHP2I0Q6TKhJzX6qGiJhQB rKWpkfW3KPOuKqNdaayiWj7d6TWnGn6SpUPZl7gnhvFmi3DfV3dacwXu3SaqJYB80tNQ r2waVvRlJ1g6wDBZfF11CLqrPb3+CRsWe9ZJH7jvwpVYSmhcgiKtZNxUjZTcGqJV7C28 1gRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=y5g3fBEUNwXvlk/Z3ciVZk4q5wc7+fqLaTKBv5+IjH4=; b=bPWlRYbH/YuT6/IPgQOXIXILAZ1L5alhspk0rNIgVC9y+qx0xQSLaQ7pQB7uBuoDL5 NIdpJ2oVrslQWZ1O0lytVhEbocIqDB98QeJM5p/KixBM/794nFkHDwlv1b/05v51n5W+ mLxhO6SMAwlGj6lk8aKDBDcMiCDD4wQ6ZUzwmO7tPkcNrjuaX+Sq429hH+kZGRnF005C AmIzOWZEBpv6MydVLMERa8Pz8QM0y2CfPaef7pfVdmlzE7w3lS6GWfWmfvM53eIlyzIs CdKwjUhbJAxdP5K0Yw5z+/TXv8RazG7Y1B6prKw+bFjFwOuCtV8UU3SGAvKAvVWv/v/P 7v9g== X-Gm-Message-State: AODbwcC+WT8+bGkrwboYLX0Gr6doHYZamxEP4UBjEUzgcT7Rj/uCJVvz Ti8FsuoNWq9kDrI/MS5UqlPGeMr9rUeS X-Received: by 10.25.233.90 with SMTP id g87mr16727409lfh.161.1497167474072; Sun, 11 Jun 2017 00:51:14 -0700 (PDT) MIME-Version: 1.0 Received: by 10.46.8.2 with HTTP; Sun, 11 Jun 2017 00:50:53 -0700 (PDT) From: Damjan Jovanovic Date: Sun, 11 Jun 2017 09:50:53 +0200 Message-ID: Subject: [patch] NAT hole punching, RFC 4787, and PF/LibAlias/IPFILTER To: freebsd-net@freebsd.org Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.23 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Jun 2017 07:51:17 -0000 Hi Gaming, VoIP, WebRTC, peer to peer, and many other UDP applications, require the ability to send to and receive from multiple peers through a single UDP socket, and/or communicate the address of this socket to others so they know where to transmit to. Historically NAT usually got in the way, but many applications are NAT-friendly these days, and can establish connections using NAT hole punching, which is the best available technique of NAT traversal, able to work through any number of layers of NAT (eg. both SOHO NAT and carrier grade NAT), requires no special configuration, allows applications to discover the external IP:port that the NAT gave them, and even allows clients to connect to each other when both are NATed. What NAT hole punching needs to work most of all, is what RFC 4787 calls an endpoint-independent mapping NAT, also called a "full cone" NAT: all UDP packets from the internal IP:port pair X:x, go through the same external Y:y no matter the Z:z, and nothing but X:x uses Y:y: Internal External X:x -----> NAT Y:y ----> Z:z This allows X:x to discover the Y:y that the NAT gives it by querying an external server (eg. a STUN server), and rely on packets sent to any Z:z to have Y:y as the source. It can communicate Y:y to a Z:z somehow, and have that Z:z send to it (possibly after first sending to Z:z). This is a mandatory requirement in RFC 4787. Sadly, of FreeBSD's firewalls/NATs, only IPFILTER supports this desirable property (as does "iptables" on Linux). PF's NAT and the LibAlias-based NATs (IPFW, and presumably natd and pppd) are "symmetric" NATs, the worst kind, randomly choosing a different Y:y for each Z:z from the same X:x, which makes it impossible for X:x to predict its Y:y, which makes it impossible for Z:z to learn about Y:y and reach it, especially if Z:z is itself also behind a symmetric NAT. Connections will either fail, or applications will resort to relaying data through other servers (eg. TURN), often compromising bandwidth, latency, security, and/or privacy, and increasing cost. So I've written patches to change NAT port selection in PF and LibAlias to endpoint-independent mapping. Please see here: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=219803 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=219918 Currently neither are "full cone" NATs: Z:z can only send to X:x through Y:y if X:x previously sent to Z:z, so they are "address- and port-restricted cone" NATs, or rather an endpoint-independent mapping NAT with address and port-dependent filtering. But applications can discover this using a protocol such as STUN, and can still connect to known peers by sending them a packet first. There's more work to do. RFC 4787 lists several requirements, of which we still fail on at least timeouts and hairpinning. Hairpinning is particularly difficult: on IPFW the hairpinned packet doesn't even reach LibAlias, and on PF there's a whole new path through the code. It may also be desirable to implement a full-cone NAT, at least as an optional extra due to the lower security, but that requires a different traversal of the firewall rules, as unsolicited packets from Z:z to Y:y will match a NAT rule backwards. Would anyone like to help? Thank you Damjan Jovanovic References: [1] http://alumnus.caltech.edu/~dank/peer-nat.html [2] http://www.brynosaurus.com/pub/net/p2pnat [3] https://tools.ietf.org/html/rfc4787 [4] https://tools.ietf.org/html/rfc5128