non return plugin callback now will be triggered together (#162)
* add failtoban plugin * fmt * bump ver * add failtoban e2e * add readme * update readme
This commit is contained in:
parent
bffa03dde0
commit
2067fcb003
6 changed files with 189 additions and 10 deletions
17
plugin/failtoban/README.md
Normal file
17
plugin/failtoban/README.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# fail to ban for sshpiperd
|
||||
|
||||
put ip to jail for a while after failed to login for several times.
|
||||
|
||||
## Usage
|
||||
|
||||
put this plugin after other plugins, like:
|
||||
|
||||
```
|
||||
sshpiperd <main plguin> -- failtoban
|
||||
```
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
* max-failures: max failures before ban, default 5
|
||||
* ban-duration: ban duration, default 1h
|
||||
72
plugin/failtoban/main.go
Normal file
72
plugin/failtoban/main.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//go:build full || e2e
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
gocache "github.com/patrickmn/go-cache"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tg123/sshpiper/libplugin"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
libplugin.CreateAndRunPluginTemplate(&libplugin.PluginTemplate{
|
||||
Name: "failtoban",
|
||||
Usage: "sshpiperd fixed plugin, only password auth is supported",
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{
|
||||
Name: "max-failures",
|
||||
Usage: "max failures",
|
||||
EnvVars: []string{"SSHPIPERD_FAILTOBAN_MAX_FAILURES"},
|
||||
Value: 5,
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Name: "ban-duration",
|
||||
Usage: "ban duration",
|
||||
EnvVars: []string{"SSHPIPERD_FAILTOBAN_BAN_DURATION"},
|
||||
Value: 60 * time.Minute,
|
||||
},
|
||||
},
|
||||
CreateConfig: func(c *cli.Context) (*libplugin.SshPiperPluginConfig, error) {
|
||||
|
||||
maxFailures := c.Int("max-failures")
|
||||
banDuration := c.Duration("ban-duration")
|
||||
|
||||
cache := gocache.New(banDuration, banDuration/2*3)
|
||||
|
||||
return &libplugin.SshPiperPluginConfig{
|
||||
NoClientAuthCallback: func(conn libplugin.ConnMetadata) (*libplugin.Upstream, error) {
|
||||
// in case someone put the failtoban plugin before other plugins
|
||||
return &libplugin.Upstream{
|
||||
Auth: libplugin.CreateNextPluginAuth(map[string]string{}),
|
||||
}, nil
|
||||
},
|
||||
NewConnectionCallback: func(conn libplugin.ConnMetadata) error {
|
||||
ip, _, _ := net.SplitHostPort(conn.RemoteAddr())
|
||||
|
||||
failed, found := cache.Get(ip)
|
||||
if !found {
|
||||
// init
|
||||
return cache.Add(ip, 0, banDuration)
|
||||
}
|
||||
|
||||
if failed.(int) >= maxFailures {
|
||||
return fmt.Errorf("failtoban: ip %v too auth many failures", ip)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
UpstreamAuthFailureCallback: func(conn libplugin.ConnMetadata, method string, err error, allowmethods []string) {
|
||||
ip, _, _ := net.SplitHostPort(conn.RemoteAddr())
|
||||
failed, _ := cache.IncrementInt(ip, 1)
|
||||
log.Debugf("failtoban: %v auth failed %v times, max allowed %v", ip, failed, maxFailures)
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue