2010-05-11 5 views
27

Je me demande si cela est la meilleure façon de faire correspondre une chaîne qui commence par une adresse IP privée (Regex style Perl):Adresse IP privée Identifier dans une expression régulière

(^127\.0\.0\.1)|(^192\.168)|(^10\.)|(^172\.1[6-9])|(^172\.2[0-9])|(^172\.3[0-1]) 

Merci beaucoup!

+3

Tout d'abord, vous devez examiner RFC1918 pour obtenir la bonne liste. Deuxièmement, je suggère qu'une solution n'impliquant pas les expressions rationnelles sera plus facile à maintenir. Une fois que vous avez converti une adresse IP en numérique, il est assez facile de la faire correspondre à une liste de plages IP privées. Cela vous permettra également d'utiliser facilement les listes de bogons disponibles publiquement, qui contiennent beaucoup plus que RFC1918. – derobert

+1

@derobert true, mais pour des utilisations telles qu'un filtre d'adresse distant Tomcat, vous avez besoin d'une expression régulière. – Raedwald

+0

C'est une erreur courante de débutant de penser que '^' signifie "non" dans ce contexte, donc il convient de souligner: Chaque '^' dans votre expression ancre simplement la correspondance au début de la ligne. Dans la regex traditionnelle, il n'y a pas de moyen simple de dire "pas cette chaîne", bien que les expressions Perl-compatibles/PCRE aient des lookaheads négatifs avec '(?! ...)' – tripleee

Répondre

48

Je suppose vous voulez faire correspondre ces gammes:

 
127. 0.0.0 – 127.255.255.255  127.0.0.0 /8 
10. 0.0.0 – 10.255.255.255  10.0.0.0 /8 
172. 16.0.0 – 172. 31.255.255 172.16.0.0 /12 
192.168.0.0 – 192.168.255.255 192.168.0.0 /16 

il vous manque quelques points qui provoqueraient à accepter par exemple 172.169.0.0 même si cela ne devrait pas être acceptée. Je l'ai réparé ci-dessous. Enlevez les nouvelles lignes, c'est juste pour la lisibilité.

(^127\.)| 
(^10\.)| 
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)| 
(^192\.168\.) 

Notez également que cela suppose que les adresses IP ont déjà été validés - il accepte des choses comme 10.foobar.

+0

Si vous souhaitez exclure les adresses IP privées du suivi google analytics, utilisez ceci: https://gist.github.com/1000402 –

+2

La première ligne doit être (^ 127 \.) | –

+0

Il ne valide pas sur les IP internes de nos réseaux: Par exemple: 10.131.43.84 Votre bloc 10 est cassé – mfriis

3

Apparence correcte. Personnellement, je changerais le premier à:

^127\.0 

Avec ceci: (^127\.0\.0\.1)-vous quelque chose qui commence par 127.0.0.1 et va manquer 127.0.0.2*, 127.0.2.*, 127.0.* etc.

+2

Je sais que c'est vieux, mais cette question était première ou seconde sur ma recherche google. Je crois que tout le bloc 127.0.0.0/8 est réservé pour le bouclage, de sorte que 0 ne devrait même pas être là. –

3

Ceci est dans le cas où vous décidez d'aller avec mon commentaire, en vous suggérant de ne pas utiliser d'expressions rationnelles. Non testé (mais probablement fonctionne, ou au moins proche), en Perl:

@private = (
    {network => inet_aton('127.0.0.0'), mask => inet_aton('255.0.0.0') }, 
    {network => inet_aton('192.168.0.0'), mask => inet_aton('255.255.0.0') }, 
    # ... 
); 

$ip = inet_aton($ip_text); 
if (grep $ip & $_->{mask} == $_->{network}, @private) { 
    # ip address is private 
} else { 
    # ip address is not private 
} 

Notez maintenant comment @private est juste des données, que vous pouvez facilement changer. Ou télécharger à la volée à partir du Cymru Bogon Reference. Edit: Il me vient à l'esprit que demander une regexp Perl ne signifie pas que vous connaissez Perl, donc la ligne clé est le 'grep', qui boucle simplement sur chaque plage d'adresses privée. Vous prenez votre IP, bitwise et avec le masque de réseau, et comparez à l'adresse réseau. Si égal, sa partie de ce réseau privé.

13

Ceci est la même que la bonne réponse de Mark, mais incluant maintenant les adresses privées IPv6.

/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/ 
+4

Pas bon - Selon Wikipedia, (http://en.wikipedia.org/wiki/Unique_local_address), le bloc (fc00 ::/7) est réservé aux adresses locales uniques. Cette Regex ajoute seulement l'adresse localhost (:: 1) à la solution acceptée. – dana

+3

Selon https://github.com/rails/rails/pull/12651/files l'expression rationnelle pour cela serait '^ [fF] [cCdD]' - Je suis en train d'éditer la réponse en conséquence. – blueyed

+0

Le caractère '/' au début et à la fin du script me suggère que vous utilisez l'expression dans un langage comme Javascript, mais cela n'est pas valable dans d'autres langues. Malgré cela, une version plus courte (et sans les barres obliques) est '^ (127 \.) | (192 \ .168 \.) | (10 \.) | (172 \ .1 [6-9] \.) | (172 \ .2 [0-9] \.) | (172 \ .3 [0-1] \.) | (:: 1 $) | ([fF] [cCdD]) ' – Mrdev

8

J'ai produit ce

REGEXP POUR LA CLASSE A NETWORKS:

(10)(\.([2]([0-5][0-5]|[][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9])){3}

REGEXP POUR LES RÉSEAUX DE CLASSE B:

(172)\.(1[6-9]|2[0-9]|3[0-1])(\.([2][0-5][0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9])){2}

REGEXP POUR LES RÉSEAUX DE CLASSE C :

(192)\.(168)(\.[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]){2}

Laissez-moi savoir si vous rencontrez une erreur

Si vous êtes sûr de votre sortie (disons par exemple netstat) et vous avez pas besoin de vérifier sur la validité de l'adresse IP, car il est déjà fait , alors vous pouvez attraper des adresses IP privées avec cette formule

grep -P "(10. | 192.168 | 172.1 [6-9]. | 172.2 [0-9]. | 172.3 [01].). *"

+3

En utilisant simplement [[ 2] [0-5] [0-5] 'pour la plage 200 à 255, les nombres comme 206 à 209 et 216 à 219, etc. ne correspondent pas. Vous devrez le remplacer par '([0-9] | [1-9] [0-9] | 1 [0-9] [0-9] | 2 [0-4] [0-9] | 25 [0-5]) '. – kielabokkie

+0

Dans quelle langue cela est-il utilisé? Je ne peux pas le faire fonctionner, https://regex101.com/r/jdVmny/1 – Justin

1

Si vous recherchez system.net defaultProxy et config bypasslist config qui utilise un proxy pour externe, mais utilise des connexions directes pour les hôtes internes (pourrait faire avec un soutien ipv6) ...

<system.net> 
    <defaultProxy enabled="true"> 
    <proxy proxyaddress="http://proxycluster.privatedomain.net:8080" bypassonlocal="True" /> 
    <bypasslist> 
     <!-- exclude local host --> 
     <add address="^(http|https)://localhost$" /> 
     <!-- excludes *.privatedomain.net --> 
     <add address="^(http|https)://.*\.privatedomain\.net$" /> 
     <!-- excludes simple host names --> 
     <add address="^(http|https)://[a-z][a-z0-9\-_]*$" /> 
     <!-- exclude private network addresses 192.168, 172.16..31 through 31, 127.* etc. --> 
     <add address="^(http|https)://((((127)|(10))\.[0-9]+\.[0-9]+\.[0-9]+)|(((172\.(1[6-9]|2[0-9]|3[0-1]))|(192\.168))\.[0-9]+\.[0-9]+))$"/> 
    </bypasslist> 
    </defaultProxy> 
    <connectionManagement> 
    <add address="*" maxconnection="10" /> 
    </connectionManagement> 
</system.net> 
-1

FWIW ce modèle était de plus de 10% plus rapide en utilisant pattern.matcher:

^1((0)|(92\\.168)|(72\\.((1[6-9])|(2[0-9])|(3[0-1])))|(27))\\. 
+1

J'ai fait quelques tests, mais il semble être d'environ 100% plus lent. Pouvez-vous fournir quelques tests pour sauvegarder cela? –

0
 //RegEx to check for the following ranges. IPv4 only 
     //172.16-31.xxx.xxx 
     //10.xxx.xxx.xxx 
     //169.254.xxx.xxx 
     //192.168.xxx.xxx 

    var regex = /(^127\.)|(^(0)?10\.)|(^172\.(0)?1[6-9]\.)|(^172\.(0)?2[0-9]\.)|(^172\.(0)?3[0-1]\.)|(^169\.254\.)|(^192\.168\.)/; 
2

ici est ce que je l'utilise en python:

rfc1918 = re.compile('^(10(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){3}|((172\.(1[6-9]|2[0-9]|3[01]))|192\.168)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){2})$') 

vous pouvez supprimer le^et/ou des ancres $ si vous le souhaitez.

Je préfère l'expression rationnelle ci-dessus car elle supprime les octets invalides (tout ce qui est supérieur à 255).

Exemple d'utilisation:

if rfc1918.match(ip): 
    print "ip is private" 
Questions connexes