#! /usr/bin/perl # # Purpose: # FlowTracker_Main.cgi collects user filter criteria and creates a # flow-tools filter file that will be used to create and maintain # FlowTracker tracking graphs. # # Description: # The script responds to an HTML form from the user in order to collect # parameters that will control the collection of netflow data into # RRDtool databases. It also responds to house-keeping chores such as # revising or removing exitsing trackings. # # Input arguments (received from the form): # Name Description # ----------------------------------------------------------------------- # device_name An identifying name of the device (e.g. router1) # source_addresses Constrain flows examined to these source IP addresses # source_ports Constrain flows examined to these source ports # source_ifs Constrain flows examined to these input interfaces # source_ases Constrain flows examined to these source ASes # dest_addresses Constrain flows examined to these dest. IP addresses # dest_ports Constrain flows examined to these dest. ports # dest_ifs Constrain flows examined to these output interfaces # dest_ases Constrain flows examined to these dest. ASes # tos_fields Constrain flows examined by specified TOS field values # tcp_flags Constrain flows examined by specified TCP flag values # protocols Constrain flows examined to these protocols # tracking_label Label used for identifying Tracking filter and HTML file # tracking_type Whether request is for an Individual or Group tracking # general_comment Useful for explaining a particular set of Tracking graphs # revision_comment Comment to explain revision of filtering criteria # notate_graphs Indicates whether user wants to notate graphs with revision # # Modification history: # Author Date Vers. Description # ----------------------------------------------------------------------- # J. Loiacono 07/04/2006 3.0 Original version. # J. Loiacono 12/25/2006 3.1 Added Archive capability, permissions # J. Loiacono 02/14/2007 3.2 Changes to incorporate groups # #$Author$ #$Date$ #$Header$ # ########################################################################### # # BEGIN EXECUTABLE STATEMENTS # use FlowViewer_Configuration; use FlowViewer_Utilities; if ($debug_tracker eq "Y") { open (DEBUG,">$work_directory/DEBUG_TRACKER"); } # Retrieve parameters for a 'Remove' or 'Review/Revise' action ($action,$tracking_label) = split(/\^/,$ENV{'QUERY_STRING'}); if ($action eq "Solicit") { $action = "Solicit Revision"; } if ($action eq "Revise") { $action = "Revise Tracking"; } if ($action eq "Archive") { $action = "Archive Tracking"; } if ($action eq "Restart") { $action = "Restart Tracking"; } if ($action eq "Remove") { $action = "Remove Tracking"; } $tracking_label =~ s/~/ /g; if ($debug_tracker eq "Y") { print DEBUG "In FlowTracker_Main...\n"; } # Otherwise retrieve the form inputs read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $FORM{$name} = $value; } # Clean up input $FORM{source_address} =~ s/\s+//g; $FORM{source_address} =~ s/,/, /g; $FORM{source_port} =~ s/\s+//g; $FORM{source_port} =~ s/,/, /g; $FORM{source_if} =~ s/\s+//g; $FORM{source_if} =~ s/,/, /g; $FORM{source_as} =~ s/\s+//g; $FORM{source_as} =~ s/,/, /g; $FORM{dest_address} =~ s/\s+//g; $FORM{dest_address} =~ s/,/, /g; $FORM{dest_port} =~ s/\s+//g; $FORM{dest_port} =~ s/,/, /g; $FORM{dest_if} =~ s/\s+//g; $FORM{dest_if} =~ s/,/, /g; $FORM{dest_as} =~ s/\s+//g; $FORM{dest_as} =~ s/,/, /g; $FORM{protocols} =~ s/\s+//g; $FORM{protocols} =~ s/,/, /g; $FORM{tos_fields} =~ s/\s+//g; $FORM{tos_fields} =~ s/,/, /g; $FORM{tcp_flags} =~ s/\s+//g; $FORM{tcp_flags} =~ s/,/, /g; # Parameters for generating a FlowTracker report if ($action eq "") { $action = $FORM{'action'}; } if ($tracking_label eq "") { $tracking_label = $FORM{'tracking_label'}; } $device_name = $FORM{'device_name'}; $source_addresses = $FORM{'source_address'}; $source_ports = $FORM{'source_port'}; $source_ifs = $FORM{'source_if'}; $source_ases = $FORM{'source_as'}; $dest_addresses = $FORM{'dest_address'}; $dest_ports = $FORM{'dest_port'}; $dest_ifs = $FORM{'dest_if'}; $dest_ases = $FORM{'dest_as'}; $protocols = $FORM{'protocols'}; $tcp_flags = $FORM{'tcp_flags'}; $tos_fields = $FORM{'tos_fields'}; $general_comment = $FORM{'general_comment'}; $revision_comment = $FORM{'revision_comment'}; $notate_graphs = $FORM{'notate_graphs'}; $flow_select = $FORM{'flow_select'}; $tracking_type = $FORM{'tracking_type'}; # Build call string to provide filter parameters to either FlowGrapher or FlowTracker $call_string = "device_name=$device_name&"; $call_string .= "source_addresses=$source_addresses&"; $call_string .= "source_ports=$source_ports&"; $call_string .= "source_ifs=$source_ifs&"; $call_string .= "source_ases=$source_ases&"; $call_string .= "dest_addresses=$dest_addresses&"; $call_string .= "dest_ports=$dest_ports&"; $call_string .= "dest_ifs=$dest_ifs&"; $call_string .= "dest_ases=$dest_ases&"; $call_string .= "protocols=$protocols&"; $call_string .= "tcp_flags=$tcp_flags&"; $call_string .= "tos_fields=$tos_fields&"; $call_string =~ s/\s+//g; $FORM{'start_date'} = "01/01/2000"; $FORM{'start_time'} = "00:00:00"; $FORM{'end_date'} = "01/01/2000"; $FORM{'end_time'} = "00:00:00"; $tracking_file = $tracking_label; $tracking_file =~ s/^\s+//; $tracking_file =~ s/\s+$//; $tracking_file =~ s/\&/-/g; $tracking_file =~ s/\//-/g; $tracking_file =~ s/\(/-/g; $tracking_file =~ s/\)/-/g; $tracking_file =~ s/\./-/g; $tracking_file =~ s/\s+/_/g; $tracking_file =~ tr/[A-Z]/[a-z]/; $filter_file = $filter_directory ."/". $tracking_file .".fil"; $group_file = $filter_directory ."/". $tracking_file .".grp"; $rrdtool_file = $rrdtool_directory ."/". $tracking_file .".rrd"; $html_directory = $tracker_directory ."/". $tracking_file; $html_file = $html_directory ."/index.html"; if ($tracking_label eq "") { print "Content-type:text/html\n\n"; print "
"; print ""; print ""; print ""; print "\n"; print ""; print "\n\n"; print ""; print "\n"; print "\n"; print "\n"; print "
\n Blank Tracking label. Please fill this in.\n"; exit; } if ($debug_tracker eq "Y") { print DEBUG " action: $action\n"; print DEBUG "tracking_label: $tracking_label\n"; print DEBUG " tracking_file: $tracking_file\n"; } if ($action eq "Establish Tracking") { # Make the Filter directory if it doesn't exist if (!-e $filter_directory) { mkdir $filter_directory, $filter_dir_perms || die "cannot mkdir $filter_directory: $!"; chmod $filter_dir_perms, $filter_directory; print " The directory for storing Tracking Filter files has been created:\n\n"; print " $filter_directory\n\n"; print " Please ensure this directory has adequate permissions for your\n"; print " web server process owner (e.g., 'apache') to write into it.\n\n"; } # If this is a group tracking, bring up Group Tracking input page if ($tracking_type eq "Group") { # Compare Tracking Label to existing Trackings while ($existing_filter = <$filter_directory/*>) { if ($filter_file eq $existing_filter) { print "Content-type:text/html\n\n"; print ""; print ""; print ""; print ""; print "FlowTracker $version Duplicate Found "; print "\n"; print ""; print "\n\n"; print " An existing Filter file has been found with the same Tracking label.\n\n"; print " Tracking Label: $tracking_label\n"; print " Tracking Filter File: $filter_file\n\n"; print " If you wish to replace the existing Tracking with this Group, please\n"; print " remove the existing one first, and resubmit the FlowTracker form.\n"; print "\n"; print " Or, if you wish to continue an existing Tracking, but with new filtering\n"; print " criteria, return to the previous page and select the \'Revise\' option from\n"; print " the entry in the list of 'Existing Trackings\' at the bottom.\n\n"; print " RETURN\n"; exit; } } # Create the web page to hold the RRDtool graphs if (!-e $html_directory) { mkdir $html_directory, $html_dir_perms || die "cannot mkdir $html_directory: $!"; chmod $html_dir_perms, $html_directory; } $copy_command = "cp $cgi_bin_directory/FlowTracker.png $html_directory"; system($copy_command); $icon_png_file = "$html_directory/FlowTracker.png"; chmod $html_file_perms, $icon_png_file; # Initialize the filter group file open (GROUP,">$group_file"); print GROUP " input: tracking_label: $tracking_label\n"; print GROUP " input: tracking_type: $tracking_type\n"; print GROUP " input: general_comment: $general_comment\n"; close (GROUP); &create_FlowTracker_html; # Invoke the FlowTracker_Group.cgi to collect group inputs $action = "From FlowViewer_Main"; $command_list = "$action+$tracking_label+$general_comment"; $command_list =~ s/ /~/g; $invoke_command = "$cgi_bin_directory/FlowTracker_Group.cgi $command_list"; system($invoke_command); exit; } # For Individual trackings print "Content-type:text/html\n\n"; print ""; print ""; print ""; print ""; print "(e.g., -0x0b/0x0F)\n"; print "\n"; print " Source IP: (e.g., 192.168.16.0/22) Source Port: Source Interface: Source AS: \n"; print "\n"; print " Dest IP: (e.g., 0.0.0.0/0) Dest Port: Dest Interface: Dest AS: \n"; print "\n"; print "FlowTracker $version Setup Results "; print "\n"; print ""; print "\n\n"; # Make the RRDtool directory if it doesn't exist if (!-e $rrdtool_directory) { mkdir $rrdtool_directory, $rrd_dir_perms || die "Cannot mkdir Tracking RRDtool directory: $rrdtool_directory: $!"; chmod $rrd_dir_perms, $rrdtool_directory; print " The directory for storing Tracking RRDtool files has been created:\n\n"; print " $rrdtool_directory\n\n"; print " Please ensure this directory has adequate permissions for your\n"; print " web server process owner (e.g., 'apache') to write into it.\n\n"; } # Compare Tracking Label to existing Trackings while ($existing_filter = <$filter_directory/*>) { if ($filter_file eq $existing_filter) { $match = 1; print " An existing Filter file has been found with the same Tracking label.\n\n"; print " Tracking Label: $tracking_label\n"; print " Tracking Filter File: $filter_file\n\n"; print " If you wish to replace the existing Tracking, please remove the existing\n"; print " one first, and resubmit the FlowTracker form.\n"; print "\n"; print " Or, if you wish to continue an existing Tracking, but with new filtering\n"; print " criteria, return to the previous page and select the \'Revise\' option from\n"; print " the entry in the list of 'Existing Trackings\' at the bottom.\n\n"; print " RETURN\n"; exit; } } if (!($match)) { if ($debug_tracker eq "Y") { print DEBUG "creating new filter file: $filter_file\n"; } # Create the filter to match the input specifications create_filter_file (%FORM, $filter_file); if ($debug_tracker eq "Y") { print DEBUG "created filter file: $filter_file\n"; } # Create the RRDtool database for this Tracking if ($debug_tracker eq "Y") { print DEBUG "creating new RRD file: $rrdtool_file\n"; } $start_rrd = time - (40 * 60); $rrdtool_command = "$rrdtool_bin_directory/rrdtool create $rrdtool_file ". "--step 300 ". "--start $start_rrd ". "DS:flowbits:GAUGE:600:U:U ". "RRA:AVERAGE:0.5:1:600 ". "RRA:AVERAGE:0.5:6:700 ". "RRA:AVERAGE:0.5:24:775 ". "RRA:AVERAGE:0.5:288:797 ". "RRA:MAX:0.5:1:600 ". "RRA:MAX:0.5:6:700 ". "RRA:MAX:0.5:24:775 ". "RRA:MAX:0.5:288:797"; system($rrdtool_command); chmod $rrd_file_perms, $rrdtool_file; print " You have successfully setup a new Tracking. The graphs for this\n"; print " new Tracking will appear after the next FlowTracker_Grapher run.\n\n"; print " Tracking Label: $tracking_label\n"; print " Filter File: $filter_file\n"; print " RRDtool Database: $rrdtool_file\n"; print " HTML Directory: $html_directory\n\n"; print " RETURN\n"; print "\n"; print "\n"; print "\n"; print "\n"; } open (FILTER,">>$filter_file"); print FILTER "\n\n"; print FILTER " input: tracking_type: $tracking_type\n"; print FILTER " input: device_name: $device_name\n"; print FILTER " input: tracking_label: $tracking_label\n"; print FILTER " input: general_comment: $general_comment\n"; print FILTER " input: source_addresses: $source_addresses\n"; print FILTER " input: source_ports: $source_ports\n"; print FILTER " input: source_ifs: $source_ifs\n"; print FILTER " input: source_ases: $source_ases\n"; print FILTER " input: dest_addresses: $dest_addresses\n"; print FILTER " input: dest_ports: $dest_ports\n"; print FILTER " input: dest_ifs: $dest_ifs\n"; print FILTER " input: dest_ases: $dest_ases\n"; print FILTER " input: protocols: $protocols\n"; print FILTER " input: tos_fields: $tos_fields\n"; print FILTER " input: tcp_flags: $tcp_flags\n"; chmod $filter_file_perms, $filter_file; # Create the web page to hold the RRDtool graphs if (!-e $html_directory) { mkdir $html_directory, $html_dir_perms || die "cannot mkdir $html_directory: $!"; chmod $html_dir_perms, $html_directory; } $copy_command = "cp $cgi_bin_directory/FlowTracker.png $html_directory"; system($copy_command); $icon_png_file = "$html_directory/FlowTracker.png"; chmod $html_file_perms, $icon_png_file; &create_FlowTracker_html; } elsif ($action eq "Remove Tracking") { # Start the web page output print "Content-type:text/html\n\n"; print ""; print ""; print ""; print ""; print "FlowTracker Tracking Removal "; print "\n"; print ""; print "\n\n"; if (!-e $work_directory) { mkdir $work_directory, $work_dir_perms || die "Cannot mkdir Work directory: $work_directory: $!"; chmod $work_dir_perms, $work_directory; } # Save graphs to work directory, and remove directory and contents $cp_command = "cp -R $html_directory $work_directory"; system($cp_command); $rmdir_command = "rm -r $html_directory"; system($rmdir_command); $html_file = $html_directory; $html_file =~ s#.*/##; # Move filter (or Archived) file to work directory $filter_archive = $filter_file; $filter_archive =~ s/\.fil/\.archive/; $filter_group = $filter_file; $filter_group =~ s/\.fil/\.grp/; $mv_command = "mv $filter_archive $filter_file"; system($mv_command); $mv_command = "mv $filter_file $work_directory/$html_file"; system($mv_command); $mv_command = "mv $filter_group $work_directory/$html_file"; system($mv_command); # Move rrd (or Archived) file to work directory $rrdtool_archive = $rrdtool_file; $rrdtool_archive =~ s/\.rrd/\.archive/; $mv_command = "mv $rrdtool_archive $rrdtool_file"; system($mv_command); $mv_command = "mv $rrdtool_file $work_directory/$html_file"; system($mv_command); # Output the summary web page $filter_file =~ s#.*/##; $rrdtool_file =~ s#.*/##; print " All files and directories associated with:\n\n"; print " $tracking_label\n\n"; print " have been moved to your Work directory, under subdirectory:\n\n"; print " $work_directory/$html_file\n\n"; print " If necessary, you can recreate this Tracking by moving the\n"; print " files back to the operational directories. That would be:\n\n"; print " 1) Move $filter_file back to $filter_directory\n"; print " 2) Move $rrdtool_file back to $rrdtool_directory\n"; print " 3) Move $html_file directory and remaining contents back to $tracker_directory\n\n\n"; print " RETURN\n"; print "\n"; print "\n"; print "\n"; print "\n"; } elsif ($action eq "Solicit Revision") { # Start the web page output print "Content-type:text/html\n\n"; print "\n"; print "FlowTracker Revision Inputs \n"; print "\n"; print "\n"; print ""; print "\n"; print " \n"; # Retrieve form input for Tracking to be modified open (FILTER,"<$filter_file"); while (\n"; foreach $device_name (@devices) { print ") { chop; $key = substr($_,0,8); if ($key eq " input: ") { ($input,$field,$field_value) = split(/: /); if ($field eq "device_name") { $revise_device_name = $field_value; } if ($field eq "source_addresses") { $source_address = $field_value; } if ($field eq "source_ports") { $source_port = $field_value; } if ($field eq "source_ifs") { $source_if = $field_value; } if ($field eq "source_ases") { $source_as = $field_value; } if ($field eq "dest_addresses") { $dest_address = $field_value; } if ($field eq "dest_ports") { $dest_port = $field_value; } if ($field eq "dest_ifs") { $dest_if = $field_value; } if ($field eq "dest_ases") { $dest_as = $field_value; } if ($field eq "protocols") { $protocols = $field_value; } if ($field eq "tos_fields") { $tos_fields = $field_value; } if ($field eq "tcp_flags") { $tcp_flags = $field_value; } if ($field eq "tracking_label") { $tracking_label = $field_value; } if ($field eq "tracking_type") { $tracking_type = $field_value; } if ($field eq "general_comment") { $general_comment = $field_value; } } } close (FILTER); print "Filter Criteria:\n\n"; print " Note: Multiple field entries, separated by commas, are permitted in the fields above.\n A minus sign (-) will negate an entry (e.g. -1776 for AS, would mean any AS but 1776) "; print "
"; print "Tracking Parameters:\n\n"; $tracking_label_out = $tracking_label; $len_label = length($tracking_label); if ($tracking_type eq "Group") { if ($len_label < 47) { for ($i=1;$i<=(47-$len_label);$i++) { $tracking_label_out .= " "; } } } else { if ($len_label < 42) { for ($i=1;$i<=(42-$len_label);$i++) { $tracking_label_out .= " "; } } } print " Tracking Set Label: $tracking_label_out"; print "Tracking Type: "; print "\n\n"; print " General Comment: "; print "\n\n"; print " Revision Comment: "; print "\n\n"; print " Notate Graphs: (To notate graphs with time and description of revision)"; print "\n\n"; print ""; print "\n"; print "\n"; print " \;\n\n"; print " "; print "
"; print "