Obtenir la véritable adresse IP du client sur Heroku

sur Heroku Cedar, je voulais l'adresse IP du client. Première tentative:

ENV['REMOTE_ADDR']

cela ne fonctionne pas, bien sûr, parce que toutes les requêtes sont passées par des procurations. Ainsi l'alternative était d'utiliser:

ENV['HTTP_X_FORWARDED_FOR']

Mais ce n'est pas tout à fait sûr, est-il?

S'il ne contient qu'une seule valeur, je prends ceci. Si elle contient plus d'une valeur (séparées par des virgules), je pourrais prendre la première.

mais qu'est-ce que si quelqu'un manipule cette valeur? Je ne peux pas faire confiance à ENV['HTTP_X_FORWARDED_FOR'] comme je le pouvais avec ENV['REMOTE_ADDR'] . Et il n'y a pas de liste de mandataires de confiance que je pourrais utiliser, non plus.

mais il doit y avoir d'une manière ou d'une autre pour obtenir de manière fiable l'adresse IP du client, toujours. Vous en connaissez une?

Dans leurs docs , Heroku explique que X-Forwarded-For est "l'adresse IP du client qui se connecte à la Heroku routeur".

cela sonne comme si Heroku pouvait écraser le X-Forwarded-For avec L'IP distante d'origine. Cela permettrait d'éviter l'usurpation, à droite? Quelqu'un peut-il vérifier?

22
demandé sur kiril 2013-08-16 05:12:41

3 réponses

de Jacob, Le Directeur de la sécurité D'Heroku à L'époque:

le routeur n'écrase pas X-Forwarded-For , mais il garantit que l'origine réelle sera toujours dernier dans la liste.

cela signifie que, si vous accédez à une application Heroku de la manière normale, vous verrez juste votre adresse IP dans l'en-tête X-Forwarded-For :

$ curl http://httpbin.org/ip
{
  "origin": "123.124.125.126",
}

si vous essayez de spoof L'IP, votre origine présumée est reflétée, mais - de manière critique - est votre vraie IP. Évidemment, c'est tout ce dont nous avons besoin, donc il y a une solution claire et sûre pour obtenir L'adresse IP du client sur Heroku:

$ curl -H"X-Forwarded-For: 8.8.8.8" http://httpbin.org/ip
{
  "origin": "8.8.8.8, 123.124.125.126"
}

C'est tout le contraire de ce qui est décrit sur Wikipedia , soit dit en passant.

PHP de mise en œuvre:

function getIpAddress() {
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ipAddresses = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        return trim(end($ipAddresses));
    }
    else {
        return $_SERVER['REMOTE_ADDR'];
    }
}
30
répondu caw 2017-12-18 20:29:45

je travaille dans le service de support D'Heroku et j'ai passé du temps à en discuter avec nos ingénieurs routeurs. Je voulais poster des informations supplémentaires pour clarifier certaines choses sur ce qui se passe ici.

l'exemple fourni dans la réponse ci-dessus vient d'avoir l'adresse IP du client affichée en dernier par coïncidence et ce n'est pas vraiment garanti. La raison pour laquelle elle ne l'a pas été en premier lieu est que la demande initiale revendiquait une transmission pour la période D'enquête indiquée dans la demande initiale. X-Forwarded-For en-tête. Lorsque le routeur Heroku a reçu la requête, il a juste ajouté L'IP qui se connectait directement à la liste X-Forwarded-For après celle qui avait été injectée dans la requête. Notre routeur ajoute toujours L'IP qui est connectée à L'AWS ELB devant notre plate-forme comme dernière IP dans la liste. Cette IP pourrait être la première (et dans le cas où il n'y a qu'une IP, c'est presque certainement le cas), mais à l'instant où il y a plusieurs IP enchaînés, tous les paris sont éteints. La Convention est toujours pour ajouter la dernière IP de la chaîne à la fin de la liste (ce qui est ce que nous faisons), mais à tout moment de la chaîne cette chaîne peut être modifiée et différents IP peuvent être insérés. Ainsi, la seule IP fiable (du point de vue de notre plateforme) est la dernière IP de la liste.

pour illustrer, disons que quelqu'un initie une requête et ajoute arbitrairement 3 IPs supplémentaires à L'en-tête X-Forwarded-For:

curl -H "X-Forwarded-For: 12.12.12.12,15.15.15.15,4.4.4.4" http://www.google.com

imaginez ceci la propriété intellectuelle de machine était 9.9.9.9 et qu'elle devait passer par un mandataire (par exemple, le mandataire d'une université à l'échelle du campus). Disons que ce proxy avait une IP de 2.2.2.2. En supposant qu'il n'ait pas été configuré pour supprimer les en-têtes X-Forwarded-For (ce qui ne serait probablement pas le cas), il aurait simplement mis l'IP 9.9.9 à la fin de la liste et transmis la demande à Google. À ce stade, l'en-tête ressemblerait à ceci:

X-Forwarded-For: 12.12.12.12,15.15.15.15,4.4.4.4,9.9.9.9

cette requête passera alors par le point final de Google, qui sera ajouté L'IP du mandataire de L'Université de 2.2.2.2, donc l'en-tête ressemblera finalement à ceci dans les journaux de Google:

X-Forwarded-For: 12.12.12.12,15.15.15.15,4.4.4.4,9.9.9.9,2.2.2.2

alors, quelle est L'adresse IP du client? C'est impossible à dire du point de vue de Google. En réalité, L'IP du client est de 9.9.9.9. La dernière IP listée est 2.2.2.2 cependant et la première est 12.12.12. Tout ce que Google sait est que l'IP 2.2.2.2 est certainement correcte parce que c'était L'IP qui s'est connecté à leur service – mais ils ne savent pas si c'était le client initial pour la demande ou non à partir des données disponibles. De la même manière, lorsqu'il n'y a qu'une IP dans cet en – tête-c'est L'IP qui est directement connectée à notre service, donc nous savons qu'elle est fiable.

d'un point de vue pratique, cette PI sera probablement fiable la plupart du temps (parce que la plupart des gens ne se soucieront pas de spoof leur PI). Malheureusement, il est impossible d'empêcher ce genre de mystification et au moment où une demande arrive à la Routeur Heroku, il nous est impossible de dire si les IPs d'une chaîne X-Forwarded-For ont été trafiquées ou non.

toutes les questions de fiabilité mises à part, ces chaînes IP doivent toujours être lues de gauche à droite. L'adresse IP client devrait être toujours L'adresse IP la plus à gauche.

23
répondu Joel Watson 2016-05-05 22:52:04

vous ne pouvez jamais vraiment faire confiance à toute information provenant du client. C'est plus une question de confiance et de vérification. Même Heroku peut être influencé pour fournir une mauvaise valeur HTTP_X_FORWARDED_FOR s'ils ont un bug dans leur code, ou ils se font pirater d'une façon ou d'une autre. Une autre option serait une autre machine Heroku se connectant à votre serveur en interne et contournant leur proxy tout en simulant REMOTE_ADDR et / ou HTTP_X_FORWARDED_FOR .

le meilleur réponse ici dépendra de ce que vous essayez de faire. Si vous essayez de vérifier vos clients, un certificat côté client peut être une solution plus appropriée. Si tout ce que vous avez besoin de L'IP est la géolocalisation, faire confiance à l'entrée peut être suffisant. Dans le pire des cas, quelqu'un va simuler l'emplacement et obtenir le mauvais contenu... Si vous avez un cas d'utilisation différent, il y a beaucoup d'autres solutions entre ces deux extrêmes.

3
répondu kichik 2015-05-02 18:41:52