To podstawowa zasada przy projektowaniu aplikacji – nigdy nie polegaj na danych otrzymanych ze świata zewnętrznego. Nie polegaj – znaczy nie zakładaj, że są poprawne.
Aplikacje często chcą zapisywać adres IP z którego korzysta klient. Gdy połączenie jest bezpośrednie to zwyczajowe sięgnięcie do zmiennej REMOTE_ADDR dostarczanej przez serwer WWW jest OK. To jest dość pewna informacja, dlatego, że połączenie TCP przyszło z tego adresu i tego nasz serwer może być pewien. Oczywiście nie jest to jednoznaczne z tym że fizycznie klient miał taki adres IP. Przyczyn może być całkiem sporo – od różnych NATów/PATów, przez tunelowanie połączenia (SSH) lub użycie proxy.
No i ten ostatni przypadek jest dość ciekawy ;) otóż proxy powinno dodawać nagłówek X-Forwarded-For. I większość to robi domyślnie. Ale już poleganie na tym (czyli nie zapamiętywanie wartości REMOTE_ADDR gdy jest podany X-Forwarded-For) może prowadzić do pomyłek :) Otóż po pierwsze – mogą to być adresy prywatne (sieci 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8) i będzie to jak najbardziej prawdziwa informacja jeśli proxy widzi komputer klienta pod prywatnym adresem – bardzo częste w firmowych sieciach.
Dalej, nawet bez jakiegoś podsyłania spreparowanych nagłówków można osiągnąć coś takiego:

Serwis z którego to jest zrzut ekranu oczywiście podaje też adres proxy (tak na marginesie, nie wiedziałem, że w Kalifornii mieszkam :) ), ale jeżeli ktoś zapisze sobie w logach tylko wartość z X-Forwarded-For… Nie szukajmy daleko:
Ruby on Rails wiki – to jest wersja strony, którą zrobiłem przez proxy. Na samym końcu:
Created on May 01, 2008 19:38 by NetManiac (127.0.0.1)
Zawsze zapamiętujcie parę REMOTE_ADDR i X-Forwarded-For.
Popularity: 18% [?]




Zawsze zapisujcie trójkę :)
- REMOTE_ADDR
- HTTP_X_FORWARDED_FOR
- HTTP_CLIENT_IP
Ja zapamiętuję jeden adres IP – ten który mi poda request.remote_ip w Railsach. Jest to metoda, która sprawdza te 3 wartości, filtruje 127.0.0.1, prywatne sieci i w 99.9% przypadków wypluwa taki adres IP, o który nam chodzi.