AWS::Networks - Parser und Filter für AWS IP-Adressbereiche
Veröffentlicht von Thomas Fahle am (Permalink)
Amazon Web Services (AWS) veröffentlicht seine aktuellen IP-Adressbereiche regelmäßig im JSON-Format.
AWS::Networks von Jose Luis Martinez Torres stellt einen Parser und verschiedene Filter für AWS Netzwerkbereiche bereit.
Diese so ermittelten Netzwerkbereiche können dann mit bereits existierenden CPAN Modulen für IP-Adressbereiche, wie Net::CIDR::Set, weiter verarbeitet werden.
AWS::Networks in Version 0.01, das für diesen Beitrag verwendet wird, kann leider nur IPv4 Adressbereiche aus den von AWS bereitgestellten Daten parsen bzw. filtern.
Basics
Das nachfolgende Beispiel lädt die ip-ranges.json Datei von AWS herunter, zeigt den Zeitpunkt der Veröffentlichung an und listet alle AWS IP-Adressbereiche im CIDR-Format auf.
#!/usr/bin/perl use strict; use warnings; use AWS::Networks; my $nets = AWS::Networks->new(); print $nets->sync_token->iso8601, "\n"; foreach my $cidr ( @{ $nets->cidrs } ) { print "$cidr\n"; }
Das Programm erzeugt folgende (gekürzte) Ausgabe:
2017-06-22T22:12:11 13.32.0.0/15 13.52.0.0/15 13.54.0.0/15 13.56.0.0/16 13.57.0.0/16 13.58.0.0/15 ..... 54.240.128.0/18 204.246.164.0/22 204.246.168.0/22 204.246.174.0/23 204.246.176.0/20 205.251.192.0/19 205.251.249.0/24 205.251.250.0/23 205.251.252.0/23 205.251.254.0/24 216.137.32.0/19
Wer bereits eine ip-ranges.json Datei lokal vorliegen hat, kann diese wie folgt mit File::Slurp einlesen:
#!/usr/bin/perl use strict; use warnings; use File::Slurp; use JSON; use AWS::Networks; # https://ip-ranges.amazonaws.com/ip-ranges.json my $ip_ranges_json_file = 'ip-ranges.json'; my $json = read_file($ip_ranges_json_file); my $nets = AWS::Networks->new( netinfo => decode_json($json) ); print $nets->sync_token->iso8601, "\n"; foreach my $cidr ( @{ $nets->cidrs } ) { print "$cidr\n"; }
Ausgabe des Programms wie oben.
Hinweis: Das Modul AWS::IP, das eine ähnliche Funktionalität anbietet, verwendet einen Cache für die ip-ranges.json Datei.
Ist diese IP eine AWS IP Adresse?
Das nachfolgende Kommandozeilentool prüft, ob eine IPv4 Adresse in den AWS IP-Adressbereichen enthalten ist:
#!/usr/bin/perl use strict; use warnings; use feature 'say'; use AWS::Networks; use Net::CIDR::Set; my $ip = $ARGV[0]; unless ($ip) { die "Usage: $0 IPv4-address\n"; } my $nets = AWS::Networks->new(); my $cidrs = $nets->cidrs; my $cidr_set = Net::CIDR::Set->new(@$cidrs); if ( $cidr_set->contains($ip) ) { say "Yes - $ip is a AWS IP."; } else { say "No - $ip is not a AWS IP."; }
Das Programm erzeugt folgende Ausgabe:
$ perl ip.pl 216.137.32.6 Yes - 216.137.32.6 is a AWS IP. $ perl ip.pl 127.0.0.1 No - 127.0.0.1 is not a AWS IP.
Jose Luis Martinez Torres liefert mit der Distribution auch das umfangreichere Tool aws_ip aus.
Nach Services filtern
Die Methode services() liefert eine Liste aller verfügbaren Services:
#!/usr/bin/perl use strict; use warnings; use feature 'say'; use AWS::Networks; my $nets = AWS::Networks->new(); foreach my $service ( @{ $nets->services } ) { say "$service"; }
Das Programm erzeugt folgende Ausgabe:
EC2 CLOUDFRONT ROUTE53_HEALTHCHECKS ROUTE53 S3 AMAZON
Die Methode by_service( ) liefert eine Liste aller Netzwerkbereiche für einen bestimmten Service
Eine Übersicht über alle Netzwerkbereiche für alle Services erhält man wie folgt:
#!/usr/bin/perl use strict; use warnings; use feature 'say'; use AWS::Networks; my $nets = AWS::Networks->new(); foreach my $service ( @{ $nets->services } ) { say "$service"; my $aws_networks_object = $nets->by_service($service); foreach my $cidr ( @{ $aws_networks_object->cidrs } ) { say "\t$cidr"; } }
Das Programm erzeugt folgende (gekürzte) Ausgabe:
ROUTE53 52.95.110.0/24 205.251.192.0/21 ROUTE53_HEALTHCHECKS 54.183.255.128/26 54.228.16.0/26 .... AMAZON 13.32.0.0/15 13.52.0.0/15 13.54.0.0/15 .... CLOUDFRONT 13.32.0.0/15 13.54.63.128/26 .... S3 52.82.188.0/22 52.92.0.0/20 .... EC2 13.52.0.0/15 13.54.0.0/15 13.56.0.0/16 ....
Nach Regionen filtern
Die Methode regions() liefert eine Liste aller verfügbaren AWS Regionen und die Methode by_region() liefert eine Liste aller Netzwerkbereiche für eine bestimmte Region.
Eine Übersicht über alle Netzwerkbereiche für alle Regionen erhält man wie folgt:
#!/usr/bin/perl use strict; use warnings; use feature 'say'; use AWS::Networks; my $nets = AWS::Networks->new(); foreach my $region ( @{ $nets->regions } ) { say "$region"; my $aws_networks_object = $nets->by_region($region); foreach my $cidr ( @{ $aws_networks_object->cidrs } ) { say "\t$cidr"; } }
Das Programm erzeugt folgende (gekürzte) Ausgabe:
cn-north-1 52.80.0.0/16 52.94.249.0/28 52.95.255.144/28 54.222.0.0/19 .... sa-east-1 18.231.0.0/16 52.67.0.0/16 52.92.39.0/24 .... eu-west-1 34.240.0.0/13 34.248.0.0/13 46.51.128.0/18 ....
Nach Regionen und Services filtern
Manchmal möchte man die IP-Adressbereiche für einen bestimmten Service in einer bestimmten Region ermitteln.
Hierzu ermittelt man zunächst alle IP-Adressbereiche für den gewünschten Service und alle IP-Adressbereiche für die gewünschte Region.
Diese beiden Sets (Mengen) werden mit und zu einer neuen Menge verknüpft.
#!/usr/bin/perl use strict; use warnings; use feature 'say'; use AWS::Networks; use Net::CIDR::Set; my $region_set = cidr_set_for_region('eu-west-1'); my $service_set = cidr_set_for_service('EC2'); my $overlap = $region_set->intersection($service_set); my $iter = $overlap->iterate_cidr; while ( my $cidr = $iter->() ) { say $cidr; } exit(); # Returns a Net::CIDR::Set object filled with AWS CIDRs for $service sub cidr_set_for_service { my $service = shift; my $nets = AWS::Networks->new(); my $s = $nets->by_service($service); my $cidrs = $s->cidrs; my $cidr_set = Net::CIDR::Set->new(@$cidrs); return $cidr_set; } # Returns a Net::CIDR::Set object filled with AWS CIDRs for $region sub cidr_set_for_region { my $region = shift; my $nets = AWS::Networks->new(); my $r = $nets->by_region($region); my $cidrs = $r->cidrs; my $cidr_set = Net::CIDR::Set->new(@$cidrs); return $cidr_set; }
Das Programm erzeugt folgende Ausgabe:
34.240.0.0/12 46.51.128.0/18 46.51.192.0/20 46.137.0.0/17 46.137.128.0/18 52.16.0.0/14 52.30.0.0/15 52.48.0.0/14 52.95.244.0/24 52.95.255.64/28 52.208.0.0/13 54.72.0.0/14 54.76.0.0/15 54.78.0.0/16 54.154.0.0/15 54.170.0.0/15 54.194.0.0/15 54.216.0.0/15 54.220.0.0/16 54.228.0.0/15 54.246.0.0/15 79.125.0.0/17 176.34.64.0/18 176.34.128.0/17 185.48.120.0/22
IP-Ranges zur Kontrolle ausgehenden Datenverkehrs (egress control)
In der offiziellen AWS Dokumentation wird folgendes Beispiel Implementieren der Kontrolle ausgehenden Datenverkehrs aufgeführt, das als Ausgangspunkt für das nachfolgende Programm dient.
"Um einer Instance nur den Zugriff auf AWS-Services zu erlauben, erstellen Sie eine Sicherheitsgruppe mit Regeln, die ausgehenden Datenverkehr zu den CIDR-Blöcken in der AMAZON-Liste zulassen, abzüglich der CIDR-Blöcke, die auch in der EC2-Liste enthalten sind."
Hierzu ermittelt man zunächst alle IP-Adressbereiche für die gewünschten Services (AMAZON und EC2).
Anschließend wird die Menge der EC2-Bereiche von der Menge der AMAZON-Bereiche abgezogen.
#!/usr/bin/perl use strict; use warnings; use feature 'say'; use AWS::Networks; use Net::CIDR::Set; # http://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html # Implementing Egress Control # To allow an instance to access only AWS services, create a security group # with rules that allow outbound traffic to the CIDR blocks in the AMAZON list, # minus the CIDR blocks that are also in the EC2 list. my $amazon_set = cidr_set_for_service('AMAZON'); my $ec2_set = cidr_set_for_service('EC2'); my $egress_set = $amazon_set->diff($ec2_set); my $iter = $egress_set->iterate_cidr; while ( my $cidr = $iter->() ) { say $cidr; } exit(); # Returns a Net::CIDR::Set object filled with # AWS CIDRs for $service sub cidr_set_for_service { my $service = shift; my $nets = AWS::Networks->new(); my $s = $nets->by_service($service); my $cidrs = $s->cidrs; my $cidr_set = Net::CIDR::Set->new(@$cidrs); return $cidr_set; }
Das Programm erzeugt folgende (gekürzte) Ausgabe:
13.32.0.0/15 27.0.0.0/22 43.250.192.0/23 52.46.0.0/18 52.46.64.0/19 52.82.187.0/24 52.82.188.0/22 52.82.196.0/22 52.82.200.0/21 52.82.208.0/20 .... 204.246.174.0/23 204.246.176.0/20 205.251.192.0/19 205.251.224.0/20 205.251.240.0/22 205.251.244.0/23 205.251.247.0/24 205.251.248.0/22 205.251.252.0/23 205.251.254.0/24 207.171.160.0/19 216.137.32.0/19
Siehe auch
- AWS IP Address Ranges
- AWS::Networks -Parse and query official AWS network ranges
- Net::CIDR::Set - Manipulate sets of IP addresses
- AWS::IP - Get and search AWS IP ranges in a caching, auto-refreshing way
- Paws - A Perl SDK for AWS (Amazon Web Services) APIs