Skip to content

Commit

Permalink
update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
hugefiver committed Jul 12, 2024
1 parent 4921439 commit e24d337
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 31 deletions.
48 changes: 34 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,9 @@
* __可用__
* __It Does Work__

* ~~_开发中_~~
* ~~_In Developing_~~

## Why Write This

<details>
长期以来,服务器的22端口始终有人试图爆破,每次登陆都会显示有数百次失败的尝试。

一段时间之前我已经更换为密钥登陆(__建议停止口令登陆SSH而使用密钥,尤其是您正在遭受穷举的情况下__),可以说是~~基本~~没有被穷尽成功的可能,但是看着log里的记录还是很烦。

即便使用了`fail2ban`仍收效甚微,即使在每次登录失败即封禁IP一周的情况下,本月仍有千余条IP的登陆失败记录。

虽然暂时通过更换端口的方式缓解了这样的现象,但仍不能保证以后新的端口不会被爆破。

所以写这个__假的SSH服务器__。首先是迷惑攻击者认为端口仍在正常工作,然而其实是不可能入侵成功的。其次收集访问者的IP和相关信息。最终目的是分析访问者信息,形成封禁策略,可以应用于其他的服务器上。
</details>
Make self happy.

## TODO

Expand Down Expand Up @@ -60,6 +47,18 @@ Usage of FakeSSH:
log level: [debug|info|warning] (default "info")
-log file
log file
-max maxconn
see maxconn
-maxconn max:loss_ratio:hard_max
max connections in format max:loss_ratio:hard_max, every value is optional means [default, 1.0, default]
-maxsucc maxsuccconn
see maxsuccconn
-maxsuccconn max:loss_rate:hard_max
max success connections in format max:loss_rate:hard_max, see maxconn
-mc maxconn
see maxconn
-msc maxsuccconn
see maxsuccconn
-passwd
log password to file
-r float
Expand All @@ -72,6 +71,8 @@ Usage of FakeSSH:
max try times (default 3)
-type string
type for generate private key (default "ed25519")
-user user:password
users in format user:password, can set more than one
-version string
ssh server version (default "OpenSSH_9.3p1")
```
Expand All @@ -87,3 +88,22 @@ Usage of FakeSSH:
4. Option for `rsa` is key size, default is `4096`.

5. Option for `ecdsa` is curve type, such as `P256`, `P384`, `P521`, and default is `P384`.

### max connections

You can use the commandline option `-maxconn` (or shorter `-mc`) to set the max connections, the `server.max_conn` in configure file does it the same.

And `-maxsuccconn` (shorter `-msc` or `server.max_succ_conn` in configure file) to set the max success connections, with the same syntax.

The format of `-maxconn` and `-maxsuccconn` is `max:loss_ratio:hard_max`, and the format of configure file is shown in [this file](./conf/config.toml).

It means when the count of connections mathes `max`, it will loss the connection with the ratio. And the ratio will increase literally, and it will be `1.0` when connections equal or larger than `hard_max`.

* `max` is interger, optional means `0`:
* `max < 0` => unlimited connections.
* `max = 0` => use program default value, current is `100` for `maxconn` and `unlimited` for `maxsuccconn`.
* `loss_ratio` is float, optional means `0`:
* `loss_ratio < 0` => not loss connections until it reaches `hard_max`.
* `hard_max` is interger, optional means `0`:
* `hard_max <= 0` when `max < 0` => unlimited connections.
* `hard_max <= 0` when `max >= 0` => it will be the max value of `max * 2` and default value(current if `65535`)
8 changes: 4 additions & 4 deletions conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ type BaseConfig struct {

Users []*User `toml:"users"`

MaxConns MaxConnectionsConfig `toml:"max_conns"`
MaxSuccConns MaxConnectionsConfig `toml:"max_succ_conns"`
MaxConn MaxConnectionsConfig `toml:"max_conn"`
MaxSuccConn MaxConnectionsConfig `toml:"max_succ_conn"`
} `toml:"server"`

Log struct {
Expand Down Expand Up @@ -230,15 +230,15 @@ func MergeConfig(c *AppConfig, f *FlagArgsStruct, set StringSet) error {
if err != nil {
return err
}
c.Server.MaxConns = mc
c.Server.MaxConn = mc
}

if f.MaxSuccConns != "" {
mc, err := parseMaxConnString(f.MaxSuccConns)
if err != nil {
return err
}
c.Server.MaxSuccConns = mc
c.Server.MaxSuccConn = mc
}

return nil
Expand Down
6 changes: 3 additions & 3 deletions conf/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#password = "123456"

# How many connections can be connected at the same time
[server.max_conns]
[server.max_conn]
# `max` < 0 means unlimited
# `max` = 0 or optional means default: 100
max = 0
Expand All @@ -36,8 +36,8 @@ hard_max = 0
# if connections match `max`, it will literally increase to 1.0 when connectios meet `hard_max`
loss_ratio = 1.0

# Same as `max_conns`, but for successful connections
[server.max_succ_conns]
# Same as `max_conn`, but for successful connections
[server.max_succ_conn]
max = 0
hard_max = 0
loss_ratio = 1.0
Expand Down
2 changes: 1 addition & 1 deletion conf/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func GetArg() (args *FlagArgsStruct, set StringSet, helper func()) {

StringArrayVar(f, &args.Users, "user", "users in format `user:password`, can set more than one")

f.StringVar(&args.MaxConns, "maxconn", "", "max connections in format `max:loss_rate:hard_max`, every value is optional means [default, 1.0, default]")
f.StringVar(&args.MaxConns, "maxconn", "", "max connections in format `max:loss_ratio:hard_max`, every value is optional means [default, 1.0, default]")
f.StringVar(&args.MaxConns, "max", "", "see `maxconn`")
f.StringVar(&args.MaxConns, "mc", "", "see `maxconn`")
f.StringVar(&args.MaxSuccConns, "maxsuccconn", "", "max success connections in format `max:loss_rate:hard_max`, see maxconn")
Expand Down
26 changes: 17 additions & 9 deletions ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ func StartSSHServer(config *ssh.ServerConfig, opt *Option) {
}

lossRatio := opt.MaxConnections.LossRatio
if lossRatio <= 0 || lossRatio >= 1 {
if lossRatio <= 0 {
lossRatio = 0.
} else if lossRatio >= 1 {
lossRatio = 1.
}

Expand All @@ -108,7 +110,9 @@ func StartSSHServer(config *ssh.ServerConfig, opt *Option) {
}

succLossRatio := opt.MaxSuccConnections.LossRatio
if succLossRatio <= 0 || succLossRatio >= 1 {
if succLossRatio <= 0 {
succLossRatio = 0.
} else if succLossRatio >= 1 {
succLossRatio = 1.
}

Expand All @@ -129,6 +133,7 @@ func StartSSHServer(config *ssh.ServerConfig, opt *Option) {
if !checkMaxConnections(connections.Add(1), maxConn, hardMaxConn, lossRatio) {
_ = conn.Close()
connections.Add(-1)
log.Infof("[Disconnect] matches max connections limit, disconnect from: %s", conn.RemoteAddr().String())
continue
}

Expand Down Expand Up @@ -176,6 +181,7 @@ func handleConn(sshCtx *SSHConnectionContext, config *ssh.ServerConfig) {
ok := !sshCtx.CheckMaxConnections()
defer sshCtx.SuccConnections.Add(-1)
if !ok {
log.Infof("[Disconnect] matches max success connections, disconnect from %s", sshCtx.RemoteAddr().String())
return
}

Expand Down Expand Up @@ -224,7 +230,7 @@ func handleConn(sshCtx *SSHConnectionContext, config *ssh.ServerConfig) {
}
}

func checkMaxConnections(curr, max, hardMax int64, rate float64) bool {
func checkMaxConnections(curr, max, hardMax int64, ratio float64) bool {
if max <= 0 {
return hardMax <= 0 || curr <= hardMax
}
Expand All @@ -233,14 +239,16 @@ func checkMaxConnections(curr, max, hardMax int64, rate float64) bool {
return false
}

if rate <= 0 || rate >= 1 {
return rate <= 0
if ratio <= 0 {
return curr <= hardMax
} else if ratio >= 1 {
return ratio <= 0
}

increaseRate := (1 - rate) * (float64(curr-max) / float64(hardMax-max))
if increaseRate < 0 {
increaseRate = 0
increaseRatio := (1 - ratio) * (float64(curr-max) / float64(hardMax-max))
if increaseRatio < 0 {
increaseRatio = 0
}

return rand.Float64() >= (rate + increaseRate)
return rand.Float64() >= (ratio + increaseRatio)
}

0 comments on commit e24d337

Please sign in to comment.