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?

6
  • Are you behind a filewall or a nat router? Is python saying your something like 192.168.... or 10.10.... ? You want to know your external IP address? Commented Apr 13, 2010 at 14:37
  • According to whatismyip, my IP is 128.2.xxx.xxx According to Python, my IP is 72.47.xxx.xxx Commented Apr 13, 2010 at 14:41
  • Where is your python server, on a local work network or on the internet? Tools like tracert or traceroute can help you determine where your server is if you don't know. Commented Apr 13, 2010 at 14:43
  • My Python server is on the internet (Mediatemple). Does Python get the IP of the server running the code (in this case, Mediatemple) or does it get the IP of the visitor going to the page? Commented Apr 13, 2010 at 14:49
  • Sorry, just reread your post. You are indeed getting the address of your server. I'll complete my answer for you below. Commented Apr 13, 2010 at 15:09

2 Answers 2

4

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"];
}
Sign up to request clarification or add additional context in comments.

Comments

0

I found a simple solution:

import getenv
print getenv("REMOTE_ADDR")

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

1 Comment

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