Domanda

Sono dietro un router, ho bisogno di un semplice comando per scoprire il mio IP pubblico (invece di cercare su Google qual è il mio IP e fare clic su uno dei risultati)

Esistono protocolli standard per questo? Ho sentito parlare di STUN ma non so come posso usarlo?

P.S. Sto programmando di scrivere un breve script Python per farlo

È stato utile?

Soluzione

MODIFICA : curlmyip.com non è più disponibile. (grazie maxywb)

Post originale :

Al momento di scrivere questo post, curlmyip.com funziona. Dalla riga di comando:

curl curlmyip.com

È un sito Web di terze parti, che potrebbe essere o meno disponibile un paio d'anni lungo la strada. Ma per il momento, sembra abbastanza semplice e pertinente.

Altri suggerimenti

Questo potrebbe essere il modo più semplice. Analizza l'output dei seguenti comandi:

  1. esegui un traceroute per trovare un router che sia a meno di 3 hop dalla tua macchina.
  2. esegui ping con l'opzione per registrare il percorso di origine e analizzare l'output. Il primo indirizzo IP nel percorso registrato è quello pubblico.

Ad esempio, sono su un computer Windows, ma la stessa idea dovrebbe funzionare anche da Unix.

> tracert -d www.yahoo.com

Tracing route to www-real.wa1.b.yahoo.com [69.147.76.15]
over a maximum of 30 hops:

  1    <1 ms    <1 ms    <1 ms  192.168.14.203
  2     *        *        *     Request timed out.
  3     8 ms     8 ms     9 ms  68.85.228.121
  4     8 ms     8 ms     9 ms  68.86.165.234
  5    10 ms     9 ms     9 ms  68.86.165.237
  6    11 ms    10 ms    10 ms  68.86.165.242

Il 68.85.228.121 è un router Comcast (il mio provider). Possiamo eseguire il ping:

> ping -r 9 68.85.228.121 -n 1

Pinging 68.85.228.121 with 32 bytes of data:

Reply from 68.85.228.121: bytes=32 time=10ms TTL=253
    Route: 66.176.38.51 ->
           68.85.228.121 ->
           68.85.228.121 ->
           192.168.14.203

Voila! Il 66.176.38.51 è il mio IP pubblico.

Ho creato un programma che si collega a http://automation.whatismyip.com/n09230945.asp è scritto in D per convincere qualcun altro a dirti cosa vedono il tuo IP in quanto è probabilmente il modo più affidabile:

/*
    Get my IP address
*/


import tango.net.http.HttpGet;
import tango.io.Stdout;

void main()
{
      try
      {
          auto page = new HttpGet ("http://automation.whatismyip.com/n09230945.asp");
          Stdout(cast(char[])page.read);
      }
      catch(Exception ex)
      {
          Stdout("An exception occurred");
      }
}

Modifica codice Python dovrebbe essere come:

from urllib import urlopen
print urlopen('http://automation.whatismyip.com/n09230945.asp').read()

Il targeting www.whatsmyip.org è scortese. Sostengono di non farlo sulla pagina.

Solo un sistema sullo stesso livello di NAT del tuo target vedrà lo stesso IP. Ad esempio, la tua applicazione potrebbe essere dietro più livelli di NAT (questo accade di più quando ti allontani dagli Stati Uniti, dove si trova la sovrabbondanza di IP).

STUN è davvero il metodo migliore. In generale, dovresti pianificare di eseguire un server (STUN) da qualche parte l'applicazione può chiedere: non codificare i server di altre persone. Devi codificare per inviare alcuni messaggi specifici come descritto in rfc5389.

Suggerisco una buona lettura e collegamenti correlati. http://www.ietf.org/html.charters/behave-charter.html

Potresti preferire guardare IPv6 e Teredo per assicurarti di avere sempre accesso IPv6. (Microsoft Vista lo rende molto semplice, mi hanno detto)

Ogni volta che volevo farlo, raschiavo whatismyip.org . Quando vai sul sito, ti dà il tuo IP pubblico in chiaro. Chiaro e semplice.

Basta che il tuo script acceda a quel sito e leggi l'IP.

Non so se lo stavi insinuando o meno nel tuo post, ma non è possibile ottenere il tuo IP pubblico dal tuo computer. Deve provenire da una fonte esterna.

Modifica 2013: questo sito restituisce un'immagine ora anziché testo, quindi è inutile per questo scopo.

Mi piace il ipify.org :

  • è gratuito (anche a livello di programmazione e persino di traffico intenso)
  • response contiene solo l'indirizzo IP senza immondizia (nessuna necessità di analisi)
  • puoi anche richiedere una risposta in JSON
  • funziona sia per IPv4 che per IPv6
  • è ospitato nel cloud
  • è open source
$ curl api.ipify.org
167.220.196.42

$ curl "api.ipify.org?format=json"
{"ip":"167.220.196.42"}

Come menzionato da diverse persone, STUN è davvero la soluzione corretta.

Se la rete ha un server UpNp in esecuzione sul gateway, è possibile comunicare con il gateway e chiederlo per il proprio indirizzo IP esterno.

Il tuo modo più semplice potrebbe essere quello di chiedere a un server all'esterno della tua rete.

Una cosa da tenere a mente è che destinazioni diverse potrebbero vedere un indirizzo diverso per te. Il router potrebbe essere multihomed. Ed è proprio qui che iniziano i problemi.

Per ottenere il tuo IP esterno, potresti fare una query dns a un server opendns con lo speciale nome host " myip.opendns.com " ;:

from subprocess import check_output

ip = check_output(["dig", "+short", "@resolver1.opendns.com",
                   "myip.opendns.com"]).decode().strip()

Su Windows, puoi provare nslookup .

Non esiste un modulo DNS in Python stdlib che consenta di specificare un server DNS personalizzato. Puoi utilizzare librerie di terze parti, ad es. Twisted per eseguire la query dns:

from twisted.internet     import task # $ pip install twisted
from twisted.names.client import Resolver
from twisted.python.util  import println

def main(reactor):
    opendns_resolvers = [("208.67.222.222", 53), ("208.67.220.220", 53)]
    resolver = Resolver(servers=opendns_resolvers, reactor=reactor)
    # use magical hostname to get our public ip
    return resolver.getHostByName('myip.opendns.com').addCallback(println)
task.react(main)

Ecco lo stesso usando dnspython library :

import dns.resolver # $ pip install dnspython

resolver = dns.resolver.Resolver(configure=False)
resolver.nameservers = ["208.67.222.222", "208.67.220.220"]
print(resolver.query('myip.opendns.com')[0])

un altro modo sfacciato: se il tuo router ha la possibilità di aggiornare il suo IP web su DynDNS , puoi ottenere il tuo IP con qualcosa come :

IP=`resolveip -s myalias.dyndns-home.com`

Duck Duck Go dà accesso gratuito alla loro API in base alla propria pagina qui: https://duckduckgo.com/api

Ecco l'URL che colpisci se vuoi il tuo indirizzo IP: http://api.duckduckgo.com/?q=my+ip&format= json

Restituisce un oggetto JSON. L'attributo Answer ha una stringa leggibile dall'uomo con dentro il tuo indirizzo IP. Esempio:

{
    ...
    "Answer": "Your IP address is ww.xx.yyy.zzz in <a href=\"http://open.mapquest.com/?q=aaaaa(bbbbb)\">aaaaa(bbbbb)</a>"
    ...
}

Puoi estrarre l'indirizzo IP da quella stringa usando split () [4] , se pensi che sia un presupposto sicuro che questa stringa non cambierà mai o sei disposto a è necessario ripararlo periodicamente.

In alternativa, se si desidera avere un metodo a prova di futuro, è possibile eseguire il ciclo su tutto ciò che viene restituito da split () e restituire il primo elemento che è un indirizzo IP. Vedi qui per la convalida degli indirizzi IP: Come convalidare l'indirizzo IP in Python?

curl api.infoip.io - dettagli completi

curl api.infoip.io/ip - solo l'indirizzo IP

curl api.infoip.io/country - solo il nome del paese

... e più o meno lo stesso

puoi visualizzare i documenti su http://docs.ciokan.apiary.io/

Ti sto condividendo il mio metodo per recuperare l'indirizzo IP pubblico di un server senza dover usare API esterne (che ovviamente è un rischio per la sicurezza)

INTERFACE=`ip route get 8.8.8.8 | grep 8.8.8.8 | cut -d' ' -f5`
HOSTIP=`ifconfig $INTERFACE | grep "inet " | awk -F'[: ]+' '{ print $4 }'`

O in python se preferisci:

import subprocess
public_ip = subprocess.check_output(["ifconfig `ip route get 8.8.8.8 | grep 8.8.8.8 | cut -d' ' -f5` | grep \'inet \' | awk -F'[: ]+' '{ print $4 }'"], shell=True)

Funziona così:

  • determina l'interfaccia migliore per raggiungere il server DNS di Google
  • greps IP pubblico dalla voce ifconfig per quell'interfaccia

Ora è abbastanza economico ospitare il tuo " serverless " API. Tutti i principali fornitori di servizi cloud hanno un servizio per questo. Ad esempio, utilizzando Google Cloud Functions è sufficiente:

exports.requestIP = (req, res) => {
    res.status(200).send(req.ip)
}

Questo approccio è probabilmente più affidabile rispetto all'utilizzo dei servizi pubblici di cui sopra e puoi aggiungere una lunga stringa casuale al nome della funzione per mantenerlo privato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top