I have Apache 2.4 installed on Debian 9.9, basically doing nothing but serving an instance of Roundcube (currently 1.4 RC-1).
The document root of Apache is /home/web (because reasons), and the Roundcube instance is installed in /home/web/mail.
The Apache user (www-data) has full read/write access to the entire /home/web directory tree.
The document root has an index file that redirects to and I'm using mod_rewrite to change any HTTP requests to HTTPS.
Today I noticed (and don't know how long it's been happening) that when I hit mydomain.co.uk it logs a 401 error in Apache:
192.168.10.79 - - [09/Jun/2019:18:49:59 +0100] "GET /mail/ HTTP/1.1" 401 2955 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0)
Gecko/20100101 Firefox/67.0"This is particularly a problem when accessing it externally as it's triggering a fail2ban rule and banning my clients.
The 401 error means "authentication failed" but I have not set up any authentication on this directory with Apache which AIUI requires the presence of a .htpasswd file - I've checked for the existence of this file in my Apache document root, and there is none - or the use of an auth clause in the virtualhost file - of which also there is none.
How can I find the cause, and prevent, this 401 error?
Some debug information from Fiddler:
GET HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: en-GB
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host:
Connection: Keep-Alive
Cookie: roundcube_sessid=sadh0s1j2rn769rvebhpsv6m81
HTTP/1.0 401 Unauthorized
Date: Mon, 10 Jun 2019 08:27:28 GMT
Server: Apache/2.4.25 (Debian)
Strict-Transport-Security: max-age=63072000; includeSubdomains;
Expires: Mon, 10 Jun 2019 08:27:28 GMT
Cache-Control: private, must-revalidate
Pragma: private
Last-Modified: Mon, 10 Jun 2019 08:27:28 GMT
X-UA-Compatible: IE=edge
X-Frame-Options: sameorigin
Content-Language: en
Vary: Accept-Encoding
X-Robots-Tag: noindex, nofollow
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Length: 5435If I look in Fiddler under the "Auth" tab:
No Proxy-Authenticate Header is present.
No WWW-Authenticate Header is present.Some further degug information from wget:
DEBUG output created by Wget 1.18 on linux-gnueabi.
Reading HSTS entries from /home/darren/.wget-hsts
URI encoding = ‘UTF-8’
Converted file name 'mail' (UTF-8) -> 'mail' (UTF-8)
--2019-06-10 13:34:43--
Certificates loaded: 151
Resolving ()... XX.XX.XX.XX
Caching => XX.XX.XX.XX
Connecting to ()|XX.XX.XX.XX|:443... connected.
Created socket 3.
Releasing 0x004bf2e0 (new refcount 1).
---request begin---
GET /mail HTTP/1.1
User-Agent: Wget/1.18 (linux-gnueabi)
Accept: */*
Accept-Encoding: identity
Host:
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 301 Moved Permanently
Date: Mon, 10 Jun 2019 12:34:43 GMT
Server: Apache/2.4.25 (Debian)
Strict-Transport-Security: max-age=63072000; includeSubdomains;
Location:
Content-Length: 331
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
---response end---
301 Moved Permanently
Registered socket 3 for persistent reuse.
Parsed Strict-Transport-Security max-age = 63072000, includeSubDomains = true
Added new HSTS host: (max-age: 63072000, includeSubdomains: true)
URI content encoding = ‘iso-8859-1’
Location: [following]
Skipping 331 bytes of body: [<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a hreSkipping 157 bytes of body: [f="">here</a>.</p>
<hr>
<address>Apache/2.4.25 (Debian) Server at Port 443</address>
</body></html>
] done.
URI content encoding = None
Converted file name 'mail' (UTF-8) -> 'mail' (UTF-8)
--2019-06-10 13:34:43--
Reusing existing connection to
Reusing fd 3.
---request begin---
GET /mail/ HTTP/1.1
User-Agent: Wget/1.18 (linux-gnueabi)
Accept: */*
Accept-Encoding: identity
Host:
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.0 401 Unauthorized
Date: Mon, 10 Jun 2019 12:34:43 GMT
Server: Apache/2.4.25 (Debian)
Strict-Transport-Security: max-age=63072000; includeSubdomains;
Set-Cookie: roundcube_sessid=9dd09n33d6k3f1kil69f90bkk6; path=/; secure; HttpOnly
Expires: Mon, 10 Jun 2019 12:34:43 GMT
Cache-Control: private, no-cache, no-store, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Last-Modified: Mon, 10 Jun 2019 12:34:43 GMT
X-Frame-Options: sameorigin
Content-Language: en
Vary: Accept-Encoding
X-Robots-Tag: noindex, nofollow
Connection: close
Content-Type: text/html; charset=UTF-8
---response end---
401 Unauthorized
Stored cookie -1 (ANY) / <session> <secure> [expiry none] roundcube_sessid 9dd09n33d6k3f1kil69f90bkk6
Disabling further reuse of socket 3.
Username/Password Authentication Failed.
Saving HSTS entries to /home/darren/.wget-hsts 2 Answers
The 401 Unauthorized Error is an HTTP response status code indicating that the request sent by the client could not be authenticated, but can have many causes.
I would suggest:
Post the text entire request and response for us to examine. Of special interest is the
WWW-Authenticateresponse header, which contains one or more challenges strings, each indicating how proper authentication can be obtained to access the requested resource.Check the Apache server logs (may require enabling verbose logging).
If the client is banned, the error code is usually 401.
Clear all cookies and the browser cache on the client browser.
Use the browser with all extensions disabled. In Firefox this is the Safe mode, and in Chrome the Incognito mode.
Search on the server if your application is set to return this error code.
This is a new "feature" in Roundcube.
We return 401 when user is not logged in. The code is in index.php and it can be modified by a plugin.
These are the offending lines in the Roundcube index.php:
$plugin = $RCMAIL->plugins->exec_hook('unauthenticated', array( 'task' => 'login', 'error' => $session_error, 'http_code' => !$session_error ? 401 : 200 )); $RCMAIL->set_task($plugin['task']);
// if ($plugin['http_code'] == 401) {
// header('HTTP/1.0 401 Unauthorized');
// }I've commented out the last three lines to stop the 401 error being produced.