1 / 38

Brocade ADX Openscript

Brocade ADX Openscript. March 2013. Derek Kang ( dkang@brocade.com ), Solutions Architect. Agenda. OpenScript Architecture Quick Start Perl Basics OpenScript Examples Best Practices. OpenScript Architecture. What is OpenScript?. Open-Standard (Perl) Based

Download Presentation

Brocade ADX Openscript

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Brocade ADX Openscript March 2013 Derek Kang (dkang@brocade.com), Solutions Architect

  2. Agenda • OpenScript Architecture • Quick Start • Perl Basics • OpenScript Examples • Best Practices

  3. OpenScript Architecture

  4. What is OpenScript? Open-Standard (Perl) Based Application Delivery Programming Engine Predictable Scripting Engine with Performance Estimator Learn, Browse, Share Scripts through OpenScript Community www.brocade.com/openscript

  5. OpenScript Architecture MP App Core Compile OpenScript Engine (event, context) • Event Driven Model • Script Attached to Virtual Port • Resource Profile Per Script (result) • Performance estimation • Catching syntax errors Content Switching Engine TCP/UDP/IP Limits the resource consumption of a script Packet In Packet Out • 1 MB memory foot print • Watch-dog timer (200 ms) • 100 KB data collection per event

  6. OpenScript Quick Start

  7. OpenScript Quick Start ADX SLB Config OpenScript “sorry.pl” 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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); } http://20.1.1.1 Sorry. Get back later. script “sorry.pl” rs1 rs2

  8. OpenScript Quick Start Steps With CLI 3. Upload the script to the ADX 2. Write a script on your choice of editor 1. Configure basic L4 SLB ADX#copytftp usb0 10.120.61.68 sorry.pl sys\dpscript\sorry.pl ADX#show script all index name In Use 1 sorry.pl 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 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); } 4. Compile the script ADX#copytftp usb0 10.120.61.68 sorry.pl sys\dpscript\sorry.pl ADX#show script all index name In Use 1 sorry.pl ADX#config term ADX(config)#script compile sorry.pl This 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 port server virtual v1 20.1.1.1 port http script “sorry.pl”

  9. OpenScript Quick Start Steps With Web GUI 1 2 3 4 0 GUI Version Check

  10. Perl Basics

  11. Regex $string =~ m/pattern/ 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”; $string =~ s/pattern1/pattern2 x-abc-abcd my $string = “ab-abc-abcd”; $string =~ s/ab/x/g print “$string”; x-xc-xcd

  12. Hash / List / Array %my_hash_table = ( 1030=>”rs1”, 1031=>”rs2” ) $value = $my_hash_table{1030 } rs1 @my_array = (“url1”, “url2”, “url3”); $value = $my_array[ 0 ]; url1 @my_two_dim_array = ([ “url1”, 10 ], [ “url2”, 20 ], [ “url3”, 30 ]) $value = $my_two_dim_array[ 1 ][ 1 ] $size = scalar ( @my_array) 20 3

  13. Pack, Unpack, Split, Join and Substr 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) unpack (template, scalar) 10.1.0.0 split (‘separator’, scalar) join (‘joiner’, list) $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 substr (data, start, size) 1110

  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

  15. Loop for ($i=2; $i<=3; $i++) {print “$i";} for$i (2..3) {print “$i";} 2 3 @url = (url1, url2, url3); foreach $i (@url) {print “$i\n”;} @url = (url1, url2, url3); foreach (@url) { print “$_\n”; } url1 url2 url3 $count = 1; while ($count <= 11 ) { $count++;last; $count++;} print “$count\n”; 2

  16. OpenScript Examples

  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 DoSattack? • 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

  18. Drop DNS Dynamic Update (DNS Dynamic Update Message) (ADX CLI Config) 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 (dnsdos.pl) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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); } }

  19. Blocking Access to Certain URLs based on Client IP addresses • 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”. www.mycompany.com www.mycompany.com/datapublic All PCs www.mycompany.com/data www.mycompany.com/data/ www.mycompany.com/data/* Intranet PCs

  20. Blocking Access to Certain URLs based on Client IP addresses 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 • 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); } } 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 • If an external client tries to access www.mycompany.com/data, return a warning page. Regular Expression to match the URL

  21. SIP VIA Header IP Replacement SIP/2.0 200 OK Via: SIP/2.0/UDP server.foo.com;branch=z9hG4bKnashds8;received=192.0.2.3 Via: SIP/2.0/UDP bigbox.site3.com;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2 Via: SIP/2.0/UDP pc3.atlanta.com;branch=z9hG4bK776asdhds ;received=192.0.2.1 To: Bob <sip:bob.com>;tag=a6c85cf From: Alice <sip:alice.com>;tag=1928301774 Call-ID: a84b4c76e66710.atlanta.com CSeq: 314159 INVITE Contact: <sip:bob.0.2.4> Content-Type: application/sdp Content-Length: 131 SIP/2.0 200 OK Via: SIP/2.0/UDP server.foo.com;branch=z9hG4bKnashds8;received=10.1.1.100 Via: SIP/2.0/UDP bigbox.site3.com;branch=z9hG4bK77ef4c2312983.1;received=10.1.1.100 Via: SIP/2.0/UDP pc3.atlanta.com;branch=z9hG4bK776asdhds ;received=10.1.1.100 To: Bob <sip:bob.com>;tag=a6c85cf From: Alice <sip:alice.com>;tag=1928301774 Call-ID: a84b4c76e66710.atlanta.com CSeq: 314159 INVITE Contact: <sip:bob.0.2.4> Content-Type: application/sdp Content-Length: 131

  22. SIP VIA Header IP Replacement 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 use 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”);                 } }

  23. OpenScript Best Practices

  24. OpenScript Best Practices • Readability • Performance • Trouble Shooting

  25. Variable Names and Spaces Around No CamelCase DO my $variable_that_contains_my_server_name = gather_server_stats (gigantic_apache_web_server); DO NOT my $variableThatContainsMyServerName = gatherServerStats (giganticApacheWebServer) ;

  26. Spaces Around Operators and After Commas DO my %server_list = (1030=>”rs1”, 1031=>”rs2” ); DO NOT my %server_list=(1030=>”rs1”,1031=>”rs2” );

  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

  28. Compile with “Strict” use strict; use Sub::StrictDecl; …………………………… ……………………………. script compile <script file name> strict Or include in the OpenScript code 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 utilization ADX(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. * the strict option in the compilation CLI and Sub:StrictDecl require 12.4.00f or later.

  29. SLB Forwarding API Use OS_HTTP_REQUEST () { if ( EXPR ) { OS_SLB::forward(1); } else { OS_SLB::forward(2); } } OS_HTTP_REQUEST () { if ( EXPR ) { OS_SLB::forward(1); } OS_SLB::forward(2); } Wrong

  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%

  31. BEGIN Subroutine my %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); } • 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. Do As Many As Operations in the BEGIN 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 }; Main Event Handler

  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 purpose • OS_SLB::log: Use to log unexpected and rare eventsin production environment

  33. Use Memory To Save CPU 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(); } } sub 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(); } }

  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}; }

  35. Trouble Shooting Where To Start • 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? • show script <script name> program • scriptupdate <script name> • show script <script name> detail <vip name> <port> • script compile <script name> strict • use “print” in the script • url debug 3, debug filter, packet capture

  36. Trouble Shooting What To Gather To Escalate • 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

  37. Trouble Shooting Example ADX#showserver 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) My OpenScript code does not send a sorry page out though all servers are down. ADX(config)#script compile sorry.pl strict This 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 show script sorry.pl program 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); } show run ADX#showscript sorry.pl detail v1 80 ===============================================Virtual Server: v1 Service-Port: http Script State: ACTIVE Last Updated: 00:59:21, GMT+00, Sun Mar 3 2013 Script Restart: 0 Total Connections: 0 Concurrent Connections: 0 Error Counters: exceed max rewrite entry: Hits Per Event: HTTP Request event: 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 ? server l7-dont-reset-on-vip-port-fail

  38. Thank You

More Related