pradt2 / always-online-stun

A list of publicly available STUN servers, refreshed every hour.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

A TURN list would be amazing!

TheRook opened this issue · comments

I love the STUN list, but if you could also have a list of servers that allow anonymous TURN that would be A+.

Anyway, thanks for the list!

commented

Hi, thanks for opening the issue.

I agree that a TURN server list would be awesome.

I don't know of any publicly available TURN servers though, do you?

If we could compile a sizeable list (a dozen or so of working servers), I would be willing to add support for TURN testing.

commented

I see. Okay, I'll take a look at this this week.

@pradt2 Here is some python that will do the trick:
pip install aiortc

import asyncio
import socket
from aiortc import RTCIceServer, RTCPeerConnection, RTCSessionDescription
from aiortc.contrib.signaling import object_from_string, object_to_string

async def check_turn_connection(turn_server, turn_port):
    try:
        # Create an RTCIceServer with the TURN server details
        ice_server = RTCIceServer(urls=f"turn:{turn_server}:{turn_port}", username=None, credential=None)

        # Create a peer connection with the TURN server as the only ICE server
        pc = RTCPeerConnection(ice_servers=[ice_server])

        # Create an offer to gather ICE candidates
        offer = await pc.create_offer()
        await pc.set_local_description(offer)

        # Wait for ICE gathering to complete
        while not pc.iceGatheringState == 'complete':
            await asyncio.sleep(0.1)

        # Check if an ICE candidate with an empty 'usernameFragment' exists
        anonymous_turn_supported = any(
            candidate.get('usernameFragment') == '' for candidate in pc.localDescription.sdp_candidates)

        if anonymous_turn_supported:
            print(f"The server at {turn_server}:{turn_port} supports anonymous TURN.")
        else:
            print(f"The server at {turn_server}:{turn_port} does not support anonymous TURN.")

    except Exception as e:
        print(f"Error occurred while checking {turn_server}:{turn_port}: {e}")

    finally:
        # Close the peer connection
        await pc.close()

async def main():
    # Read the list of IP:PORT pairs from a file
    with open('turn_servers.txt', 'r') as file:
        turn_servers = [line.strip() for line in file]

    # Check TURN connection for each server in the list
    tasks = [check_turn_connection(turn_server.split(':')[0], int(turn_server.split(':')[1]))
             for turn_server in turn_servers]

    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main())

Hi, I did some work on this and what I found out that indeed there are STUN providers that also support unauthenticated TURN requests, but these providers are usually some niche online telephony companies.

I worry that, unlike STUN, directing potentially significant amounts of TURN traffic to these services might be disruptive for the company/customers or at least it might rack up their hosting costs.

So, unlike what I do with STUN (opt-out if a company wishes to be removed), being on an open TURN list should probably be opt-in.

To sum up, if a TURN service provider comes here and says they agree to be on the list, I will gladly add them and enable TURN checks, but until then, I'll be offering STUN links only.

Do you agree?

BTW neither peerjs nor openrelay offer unauthenticated TURN anymore.

BTW neither peerjs nor openrelay offer unauthenticated TURN anymore.

Hmm, that is unfortunate. I also noticed that nmap NSE doesn't seem to detect TURN-ability. The https://veilid.com/ project is running TURN servers and webrtc, but these are ephemeral addresses on a new protocol.

Well thanks for looking into it, and thanks for keeping the STUN list active!