mirror of
https://git.sr.ht/~hamburghammer/sshlog
synced 2024-12-23 05:27:41 +01:00
Compare commits
4 commits
74b456241a
...
fc61e9f469
Author | SHA1 | Date | |
---|---|---|---|
fc61e9f469 | |||
26baa83da8 | |||
a63e9965f2 | |||
a3eddde736 |
4 changed files with 38 additions and 12 deletions
17
README.md
17
README.md
|
@ -4,7 +4,7 @@ A small tool to log IPs, usernames and passwords from incoming ssh-auth requests
|
||||||
It opens a minimal SSH-Server and listens on IPv4 and IPv6 for auth requests.
|
It opens a minimal SSH-Server and listens on IPv4 and IPv6 for auth requests.
|
||||||
The goal of this little tool is to log the requests coming from bots living inside the wild internet.
|
The goal of this little tool is to log the requests coming from bots living inside the wild internet.
|
||||||
|
|
||||||
# Install
|
## Install
|
||||||
Make sure you have Golang installed and configured.
|
Make sure you have Golang installed and configured.
|
||||||
```shell
|
```shell
|
||||||
git clone https://git.sr.ht/~hamburghammer/sshlog
|
git clone https://git.sr.ht/~hamburghammer/sshlog
|
||||||
|
@ -13,7 +13,7 @@ go build
|
||||||
```
|
```
|
||||||
Now you should be able to execute the newly generated executable with `./sshlog`.
|
Now you should be able to execute the newly generated executable with `./sshlog`.
|
||||||
|
|
||||||
# Usage
|
## Usage
|
||||||
Start with:
|
Start with:
|
||||||
```shell
|
```shell
|
||||||
sshlog -p 2222
|
sshlog -p 2222
|
||||||
|
@ -27,7 +27,15 @@ Output:
|
||||||
2021/06/02 23:08:54 SRC=127.0.0.1 USERNAME=test PASSWORD=fooof
|
2021/06/02 23:08:54 SRC=127.0.0.1 USERNAME=test PASSWORD=fooof
|
||||||
```
|
```
|
||||||
|
|
||||||
## Options
|
Output with `--json`:
|
||||||
|
```text
|
||||||
|
2021/09/02 12:43:42 Starting ssh logger on port 2222...
|
||||||
|
{"date": "2021-09-02T12:44:15+02:00", "src": "127.0.0.1", "username": "test", "password": "foo"}
|
||||||
|
{"date": "2021-09-02T12:44:18+02:00", "src": "127.0.0.1", "username": "test", "password": "foof"}
|
||||||
|
{"date": "2021-09-02T12:44:21+02:00", "src": "127.0.0.1", "username": "test", "password": "fooof"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
```text
|
```text
|
||||||
A small tool to log IPs, usernames and passwords from incoming ssh-auth requests.
|
A small tool to log IPs, usernames and passwords from incoming ssh-auth requests.
|
||||||
|
|
||||||
|
@ -36,12 +44,13 @@ USAGE:
|
||||||
|
|
||||||
FLAGS:
|
FLAGS:
|
||||||
-h, --help Prints this help message and exits.
|
-h, --help Prints this help message and exits.
|
||||||
|
--json Log in JSON instead of plain text.
|
||||||
-k, --key string Path to the host key for the ssh server.
|
-k, --key string Path to the host key for the ssh server.
|
||||||
If absent it will automatically generate a new one for each run.
|
If absent it will automatically generate a new one for each run.
|
||||||
-4, --onlyIPv4 Only listens on IPv4.
|
-4, --onlyIPv4 Only listens on IPv4.
|
||||||
-p, --port string Port to listen for incoming connections. (default "22"))
|
-p, --port string Port to listen for incoming connections. (default "22"))
|
||||||
```
|
```
|
||||||
|
|
||||||
# Utils
|
## Utils
|
||||||
Inside the `util` directory you might find some additional information like how to create Systemd service for sshlog.
|
Inside the `util` directory you might find some additional information like how to create Systemd service for sshlog.
|
||||||
|
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -4,5 +4,5 @@ go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||||
)
|
)
|
||||||
|
|
7
go.sum
7
go.sum
|
@ -1,10 +1,11 @@
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
|
24
main.go
24
main.go
|
@ -12,6 +12,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
flags "github.com/spf13/pflag"
|
flags "github.com/spf13/pflag"
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ var (
|
||||||
isHelp bool
|
isHelp bool
|
||||||
keyPath string
|
keyPath string
|
||||||
onlyIPv4 bool
|
onlyIPv4 bool
|
||||||
|
isJson bool
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -30,6 +32,7 @@ func init() {
|
||||||
flags.StringVarP(&keyPath, "key", "k", "", "Path to the host key for the ssh server.\nIf absent it will automatically generate a new one for each run.")
|
flags.StringVarP(&keyPath, "key", "k", "", "Path to the host key for the ssh server.\nIf absent it will automatically generate a new one for each run.")
|
||||||
flags.BoolVarP(&isHelp, "help", "h", false, "Prints this help message and exits.")
|
flags.BoolVarP(&isHelp, "help", "h", false, "Prints this help message and exits.")
|
||||||
flags.BoolVarP(&onlyIPv4, "onlyIPv4", "4", false, "Only listens on IPv4.")
|
flags.BoolVarP(&onlyIPv4, "onlyIPv4", "4", false, "Only listens on IPv4.")
|
||||||
|
flags.BoolVar(&isJson, "json", false, "Log in JSON instead of plain text.")
|
||||||
flags.Parse()
|
flags.Parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,12 +85,13 @@ func startAccepting(listener net.Listener, hostKey ssh.Signer) {
|
||||||
|
|
||||||
func getKey(path string) []byte {
|
func getKey(path string) []byte {
|
||||||
if path != "" {
|
if path != "" {
|
||||||
privateBytes, err := ioutil.ReadFile("private-key.pem")
|
privateBytes, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to load private key (%s)", path)
|
log.Fatalf("Failed to load private key: %s", path)
|
||||||
}
|
}
|
||||||
return privateBytes
|
return privateBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
privatekey, err := rsa.GenerateKey(rand.Reader, 2048)
|
privatekey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Cannot generate RSA key\n")
|
log.Fatalf("Cannot generate RSA key\n")
|
||||||
|
@ -105,9 +109,21 @@ func getKey(path string) []byte {
|
||||||
|
|
||||||
func PrintData(con net.Conn, hostKey ssh.Signer) {
|
func PrintData(con net.Conn, hostKey ssh.Signer) {
|
||||||
serverConfig := ssh.ServerConfig{PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
|
serverConfig := ssh.ServerConfig{PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
|
||||||
log.Printf("SRC=%s USERNAME=%s PASSWORD=%s\n", getIPWithoutPort(conn.RemoteAddr().String()), conn.User(), string(password))
|
ip := getIPWithoutPort(conn.RemoteAddr().String())
|
||||||
|
|
||||||
return nil, fmt.Errorf("password rejected for %q", conn.User())
|
if isJson {
|
||||||
|
fmt.Printf(
|
||||||
|
"{\"date\": \"%s\", \"src\": \"%s\", \"username\": \"%s\", \"password\": \"%s\"}\n",
|
||||||
|
time.Now().Format(time.RFC3339),
|
||||||
|
ip,
|
||||||
|
conn.User(),
|
||||||
|
string(password),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
log.Printf("SRC=%s USERNAME=%s PASSWORD=%s\n", ip, conn.User(), string(password))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("password rejected for %s", conn.User())
|
||||||
}}
|
}}
|
||||||
|
|
||||||
serverConfig.AddHostKey(hostKey)
|
serverConfig.AddHostKey(hostKey)
|
||||||
|
|
Loading…
Reference in a new issue