diff --git a/ChangeLog b/ChangeLog
index ceb3c822..86b407ac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -41,6 +41,7 @@ ver. 0.10.3-dev-1 (20??/??/??) - development edition
* `filter.d/sshd.conf`:
- failregex got an optional space in order to match new log-format (see gh-2061);
- fixed ddos-mode regex to match refactored message (some versions can contain port now, see gh-2062);
+ - fixed root login refused regex (optional port before preauth, gh-2080);
* `action.d/badips.py`: implicit convert IPAddr to str, solves an issue "expected string, IPAddr found" (gh-2059);
* `action.d/hostsdeny.conf`: fixed IPv6 syntax (enclosed in square brackets, gh-2066);
* (Free)BSD ipfw actionban fixed to allow same rule added several times (gh-2054);
diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf
index d8bb5edf..6b75f9dd 100644
--- a/config/filter.d/sshd.conf
+++ b/config/filter.d/sshd.conf
@@ -21,7 +21,7 @@ _daemon = sshd
# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
__pref = (?:(?:error|fatal): (?:PAM: )?)?
# optional suffix (logged from several ssh versions) like " [preauth]"
-__suff = (?: \[preauth\])?\s*
+__suff = (?: port \d+)?(?: \[preauth\])?\s*
__on_port_opt = (?: port \d+)?(?: on \S+(?: port \d+)?)?
# for all possible (also future) forms of "no matching (cipher|mac|MAC|compression method|key exchange method|host key type) found",
@@ -36,7 +36,7 @@ cmnfailre = ^[aA]uthentication (?:failure|error|failed) for .*
^User not known to the underlying authentication module for .* from \s*%(__suff)s$
^Failed \S+ for invalid user (?P\S+)|(?:(?! from ).)*? from %(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
^Failed \b(?!publickey)\S+ for (?Pinvalid user )?(?P\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+) from %(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
- ^ROOT LOGIN REFUSED.* FROM \s*%(__suff)s$
+ ^ROOT LOGIN REFUSED FROM \s*%(__suff)s$
^[iI](?:llegal|nvalid) user .*? from %(__on_port_opt)s\s*$
^User .+ from not allowed because not listed in AllowUsers\s*%(__suff)s$
^User .+ from not allowed because listed in DenyUsers\s*%(__suff)s$
diff --git a/fail2ban/tests/config/filter.d/zzz-sshd-obsolete-multiline.conf b/fail2ban/tests/config/filter.d/zzz-sshd-obsolete-multiline.conf
index 5560716d..0379a626 100644
--- a/fail2ban/tests/config/filter.d/zzz-sshd-obsolete-multiline.conf
+++ b/fail2ban/tests/config/filter.d/zzz-sshd-obsolete-multiline.conf
@@ -14,7 +14,7 @@ _daemon = sshd
# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
__pref = (?:(?:error|fatal): (?:PAM: )?)?
# optional suffix (logged from several ssh versions) like " [preauth]"
-__suff = (?: \[preauth\])?\s*
+__suff = (?: port \d+)?(?: \[preauth\])?\s*
__on_port_opt = (?: port \d+)?(?: on \S+(?: port \d+)?)?
# single line prefix:
@@ -33,8 +33,8 @@ cmnfailre = ^%(__prefix_line_sl)s[aA]uthentication (?:failure|error|failed) for
^%(__prefix_line_sl)sUser not known to the underlying authentication module for .* from \s*%(__suff)s$
^%(__prefix_line_sl)sFailed \S+ for invalid user (?P\S+)|(?:(?! from ).)*? from %(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
^%(__prefix_line_sl)sFailed \b(?!publickey)\S+ for (?Pinvalid user )?(?P\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+) from %(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
- ^%(__prefix_line_sl)sROOT LOGIN REFUSED.* FROM \s*%(__suff)s$
- ^%(__prefix_line_sl)s[iI](?:llegal|nvalid) user .*? from %(__on_port_opt)s\s*$
+ ^%(__prefix_line_sl)sROOT LOGIN REFUSED.* FROM %(__suff)s$
+ ^%(__prefix_line_sl)s[iI](?:llegal|nvalid) user .*? from %(__suff)s$
^%(__prefix_line_sl)sUser .+ from not allowed because not listed in AllowUsers\s*%(__suff)s$
^%(__prefix_line_sl)sUser .+ from not allowed because listed in DenyUsers\s*%(__suff)s$
^%(__prefix_line_sl)sUser .+ from not allowed because not in any group\s*%(__suff)s$
@@ -50,8 +50,8 @@ cmnfailre = ^%(__prefix_line_sl)s[aA]uthentication (?:failure|error|failed) for
mdre-normal =
-mdre-ddos = ^%(__prefix_line_sl)sDid not receive identification string from %(__on_port_opt)s%(__suff)s
- ^%(__prefix_line_sl)sConnection reset by %(__on_port_opt)s%(__suff)s
+mdre-ddos = ^%(__prefix_line_sl)sDid not receive identification string from %(__suff)s
+ ^%(__prefix_line_sl)sConnection reset by %(__suff)s
^%(__prefix_line_ml1)sSSH: Server;Ltype: (?:Authname|Version|Kex);Remote: -\d+;[A-Z]\w+:.*%(__prefix_line_ml2)sRead from socket failed: Connection reset by peer%(__suff)s$
mdre-extra = ^%(__prefix_line_sl)sReceived disconnect from %(__on_port_opt)s:\s*14: No supported authentication methods available%(__suff)s$
diff --git a/fail2ban/tests/files/logs/sshd b/fail2ban/tests/files/logs/sshd
index e80eb30c..7d93642d 100644
--- a/fail2ban/tests/files/logs/sshd
+++ b/fail2ban/tests/files/logs/sshd
@@ -24,6 +24,8 @@ Feb 25 14:34:11 belka sshd[31603]: Failed password for invalid user ROOT from aa
# failJSON: { "time": "2005-01-05T01:31:41", "match": true , "host": "1.2.3.4" }
Jan 5 01:31:41 www sshd[1643]: ROOT LOGIN REFUSED FROM 1.2.3.4
# failJSON: { "time": "2005-01-05T01:31:41", "match": true , "host": "1.2.3.4" }
+Jan 5 01:31:41 www sshd[1643]: ROOT LOGIN REFUSED FROM 1.2.3.4 port 12345 [preauth]
+# failJSON: { "time": "2005-01-05T01:31:41", "match": true , "host": "1.2.3.4" }
Jan 5 01:31:41 www sshd[1643]: ROOT LOGIN REFUSED FROM ::ffff:1.2.3.4
#4