Descobrir IP pública programaticamente
-
03-07-2019 - |
Pergunta
Estou atrás de um router, eu preciso de um comando simples para descobrir o meu ip público (em vez de pesquisando qual é o meu ip e clicar em um dos resultados)
Existem protocolos padrão para isso? Eu ouvi sobre STUN mas eu não sei como eu posso usá-lo?
P.S. Estou pensando em escrever um script python curto para fazê-lo
Solução
Editar : curlmyip.com não está mais disponível. (Graças maxywb)
Original Publicar :
Como de escrever este post, curlmyip.com funciona. A partir da linha de comando:
curl curlmyip.com
É um site de terceiros, que podem ou não estar disponíveis alguns anos abaixo da estrada. Mas, por enquanto, parece muito simples e direto ao ponto.
Outras dicas
Esta pode ser a maneira mais fácil. Analisar a saída dos seguintes comandos:
- executar um traceroute para encontrar um roteador que é inferior a 3 saltos para fora de sua máquina.
- ping executado com a opção para gravar a rota de origem e analisar a saída. O primeiro endereço IP na rota gravada é o seu público.
Por exemplo, estou em uma máquina Windows, mas a mesma idéia deve funcionar a partir de unix também.
> 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
O 68.85.228.121 é um Comcast (meu provedor) router. Podemos executar ping que:
> 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! O 66.176.38.51 é o meu IP público.
Eu fiz um programa que se conecta a http://automation.whatismyip.com/n09230945.asp ele é escrito em D um alguém tirando outra coisa para lhe dizer o que eles vêem o seu ip como é provavelmente a maneira mais confiável:
/*
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");
}
}
O código de edição python deve ser como:
from urllib import urlopen
print urlopen('http://automation.whatismyip.com/n09230945.asp').read()
Segmentação www.whatsmyip.org é rude. Eles apelo para não fazer isso na página.
Apenas um sistema no mesmo nível de NAT como seu alvo vai ver o mesmo IP. Por exemplo, seu aplicativo pode estar por trás de várias camadas de NAT (isso acontece mais como você se afastar dos EUA, onde o excesso de IPs são).
STUN é realmente o melhor método. Em geral, você deve ser o planejamento para executar um (STUN) em algum lugar do servidor que você aplicação pode perguntar: não faça servidores rígidos códigos de outras pessoas. Você tem que código para enviar algumas mensagens específicas, conforme descrito no rfc5389.
Eu sugiro uma boa leitura de e links relacionados. http://www.ietf.org/html.charters/behave-charter.html
Você pode preferir olhar para IPv6 e Teredo para se certificar de que você sempre tem acesso IPv6. (Microsoft Vista faz isso muito fácil, me disseram)
Sempre que eu queria fazer isso, gostaria apenas de raspar whatismyip.org . Quando você vai para o site, dá-lhe o seu IP público de texto simples. Puro e simples.
Basta ter o seu acesso script que site e ler o IP.
Eu não sei se você estava implicando isso em seu post ou não, mas não é possível obter o seu IP público de seu próprio computador. Ele tem que vir de uma fonte externa.
2013 edit:. Este site devolve uma imagem agora em vez de texto, por isso é inútil para esta finalidade
Eu gosto do ipify.org :
- é gratuito para uso (mesmo por meio de programação e até mesmo tráfego intenso)
- resposta contém apenas o endereço IP sem qualquer lixo (sem necessidade de análise)
- você também pode solicitar resposta em JSON
- funciona tanto para IPv4 e IPv6
- ele está hospedado na nuvem
- é open source
$ curl api.ipify.org
167.220.196.42
$ curl "api.ipify.org?format=json"
{"ip":"167.220.196.42"}
Como mencionado por várias pessoas, STUN é realmente a solução adequada.
- uma lista de STUN servidores públicos
- um software livre cliente STUN
- padrão STUN
Se a rede tiver um servidor UPnP em execução no gateway que você é capaz de falar com o gateway e pedir-lhe para o seu endereço IP fora.
A sua forma mais simples pode ser a de pedir algum servidor do lado de fora da sua rede.
Uma coisa a ter em mente é que os diferentes destinos podem ver um endereço diferente para você. O router podem ser diversas bases. E realmente isso é apenas onde os problemas começam.
Para obter o seu IP externo, você poderia fazer uma consulta DNS para um servidor OpenDNS com o hostname especial "myip.opendns.com":
from subprocess import check_output
ip = check_output(["dig", "+short", "@resolver1.opendns.com",
"myip.opendns.com"]).decode().strip()
No Windows, você pode tentar nslookup
.
Não há módulo de dns em Python stdlib que permitiria especificar servidor DNS personalizado. Você pode usar bibliotecas de terceiros por exemplo, torcida para fazer a consulta 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)
Aqui é a mesma coisa usando dnspython
biblioteca :
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])
outra maneira atrevida: Se o seu roteador tem a opção de atualizá-lo da web IP na DynDNS , você pode começar seu próprio IP com algo como :
IP=`resolveip -s myalias.dyndns-home.com`
Duck Duck Go dá livre acesso a sua API de acordo com sua própria página aqui: https://duckduckgo.com/api
Aqui está o URL de bater se você quiser que o seu endereço IP: http://api.duckduckgo.com/?q=my+ip&format=json
que retorna um objeto JSON. O atributo Answer
tem uma string legível com o seu endereço IP na mesma. Exemplo:
{
...
"Answer": "Your IP address is ww.xx.yyy.zzz in <a href=\"http://open.mapquest.com/?q=aaaaa(bbbbb)\">aaaaa(bbbbb)</a>"
...
}
Você poderia extrair o endereço IP daquele cadeia utilizando split()[4]
, se você acha que é uma suposição segura que esta cadeia nunca vai mudar ou você está disposto a necessidade de periodicamente corrigi-lo.
Como alternativa, se você quer ter um método mais à prova do futuro, você poderia loop sobre tudo voltou por split()
e retornar o primeiro item que é um endereço IP. Veja aqui para validar endereços IP:
Como validar endereços IP em Python?
curl api.infoip.io
- detalhes completos
curl api.infoip.io/ip
- apenas o endereço IP
curl api.infoip.io/country
- apenas o nome do país
... e mais do mesmo
Você pode visualizar os documentos em http://docs.ciokan.apiary.io/
Eu estou compartilhando o meu método de recuperar endereço IP público de um servidor sem ter que usar APIs externas (que é um risco de curso de segurança)
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 }'`
Ou em python se você prefere:
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)
Ele funciona assim:
- determina a melhor interface para alcançar o servidor google dns
- greps IP público a partir da entrada
ifconfig
para essa interface
Agora é muito barato para hospedar seu próprio API "sem servidor". Todos os principais provedores de nuvem têm um serviço para isso. Por exemplo, usando funções do Google Cloud tudo o que preciso é:
exports.requestIP = (req, res) => {
res.status(200).send(req.ip)
}
Esta abordagem é provavelmente mais confiável do que usando os serviços públicos acima e você pode adicionar uma cadeia longa aleatório para o nome da função para mantê-lo privado.