cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1205
Views
10
Helpful
2
Replies
Highlighted
Beginner

Permanently block an IP after X amount of login failures?

Hi,

 

     I am struggling to find a solution to do the following:  Permanently block an ip after X amount of login failures?  I know it sounds simple, but, maybe someone can give me an example.  I don't want to block a range of ip's, just a specific one after X amount of login failures.  I wasn't sure if this is an EEM script that has to be created or something else?  Also, this can be a login that was tried after X amount of tries OR a login failure using different key words.  Basically, I am trying to keep out some of the crap coming from China and so on......

I am currently using a Cisco 3825.  We don't have a firewall solution yet.....

Thanks for everyone's help.

 

Cheers.

 

Jason

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted
Cisco Employee

EEM can do this but your ACL will be entirely host based and thats going to be taxing on resources.   If you execute "login on-failure log every 1" this will generate a log message that includes the source IP address and username attempting to login.   The syslog message can be used to trigger EEM and after a configurable amount of login attempts from the same IP address, update ACL 51 to deny the ip address. 

In global config mode execute:

login on-failure log every 1

!### set to 2 login failures will block the ip address.  update as appropriate.

event manager environment _block 2

!### Place this TCL file on the router and register with EEM.  Assuming the local media is called

!### "flash" and you save the TCL file as "acl_block.tcl"

event manager directory user policy "flash:/"

event manager policy acl_block.tcl type user

 

 

 

######START acl_block.tcl #####

::cisco::eem::event_register_syslog pattern "SEC_LOGIN-4-LOGIN_FAILED: Login failed .*"

namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
array set arr_einfo [event_reqinfo]
set msg "$arr_einfo(msg)"
regexp {\[user:\s+([A-Za-z0-9.]+)\]\s+\[Source:\s+([0-9.]+)\]} $msg match user ipaddress
# If CTXT exists read it, if not create it.
if { [catch {context_retrieve LOGINCTXT remoteips} result] } {
    array set remoteips [list]
} else {
    array set remoteips $result
}
# If LOGINCTXT does not exist create the counter as 1  and save LOGINCTXT.
        if { ! [info exists remoteips($ipaddress)] } {
            set remoteips($ipaddress) 1

            if { [catch {context_save LOGINCTXT remoteips} result] } {
                  error $result $errorInfo
                 }

        } else {
        incr remoteips($ipaddress)
        set loginfailures $remoteips($ipaddress)
        puts "loginfail = $loginfailures"

        }
if {[info exists loginfailures]} {
    if {($loginfailures >= $_block)} {
    # Open the CLI
    if [catch {cli_open} result] {
       error $result $errorInfo
    } else {
    array set cli1 $result
    }
# Go into enable mode
    if [catch {cli_exec $cli1(fd) "en"} result] {
        error $result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "conf t"} result] {
        error $result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "access-list 51 deny $ipaddress"} result] {
        error $result $errorInfo
    }
action_syslog msg "EEM writing access-list 51 deny $ipaddress"

catch {cli_close $cli1(fd) $cli1(tty_id)}
    }

            if { [catch {context_save LOGINCTXT remoteips} result] } {
                  error $result $errorInfo
                 }

}


########END acl_block.tcl ########

 

 

 

 

 

 

View solution in original post

2 REPLIES 2
Highlighted
Cisco Employee

EEM can do this but your ACL will be entirely host based and thats going to be taxing on resources.   If you execute "login on-failure log every 1" this will generate a log message that includes the source IP address and username attempting to login.   The syslog message can be used to trigger EEM and after a configurable amount of login attempts from the same IP address, update ACL 51 to deny the ip address. 

In global config mode execute:

login on-failure log every 1

!### set to 2 login failures will block the ip address.  update as appropriate.

event manager environment _block 2

!### Place this TCL file on the router and register with EEM.  Assuming the local media is called

!### "flash" and you save the TCL file as "acl_block.tcl"

event manager directory user policy "flash:/"

event manager policy acl_block.tcl type user

 

 

 

######START acl_block.tcl #####

::cisco::eem::event_register_syslog pattern "SEC_LOGIN-4-LOGIN_FAILED: Login failed .*"

namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
array set arr_einfo [event_reqinfo]
set msg "$arr_einfo(msg)"
regexp {\[user:\s+([A-Za-z0-9.]+)\]\s+\[Source:\s+([0-9.]+)\]} $msg match user ipaddress
# If CTXT exists read it, if not create it.
if { [catch {context_retrieve LOGINCTXT remoteips} result] } {
    array set remoteips [list]
} else {
    array set remoteips $result
}
# If LOGINCTXT does not exist create the counter as 1  and save LOGINCTXT.
        if { ! [info exists remoteips($ipaddress)] } {
            set remoteips($ipaddress) 1

            if { [catch {context_save LOGINCTXT remoteips} result] } {
                  error $result $errorInfo
                 }

        } else {
        incr remoteips($ipaddress)
        set loginfailures $remoteips($ipaddress)
        puts "loginfail = $loginfailures"

        }
if {[info exists loginfailures]} {
    if {($loginfailures >= $_block)} {
    # Open the CLI
    if [catch {cli_open} result] {
       error $result $errorInfo
    } else {
    array set cli1 $result
    }
# Go into enable mode
    if [catch {cli_exec $cli1(fd) "en"} result] {
        error $result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "conf t"} result] {
        error $result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "access-list 51 deny $ipaddress"} result] {
        error $result $errorInfo
    }
action_syslog msg "EEM writing access-list 51 deny $ipaddress"

catch {cli_close $cli1(fd) $cli1(tty_id)}
    }

            if { [catch {context_save LOGINCTXT remoteips} result] } {
                  error $result $errorInfo
                 }

}


########END acl_block.tcl ########

 

 

 

 

 

 

View solution in original post

Highlighted

Please, How is possible to write the ACL 51 with a sequence number at the end (permit any) ? So when the script write the ACL 51 deny failed login IP dynamically and the others IP are allowed.

I applied the ACL 51 on the line vty 0 4

 

Thanks a lot for your help.

Content for Community-Ad