![是什么原因导致了此 Apache 401 错误?](https://linux22.com/image/1593907/%E6%98%AF%E4%BB%80%E4%B9%88%E5%8E%9F%E5%9B%A0%E5%AF%BC%E8%87%B4%E4%BA%86%E6%AD%A4%20Apache%20401%20%E9%94%99%E8%AF%AF%EF%BC%9F.png)
我在 Debian 9.9 上安装了 Apache 2.4,基本上什么也不做,只是为 Roundcube 实例提供服务(目前是 1.4 RC-1)。
Apache 的文档根目录是/home/web
(因为原因),并且 Roundcube 实例安装在/home/web/mail
。
Apache 用户 ( www-data
) 对整个/home/web
目录树具有完全的读/写访问权限。
文档根目录有一个重定向到的索引文件www.mydomain.co.uk/mail
,我正在使用它mod_rewrite
来将任何 HTTP 请求更改为 HTTPS。
今天我注意到(不知道这种情况已经持续了多久),当我点击mydomain.co.uk
它时,Apache 中会记录 401 错误:
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"
当从外部访问它时,这尤其会成为一个问题,因为它会触发 fail2ban 规则并禁止我的客户端。
401 错误意味着“身份验证失败”,但是我尚未使用 Apache 在此目录上设置任何身份验证,而 AIUI 需要文件的存在.htpasswd
- 我已经检查过我的 Apache 文档根目录中是否存在此文件,但不存在 - 或者在虚拟主机文件中使用了 auth 子句 - 但也没有。
我如何才能找到原因并避免此 401 错误?
来自Fiddler的一些调试信息:
GET https://www.mydomain.co.uk/mail/ 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: www.mydomain.co.uk
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: 5435
如果我在 Fiddler 中的“Auth”选项卡下查看:
No Proxy-Authenticate Header is present.
No WWW-Authenticate Header is present.
来自 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-- https://www.mydomain.co.uk/mail
Certificates loaded: 151
Resolving www.mydomain.co.uk (www.mydomain.co.uk)... XX.XX.XX.XX
Caching www.mydomain.co.uk => XX.XX.XX.XX
Connecting to www.mydomain.co.uk (www.mydomain.co.uk)|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: www.mydomain.co.uk
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: https://www.mydomain.co.uk/mail/
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: www.mydomain.co.uk:443 (max-age: 63072000, includeSubdomains: true)
URI content encoding = ‘iso-8859-1’
Location: https://www.mydomain.co.uk/mail/ [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="https://www.mydomain.co.uk/mail/">here</a>.</p>
<hr>
<address>Apache/2.4.25 (Debian) Server at www.mydomain.co.uk 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-- https://www.mydomain.co.uk/mail/
Reusing existing connection to www.mydomain.co.uk:443.
Reusing fd 3.
---request begin---
GET /mail/ HTTP/1.1
User-Agent: Wget/1.18 (linux-gnueabi)
Accept: */*
Accept-Encoding: identity
Host: www.mydomain.co.uk
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 www.mydomain.co.uk -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
答案1
401 未授权错误是一个 HTTP 响应状态代码,表示无法验证客户端发送的请求,但可能有很多原因。
我会建议:
发布整个请求和响应的文本以供我们检查。特别有趣的是
WWW-Authenticate
响应标头,其中包含一个或多个挑战字符串,每个字符串都指示如何获得正确的身份验证以访问请求的资源。检查 Apache 服务器日志(可能需要启用详细日志记录)。
如果客户端被禁止,错误代码通常为401。
清除客户端浏览器上的所有 Cookie 和浏览器缓存。
使用禁用所有扩展的浏览器。在 Firefox 中这是安全模式,在 Chrome 中这是隐身模式。
如果您的应用程序设置为返回此错误代码,请在服务器上搜索。
答案2
这是 Roundcube 的一个新“功能”。
当用户未登录时,我们返回 401。代码在 index.php 中,可以通过插件进行修改。
这些是 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');
// }
我注释掉了最后三行以阻止产生 401 错误。