2 - Brocade Community Forums

Download Report

Transcript 2 - Brocade Community Forums

BROCADE ADX OPENSCRIPT
March 2013
Derek Kang ([email protected]), Solutions Architect
1
Agenda
• OpenScript Architecture
• Quick Start
• Perl Basics
• OpenScript Examples
• Best Practices
2
OpenScript Architecture
3
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
4
OpenScript Architecture
App Core
MP
Compile
OpenScript Engine
(event,
context)
(result)
Content Switching Engine
•
•
Packet Out
Packet In
TCP/UDP/IP
Performance estimation
Catching syntax errors
•
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
5
OpenScript Quick Start
6
OpenScript Quick Start
ADX SLB Config
server l7-dont-reset-on-vip-port-fail
server real rs1 10.1.1.10
port 80 group-id 10 10
Sorry.
Get back later.
http://20.1.1.1
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
rs1
rs2
OpenScript “sorry.pl”
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\nContentLength:21\r\nConnection:close\r\nContentType: 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);
}
7
OpenScript Quick Start
Steps With CLI
1. Configure basic L4 SLB
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
2. Write a script on your
choice of editor
use OS_SLB;
use OS_HTTP_REQUEST;
sub BEGIN {
$page = "HTTP/1.1 200 OK\r\nContentLength:21\r\nConnection:close\r\nContentType: 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);
}
5. Attach the script to the VIP port
3. Upload the script to the ADX
ADX#copy tftp usb0 10.120.61.68 sorry.pl sys\dpscript\sorry.pl
ADX#show script all
index
name
In Use
1
sorry.pl
4. Compile the script
ADX#copy tftp 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
server virtual v1 20.1.1.1
port http script “sorry.pl”
8
OpenScript Quick Start
Steps With Web GUI
4
3
1
0
GUI Version Check
2
9
Perl Basics
10
Regex
$string
$string
=~ m/pattern/
=~ 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”;
x-abc-abcd
my $string = “ab-abc-abcd”;
$string =~ s/ab/x/g
print “$string”;
x-xc-xcd
11
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
12
Pack, Unpack, Split, Join and Substr
my @ip = split('\.', "10.1.2.3");
my @net_mask = split('\.', "255.255.0.0");
pack (template, list)
unpack (template, scalar)
my $net_ip = pack("C4", @ip) & pack("C4", @net_mask);
my $net = join( '.', unpack("C4", $net_ip) );
10.1.0.0
print "$net\n";
split (‘separator’, scalar)
join (‘joiner’, list)
substr (data, start, size)
$hex_string = "\x7e\xf1";
my $bin_string = unpack("b*", $hex_string);
print "$bin_string\n";
0111111010001111
my $field = substr ($bin_string, 4, 4);
print "$field\n";
1110
13
Conditional Statements
if (EXPR) BLOCK
if (EXPR) BLOCK else BLOCK
if ( $string == “birthday” ) {
print "Happy Birthday!\n";
} elsif ($string == “christmas”) {
print "Happy Christmas!\n";
if (EXPR) BLOCK elsif (EXPR) BLOCK
if (EXPR) BLOCK elsif (EXPR) BLOCK else BLOCK
} else {
print "Happy Whatever!\n";
}
14
Loop
2 3
for ($i=2; $i<=3; $i++) {
print “$i";
}
@url = (url1, url2, url3);
foreach $i (@url) {
print “$i\n”;
}
url1 url2 url3
@url = (url1, url2, url3);
foreach (@url) {
print “$_\n”;
}
$count = 1;
while ($count <= 11 ) {
$count++;
last;
$count++;
}
print “$count\n”;
2
for $i (2..3) {
print “$i";
}
15
OpenScript Examples
16
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
17
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);
}
}
18
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”.
All PCs
www.mycompany.com
www.mycompany.com/datapublic
Intranet PCs
www.mycompany.com/data
www.mycompany.com/data/
www.mycompany.com/data/*
19
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;
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.
if (!($client_ip =~ m/^$local_subnet/) && $url =~ m/www.mycompany.com\/data($|\/.*)/) {
OS_SLB::reply($page);
} else {
OS_SLB::forward(1);
Regular Expression to match the URL
}
}
20
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
21
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”);
}
}
22
OpenScript Best Practices
23
OpenScript Best Practices
• Readability
• Performance
• Trouble Shooting
24
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) ;
25
Spaces Around Operators and After Commas
DO
my %server_list = (1030=>”rs1”, 1031=>”rs2” );
DO NOT
my %server_list=(1030=>”rs1”,1031=>”rs2” );
26
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
27
Compile with “Strict”
script compile <script file name> strict
Or include in the OpenScript code
use strict;
use Sub::StrictDecl;
……………………………
…………………………….
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.
28
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
29
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%
30
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;
Main Event Handler
$net = join (‘.', unpack("C4", $net_hex) );
$group_name = $network_group { $net };
31
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 events in production environment
32
Use Memory To Save CPU
sub HTTP_REQUEST {
my $host = OS_HTTP_REQUEST::host;
my %host_server_mapping;
} elsif ( $host =~ m/www.host2.com ) {
OS_SLB::forward (rs2);
sub BEGIN {
%host_server_mapping = {
“www.host1.com”=>”rs1”,
“www.host2.com”=>”rs2”,
“www.host3.com”=>”rs3”};
}
} elsif { $host =~ m/www.host3.com ) {
OS_SLB::forward (rs3);
sub HTTP_REQUEST {
my $host = OS_HTTP_REQUEST::host;
if ( $host =~ m/www.host1.com/) {
OS_SLB::forward (rs1);
my $server = $host_server_mapping {$host};
} else {
OS_SLB:reset_client();
}
if ( $server ) {
OS_SLB::forward($server);
} else {
OS_SLB:reset_client();
}
}
}
33
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};
}
34
Trouble Shooting
Where To Start
• Is my script attached to a VIP?
• Did the script modification take into effect?
• Do event counters increase?
show script <script name> program
• Does my script reset?
show script <script name> detail <vip name> <port>
• Is there any typo in OpenScript APIs?
script compile <script name> strict
• Is the cause of a problem not identified?
script update <script name>
use “print” in the script
url debug 3, debug filter, packet capture
35
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
36
Trouble Shooting Example
My OpenScript code does not send a sorry page out
though all servers are down.
ADX#show server bind
Bind info
Virtual server: test
Status: enabled IP: 20.1.1.1
ADX(config)#script compile sorry.pl strict
http -------> rs1: 10.10.1.10, http (Failed)
show script sorry.pl program This script is compiled successfully.
rs2: 10.10.1.1, http (Failed)
Performance for this script:
use OS_SLB;
- Approximately 4100 connections/second at 10% CPU utilization
use OS_HTTP_REQUEST;
- Approximately 20600 connections/second at 50% CPU utilization
show run
- Approximately 41200 connections/second at 100% CPU utilization
my $page;
ADX#show script sorry.pl detail v1 80
server real rs1 10.1.1.10
===============================================
port 80 group-id 10 10
sub BEGIN {
Virtual Server:
v1
$page = "HTTP/1.1 200 OK\r\nContentService-Port:
http
server real rs2 10.1.1.11
Length:21\r\nConnection:close\r\nContent- Script State:
ACTIVE
port 80 group-id 10 10
Type: text/html; charset=UTF-8\r\n\r\n.
Last Updated:
00:59:21, GMT+00, Sun Mar 3 2013
Sorry .Get. back later.”;
server virtual v1 20.1.1.1 }
Script Restart:
0
port 80 script “sorry.pl”
bind 80 rs1 80 rs2 80
sub HTTP_REQUEST {
Total Connections:
0
OS_SLB::forward (10);
Concurrent Connections: 0
}
Error Counters:
sub SERVER_SELECTION_FAILURE {
exceed max rewrite entry:
OS_SLB::reply($page);
}
Hits Per Event:
HTTP Request event:
server l7-dont-reset-on-vip-port-fail
37
THANK YOU
38