Match IP adres met CIDR notatie

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Keuvie
  • Registratie: Oktober 2005
  • Laatst online: 21-09 16:41
Hi all,

Ik ben op zoek naar een manier om een ip adres tegen een lijst te matchen waar CIDR blocks in staan met commentaar:

Voorbeeld:
192.168.192.0/24 TESTCOMMENT

Ik heb ipset en grepcidr geprobeerd, maar die boden niet hetgeen wat ik nodig had:

code:
1
2
3
4
$ ipset create foo hash:net comment
$ ipset add foo 192.168.192.0/24 comment TESTCOMMENT
$ sudo ipset test foo 192.168.192.168
192.168.192.168 is in set foo.


code:
1
2
3
4
5
6
$ cat foo.txt 
192.168.192.0/24 TESTCOMMENT
$ grepcidr -f foo.txt <(echo 192.168.192.168)
192.168.192.168
$ grepcidr -f foo.txt <(echo 192.168.0.168)
$


Ik zoek dus een manier om het ip tegen een lijst te houden en de regel, dan wel het comment terug te krijgen.

Welke manieren zou ik nog meer kunnen testen?

Acties:
  • +1 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Nu online
Na even zoeken vond ik rgxg om een regular expression voor een CIDR-blok te genereren. Dat zou je met awk zo kunnen gebruiken:

Bash:
1
awk -v ip=192.168.192.168 '{ "rgxg cidr " $1 | getline regex; if (ip ~ regex) print $2 }' foo.txt


Dat kun je verpakken in een kort shell-scriptje dat het ip gewoon als positioneel argument accepteert. Dit roept dus wel voor elke regel in foo.txt rgxg aan.

Met Python 3.3 of hoger kan het ook vrij simpel zonder extra tools:
Python:
1
2
3
4
5
6
7
8
import sys
from ipaddress import ip_address, ip_network

address = ip_address(sys.argv[1])
for line in open('foo.txt'):
    cidr, comment = line.strip().split(maxsplit=1)
    if address in ip_network(cidr):
        print(comment)

Acties:
  • 0 Henk 'm!

  • Keuvie
  • Registratie: Oktober 2005
  • Laatst online: 21-09 16:41
Ik had rgxr ook gevonden, maar helaas nog niet zo bedreven in awk. Ik ga het verder ontleden om te kijken wat er precies gebeurt.

Voor Python is ook een hele mooie oplossing.

Bedankt voor jouw antwoord!

Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Nu online
Ik ben ook niet met alle awk-functies even bekend en ik zie nog een probleem met die getline pipe. Je moet die eigenlijk nog expliciet sluiten (dat wordt een probleem als foo.txt groeit). En omdat de evaluatievolgorde "unspecified" is, zou je de string concatenation links van de pipe tussen haakjes moeten zetten (zonder werkte het wel met GNU awk bij mij).

Je kunt het matchen van IP tegen CIDR ook in een functie stoppen. Hier met close en extra haakjes:
Awk:
1
2
3
4
5
6
7
8
function match_cidr(s, cidr)
{
    ("rgxg cidr " cidr) | getline regex
    close("rgxg cidr " cidr)
    return s ~ regex
}

match_cidr(ip, $1) { print $2 }

Na de functiedefinitie is het awk-programma heel simpel: de functie wordt aangeroepen voor elke regel, waarbij het tweede argument steeds het eerste veld van de invoer is (het CIDR-blok in foo.txt). Als de functie true teruggeeft, wordt de actie (tussen accolades) uitgevoerd, hier dus het printen van het tweede veld. En dat is goed voor deze test, maar niet hetzelfde als de Python-oplossing, want die print de hele rest van de regel. Met awk zou je dan een loop over de resterende woorden moeten doen, maar je kunt ook gewoon 'print' zonder argumenten gebruiken of de hele actie (inclusief accolades) weglaten om de hele regel (inclusief CIDR) te printen.

Acties:
  • 0 Henk 'm!

  • Keuvie
  • Registratie: Oktober 2005
  • Laatst online: 21-09 16:41
Door jouw hulp bedacht ik mij dat ik de lijst ook kon vergelijken met het IP adres. Ik heb nu alle ranges direct als regex opgeslagen in de textfile:

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

Hierdoor kan ik het volgende uitvoeren:

code:
1
2
$ ip=192.168.192.168; while read line; do if [[ $ip =~ ${line%% *} ]]; then echo ${line##* }; fi; done < foo.tx
TESTCOMMENT


Ik ga mij nog wel verdiepen in jouw methode.

Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 29-09 21:21

Hero of Time

Moderator LNX

There is only one Legend

En hoe wil je met die regex andere CIDR notaties gaan matchen, als dit niet in de reeks valt die je verwacht? Want je kijkt nu naar een /24 reeks, wat als je twee /25 reeksen hebt met aparte comments? Of een /23?

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • Keuvie
  • Registratie: Oktober 2005
  • Laatst online: 21-09 16:41
Scherp, dat probleem zou (aanname) niet vaak moeten voorkomen omdat het een lijst betreft met de ranges van CDN blocks per aanbieder(MaxCDN, Cloudflare).

Het is dus een informatieve lijst in plaats van eentje waar andere scripts van afhankelijk zijn.

Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 29-09 21:21

Hero of Time

Moderator LNX

There is only one Legend

Dan nog kan er kleinere of grotere subnetten zijn dan de standaard klasse A, B en C die veelal gebruikt worden.

Commandline FTW | Tweakt met mate

Pagina: 1