# Copyright (c) 2012 Flowerfire, Inc. All Rights Reserved. f5_ssl_vpn = { plugin_version = "3.0" info.1.manufacturer = "F5" info.1.device = "SSL VPN" info.1.version.1 = "" # 2012-09-26 - 1.0 - GMF - Initial implementation # 2012-10-19 - 2.0 - GMF - Modified autodetect; added support for "allow ACL" lines and associated fields; added service # 2012-10-20 - 2.0.1 - GMF - Added severity field # 2012-10-20 - 3.0 - GMF - Added many additional fields, field_associations, and more # The name of the log format log.format.format_label = "F5 SSL VPN" log.miscellaneous.log_data_type = "syslog_required" log.miscellaneous.log_format_type = "network_device" # The log is in this format if any of the first 100 lines match this regular expression #Oct 12 16:05:28 5.5.5.5 Oct 12 16:04:51 tmm notice tmm[7762]: 01490506:5: 476d63ee: Received User-Agent header: Mozilla%2f5.0%20(compatible%3b%20MSIE%209.0%3b%20Windows%20NT%206.1%3b%20Win64%3b%20x64%3b%20Trident%2f5.0). log.format.autodetect_regular_expression = "[0-9]+:[0-9]+: [0-9a-f]+: Received User-Agent header:" log.format.autodetect_lines = 100 # Log fields log.fields = { severity = "" username = "" client_ip = "" client_info = "" cpu = "" ui_mode = "" vip = "" listener = "" user_agent.type = "agent" url = { type = "page" hierarchy_dividers = "/?" left_to_right = true leading_divider = "true" } # url protocol = "" client_port = "" server_ip = "" server_port = "" session_id = "" browser_platform = "" ui_mode = "" service = "" auth_type = "" auth_result = "" accesses = "" sessions = "" bytes_in = "" bytes_out = "" http_bytes_in = "" http_bytes_out = "" duration = "" failed_logins = "" successful_logins = "" } # log.fields log.parsing_filters.parse = ` # Strip off additional syslog header if (matches_regular_expression(v.syslog_message, "^[A-Z][a-z][a-z] [0-9 ]+ [0-9:]+ [^ ]+ (.*)$")) then v.syslog_message = $1; #Jul 31 14:03:28 tmm notice tmm[7661]: 01490506:5: 56c3ac77: Received User-Agent header: Mozilla%2f5.0%20(Windows%20NT%206.1%3b%20WOW64%3b%20rv%3a13.0)%20Gecko%2f20100101%20Firefox%2f13.0.1. if (matches_regular_expression(v.syslog_message, "^([a-z0-9.]+) ([a-z]+)[[]([0-9]+)[]]: ([0-9a-f]{8}:[0-9]): ([a-z0-9]+): (.*)$")) then ( v.key = $5; set_collected_field(v.key, 'severity', $1); # set_collected_field(v.key, 'process', $2); # set_collected_field(v.key, 'pid', $3); set_collected_field(v.key, 'logging_device', get_collected_field('', 'logging_device')); set_collected_field(v.key, 'date', get_collected_field('', 'date')); set_collected_field(v.key, 'time', get_collected_field('', 'time')); # set_collected_field('', 'id', $4); set_collected_field(v.key, 'session_id', $5); v.message = $6; #Jul 31 14:03:28 tmm notice tmm[7661]: 01490506:5: 56c3ac77: Received User-Agent header: Mozilla%2f5.0%20(Windows%20NT%206.1%3b%20WOW64%3b%20rv%3a13.0)%20Gecko%2f20100101%20Firefox%2f13.0.1. if (matches_regular_expression(v.message, '^Received User-Agent header: (.*)$')) then ( v.user_agent = convert_escapes($1); set_collected_field(v.key, 'user_agent', v.user_agent); ); #Jul 31 14:03:28 tmm notice tmm[7661]: 01490544:5: 56c3ac77: Received client info - Type: Mozilla Version: 5 Platform: Win7 CPU: WOW64 UI Mode: Full Javascript Support: 1 ActiveX Support: 0 Plugin Support: 1 else if (matches_regular_expression(v.message, '^Received client info - (.*)$')) then ( v.client_info = $1; set_collected_field(v.key, 'client_info', v.client_info); if (matches_regular_expression(v.client_info, 'CPU: ([^ ]+)')) then set_collected_field(v.key, 'cpu', $1); if (matches_regular_expression(v.client_info, 'UI Mode: ([^ ]+)')) then set_collected_field(v.key, 'ui_mode', $1); if (matches_regular_expression(v.client_info, 'Platform: ([^ ]+)')) then set_collected_field(v.key, 'browser_platform', $1); ); #Jul 31 14:32:05 test notice apd[5300]: 01490010:5: 94f09622: Username 'abc' else if (matches_regular_expression(v.message, "^Username '([^']+)'")) then set_collected_field(v.key, 'username', $1); #Jul 31 14:03:28 tmm notice tmm[7661]: 01490500:5: 56c3ac77: New session from client IP 192.168.50.233 (ST=/CC=/C=) at VIP 192.168.20.182 Listener /Common/vip_ltm else if (matches_regular_expression(v.message, '^New session from client IP ([^ ]+) [(][^)]+[)] at VIP ([^ ]+) Listener (.*)$')) then ( set_collected_field(v.key, 'client_ip', $1); set_collected_field(v.key, 'vip', $2); set_collected_field(v.key, 'listener', $3); set_collected_field(v.key, 'session_start_time_epoc', date_time_to_epoc(normalize_date(get_collected_field('', 'date'), 'auto') . ' ' . get_collected_field('', 'time'))); set_collected_field(v.key, 'session_start_time', get_collected_field('', 'time')); set_collected_field(v.key, 'session_start_date', get_collected_field('', 'date')); ); # if "New session from client IP" #Jul 31 14:14:13 tmm notice tmm[7661]: 01490521:5: 56c3ac77: Session statistics - bytes in: 23066, bytes out: 157105 else if (matches_regular_expression(v.message, '^Session statistics - bytes in: ([0-9]+), bytes out: ([0-9]+)$')) then ( set_collected_field(v.key, 'bytes_in', $1); set_collected_field(v.key, 'bytes_out', $2); # Compute the session duration v.session_end_time_epoc = date_time_to_epoc(normalize_date(get_collected_field('', 'date'), 'auto') . ' ' . get_collected_field('', 'time')); set_collected_field(v.key, 'duration', v.session_end_time_epoc - get_collected_field(v.key, 'session_start_time_epoc')); set_collected_field(v.key, 'date', get_collected_field(v.key, 'session_start_date')); set_collected_field(v.key, 'time', get_collected_field(v.key, 'session_start_time')); set_collected_field(v.key, 'accesses', 0); set_collected_field(v.key, 'sessions', 1); accept_collected_entry(v.key, false); ); # if Session statistics #Oct 12 16:06:18 5.5.5.5 Oct 12 16:05:41 tmm notice tmm[7762]: 01580005:5: 476d63ee: allow ACL: /Common/AllowAll_Keeplog:0 packet: http://www.google.co.th/extern_chrome/602fdfdd773e949d.js tcp 192.168.50.232:54707 -> 173.194.38.159:80 else if (matches_regular_expression(v.message, '^allow ACL: [^ ]+ packet: ([^ ]+) ([a-z]+) ([^:]+):([0-9]+) -> ([^:]+):([0-9]+)')) then ( set_collected_field(v.key, 'url', $1); set_collected_field(v.key, 'protocol', $2); set_collected_field(v.key, 'client_ip', $3); set_collected_field(v.key, 'client_port', $4); set_collected_field(v.key, 'server_ip', $5); set_collected_field(v.key, 'server_port', $6); # Compute the service from the server port and protocol v.service = $6 . '_' . $2; if ('rewrite_rules.services'?{v.service}) then v.service = @'rewrite_rules.services'{v.service}; set_collected_field(v.key, 'service', v.service); set_collected_field(v.key, 'accesses', 1); accept_collected_entry(v.key, true); ); # if allow ACL #Oct 12 16:06:19 5.5.5.5 Oct 12 16:05:42 tmm notice tmm[7762]: 01580005:5: 476d63ee: allow ACL: /Common/AllowAll_Keeplog:0 packet: http://www.google.co.th/csi?v=3&s=webhp&action=&e=25657,37102,39523,39978,4000116,4000354,4000472,4000553,4000648,4000742,4000833,4000879,4000955,4001064,4001075,4001128,4001131,4001183,4001188,4001192,4001267,4001282,4001431,4001463,4001569&ei=e913UL_TFJHMrQfL6IC4AQ&imc=2&imn=2&imp=2&adh=&rt=xjsls.3507,prt.3779,ol.4346,iml.3861,xjses.13141,xjsee.14023,xjs.14088,wsrt.545,cst.0,dnst.0,rqst.4267,rspt.3936 tcp 192.168.50.232:54711 -> 173.194.38.159:80%230&resourcetype=remote_desktop&cgc=0&errorcode=0&logon=/Common/WebPortal_act_logon_page_ag&webtop_cust_grp=/Common/FullWebtop_customization&webtop_id=/Common/FullWebtop&uilang=en&uimode=0&ctype=IE&cversion=9&cjs=1&cactivex=1&cplugin=0&cplatform=Win7&cpu=x64&logout=/Common/WebPortal_logout&general_ui=/Common/WebPortal_general_ui&eps=/Common/WebPortal_eps&installation=/Common/WebPortal_frameworkinstallation&errormap=/Common/WebPortal_errormap&defaultlang=en&wa_res=/Common/WebPortal_pa_res+/Common/www.google.com&na_res=/Common/TST_Network&rd_res=/Common/remote_AD_Server HTTP/1.0" 200 16784 "-" "-" else if (matches_regular_expression(v.message, '^allow ACL: [^ ]+ packet: ([a-z]+://[^ ]+) -> ([^ ]+) [^ ]+ ([0-9]+) ([0-9]+)')) then ( set_collected_field(v.key, 'url', $1); set_collected_field(v.key, 'http_bytes_out', $3); set_collected_field(v.key, 'http_bytes_in', $4); set_collected_field(v.key, 'accesses', 1); accept_collected_entry(v.key, true); ); # if allow ACL [HTTP] #Jul 31 14:48:59 test warning apd[5300]: 01490109:4: 2fcea3a6: LDAP module: authentication with '(sAmAccountName=abc)' failed: Invalid credentials, 80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 52e, v1772 (49) else if (matches_regular_expression(v.message, "^LDAP module: authentication with '([^']+)' failed")) then ( set_collected_field(v.key, 'username', $1); set_collected_field(v.key, 'failed_logins', 1); accept_collected_entry(v.key, false); set_collected_field(v.key, 'failed_logins', 0); ); #Oct 12 16:05:48 5.5.5.5 Oct 12 16:05:12 apm info apd[10789]: 01490017:6: 476d63ee: LDAP agent: Auth (logon attempt:1): authenticate with 'test' failed else if (matches_regular_expression(v.message, "^(LDAP|AD) agent: Auth [(][^)]+[)]: authenticate with '([^']*)' ([a-z]+)")) then ( set_collected_field(v.key, 'auth_type', $1); set_collected_field(v.key, 'username', $2); v.auth_result = $3; set_collected_field(v.key, 'auth_result', v.auth_result); if (matches_regular_expression(v.auth_result, '^success')) then set_collected_field(v.key, 'successful_logins', 1); else if (matches_regular_expression(v.auth_result, '^fail')) then set_collected_field(v.key, 'failed_logins', 1); accept_collected_entry(v.key, false); set_collected_field(v.key, 'successful_logins', 0); set_collected_field(v.key, 'failed_logins', 0); ); ); ` # Database fields database.fields = { # device = "" # process = "" # pid = "" severity = "" username = "" client_ip = "" web_browser = "" operating_system = "" vip = "" listener = "" url = { label = "$lang_stats.field_labels.url" log_field = "url" type = "string" suppress_top = 1 suppress_bottom = 3 } # url file_type = "" protocol = "" client_port = "" server_ip = "" server_port = "" session_id = "" cpu = "" ui_mode = "" browser_platform = "" ui_mode = "" service = "" auth_type = "" auth_result = "" } # database.fields # Log Filters log.filters = { simplify_url = { label = "$lang_admin.log_filters.simplify_url_label" comment = "$lang_admin.log_filters.simplify_url_comment" value = "if (matches_regular_expression(url, '^([^:]+://[^/]+/)')) then url = $1 . '(omitted)'" } # simplify_url } # log.filters database.numerical_fields = { accesses = { default = true # entries_field = true } # sessions sessions = { default = true # entries_field = true } # sessions bytes_in = { default = true integer_bits = 64 display_format_type = "bandwidth" } bytes_out = { default = true integer_bits = 64 display_format_type = "bandwidth" } duration = { default = true integer_bits = 64 display_format_type = duration_compact } # duration successful_logins = { default = true } # successful_logins failed_logins = { default = true } # failed_logins http_bytes_in = { default = true integer_bits = 64 display_format_type = "bandwidth" } http_bytes_out = { default = true integer_bits = 64 display_format_type = "bandwidth" } } # database.numerical_fields create_profile_wizard_options = { # This shows which numerical fields are related to which non-numerical fields. database_field_associations = { username = { successful_logins = true failed_logins = true } auth_result = { successful_logins = true failed_logins = true } auth_type = { successful_logins = true failed_logins = true } # Session-related fields vip = { sessions = true bytes_in = true bytes_out = true successful_logins = true failed_logins = true } listener = { sessions = true bytes_in = true bytes_out = true successful_logins = true failed_logins = true } cpu = { sessions = true bytes_in = true bytes_out = true successful_logins = true failed_logins = true } ui_mode = { sessions = true bytes_in = true bytes_out = true successful_logins = true failed_logins = true } browser_platform = { sessions = true bytes_in = true bytes_out = true successful_logins = true failed_logins = true } ui_mode = { sessions = true bytes_in = true bytes_out = true successful_logins = true failed_logins = true } web_browser = { sessions = true bytes_in = true bytes_out = true successful_logins = true failed_logins = true } operating_system = { sessions = true bytes_in = true bytes_out = true successful_logins = true failed_logins = true } # Access-related fields protocol = { accesses = true } client_port = { accesses = true } server_ip = { accesses = true } server_port = { accesses = true } service = { accesses = true } } # database_field_associations # How the reports should be grouped in the report menu report_groups = { date_time_group = "" } # report_groups snapons = { # Add the standard reports add_standard_reports = { name = "add_standard_reports" label = "add_standard_reports" snapon = "add_standard_reports" } # add_standard_reports # Attach a concurrent_events snapon to compute concurrent connections concurrent_connections = { snapon = "concurrent_events" name = "concurrent_connections" label = "$lang_admin.snapons.plugins.flash_media_server.concurrent_connections" parameters = { date_time_field.parameter_value = "date_time" duration_field.parameter_value = "duration" concurrent_events_name = { parameter_value = "$lang_admin.snapons.plugins.flash_media_server.concurrent_connections" final_node_name = "concurrent_connections" } } # parameters requires_database_fields = { date_time = true duration = true } } # concurrent_connections } # snapons } # create_profile_wizard_options } # f5_ssl_vpn