brocade adx openscript

38
BROCADE ADX OPENSCRIPT March 2013 1 Derek Kang ([email protected] ), Solutions Architect

Upload: magee-sandoval

Post on 31-Dec-2015

134 views

Category:

Documents


0 download

DESCRIPTION

Brocade ADX Openscript. March 2013. Derek Kang ( [email protected] ), Solutions Architect. Agenda. OpenScript Architecture Quick Start Perl Basics OpenScript Examples Best Practices. OpenScript Architecture. What is OpenScript?. Open-Standard (Perl) Based - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Brocade ADX  Openscript

1

BROCADE ADX OPENSCRIPTMarch 2013

Derek Kang ([email protected]), Solutions Architect

Page 2: Brocade ADX  Openscript

2

Agenda

• OpenScript Architecture

• Quick Start

• Perl Basics

• OpenScript Examples

• Best Practices

Page 3: Brocade ADX  Openscript

3

OpenScript Architecture

Page 4: Brocade ADX  Openscript

4

What is OpenScript?

Open-Standard (Perl) Based Application Delivery Programming

Engine

Predictable Scripting Engine with Performance Estimator

Learn, Browse, Share Scripts through OpenScript Communitywww.brocade.com/openscript

Page 5: Brocade ADX  Openscript

5

OpenScript Architecture

Content Switching Engine

OpenScript Engine

TCP/UDP/IP

Pack

et

In

Packe

t Out

(event, context)

(result)

App Core

• Event Driven Model

• Script Attached to Virtual Port

• Resource Profile Per Script

Limits the resource consumption of a script• 1 MB memory foot print• Watch-dog timer (200 ms)• 100 KB data collection per event

MP

Compile

• Performance estimation• Catching syntax errors

Page 6: Brocade ADX  Openscript

6

OpenScript Quick Start

Page 7: Brocade ADX  Openscript

7

OpenScript Quick Start

Sorry.Get back later.

use OS_SLB;use OS_HTTP_REQUEST;

my $page;

sub BEGIN { $page = "HTTP/1.1 200 OK\r\nContent- Length:21\r\nConnection:close\r\nContent- Type: text/html; charset=UTF-8\r\n\r\n. Sorry .Get. back later.”;}

sub HTTP_REQUEST { OS_SLB::forward (10);}

sub SERVER_SELECTION_FAILURE { OS_SLB::reply($page);}

server l7-dont-reset-on-vip-port-fail

server real rs1 10.1.1.10 port 80 group-id 10 10

server real rs2 10.1.1.11 port 80 group-id 10 10

server virtual v1 20.1.1.1 port 80 bind 80 rs1 80 rs2 80

http://20.1.1.1

rs1 rs2

OpenScript “sorry.pl”ADX SLB Config

script “sorry.pl”

123456789

10111213141516171819

Page 8: Brocade ADX  Openscript

8

OpenScript Quick StartSteps With CLI

use OS_SLB;use OS_HTTP_REQUEST;

sub BEGIN { $page = "HTTP/1.1 200 OK\r\nContent- Length:21\r\nConnection:close\r\nContent- Type: text/html; charset=UTF-8\r\n\r\n. Sorry .Get. back later.”;}

sub HTTP_REQUEST { OS_SLB::forward (10);}

sub SERVER_SELECTION_FAILURE { OS_SLB::reply($page);}

server l7-dont-reset-on-vip-port-fail

server real rs1 10.1.1.10 port 80 group-id 10 10

server real rs2 10.1.1.11 port 80 group-id 10 10

server virtual v1 20.1.1.1 port 80 bind 80 rs1 80 rs2 80

1. Configure basic L4 SLB

2. Write a script on your choice of editor

3. Upload the script to the ADX

4. Compile the script

ADX#copy tftp usb0 10.120.61.68 sorry.pl sys\dpscript\sorry.plADX#show script allindex name In Use 1 sorry.pl

ADX#copy tftp usb0 10.120.61.68 sorry.pl sys\dpscript\sorry.plADX#show script allindex name In Use 1 sorry.pl ADX#config termADX(config)#script compile sorry.plThis script is compiled successfully.Performance for this script: - Approximately 9548 connections/second at 10% CPU utilization - Approximately 47744 connections/second at 50% CPU utilization - Approximately 95488 connections/second at 100% CPU utilization

5. Attach the script to the VIP portserver virtual v1 20.1.1.1

port http script “sorry.pl”

Page 9: Brocade ADX  Openscript

9

OpenScript Quick StartSteps With Web GUI

1

2

3

4

0GUI Version Check

Page 10: Brocade ADX  Openscript

10

Perl Basics

Page 11: Brocade ADX  Openscript

11

Regex

$string =~ m/pattern/

$string =~ s/pattern1/pattern2

my $string = “ab-abc-abcd”;$string =~ m/(.*)-/;print “$1\n”;

ab-abc

my $string = “ab-abc-abcd”;$string =~ m/(.*?)-/print “$1\n”;

ab

my $string = “ab-abc-abcd”;$string =~ s/ab/x/print “$string”;

my $string = “ab-abc-abcd”;$string =~ s/ab/x/gprint “$string”;

x-xc-xcd

x-abc-abcd

Page 12: Brocade ADX  Openscript

12

Hash / List / Array

rs1

url1

20

3

@my_array = (“url1”, “url2”, “url3”);$value = $my_array [ 0 ];

@my_two_dim_array = ( [ “url1”, 10 ], [ “url2”, 20 ], [ “url3”, 30 ] )

$value = $my_two_dim_array [ 1 ] [ 1 ]$size = scalar ( @my_array )

%my_hash_table = ( 1030=>”rs1”, 1031=>”rs2” )

$value = $my_hash_table { 1030 }

Page 13: Brocade ADX  Openscript

13

Pack, Unpack, Split, Join and Substr

unpack (template, scalar)

$hex_string = "\x7e\xf1";

my $bin_string = unpack("b*", $hex_string);print "$bin_string\n";

my $field = substr ($bin_string, 4, 4);print "$field\n";

0111111010001111

1110substr (data, start, size)

my @ip = split('\.', "10.1.2.3");my @net_mask = split('\.', "255.255.0.0");

my $net_ip = pack("C4", @ip) & pack("C4", @net_mask);my $net = join( '.', unpack("C4", $net_ip) );

print "$net\n";

pack (template, list)

10.1.0.0

split (‘separator’, scalar)

join (‘joiner’, list)

Page 14: Brocade ADX  Openscript

14

Conditional Statements

if ( $string == “birthday” ) {

print "Happy Birthday!\n";

} elsif ($string == “christmas”) {

print "Happy Christmas!\n";

} else {

print "Happy Whatever!\n";

}

if (EXPR) BLOCK

if (EXPR) BLOCK else BLOCK

if (EXPR) BLOCK elsif (EXPR) BLOCK

if (EXPR) BLOCK elsif (EXPR) BLOCK else BLOCK

Page 15: Brocade ADX  Openscript

15

Loop

2 3for $i (2..3) {

print “$i";}

url1 url2 url3@url = (url1, url2, url3);foreach $i (@url) {

print “$i\n”;}

$count = 1;while ($count <= 11 ) {

$count++;last;$count++;

}print “$count\n”;

for ($i=2; $i<=3; $i++) {

print “$i";}

2

@url = (url1, url2, url3);foreach (@url) {

print “$_\n”;}

Page 16: Brocade ADX  Openscript

16

OpenScript Examples

Page 17: Brocade ADX  Openscript

17

Mitigate DNS Dynamic Update Attack

• What is DNS dynamic update?• To update a DNS record on the DNS server dynamically, e.g., IP

address change.

• What is DNS dynamic DoS attack?• The attack sends a DNS server a crafted DNS dynamic update

message to cause a server crash.

• Some DNS Server S/Ws based on BIND 9 software are vulnerable to the attack.

• Solution−Drop DNS dynamic update messages using OpenScript

Page 18: Brocade ADX  Openscript

18

Drop DNS Dynamic Update(ADX CLI Config)

(DNS Dynamic Update Message)

use OS_UDP;use OS_SLB;

sub UDP_CLIENT_DATA{ $payload = OS_UDP::payload; $mydata = unpack( "b*", $payload); $mystring = substr ($mydata, 17, 4);

if ($mystring == "0101" ) { OS_SLB::drop; } else { OS_SLB::forward(10); }}

(dnsdos.pl)

server real rs1 10.1.1.2 port 53 group-id 10 10!server real rs2 10.1.1.3 port 53 group-id 10 10

server virtual v1 10.1.1.100 port 53 port 53 script dnsdos.pl bind 53 rs1 53 rs2 1

234567891011121314

Page 19: Brocade ADX  Openscript

19

• You want to allow only Intranet clients to access an URL www.mycompany.com/data/, on your company web server.

• Your Intranet clients belong to IP subnet 10.x.x.x/8

• If someone outside tries to access, return a page with a message “You are not allowed to access the content”.

Blocking Access to Certain URLs based on Client IP addresses

www.mycompany.com/datawww.mycompany.com/data/www.mycompany.com/data/*

www.mycompany.comwww.mycompany.com/datapublic

All PCs

Intranet PCs

Page 20: Brocade ADX  Openscript

20

Blocking Access to Certain URLs based on Client IP addresses

use OS_IP;use OS_SLB;use OS_HTTP_REQUEST;

my $local_subnet;my $page;

sub BEGIN {$local_subnet = “10.”;$page = "HTTP/1.1 200 OK\r\nContent-Length: 43\r\nConnection:

close\r\nContent-Type: text/html; charset=UTF-8\r\n\r\nYou are not allowed to access the content.";}

sub HTTP_REQUEST {my $client_ip = OS_IP::src;my $url = OS_HTTP_REQUEST::url;

if (!($client_ip =~ m/^$local_subnet/) && $url =~ m/www.mycompany.com\/data($|\/.*)/) {

OS_SLB::reply($page);} else {

OS_SLB::forward(1);}

}

• If an external client tries to access www.mycompany.com/data, return a warning page.

List OpenScript API modules to use

Initialization sub routine• Define 10.x.x.x as an internal

network• Prepare a web page to return for

warning to external clients

Main routine

Regular Expression to match the URL

123456789

10111213141516171819202122

Page 21: Brocade ADX  Openscript

21

SIP VIA Header IP ReplacementSIP/2.0 200 OKVia: SIP/2.0/UDP server.foo.com;branch=z9hG4bKnashds8;received=192.0.2.3Via: SIP/2.0/UDP bigbox.site3.com;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2Via: SIP/2.0/UDP pc3.atlanta.com;branch=z9hG4bK776asdhds ;received=192.0.2.1To: Bob <sip:bob.com>;tag=a6c85cfFrom: Alice <sip:alice.com>;tag=1928301774Call-ID: a84b4c76e66710.atlanta.comCSeq: 314159 INVITEContact: <sip:bob.0.2.4>Content-Type: application/sdpContent-Length: 131 SIP/2.0 200 OK

Via: SIP/2.0/UDP server.foo.com;branch=z9hG4bKnashds8;received=10.1.1.100Via: SIP/2.0/UDP bigbox.site3.com;branch=z9hG4bK77ef4c2312983.1;received=10.1.1.100Via: SIP/2.0/UDP pc3.atlanta.com;branch=z9hG4bK776asdhds ;received=10.1.1.100To: Bob <sip:bob.com>;tag=a6c85cfFrom: Alice <sip:alice.com>;tag=1928301774Call-ID: a84b4c76e66710.atlanta.comCSeq: 314159 INVITEContact: <sip:bob.0.2.4>Content-Type: application/sdpContent-Length: 131

Page 22: Brocade ADX  Openscript

22

SIP VIA Header IP Replacementuse OS_IP;use OS_UDP;

my $vip;

sub BEGIN {                $vip = 10.1.1.100;  # VIP you want to put in the Via header}

sub UDP_CLIENT_DATA{ my $client_ip = OS_IP::src;                my $sip_msg = OS_UDP::payload;                                if ($sip_msg =~ s/ (.*?Via:) (.*?;) (.*?;) (received=) (\d{1,3}\. \d{1,3}\. \d{1,3}\. \d{1,3}) / $1 $2 $3 $4 $vip /xig) {                             OS_UDP::payload($sip_msg);                } else {

OS_SLB::log (“Warning : SIP client $client_ip : VIA header was not found”);                                                }}

123456789

10111213141516171819

Page 23: Brocade ADX  Openscript

23

OpenScript Best Practices

Page 24: Brocade ADX  Openscript

24

OpenScript Best Practices

• Readability

• Performance

• Trouble Shooting

Page 25: Brocade ADX  Openscript

25

Variable Names and Spaces AroundNo CamelCase

DO my $variable_that_contains_my_server_name = gather_server_stats (gigantic_apache_web_server);

DO NOTmy $variableThatContainsMyServerName = gatherServerStats (giganticApacheWebServer) ;

Page 26: Brocade ADX  Openscript

26

Spaces Around Operators and After Commas

DOmy %server_list = (1030=>”rs1”, 1031=>”rs2” );

DO NOTmy %server_list=(1030=>”rs1”,1031=>”rs2” );

Page 27: Brocade ADX  Openscript

27

Regular Expression

DO/ ( [a-fA-F0-9] ) - [a-fA-F0-9]{4} - [a-fA-F0-9]{4} - [a-fA-F0-9]{4} - [a-fA-F0-9]{12} /x

DO NOT/([a-fA-F0-9])-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/

Also, Don’t Overdo Regex

Page 28: Brocade ADX  Openscript

28

Compile with “Strict”

script compile <script file name> strictOr include in the OpenScript code

use strict;use Sub::StrictDecl;………………………………………………………….

* the strict option in the compilation CLI and Sub:StrictDecl require 12.4.00f or later.

ADX(config)#script compile hello.pl This script is compiled successfully.Performance for this script: - Approximately 5200 connections/second at 10% CPU utilization - Approximately 26200 connections/second at 50% CPU utilization - Approximately 52400 connections/second at 100% CPU utilizationADX(config)#script compile hello.pl strict S_my_exit_jump being called Compile Errors found : Undeclared subroutine &OS_SLB::Forward at -e line 11.BEGIN not safe after errors--compilation aborted at -e line 17.

Page 29: Brocade ADX  Openscript

29

SLB Forwarding API Use

OS_HTTP_REQUEST () { if ( EXPR ) { OS_SLB::forward(1); } OS_SLB::forward(2);}

OS_HTTP_REQUEST () { if ( EXPR ) { OS_SLB::forward(1); } else { OS_SLB::forward(2); }}

Wrong

Page 30: Brocade ADX  Openscript

30

No Object Oriented Convention

DO$url = OS_HTTP_REQUEST::url;

DO NOT$req_obj = OS_HTTP_REQUEST::get;$url = $req_obj->url

Not Supported, starting in 12.4.00e for increased performance by 30%

Page 31: Brocade ADX  Openscript

31

BEGIN Subroutinemy %network_group;my $net_mask_hex;

sub BEGIN {my $net_mask = "255.255.0.0";%network_group = (

"10.1.0.0“ => "GROUP_A“, "10.2.0.0“ => "GROUP_B”, “10.3.0.0“ => "GROUP_C"

);my @net_mask = split ('\.', $net_mask);$net_mask_hex = pack(C4, @netmask);

}

my $ip = OS_IP::src;my @ip = split ('\.', $ip);

my $net_hex = pack ("C4", @ip) & $net_mask_hex;

$net = join (‘.', unpack("C4", $net_hex) );$group_name = $network_group { $net };

Do As Many As Operations in the BEGIN

Main Event Handler

• Do not assign a value to a variable outside a sub routine

• Just declare the variable with the scope“my” outside a sub routine as lexical scoping is required.

Page 32: Brocade ADX  Openscript

32

Print Statement and Log

script-profile production print-output none!server virtual v1 10.24.142.86 port http port http script "hello.pl" script-profile "production”

print: Do not use in production except for debugging purposeOS_SLB::log: Use to log unexpected and rare events in production environment

Page 33: Brocade ADX  Openscript

33

Use Memory To Save CPUsub HTTP_REQUEST { my $host = OS_HTTP_REQUEST::host;

if ( $host =~ m/www.host1.com/) { OS_SLB::forward (rs1);

} elsif ( $host =~ m/www.host2.com ) { OS_SLB::forward (rs2);

} elsif { $host =~ m/www.host3.com ) { OS_SLB::forward (rs3);

} else { OS_SLB:reset_client(); }}

my %host_server_mapping;

sub BEGIN { %host_server_mapping = { “www.host1.com”=>”rs1”, “www.host2.com”=>”rs2”, “www.host3.com”=>”rs3”};}

sub HTTP_REQUEST { my $host = OS_HTTP_REQUEST::host;

my $server = $host_server_mapping {$host};

if ( $server ) { OS_SLB::forward($server); } else { OS_SLB:reset_client(); }}

Page 34: Brocade ADX  Openscript

34

Release Memory After Use

my %url_hash = ();

sub HTTP_REQUEST () {my $req_id = OS_CONN::client_connection;$url_hash {$req_id} = OS_HTTP_REQUEST::url;

}

sub HTTP_RESPONSE () {my $req_id = OS_CONN::client_connection;print “url from the corresponding request is

$url_hash{$req_id} \n”;delete $url_hash{$req_id};

}

Page 35: Brocade ADX  Openscript

35

Trouble Shooting

• Is my script attached to a VIP?

• Did the script modification take into effect?

• Do event counters increase?

• Does my script reset?

• Is there any typo in OpenScript APIs?

• Is the cause of a problem not identified?

Where To Start

show script <script name> program

show script <script name> detail <vip name> <port>script compile <script name> strict

use “print” in the scripturl debug 3, debug filter, packet capture

script update <script name>

Page 36: Brocade ADX  Openscript

36

Trouble Shooting

• Problem description

• show run

• show script <script name> program

• show script <script name> detail <vip name> <port>• Gather 2~3 times after issuing “script update” to reset counters.

• url debug 3 <client ip>

• packet trace from your client PC

What To Gather To Escalate

Page 37: Brocade ADX  Openscript

37

Trouble Shooting ExampleMy OpenScript code does not send a sorry page out though all servers are down.

server real rs1 10.1.1.10 port 80 group-id 10 10

server real rs2 10.1.1.11 port 80 group-id 10 10

server virtual v1 20.1.1.1 port 80 script “sorry.pl” bind 80 rs1 80 rs2 80

use OS_SLB;use OS_HTTP_REQUEST;

my $page;

sub BEGIN { $page = "HTTP/1.1 200 OK\r\nContent- Length:21\r\nConnection:close\r\nContent- Type: text/html; charset=UTF-8\r\n\r\n. Sorry .Get. back later.”;}

sub HTTP_REQUEST { OS_SLB::forward (10);}

sub SERVER_SELECTION_FAILURE { OS_SLB::reply($page);}

ADX(config)#script compile sorry.pl strictThis script is compiled successfully.Performance for this script: - Approximately 4100 connections/second at 10% CPU utilization - Approximately 20600 connections/second at 50% CPU utilization - Approximately 41200 connections/second at 100% CPU utilization

ADX#show script sorry.pl detail v1 80===============================================Virtual Server: v1Service-Port: httpScript State: ACTIVELast Updated: 00:59:21, GMT+00, Sun Mar 3 2013

Script Restart: 0

Total Connections: 0Concurrent Connections: 0

Error Counters: exceed max rewrite entry:

Hits Per Event: HTTP Request event:

show run

show script sorry.pl program

ADX#show server bind

Bind info

Virtual server: test Status: enabled IP: 20.1.1.1 http -------> rs1: 10.10.1.10, http (Failed) rs2: 10.10.1.1, http (Failed)

?server l7-dont-reset-on-vip-port-fail

Page 38: Brocade ADX  Openscript

38

THANK YOU