Skip to content

Commit abb9cff

Browse files
elesiutatechknowlogick6543
authored
Log IP on SSH authentication failure for Built-in SSH server (#13150)
* Log IP on SSH authentication failure fixes #13094 * include string 'Failed authentication attempt' in error * update fail2ban docs also match failed authentication over command line * better logging of authentication errors with IP addresses * format ... Co-authored-by: techknowlogick <[email protected]> Co-authored-by: 6543 <[email protected]>
1 parent 42354df commit abb9cff

File tree

4 files changed

+12
-3
lines changed

4 files changed

+12
-3
lines changed

docs/content/doc/usage/fail2ban-setup.en-us.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,24 @@ sure to test this before relying on it so you don't lock yourself out.**
2020

2121
Gitea returns an HTTP 200 for bad logins in the web logs, but if you have logging options on in
2222
`app.ini`, then you should be able to go off of `log/gitea.log`, which gives you something like this
23-
on a bad authentication:
23+
on a bad authentication from the web or CLI using SSH or HTTP respectively:
2424

2525
```log
2626
2018/04/26 18:15:54 [I] Failed authentication attempt for user from xxx.xxx.xxx.xxx
2727
```
28+
```log
29+
2020/10/15 16:05:09 modules/ssh/ssh.go:188:publicKeyHandler() [E] SearchPublicKeyByContent: public key does not exist [id: 0] Failed authentication attempt from xxx.xxx.xxx.xxx
30+
```
31+
```log
32+
2020/10/15 16:08:44 ...s/context/context.go:204:HandleText() [E] invalid credentials from xxx.xxx.xxx.xxx
33+
```
2834

2935
Add our filter in `/etc/fail2ban/filter.d/gitea.conf`:
3036

3137
```ini
3238
# gitea.conf
3339
[Definition]
34-
failregex = .*Failed authentication attempt for .* from <HOST>
40+
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
3541
ignoreregex =
3642
```
3743

modules/ssh/ssh.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool {
186186

187187
pkey, err := models.SearchPublicKeyByContent(strings.TrimSpace(string(gossh.MarshalAuthorizedKey(key))))
188188
if err != nil {
189-
log.Error("SearchPublicKeyByContent: %v", err)
189+
log.Error("SearchPublicKeyByContent: %v Failed authentication attempt from %s", err, ctx.RemoteAddr())
190190
return false
191191
}
192192

routers/private/serv.go

+2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func ServCommand(ctx *macaron.Context) {
132132
for _, verb := range ctx.QueryStrings("verb") {
133133
if "git-upload-pack" == verb {
134134
// User is fetching/cloning a non-existent repository
135+
log.Error("Failed authentication attempt (cannot find repository: %s/%s) from %s", results.OwnerName, results.RepoName, ctx.RemoteAddr())
135136
ctx.JSON(http.StatusNotFound, map[string]interface{}{
136137
"results": results,
137138
"type": "ErrRepoNotExist",
@@ -317,6 +318,7 @@ func ServCommand(ctx *macaron.Context) {
317318
userMode := perm.UnitAccessMode(unitType)
318319

319320
if userMode < mode {
321+
log.Error("Failed authentication attempt for %s with key %s (not authorized to %s %s/%s) from %s", user.Name, key.Name, modeString, ownerName, repoName, ctx.RemoteAddr())
320322
ctx.JSON(http.StatusUnauthorized, map[string]interface{}{
321323
"results": results,
322324
"type": "ErrUnauthorized",

routers/repo/http.go

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func HTTP(ctx *context.Context) {
102102

103103
owner, err := models.GetUserByName(username)
104104
if err != nil {
105+
log.Error("Attempted access of unknown user from %s", ctx.RemoteAddr())
105106
ctx.NotFoundOrServerError("GetUserByName", models.IsErrUserNotExist, err)
106107
return
107108
}

0 commit comments

Comments
 (0)