Zjisteni aktualni verejne IP z terminalu a skriptu

Casto je potreba znat verejnou IP adresu, za kterou se PC schovava. Hodne znamy je web http://www.mojeip.cz/ ktery vsak jde pouzit jenom pres webovy prohlizec. Pokud potrebujeme zjistit IP v terminalu, nebo ve skriptu, museli bychom si napsat parser webove stranky. Z lenosti jsem si napsal vlastni skript na zjistovani adresy. Zde je jednoduchy skript na zjistovani IP v Pythonu:

import socket
import thread
import sys

# --------------------
port = 1234
host = '0.0.0.0'
# --------------------

print("Using TCP port %s." % (port))
buf = 1024
addr = (host, port)
NL = '\r\n'

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(addr)
serversocket.listen(500)

clients = [serversocket]

def handler(clientsocket, clientaddr):
    print("Accepted connection from: ", clientaddr)
    clientsocket.settimeout(2)
    try:
        data = clientsocket.recv(buf)
        if "GET" in data or "Host:" in data or "User-Agent" in data: # HTTP request
            clientsocket.send("HTTP/1.0 200 OK" + NL)
            clientsocket.send("Content-type: text/plain; charset=us-ascii" + NL)
            clientsocket.send("Connection: close" + NL)
            clientsocket.send(NL)
            clientsocket.send(str(clientaddr[0]) + NL)

    except socket.timeout: # Telnet request
        clientsocket.send(str(clientaddr[0]) + NL)

    except socket.error: # error
        print("Send to %s error: " % clientaddr)

    finally:
        clients.remove(clientsocket)
        clientsocket.close()

while True:
    try:
        #print("Server is listening for connections\n")
        clientsocket, clientaddr = serversocket.accept()
        clients.append(clientsocket)
        thread.start_new_thread(handler, (clientsocket, clientaddr))
    except KeyboardInterrupt: # Ctrl+C # FIXME
        print("Closing server socket...")
        serversocket.close()

Ktery nasledne muzeme zkompilovat pomoci cythonu a spustit:

$ cython --embed getip.py 
$ gcc getip.c -I/usr/include/python2.7 -lpython2.7 -o getip
$ strip getip
$ du -sh getip
59K getip
$ file getip
getip: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=12166ba5208e49ff66eb73820025b860baedc78b, stripped
$
$ ./getip
Using TCP port 1234.

Automaticke spusteni

Na automaticke spusteni po startu systemu pouzivam /usr/local/bin/getip_start

#!/bin/bash

while true; do
	/usr/local/bin/getip
	sleep 2
done

a ten se spousti z /etc/rc.local :

root@server:/home/martin# cat /etc/rc.local 
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# ...

nohup su - XXX -c "/usr/local/bin/getip_start" &
# XXX je jmeno nejakeho ne-root uzivatele, pod kterym to pobezi

# ...

exit 0

Pouziti je nasledujici

nc (netcat)

martin@martin:~$ nc ip.vancl.eu 1234
77.78.90.200
martin@martin:~$

Busybox telnet client (OpenWrt, Ubiquity)

martin@martin:~$ /bin/busybox telnet ip.vancl.eu 1234
77.78.90.200
Connection closed by foreign host
martin@martin:~$ 

wget

martin@martin:~$ wget http://ip.vancl.eu:1234/ -qO -
77.78.90.200
martin@martin:~$

martin@martin:~$ wget ip.vancl.eu:1234 -qO -
77.78.90.200
martin@martin:~$

Ubuntu telnet client

martin@martin:~$ telnet ip.vancl.eu 1234
Trying ip.vancl.eu...
Connected to ip.vancl.eu.
Escape character is '^]'.
77.78.90.200
Connection closed by foreign host.
martin@martin:~$

Jak je videt, klasicky telnet klient je nepouzitelne ukecany. Wget funguje dobre, ale kdo si ma pamatovat vsechny jeho parametry? Idealni je netcat (nc), ten vsak zvlast v embedded systemech neni.

Jak to funguje

Po spusteni zacne skript poslouchat na TCP 0.0.0.0:1234. Kdyz se nekdo pripoji, vrati mu IP a ukonci spojeni. U telnetu to tak funguje, webove prohlizece Firefox/Chrome take nemaji problem.

Pokud se vsak zkusime pripojit wgetem, wget vypise hromadu chybovych hlasek o chybejicih HTTP hlavickach. Proto jsem udelal maly hack. Skript po navazani spojeni ceka 2s. Pokud behem teto doby prijme nejake HTTP hlavicky, posle odpoved jako validni HTTP odpoved. Kdyz hlavicky neprijdou, posle jenom plain text adresu a zalomeni radku.

Odkaz na Gist, kde bude vzdy aktualni verze.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *