tech note

インフラ技術や車についてつぶやいていくブログ

BIG-IPのCookiePersistenceをIP変換するPerlスクリプトを作ってみました

f:id:tea_cat:20180913022350j:plain

こんな変換をしてくれます。

IPv4 -> IPv4_Cookie
10.1.1.100:8080 -> 1677787402.36895.0000
IPv4_Cookie -> IPv4
1677787402.36895.0000 -> 10.1.1.100:8080
IPv4_RouteDomain -> IPv4_RouteDomain_Cookie
192.0.2.1%5:80 -> rd5o00000000000000000000ffffc0000201o80
IPv4_RouteDomain_Cookie -> IPv4_RouteDomain
rd5o00000000000000000000ffffc0000201o80 -> 192.0.2.1%5:80
IPv6 -> IPv6_Cookie
2001:db8::ffff:a14:574.80 -> vi20010db8000000000000ffff0a140574.20480
IPv6_Cookie -> IPv6
vi20010db8000000000000ffff0a140574.20480 -> 2001:0db8:0000:0000:0000:ffff:0a14:0574.80
http://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html

Perlスクリプト

#!/usr/bin/perl
#
# /root/makecookie.pl Update:2011.06.07
#
#http://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html
##################################################################################

use strict;
use warnings;

#set_regexp_var
my $regexp_ipv4_pool_members = '^(\d|[01]?\d\d|2[0-4]\d|25[0-5])\.(\d|[01]?\d\d|2[0-4]\d|25[0-5])\.(\d|[01]?\d\d|2[0-4]\d|25[0-5])\.(\d|[01]?\d\d|2[0-4]\d|25[0-5])\:(\d+)$';

my $regexp_ipv4_pool_members_in_non_default_route_domains = '^(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\%(\d+)\:(\d+)$';

my $regexp_decoding_persistence_cookie_values = '^(\d+)\.(\d+)';

my $regexp_decoding_ipv4_pool_members_in_non_default_route_domains = '^rd(\d+)o00000000000000000000ffff(..)(..)(..)(..)o(\d+)';

my $regexp_decoding_ipv6_pool_members = '^vi(\w+)?\.(\d+)$';

my $regexp_ipv6_pool_members = '((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\.(\d+)$';


#arg_check
$_ = $ARGV[0];

if (scalar(@ARGV) < 1){

        &make_cookie_help;

} elsif (/$regexp_ipv4_pool_members/) {

        &IPv4_pool_members ($1, $2, $3, $4, $5);

} elsif (/$regexp_ipv4_pool_members_in_non_default_route_domains/) {

        &IPv4_pool_members_in_non_default_route_domains($1, $2, $3, $4, $5, $6);

} elsif (/$regexp_decoding_persistence_cookie_values/) {

        &Decoding_persistence_cookie_values ($1, $2);

} elsif (/$regexp_decoding_ipv4_pool_members_in_non_default_route_domains/) {

        &Decoding_IPv4_pool_members_in_non_default_route_domains($1, $2, $3, $4, $5, $6);

} elsif (/$regexp_decoding_ipv6_pool_members/) {

        &Decoding_IPv6_pool_members ($1, $2);

} elsif (/$regexp_ipv6_pool_members/) {

        &IPv6_pool_members ($&);

} else {

        &make_cookie_help;

}


#function BEGIN
sub IPv4_pool_members {

        my ($A, $B, $C, $D) = @_;
        $A *= 1;
        $B *= 256;
        $C *= 256**2;
        $D *= 256**3;
        my $IP = $A + $B + $C + $D;

        my $PORT = $_[4];
        my $MOD = $PORT % 256;
        my $NNN = int($PORT / 256);
        $PORT = $MOD * 256 + $NNN;

        my $value = "$IP" . "." . "$PORT" . ".0000";
        print $value, "\n";

#print <<EOF;
#Set-Cookie: BIGipServer[poolname]=${value}; path=/
#or
#Set-Cookie: BIGipServer[poolname]=${value}; expires=Sat, 01-Jan-2000 00:00:00 GMT; path=/
#EOF

}


sub Decoding_persistence_cookie_values {

        my ($ip , $port) = @_;
        $ip = sprintf ("%032b\n", $ip);
        $ip =~ /(.{8})(.{8})(.{8})(.{8})/;
        my $a = oct('0b' . $1);
        my $b = oct('0b' . $2);
        my $c = oct('0b' . $3);
        my $d = oct('0b' . $4);

        my $mod = int($port % 256);
        my $nnn = int($port / 256);
        $port = ($mod * 256) + $nnn;

        print "$d.$c.$b.$a:$port\n";
}

sub IPv4_pool_members_in_non_default_route_domains {

        my ($A, $B, $C, $D, $ID, $PORT) = @_;

        printf("rd%do00000000000000000000ffff%02x%02x%02x%02xo%d\n" , $ID ,$A , $B, $C ,$D ,$PORT);

}

sub Decoding_IPv4_pool_members_in_non_default_route_domains {

        my ($id, $a, $b, $c, $d, $port) = @_;
        $a = hex($a);
        $b = hex($b);
        $c = hex($c);
        $d = hex($d);

        print "$a.$b.$c.$d%$id:$port\n";

}

sub Decoding_IPv6_pool_members {

        my ($ipv6, $port) = @_;
        my $mod = $port % 256;
        my $nnn = int($port / 256);
        $port = $mod * 256 + $nnn;

        $ipv6 =~ /(....)(....)(....)(....)(....)(....)(....)(....)/;

        print "$1:$2:$3:$4:$5:$6:$7:$8.$port\n";

}

sub IPv6_pool_members {

        my $ipv6 = $_[0];
        my $count = ( () = $ipv6 =~ /\:/g );
        $ipv6 =~ /.*\.(\d+)$/;
        my $port = $1;

        my $mod = $port % 256;
        my $nnn = int($port / 256);
        $port = $mod * 256 + $nnn;

        $ipv6 =~ s/^::/0::/;
        $ipv6 =~ s/::$/::0/;
        $ipv6 =~ s/::/':0' x ( 8 - $count ) . ':'/e;
        $ipv6 =~ s/[0-9a-f]+/sprintf('%04s', $&)/egi;

        $ipv6 =~ /(....)\:(....)\:(....)\:(....)\:(....)\:(....)\:(....)\:(....)/;
        print "vi$1$2$3$4$5$6$7$8.$port\n";

}

sub make_cookie_help {

        print <<EOF;

Usage: makecookie.pl <key>

        <key>
        #IPv4 -> IPv4_Cookie
        10.1.1.100:8080 -> 1677787402.36895.0000

        #IPv4_Cookie -> IPv4
        1677787402.36895.0000 -> 10.1.1.100:8080

        #IPv4_RouteDomain -> IPv4_RouteDomain_Cookie
        192.0.2.1%5:80 -> rd5o00000000000000000000ffffc0000201o80

        #IPv4_RouteDomain_Cookie -> IPv4_RouteDomain
        rd5o00000000000000000000ffffc0000201o80 -> 192.0.2.1%5:80

        #IPv6 -> IPv6_Cookie
        2001:db8::ffff:a14:574.80 -> vi20010db8000000000000ffff0a140574.20480

        #IPv6_Cookie -> IPv6
        vi20010db8000000000000ffff0a140574.20480 ->
                                   2001:0db8:0000:0000:0000:ffff:0a14:0574.80

support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html

EOF
exit (2);
}
#Function END