javatcpudpportforwardingstun

What is STUN and does it need a port-forwarded server?


I've done some research on p2p communication without a base server, and came over STUN. From what I've read, STUN is a way of NAT "Hole Punching" that would not require a peer to be port-forwarded to be connected to. Is this correct, and what exactly does hole punching mean? It all seems very vulnerable as it is going past the firewall if it does not require port-forwarding, and I do not entirely understand what STUN does. Could STUN be used in a p2p program in Java or another language such as a chat client that sends messages over TCP/UDP ports to the peer WITHOUT a base server or WITHOUT requiring the user to port forward?


Solution

  • Consider the task of two machines wanting to communicate with each other. If the two machines are connected directly to the public Internet (not behind a router), then the two machines simply send packets back and forth to each other's public IP. Typically, machines are behind one or more routers. To simplify the problem, we assume only one level of routers.

    NAT traversal solves the problem of routers translating the outgoing port number of packets into something else (e.g. you send a request from port X, the router translates the packet to act as if it left from port Y instead). If the routers are port-forwarding, then the router doesn't actually do any translation (port X->X). Most home/corporate/etc routers are not port-forwarding, however, and thus NAT traversal comes into play. See NAT traversal and different types of NATs.

    Consider a router's firewall that does any of the non port-forwarding translations in the above article (e.g.full cone). If a router receives some packet to port X, but the router has not sent any packets from port Y, it drops the packet (after all, to whom was the packet meant? the router has no idea!). Only when some private machine sends a packet and the router makes a translation to map port X from that private machine to external port Y will external packets TO port Y be forwarded to the private machine.

    STUN traversal

    In order for two clients, A and B both behind firewalls across the Internet, to communicate directly, they must somehow know the router mapping. The general solution is to use a STUN server to determine their port mapping. Machine A sends a packet form port X to STUN. The router translated the port to Y, and the STUN server sees this and responds back to A telling him what the external port was. B does the same. Then, A and B exchange their translated ports (by using some other central server...for a simplified example, Skype might have a central login server where A and B tell the Skype server their port translations, and Skype tells A and B respectively about the port mappings). Then, B sends a packet to A's public IP using port Y, not X. Machine A "punched" its firewall, allowing it to receive packets from external port Y.

    Secure?

    You mention security: does hole punching open up a network to security violations? Potentially...I haven't studied the subject, but consider a full cone NAT. Once the mapping is made, ANY external machine can send packets to machine A's router and A will get the packets, even if A has never sent a packet to some malicious machine Z. Machine Z, of course, would have to somehow discover the mapping. Some the Wikipedia article, the diagram only shows full cone NATs having this vulnerability, but don't take my word for it. Judging by the amount of applications that use hole punching (Skype, xbox live, ...), it would appear networks rely on application and system-level firewall protections in addition to router firewall measures.

    The Ford article below briefly mentions security: "Contrary to what its name may suggest, hole punching does not compromise the security of a private network." It would seem that networks rely on system-level firewalls more than router firewalls.

    Symmetric NATs and TURN traversal

    STUN doesn't always work: some routers "behave badly." Machine A might send two packets from port X, one to stackoverflow.com and one to facebook.com. The router maps the stackoverflow.com packet FROM port Y and the facebook.com packet FROM port Z (even though machine A send both packets FROM internal port X). This is a symmetric NAT. These NATs are problematic, since the above STUN/Skype connection won't work. Replace stackoverflow.com with STUN and facebook.com with machine B (the person you're trying to Skype with). Unfortunately, STUN can find out the NAT mapping for packets A sends to STUN, but packets sent to B use an entirely different mapping. In general, it is impossible (without you being able to track outbound router packets) to determine port mappings for symmetric NATs. Thus, a central routing server is needed for clients to communicate, but this defeats the whole point of p2p. See TURN.

    Can we use this in a Java chat program?

    Any language with network library support (Java, C, etc) where you can send packets from arbitrary ports can use STUN to traversal a NAT (as long as its not a symmetric NAT, etc). In general, one always needs a central server (in this case two: STUN and a login server). The login server is used as described in the Skype example; once two clients know their port mappings, they must communicate this to each other somehow before the p2p communicate has begun (see chicken or the egg). But once A and B know each other's public IPs and NAT mappings, they can communicate directly.

    Caveat

    Though I can't possibly list all NAT traversal caveats, one important concept is keep alive: once the router has made a port mapping, how long will it last? Say I connect to a STUN server, then wait 10 minutes for B to send me a packet once I tell it the mapping. The router will likely have dropped the mapping (routers have to regularly clear out old mappings for make room for new ones, and for a minimal attempt at security). I can't find my reference, and I think it varies depending on TCP vs UDP packets, but applications I am familiar with send a keep-alive packet every ~60 seconds or less to ensure the router doesn't drop the mapping. Once the router drops the mapping and machines trying to send packets, the packets will be dropped (leading to hours of confusion for me...).

    Articles

    The last article is a great introduction to many of the ideas for routers and NAT traversal in genreal. I read it a while ago when I implemented some TURN server/client procedures, and the authors really know what they're talking about!