tags:

views:

240

answers:

2

I'm trying to set a page that displays the visitor's IP. All the methods I have tried show an IP different from the IP my computer has. I've tried:

  1. Looking up http://www.whatismyip.com/automation/n09230945.asp

  2. Using socket.getaddrinfo(socket.gethostname(), None)[0][4][0]

How can I find the real IP of the visitor?

+3  A: 

Using the low level networking interface you are actually getting the address of the server the python interpreter is running on:

"socket.gethostname(): Return a string containing the hostname of the machine where the Python interpreter is currently executing."

Getting the client ip using low-level network interface

"socket.accept() Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection."

# Echo server program
import socket

HOST = ''                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()

More info on the low level network interface

Getting the client IP from HTTP headers (if serving html)

REMOTE_ADDR is the header that contains the clients ip address you should check that first.

You should also check to for the HTTP_X_FORWARDED header in case you're visitor is going through a proxy. Be aware that HTTP_X_FORWARDED is an array that can contain multiple comma separated values depending on the number of proxies.

Also be aware that you may be NATed (Network Address Translation). If your ip is internal (10.x.x.x or 192.168.x.x to name a few) you are definitely behind a NAT router and only your external ip will be exposed to websites.

Here is a small c# snippet that shows determining the client's ip, the logic is easy to convert the python and the server headers are the same:

string clientIp = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if( !string.IsNullOrEmpty(clientIp) ) {
    string[] forwardedIps = clientIp.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries );
    clientIp = forwardedIps[forwardedIps.Length - 1];
} else {
    clientIp = context.Request.ServerVariables["REMOTE_ADDR"];
}
vfilby
A: 

I found a simple solution:

import getenv
print getenv("REMOTE_ADDR")

This will return the IP address of the computer connecting to the server.

Yongho
As mentioned in my answer above, you can use that header but it doesn't account for proxies. More info in my answer
vfilby