Code Monkey home page Code Monkey logo

always-online-stun's Introduction

Always Online: STUN servers

GitHub commit activity GitHub last commit GitHub

Have you ever thought: Gosh, why isn't there a regularly updated, comprehensive list of publicly available STUN servers?

Well, this is it. A list of online STUN servers, refreshed hourly.

How to use

Hardcode this link valid_hosts.txt into your application, and use it anytime you need a fresh list of online STUN servers.

Or, if you don't want to rely on DNS resolution, use valid_ipv4s.txt for IPv4, and valid_ipv6s.txt for IPv6 addresses.

JS example with Geolocation

const GEO_LOC_URL = "https://raw.githubusercontent.com/pradt2/always-online-stun/master/geoip_cache.txt";
const IPV4_URL = "https://raw.githubusercontent.com/pradt2/always-online-stun/master/valid_ipv4s.txt";
const GEO_USER_URL = "https://geolocation-db.com/json/";
const geoLocs = await(await fetch(GEO_LOC_URL)).json();
const { latitude, longitude } = await(await fetch(GEO_USER_URL)).json();
const closestAddr = (await(await fetch(IPV4_URL)).text()).trim().split('\n')
    .map(addr => {
        const [stunLat, stunLon] = geoLocs[addr.split(':')[0]];
        const dist = ((latitude - stunLat) ** 2 + (longitude - stunLon) ** 2 ) ** .5;
        return [addr, dist];
    }).reduce(([addrA, distA], [addrB, distB]) => distA <= distB ? [addrA, distA] : [addrB, distB])[0];
console.log(closestAddr); // prints the IP:PORT of the closest STUN server

FAQ

But hard-coding of links is baaaad?!

Well, not exactly. Hard-coding of links which were never meant to be hard-coded is bad. Here the situation is different. Since I recommend that users hard-code the links to the few specific files, I'll avoid doing anything that would make the link invalid (e.g. I won't change the name of the file, name of the repository, my Github username, etc.).

But I still don't feel comfortable hard-coding any links...

Feel free to open an issue and let's discuss your specific needs.

How often are the lists refreshed?

Hourly, you can see the timestamp of the last check in the commit message.

What RFC spec do the servers conform to?

As long as the server correctly responds to an RFC5389 BINDING request, it is judged as healthy. This is enough to establish the NAT mapping of a given socket.

Noteworthy: the server does not need to respond with an alternate IP address to be judged as healthy. This can be a problem if you need a server with full RFC5389/5780 NAT testing (endpoint mapping and filtering modes) capability.

If you need a list of servers that support RFC5389/5780 NAT testing, open an issue.

What IP versions and transport protocols are tested?

IP versions 4 and 6. UDP and TCP.

I noticed that the lists are shuffled on each check. Why?

Lazy/inconsiderate devs will tend to just grab the top-most link from the list (and TBF, can we blame them?). By shuffling the list, I ensure that we don't end up spamming the same host forever.

What servers are checked, and how can I add more publicly available servers?

The list is in candidates.txt. Feel free to create a PR adding more servers, or just open an issue and list them there.

My server is on your list, and I don't like it. What can I do?

Open an issue, and it will be removed from the automated checks within 24 hours.

always-online-stun's People

Contributors

pradt2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

always-online-stun's Issues

Add support for RFC5780

stunserver.stunprotocol.org supports NAT behavior test over udp/tcp, but can't find any other equivalent replacement on the internet. I guess it's a needle in a haystack.
If possible, hope to provide a list of servers that support RFC5780. Thank you.

Add client-side/JS fetch() use case example to readme maybe

Hey :)

as up-to-date STUN servers lists are often needed to be known in-browser, and you might not want to hard-code them, you can actually use this code in-browser to fetch them fresh from GitHub, and Microsoft will pay for the traffic + takes care for DDoS protection:

const stunServerList = (await (await fetch(
      'https://raw.githubusercontent.com/pradt2/always-online-stun/master/valid_ipv4s.txt'
)).text()).split('\n')

Bildschirmfoto 2022-03-04 um 23 49 26

[Discussion] - Opposing `candidates.txt` for maintainers that don't want their STUN servers tracked like this?

The README contains a section about being able to remove stun servers from parties that don't want their servers listed here - but is there a tracking mechanism to prevent them from being added by someone else in the future again?

Should there be a file similar to candidates.txt that lists out servers that have specifically asked to not be a part of this project? Or is there some other, better, way that you can track which servers should be rejected from new issues/PRs?

Add support for stun over tcp

Only a few servers support tcp protocol, for example, stun.mixvoip.com:3478. Hope to add a list of whether the server supports stun over tcp protocol. Thank you.

A TURN list would be amazing!

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!

Lots of hosts do not respond for my internet connection

Hi,

Thanks for this list, this is going to be super useful for my little project to find out what port ranges are used for cgnat!

I noticed that I don't get any response for lots of hosts in the hourly updated valid_ipv4s.txt using my own script pystun, I tried to validate this by running "run.sh" on Fedora 35 but that's even worse (all hosts seem to fail):

OK 0 , DNS failure 78 , p/Timeout 0 , Timeout 508 , Incorrect 47

I guess there could be a difference in connectivity depending on the Internet connection, it would also be very helpful if the capabilities of the stun servers are available.

GeoLocation / Nearest STUN server

Hey,

another one, I've wrote a TypeScript script to allocate geo location data per IP.
This can be extremely helpful for selecting the nearest and fastest STUN server.
Results attached as JSON.

import { Lookup, lookup } from "geoip-lite"
import { readFileSync, writeFileSync } from "fs"

interface ServerWithGeoLocation {
    ip: string
    port: number
    geoLocation: Lookup | null
}
const stunServersWithGeo: Array<ServerWithGeoLocation> = []

JSON.parse(readFileSync('stunServerIps.json', {
    encoding: 'utf8'
})).map((stunServer: string) => {

    const serverAddress = stunServer.split(':')
    const ip = serverAddress[0]
    const port = parseInt(serverAddress[1], 10)

    stunServersWithGeo.push({
        ip,
        port,
        geoLocation: lookup(ip)
    })
})

writeFileSync(
  'stunServersWithGeoLocation.json', 
  JSON.stringify(stunServersWithGeo, null, 2), 
  { encoding: 'utf8' }
)

The file: stunServerIps.json contains the STUN server addresses like this:

[
    "37.97.65.52:3478",
    "158.69.57.20:3478",
    "150.254.161.60:3478",
    "44.224.155.217:3478",
    "176.9.24.184:3478",
     ...
 ]

In general I can only recommend saving them as JSON too because it's easier accessible in many programming languages.

Result looks like this:

[{
   "ip": "203.13.68.16",
   "port": 3478,
   "geoLocation": {
     "range": [
       3406644224,
       3406645247
     ],
     "country": "AU",
     "region": "QLD",
     "eu": "0",
     "timezone": "Australia/Brisbane",
     "city": "Varsity Lakes",
     "ll": [
       -28.0867,
       153.4116
     ],
     "metro": 0,
     "area": 1
   }
 }, ... ]

This can be easily matches client-side with the result from a GeoLocation API call at client-side in-browser:

import * as tzlookup from "tz-lookup"

const getGeoLocation = () => {

 navigator.geolocation.getCurrentPosition((position) => {
   console.log('position', position)

   const timeZone = tzlookup(position.coords.latitude, position.coords.longitude)
   console.log('timeZone', timeZone)
 }, () => {
   console.error('Error fetching GeoLocation')
 });
}

And thus timeZone will report:

Bildschirmfoto 2022-03-05 um 19 54 58

...and we can simply go thru the nearest STUN servers now and connect to these.

stunServersWithGeoLocation.json.zip

stun.kedr.io:3478 violates rfc 5780

Hi there.

stun.kedr.io:3478 is currently responding with faulty information: It advertises an OTHER-ADDRESS attribute containing the same IP address that was used to contact it. (The port is different, but that's not enough to avoid breaking things.)

This tricks clients that understand and use that attribute into thinking their NAT's filtering behavior is the most permissive possible (Endpoint-Independent Filtering) even if it actually is much more restrictive.

It also violates RFC 5780, which states, "OTHER-ADDRESS MUST NOT be inserted into a Binding Response unless the server has a second IP address."

Given that this is likely to undermine NAT traversal, I think it might be worth removing that server from the list for now, and maybe contacting the admins to see if they'll fix it.

(To be clear in light of the FAQ, the problem here isn't a lack of RFC 5780 support; that would be harmless.)

How about realizing this as a self-triggering GitHub Action?

Hey :)

this project is truly amazing! The only thing I think that could make it even better is a self-triggering GitHub action.
It seems like that the Rust scripts being triggered "externally". But this would "stop" if the "central" infra that triggers this update script stops working for some reason. But if implemented as a GitHub Action, this would run forever, and be much more resilient?

Self-triggering can be approached when you build a GitHub Action that registers an action on push that runs the rust, and then waits a while (NOP) before it pushes to the very same repo -> recursion.

Thanks a lot for your work here!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.