From 12a9a45747f3ce3ff58464cd7ccb88f2c42438e8 Mon Sep 17 00:00:00 2001 From: benrubson <6764151+benrubson@users.noreply.github.com> Date: Sun, 9 Feb 2020 10:01:33 +0100 Subject: [PATCH 1/4] Log failed accesses --- app/Http/Controllers/Auth/LoginController.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index ea584a3b6..75ade74e7 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -101,6 +101,9 @@ class LoginController extends Controller $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); + // Also log some error message + $this->logFailedAccess($request); + return $this->sendLockoutResponse($request); } @@ -117,6 +120,9 @@ class LoginController extends Controller // user surpasses their maximum number of attempts they will get locked out. $this->incrementLoginAttempts($request); + // Also log some error message + $this->logFailedAccess($request); + return $this->sendFailedLoginResponse($request); } @@ -162,4 +168,16 @@ class LoginController extends Controller return redirect('/login'); } + /** + * Log failed accesses, matching the default fail2ban nginx/apache auth rules. + */ + protected function logFailedAccess(Request $request) + { + if (isset($_SERVER['SERVER_SOFTWARE']) && preg_match('/nginx/i', $_SERVER['SERVER_SOFTWARE'])) { + error_log('user "' . $request->get($this->username()) . '" was not found in "BookStack"', 4); + } else { + error_log('user "' . $request->get($this->username()) . '" authentication failure for "BookStack"', 4); + } + } + } From 58df3ad9566061186e62110e7c1e4a4140ed02c2 Mon Sep 17 00:00:00 2001 From: benrubson <6764151+benrubson@users.noreply.github.com> Date: Sun, 3 May 2020 16:20:02 +0200 Subject: [PATCH 2/4] Log failed accesses option --- .env.example.complete | 8 ++++++- app/Http/Controllers/Auth/LoginController.php | 21 ++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/.env.example.complete b/.env.example.complete index 04cd73b90..5b62b1a2a 100644 --- a/.env.example.complete +++ b/.env.example.complete @@ -266,4 +266,10 @@ API_DEFAULT_ITEM_COUNT=100 API_MAX_ITEM_COUNT=500 # The number of API requests that can be made per minute by a single user. -API_REQUESTS_PER_MIN=180 \ No newline at end of file +API_REQUESTS_PER_MIN=180 + +# Failed access +# message to log into webserver logs in case of failed access, for further processing by tools like Fail2Ban +# Apache users should use : user "%u" authentication failure for "BookStack" +# Nginx users should use : user "%u" was not found in "BookStack" +FAILED_ACCESS_MESSAGE='' diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 75ade74e7..c000af49e 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -169,15 +169,20 @@ class LoginController extends Controller } /** - * Log failed accesses, matching the default fail2ban nginx/apache auth rules. - */ - protected function logFailedAccess(Request $request) + * Log failed accesses, for further processing by tools like Fail2Ban + * + * @param \Illuminate\Http\Request $request + * @return void + */ + protected function logFailedAccess($request) { - if (isset($_SERVER['SERVER_SOFTWARE']) && preg_match('/nginx/i', $_SERVER['SERVER_SOFTWARE'])) { - error_log('user "' . $request->get($this->username()) . '" was not found in "BookStack"', 4); - } else { - error_log('user "' . $request->get($this->username()) . '" authentication failure for "BookStack"', 4); - } + $log_msg = env('FAILED_ACCESS_MESSAGE', ''); + + if (!is_string($request->get($this->username())) || !is_string($log_msg) || strlen($log_msg)<1) + return; + + $log_msg = str_replace("%u", $request->get($this->username()), $log_msg); + error_log($log_msg, 4); } } From 8f1f73defa321f026d487b3e9344055746bc6f58 Mon Sep 17 00:00:00 2001 From: benrubson <6764151+benrubson@users.noreply.github.com> Date: Sat, 23 May 2020 12:06:37 +0200 Subject: [PATCH 3/4] Properly use env/config functions --- app/Config/logging.php | 5 +++++ app/Http/Controllers/Auth/LoginController.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Config/logging.php b/app/Config/logging.php index 0b55dc24d..406b9f2f9 100644 --- a/app/Config/logging.php +++ b/app/Config/logging.php @@ -79,4 +79,9 @@ return [ ], ], + // Failed Access Message + // Defines the message to log into webserver logs in case of failed access, + // for further processing by tools like Fail2Ban. + 'failed_access_message' => env('FAILED_ACCESS_MESSAGE', ''), + ]; diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index c000af49e..cf9e44e43 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -176,7 +176,7 @@ class LoginController extends Controller */ protected function logFailedAccess($request) { - $log_msg = env('FAILED_ACCESS_MESSAGE', ''); + $log_msg = config('logging.failed_access_message'); if (!is_string($request->get($this->username())) || !is_string($log_msg) || strlen($log_msg)<1) return; From 9d7ce59b18c5cbeef017349f38f063a63b762188 Mon Sep 17 00:00:00 2001 From: benrubson <6764151+benrubson@users.noreply.github.com> Date: Sat, 23 May 2020 15:37:38 +0200 Subject: [PATCH 4/4] Move logFailedAccess into Activity --- app/Actions/ActivityService.php | 17 ++++++++++++++ app/Http/Controllers/Auth/LoginController.php | 22 +++---------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/app/Actions/ActivityService.php b/app/Actions/ActivityService.php index f56f1ca57..ca09aaef1 100644 --- a/app/Actions/ActivityService.php +++ b/app/Actions/ActivityService.php @@ -183,4 +183,21 @@ class ActivityService session()->flash('success', $message); } } + + /** + * Log failed accesses, for further processing by tools like Fail2Ban + * + * @param username + * @return void + */ + public function logFailedAccess($username) + { + $log_msg = config('logging.failed_access_message'); + + if (!is_string($username) || !is_string($log_msg) || strlen($log_msg)<1) + return; + + $log_msg = str_replace("%u", $username, $log_msg); + error_log($log_msg, 4); + } } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index cf9e44e43..f5479814a 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -2,6 +2,7 @@ namespace BookStack\Http\Controllers\Auth; +use Activity; use BookStack\Auth\Access\SocialAuthService; use BookStack\Exceptions\LoginAttemptEmailNeededException; use BookStack\Exceptions\LoginAttemptException; @@ -102,7 +103,7 @@ class LoginController extends Controller $this->fireLockoutEvent($request); // Also log some error message - $this->logFailedAccess($request); + Activity::logFailedAccess($request->get($this->username())); return $this->sendLockoutResponse($request); } @@ -121,7 +122,7 @@ class LoginController extends Controller $this->incrementLoginAttempts($request); // Also log some error message - $this->logFailedAccess($request); + Activity::logFailedAccess($request->get($this->username())); return $this->sendFailedLoginResponse($request); } @@ -168,21 +169,4 @@ class LoginController extends Controller return redirect('/login'); } - /** - * Log failed accesses, for further processing by tools like Fail2Ban - * - * @param \Illuminate\Http\Request $request - * @return void - */ - protected function logFailedAccess($request) - { - $log_msg = config('logging.failed_access_message'); - - if (!is_string($request->get($this->username())) || !is_string($log_msg) || strlen($log_msg)<1) - return; - - $log_msg = str_replace("%u", $request->get($this->username()), $log_msg); - error_log($log_msg, 4); - } - }