# a ruleset to accumulate errors from a parent and child sshd process # into a single context. This allows reporting of the authenticated # user information with the error's generated by the child sshd process. # note handling of deferred reporting until after tie events received # is still in flux. My old rules hanlded it by resubmitting all the # events, but it didn't handle the parent defered reporting # events. This way is cleaner, but not tested very well. type=single continue=dontcont ptype=Nregexp pattern=sshd|SSHD desc=filter out non-sshd events action=none type=single continue=dontcont ptype=TValue pattern=TRUE desc=guard for already handled action=logonly context = [EVENT_PROCESSED] type=single continue=takenext ptype=TValue pattern=TRUE desc=We will handle. action=create EVENT_PROCESSED ## Recognize the start of an ssh session # link parent and child event contexts. # #type=PairWithWindow #continue=takenext #desc=Recognize ssh session start for $1[$2] #ptype=regexp #pattern=([A-Za-z0-9._-]+) sshd\[([0-9]+)\]: \[[^]]+\] Connection from ([0-9.]+) port [0-9]+ #action=pipe session_log_$1_$2 \ # /usr/bin/mail -s "ssh failed to generate tie event for $1" alerts@email.com #desc2=Link parent and child contexts #ptype2=regexp #pattern2=$1 [A-z0-9]+\[[0-9]+\]: \[[^]]+\] SSHD child process +([0-9]+) spawned by $2 #action2=copy session_log_%1_$1 %b; \ # delete session_log_%1_$1; \ # alias session_log_%1_%2 session_log_%1_$1; \ # add session_log_%1_$1 $0; \ # event 0 "sshd: Report %1_$1 if needed"; \ # alias session_log_owner_%1_%2 session_log_owner_%1_$1 ;\ # create tie_event_received_%1_%2 ;\ # alias tie_event_received_%1_%2 tie_event_received_%1_$1 ;\ # delete ssh_tie_event_needed_%1 #window=60 ## recognize login event and save username for later use type=single desc=Start login timer ptype=regexp pattern=([A-Za-z0-9._-]+) sshd\[([0-9]+)\]: \[[^]]+\] Accepted (publickey|password) for ([A-z0-9_-]+) from [0-9.]+ port [0-9]+ (.*) action=add session_log_$1_$2 $0; add session_log_owner_$1_$2 $4 # handle logout type=single desc=Recognize ssh session end ptype=regexp pattern=([A-Za-z0-9._-]+) sshd\[([0-9]+)\]: \[[^]]+\] Closing connection to ([0-9.]+) action= delete session_log_$1_$2; delete session_log_owner_$1_$2; \ delete tie_event_received_$1_$2 ## ignore ssh IPV6 errors. # # Example input: # Nov 3 06:34:25 corphost sshd[5961]: [ID 800047 auth.error] error: \ # connect_to ::1 port 5910: Network is unreachable # type=suppress desc = ignore IPV6 errors from ssh ptype=regexp pattern=sshd\[[0-9]+\]: \[ID 800047 auth.error\] error: connect_to ::1 port [0-9]+: Network is unreachable # because the tie command can come after critical errors are reported, # we provide a way to generate a report on demand. type=single desc=Report immediate on request. ptype=regexp pattern=^sshd: Report (.*) if needed$ context = session_log_report_$1 action= report session_log_$1 /usr/bin/mailx -s "sshd error on $1" alerts@email.com ;\ delete session_log_report_$1 type=suppress desc=Discard report immediate event on request. ptype=regexp pattern=^sshd: Report (.*) if needed$ # INSERT IMMEDIATE REPORT RULES HERE # rules that should report problems immediately should go here. # e.g. channel_setup_fwd_listener: cannot listen to port: 1521 # where port is < 1024, or is some other well known port indicating # possible hacking. # # We have five possible cases: # Event is from parent process and no info from child process is needed. # Report normally. # Event is from parent process and info from child process is needed, # and tie event received (context tie_event_received_<host>_<pid> # exists). Report normally. # Event is from parent process and info from child process is needed, # but tie event not received (context tie_event_received_<host>_<pid> # does not exist). # Report using child event as trigger. # Event that has to be reported is from the child process and # we have received the tie event (context # tie_event_received_<host>_<pid> exists). Just report normally. # Event that has to be reported is from the child process and # we haven't received the tie event (context # tie_event_received_<host>_<pid> does not exist). Defer reporting # until after tie event by setting context # session_log_report_<hostname>_<child pid>. # # We may need two rules for each event if the event can come before the tie # event. One rule checks to see if the context ssh_tie_event_needed_$1 # where $1 is the reporting host. If so then it needs to set the context # session_log_report_<host>_<pid> if generated by the child process. # Note we get a less specific report this way. It should be retooled # to generate a context that the report rule can simply obsolete. # These events are generated by the child. type=single continue=takenext desc = record ssh channel_setup_fwd_listener error for $1 port < 1025 ptype=regexp pattern=([A-z._0-9-]*) sshd\[([0-9]+)\]: \[ID 800047 auth.error\] error: channel_setup_fwd_listener: cannot listen to port: ([0-9]*) context = $3 < 1025 && ! tie_event_received_$1_$2 action = add session_log_$1_$2 $0 ; \ create session_log_report_$1_$2 type=single continue=takenext desc = record ssh channel_setup_fwd_listener error for $1 port < 1025 ptype=regexp pattern=([A-z._0-9-]*) sshd\[([0-9]+)\]: \[ID 800047 auth.error\] error: channel_setup_fwd_listener: cannot listen to port: ([0-9]*) context = $3 < 1025 && tie_event_received_$1_$2 action = add session_log_$1_$2 $0 ; \ report session_log_report_$1_$2 \ /usr/bin/mailx -s "sshd bind < 1025 on $1" alerts@email.com # end immediate rules here ## report/record ssh bind errors. # Record ssh bind errors in the session log. Don't report unless # we have more than 5 of them in a 10 minute period. Then go and # find out why they are occurring. Probably a frustrated user # getting the -L options wrong. # # We record all events until a 10 minute period has passed with no # events. If the threshold is exceeded, then we report all events # recorded during the 10 minute rolling window. # # We also group channel_setup_fwd_listener with this. # # Example input: # Nov 4 23:36:38 example sshd[1131]: [ID 800047 auth.error] error: bind: \ # Address already in use # type=single continue=takenext desc = record ssh bind error for $1 ptype=regexp pattern=([A-z._0-9-]*) sshd\[([0-9]+)\]: \[ID 800047 auth.error\] error: bind: Address already in use action = add session_log_$1_$2 $0 ; \ set ssh_port_forward_errors_$1_$2 600 type=singlewiththreshold ptype=regexp pattern=([A-z._0-9-]*) sshd\[([0-9]+)\]: \[ID 800047 auth.error\] error: bind: Address already in use context = ssh_port_forward_errors_$1_$2 desc = send report on ssh forward errors if pass threshold (bind) action = report session_log_$1_$2 \ /usr/bin/mailx -s "ssh port forward errors host $1" alerts@email.com; \ delete ssh_port_forward_errors_$1_$2 thresh=5 window=600 # Similar idea to ssh bind errors except on # channel_setup_fwd_listener errors. If we have more than 5 # of them in a 10 minute period, go and find out why they are occurring. # Probably a frustrated user getting the -L options wrong. # # We record all events until a 10 minute period has passed with no # events. If the threshold is exceeded, then we report all events # recorded during the 10 minute rolling window. # # Example input: # Nov 4 23:36:38 example sshd[1131]: [ID 800047 auth.error] error: \ # channel_setup_fwd_listener: cannot listen to port: 1521 # type=single continue=takenext desc = record ssh channel_setup_fwd_listener error for $1 ptype=regexp pattern=([A-z._0-9-]*) sshd\[([0-9]+)\]: \[ID 800047 auth.error\] error: channel_setup_fwd_listener: cannot listen to port: action = add session_log_$1_$2 $0 ; \ set ssh_channel_setup_errors_$1_$2 600 type=singlewiththreshold ptype=regexp pattern=([A-z._0-9-]*) sshd\[([0-9]+)\]: \[ID 800047 auth.error\] error: channel_setup_fwd_listener: cannot listen to port: context = ssh_channel_setup_errors_$1_$2 desc = send report on ssh channel setup errors action = report session_log_$1_$2 \ /usr/bin/mailx -s "ssh port forward errors host $1" alerts@email.com ; \ delete ssh_channel_setup_errors_$1_$2 thresh=5 window=600 # Gather random sshd errors and report after 5 minutes # # This could have been set up a number of different ways, but I have one # rule to create the context only when it doesn't exist, and another rule # that adds to the context. The create rule also sets the 5 minute timeout # that will cause the event store to be delivered when it is deleted. # # Example input: # Nov 3 09:48:56 example sshd[7871]: [ID 800047 auth.crit] fatal: \ # Timeout before authentication for 37.117.12.201 # type=single continue = takenext ptype=regexp pattern=([A-Za-z0-9._-]+) sshd\[([0-9]+)\]: desc = create context to report ssh errors for host $1 pid $2 in 5 minutes context = ! session_log_5min_timer_$1_$2 action = create session_log_5min_timer_$1_$2 300 report session_log_$1_$2 \ /usr/bin/mailx -s "ssh errors for host $1 pid $2" alerts@email.com type=single continue = dontcont ptype=regexp pattern=([A-Za-z0-9._-]*) sshd\[([0-9]+)\]: desc = gather ssh errors for host $1 action = add session_log_$1_$2 $0 # Remove the handled context if we reach this point. type=single continue=dontcont ptype=TValue pattern=TRUE desc=delete EVENT_PROCESSED action=delete EVENT_PROCESSED