Created
October 31, 2011 22:14
-
-
Save jof/1329203 to your computer and use it in GitHub Desktop.
TACACS Accounting FIlter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/ruby | |
## TACACS accounting logging helper. | |
# | |
# Filter a stream of events for a condition. | |
# | |
require 'getoptlong' | |
TAC_PLUS_ACCOUNTING_LOG_PATTERN = Regexp.new('(\d{1,3}\.){3}\d{1,3}(\t+)\w+(\t+)\w+\d(\t+)(\d{1,3}\.){3}\d{1,3}(\t+)(start|stop)') | |
filters = {} | |
opts = GetoptLong.new( | |
[ '--username', GetoptLong::REQUIRED_ARGUMENT ], | |
[ '--remote_ip', GetoptLong::REQUIRED_ARGUMENT ], | |
[ '--command', GetoptLong::REQUIRED_ARGUMENT ], | |
[ '--help', GetoptLong::NO_ARGUMENT ] | |
) | |
opts.each do |opt,arg| | |
if opt == '--help' then | |
puts <<EOF | |
Usage: #{File.basename(__FILE__)} { [ --username | --remote_ip | --command ] [ string | /regex/ ] } [ file to read from ] | |
If the file to read from is omitted, stdin is used. | |
EOF | |
Kernel.exit(1) | |
end | |
filter_name = opt.delete('-') # Trim leading '--' | |
if arg.start_with?('/') then | |
filter = Regexp.new(arg) | |
else | |
filter = arg | |
end | |
filters[filter_name.to_sym] = filter | |
end | |
if ARGV.length == 0 then | |
INPUT = STDIN | |
else | |
INPUT = open(ARGV.shift, 'r') | |
end | |
raise Exception unless INPUT.is_a?(IO) | |
while (true) do | |
begin | |
line = INPUT.readline | |
rescue EOFError | |
break if INPUT.is_a?(File) # Break out of the top-most while loop. | |
rescue | |
retry # Wait for things to be appended | |
end | |
line = line.strip | |
next unless line.match(TAC_PLUS_ACCOUNTING_LOG_PATTERN) | |
parts = line.split("\t") | |
event = {} | |
# Pull off the log line elements that are consistent. | |
event[:date], event[:remote_ip], event[:username], event[:tty], event[:manager_ip], event[:start_stop] = parts.shift(6) | |
# Pull out the rest of the key/value accounting attributes. | |
parts.map! do |key_value| | |
key, value = key_value.split('=', 2) | |
event[key.to_sym] = value | |
end | |
if filters.length > 0 then | |
filters.each do |filter_name, filter| | |
if event[filter_name].match(filter) then | |
puts line | |
break | |
end | |
end | |
else | |
puts line | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment