WebRTC is pretty good at getting through complex NAT constellations, trying to punch through NATs via STUN/ICE and falling back to TURN in case that fails (but the latter requires a central coordination server).
It only needs a lightweight signalling server to relay each client's ICE candidates (which is more or less an opaque string to the server) to their peers, and if that succeeds, they can communicate P2P (audio, video, and even opaque byte streams).
All of the complex NAT traversal logic and the encrypting P2P protocol stack is baked into all modern browsers (or non-browser clients using a WebRTC library); the only thing that's needed is the signalling server, and practically a STUN server to facilitate ICE (but these use very little bandwidth and there are public ones available).