Intermediate Perl Scripting For Network Operators

2y ago
32 Views
3 Downloads
263.61 KB
40 Pages
Last View : 1m ago
Last Download : 3m ago
Upload by : Dahlia Ryals
Transcription

Intermediate Perl Scriptingfor Network OperatorsJohn Kristoff jtk@cymru.comNANOG 54John Kristoff – Team Cymru1

overview We'll assume basic Perl competency We'll introduce intermediate Perl concepts and usage We'll learn by building a set of BGP-related tools We'll try to write portable scripts We'll use real world examples you can build upon We'll assume you'll be hacking while I talk We'll not be exhaustive since our time is limited We'll encourage you to write and share more tools Get this: http://www.cymru.com/jtk/code/nanog54.tar.gzNANOG 54John Kristoff – Team Cymru2

what we'll be covering Writing safe and maintainable code Modules and subroutines Common Perl idioms (I use) References I/O operations Database integration CGINANOG 54John Kristoff – Team Cymru3

how I start most Perl scripts#!/usr/bin/perl -Tuse strict;use warnings; 1;# Id: NANOG 54John Kristoff – Team Cymru4

taint mode -T to enforce, -t for taint warnings A contrived, but illustrative example:open my fh, ARGV[0]; Then this would do what you think it does:./unsafe.pl 'rm -rf / ' Untaintmy ( file) ARGV[0] m{ \A ( [\w.-] ) \Z }xms;NANOG 54John Kristoff – Team Cymru5

routelogger.pl Receive and log BGP events from a peeri. Can send event messages to screenii. Can send event messages to syslogiii.Can send UPDATE events to a databaseNANOG 54John Kristoff – Team Cymru6

example log messages2012-01-31 17:00:00 UTC [6:341] BGP session open from 192.0.2.1 AS649002012-01-31 17:00:00 UTC [6:380] Announcement from 192.0.2.1 AS64900 for 192.0.2.0/25 192.0.2.128/25 with AS path 64900 64901, next hop 192.0.2.1 and origin 0NANOG 54John Kristoff – Team Cymru7

getting started with Net::BGP Pull in modules, prepare objects and peeruse Net::BGP::Peer;use Net::BGP::Process;my bgp Net::BGP::Process- new;my peer Net::BGP::Peer- new(%SESSION CONFIG); bgp- add peer( peer); bgp- event loop();NANOG 54John Kristoff – Team Cymru8

%SESSION CONFIG hash Remember, a hash is just a key/value list Net::BGP::Peer Object requires peer config infomy %SESSION CONFIG (Start 1, # idle state if falseThisID local addr,ThisAS local asn,PeerID peer addr,PeerAS peer asn,Listen 0, # no passive listen# note last comma);NANOG 54John Kristoff – Team Cymru9

get BGP peering config from cli A lot of people use Getopt::Long I tend to just use getopts like this:use Getopt::Std;use constant USAGE “ 0 [ options]Options:-l local addrrequired param-L local asnrequired param-r remote addrrequired param-R remote asnrequired param-hshow this message“;getopts( 'l:L:r:R:h', \my %opts );NANOG 54John Kristoff – Team Cymru10

working with the %opts hash If the switch is set, it'll evaluate to true When set the %opts key value is 1 or arg value Examples of how we use switches and values opts{h} && die USAGE;my local asn untaint addr( opts{L} ) die USAGE;NANOG 54John Kristoff – Team Cymru11

sub untaint asn;sub untaint asn {my asn shift return;returnif asn ! m{ \A \d{1,5} \Z }xms;# Net::BGP only supports 16-bit ASNsreturnif asn 0 asn 65535;( asn) asn m{ \A (\d ) \Z }xms;}return asn;NANOG 54John Kristoff – Team Cymru12

acting on UPDATE messages Setup a callback handler peer- set update callback(\&callback update);# .sub callback update {my ( peer, update ) @ ;my nlri ref update- nlri;my withdrawn ref update- withdrawn;NANOG 54John Kristoff – Team Cymru13

references Like C pointers w/o the memory management s ref \ foo; h ref \%baz; a ref \@bar; c ref \&quxDereferencing can look a bit ugly s ref 'foo'; a ref[0] 'foo';% h ref ( foo 'bar' ); The arrow notation for arrays and hashes a ref- [0] 'foo'; h ref- {foo} 'bar';NANOG 54John Kristoff – Team Cymru14

dereferencing the updates Prepend a @ to the reference and use like an arrayif ( scalar @ withdrawn ref 0 ) {my prefix list “@ withdrawn ref”;my message sprintf“Withdrawal from %s AS%s for %s”, peer- peer id, peer- peer as, prefix list;NANOG 54John Kristoff – Team Cymru15

generic stdout/syslog routine Handles messages to syslog and stdout This routine should “do the right thing” We use the standard syslog level macro names LINE is the source code line called fromlogit( LOG INFO, LINE , message );NANOG 54John Kristoff – Team Cymru16

logit initializationsub logit {my ( level, line num, message ) @ ;my stamp current timestamp; level LOG WARNING; line num 0; message 'unspecified event';NANOG 54John Kristoff – Team Cymru17

passing subroutine arguments What is wrong with this?foo( %bar, @baz, qux );sub foo { my %quux shift; # . . . } Subroutine arguments are passed as a flat list Thus we often pass by reference instead of value Passing by reference can also be more economicalNANOG 54John Kristoff – Team Cymru18

connecting to the databasemy dbh ref;if ( opts{d} ) { dbh ref db connect({dbhost opts{b},dbtype opts{i},dbport opts{p},Dbname opts{n},Dbuesr opts{u},Dbpass opts{a},});}NANOG 54John Kristoff – Team Cymru19

using named arguments Implemented as an anonymous hash reference Not always the prettiest, but Perl BP suggests itsub db connect {my ( arg ref) @ ;my db type arg ref- {dbtype} 'Pg';NANOG 54John Kristoff – Team Cymru20

without DBI placeholders Variables inline to SQL statements are dangerous What if:# baz '1; DELETE FROM foo'my sql “SELECT * FROM foo WHERE bar baz”; dbh- prepare( sql); dbh- execute; OuchNANOG 54John Kristoff – Team Cymru21

with DBI placeholders Placeholder values separated from the SQL Practically eliminates SQL injection attacks Fixed code:# baz '1; DELETE FROM foo'my sql 'SELECT * FROM foo WHERE bar ?'; dbh- prepare( sql); dbh- execute( baz); This SQL will now likely just error out, phewNANOG 54John Kristoff – Team Cymru22

routerlogger perlcritic report perlcritic -5 (OK) perlcritic -4 ( 6 violations) perlcritic -3 ( 23 violations) Formatting, croak, reused vars, regex /xperlcritic -2 ( 38 violations) Declare some vars local, don't use constantPOD, Readonly, regex, layoutperlcritic -1 ( 19 violations) Layout, regex, useless interpolationNANOG 54John Kristoff – Team Cymru23

routelogger-report.pl Summarize routelogger syslog eventsi. Total announcements and withdrawalsii. Most active prefixesiii. Alert on “golden networks”iv. Send output to STDOUT or emailNANOG 54John Kristoff – Team Cymru24

example outputTotal announcements: 15Total withdrawals: 3Most active prefixes (count, Pv4 golden net exact match update Found: 192.0.2.0/128NANOG 54John Kristoff – Team Cymru25

getting started with Net::Patricia Pull in modules, prepare objects and gather datause Net::Patricia;my pt golden4;my pt golden6;if ( opts{g} ) { pt golden4 new Net::Patricia; pt golden6 new Net::Patricia(AF INET6);parse golden nets( opts{g} );}NANOG 54John Kristoff – Team Cymru26

opening, reading and closing filesopen( my GOLDEN FILE, ' ', filename )or die“Unable to open filename: !\n”;while (defined( my line GOLDEN FILE )){# . . .}close GOLDEN FILEor die“Unable to close filename: !\n”;NANOG 54John Kristoff – Team Cymru27

Readonly and compiled regex Recall log message format from routelogger.plReadonly my UPDATE qr{( Announcement Withdrawal )\s from \s(\S ) \sAS(\S ) \s for \s(.*?) (?: with \Z )}xms;NANOG 54John Kristoff – Team Cymru28

gather statisticsnext if line ! / UPDATE/;my ( type, peer id, peer as, prefix list ) ( 1, 2, 3, 4 ); type eq 'Announcement'? announce : withdrawal ;my @prefixes split /\s/, prefix list;for my prefix (@prefixes) { {update}{ prefix} ;}NANOG 54John Kristoff – Team Cymru29

compute top 10 hash key values Some use the comparison operatormy loop counter 1;for my prefix (sort { update{ b} - update{ a} }keys %update) {push @results,“ update{ prefix}\t prefix\n”;last if loop counter 10;}NANOG 54John Kristoff – Team Cymru30

sending email Build up output and stick into array @resultsmy email Email::Simple- create(header [From from,To to,Subject '### routelogger .',],body join '', @results,);sendmail( email)NANOG 54John Kristoff – Team Cymru31

routeinjector.pl Update a peer with configured announcementsi. Monitor a database table for updatesii. Send route changes as UPDATE to peeriii. Like routelogger.pl, but with route injectionNANOG 54John Kristoff – Team Cymru32

similar to routelogger except for. Periodically see if an UPDATE is necessarymy candidate ref get routes();if ( candidate ref) {my diff Array::Diff- diff( announce ref, candidate ref );send update( diff- added, diff- deleted );}else {send update( undef, announce ref );} announce ref candidate ref;NANOG 54John Kristoff – Team Cymru33

bhrs-admin.cgi Maintain a database of announcements via CGIi. Display configured announcementsii. Add new announcementsiii. Limited CGI interface to route-injector.pl dataNANOG 54John Kristoff – Team Cymru34

example CGI, pretty lame eh?NANOG 54John Kristoff – Team Cymru35

hardening tasksdelete @ENV{qw( IFS CDPATH ENV BASH ENV )}; ENV{PATH} '/bin:/usr/bin:/usr/local/bin'; CGI::POST MAX 1024 * 16; # 16 KB CGI::DISABLE UPLOADS 1;NANOG 54John Kristoff – Team Cymru36

figuring out what to do nextmy page action param('.action') 'default';my %page choice ('add' \&add,'list' \&list,'default' \&default,);put page top(); page choice{ page action }- ();put page bottom();NANOG 54John Kristoff – Team Cymru37

in English A HTTP POST carries a field named “.action” This field takes one of 3 values: add, list or default Page is built in part based on that field value, e.g.print submit(print hidden(-name-value-override);NANOG 54-name 'Add Route' ); '.action', 'add', 1,John Kristoff – Team Cymru38

building a page is a bit of an art CGI syntax is straightforward if not cumbersome Large CGI apps will take great care Consider more modern frameworks e.g. Mason, Catalyst, CGI::ApplicationDebugging is a little trickier During dev, send errors to browser tail -f the dev web server logNANOG 54John Kristoff – Team Cymru39

in closing “I don't know Perl, I know combat Perl” “Don't run this as root” Perl Best Practices, Damien Conway Please send questions, suggestions or scripts to:jtk@cymru.comPGP key 0xFFE85F5Dhttp://www.cymru.com/jtk/NANOG 54John Kristoff – Team Cymru40

NANOG 54 John Kristoff – Team Cymru 2 overview We'll assume basic Perl competency We'll introduce intermediate Perl concepts and usage We'll learn by building a set of BGP-related tools We'll try to write portable scripts We'll use real world examples you can build upon We'll assume you'll be hacking while I talk

Related Documents:

Why Perl? Perl is built around regular expressions -REs are good for string processing -Therefore Perl is a good scripting language -Perl is especially popular for CGI scripts Perl makes full use of the power of UNIX Short Perl programs can be very short -"Perl is designed to make the easy jobs easy,

Perl can be embedded into web servers to speed up processing by as much as 2000%. Perl's mod_perl allows the Apache web server to embed a Perl interpreter. Perl's DBI package makes web-database integration easy. Perl is Interpreted Perl is an interpreted language, which means that your code can be run as is, without a

Other Perl resources from O’Reilly Related titles Learning Perl Programming Perl Advanced Perl Programming Perl Best Practices Perl Testing: A Developer’s . Intermedi

Run Perl Script Option 3: Create a Perl script my_script.pl: Run my_script.pl by calling perl: 8/31/2017 Introduction to Perl Basics I 10 print Hello World!\n; perl ./my_script.pl Option 4: For a small script with several lines, you can run it directly on the command line: perl -e print Hello World!\n;

Perl's creator, Larry Wall, announced it the next day in his State of the Onion address. Most notably, he said "Perl 6 is going to be designed by the community." Everyone thought that Perl 6 would be the version after the just-released Perl v5.6. That didn't happen, but that's why "Perl" was in the name "Perl 6."

tutorial Sorry about that but I have to keep my tutorial's example scripts short and to the point Finally, this is a tutorial for Perl/Tk only I will not be teaching perl here So if you know perl, continue But if you are a beginner to perl, I would recommend that you read my perl tutorial

Run Perl Script Option 3: Create a Perl script my_script.pl: Run my_script.pl by calling perl: 8/31/2017 Introduction to Perl Basics I 10 print Hello World!\n; perl ./my_script.pl Option 4: For a small script with several lines, you can run it directly on the command line: perl -e print Hello World!\n;

Introduction to Perl Pinkhas Nisanov. Perl culture Perl - Practical Extraction and Report Language Perl 1.0 released December 18, 1987 by Larry Wall. Perl culture Perl Poems BEFOREHAND: close door, each window & exit; wait until time. open spellbook, study, read (scan, select, tell us);