我有一个运行 apache 的 Web 服务器(Linux,Ubuntu 16.04)。我用它来托管一些使用 ServiceStack 框架开发的 Mono 的 ASP.NET 应用程序。这是我的 vhost 配置
<VirtualHost *:443>
ServerName myhost
ServerAdmin me@myhost
DocumentRoot /var/www/
ErrorLog ${APACHE_LOG_DIR}/myhost-error.log
CustomLog ${APACHE_LOG_DIR}/myhost-access.log combined
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/myhost/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/myhost/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/myhost/fullchain.pem
Header always set Strict-Transport-Security "max-age=15768000"
<Directory /var/www>
AllowOverride Nonehackathon
deny from all
</Directory>
# Configure the myservice backend and frontend
<Directory /var/www/myservice/backend>
AllowOverride None
Order allow,deny
allow from all
</Directory>
Alias /myservice "/var/www/myservice/frontend"
Alias /csc "/var/www/myservice/frontend"
<Directory /var/www/myservice/frontend>
AllowOverride None
Order allow,deny
allow from all
</Directory>
MonoMaxActiveRequests 150
MonoMaxWaitingRequests 150
MonoSetEnv MONO_THREADS_PER_CPU=100
MonoServerPath "/usr/bin/mod-mono-server4"
MonoServerPath backend "/usr/bin/mod-mono-server4"
MonoApplications backend "/myservice/backend:/var/www/myservice/backend"
KeepAliveTimeout 5
Alias /myservice/backend "/var/www/myservice/backend"
<Location /myservice/backend>
Allow from all
Order allow,deny
MonoSetServerAlias backend
SetHandler mono
</Location>
<Directory /var/www/myservice/backend>
AllowOverride None
Order allow,deny
allow from all
</Directory>
# Configure the test sites for the myservice
<Directory /var/www/test/myservice/backend>
AllowOverride None
Order allow,deny
allow from all
</Directory>
Alias /test/myservice "/var/www/test/myservice/frontend"
Alias /test/csc "/var/www/test/myservice/frontend"
<Directory /var/www/test/myservice/frontend>
AllowOverride None
Order allow,deny
allow from all
</Directory>
MonoServerPath test_backend "/usr/bin/mod-mono-server4"
MonoApplications test_backend "/test/myservice/backend:/var/www/test/myservice/backend"
<Location /test/myservice/backend>
Allow from all
Order allow,deny
MonoSetServerAlias test_backend
SetHandler mono
</Location>
# Configure WebDav access
Alias /webdav "/var/www/webdav"
<Location /webdav>
Options Indexes
DAV On
AuthType Basic
AuthName "webdav"
AuthUserFile /etc/apache2/webdav.password
Require valid-user
Order allow,deny
allow from all
</Location>
</VirtualHost>
这或多或少是有效的,但它仍然会导致 apache 日志中出现一些错误:
==> /var/log/apache2/myhost-error.log <==
[Tue Jun 13 09:00:27.874100 2017] [access_compat:error] [pid 62595:tid 140403123173120] [client 1.2.3.4:53342] AH01797: client denied by server configuration: /var/www/items, referer: https://myhost/csc/
==> /var/log/apache2/myhost-access.log <==
1.2.3.4 - - [13/Jun/2017:09:00:27 +0200] "GET /myservice/backend/items/42 HTTP/1.1" 200 578 "https://myhost/csc/" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SD; rv:11.0) like Gecko"
因此,客户端尝试访问后端的有效路由(/myservice/后端/项目/42)通过前端(我的主机/csc) 并从服务中获取了正确的结果,但出于某种原因,apache 尝试直接从 htdocs 目录访问该项目 (/var/www/项目) 。有人看到这个错误是从哪里来的吗?
答案1
因此,查看可能符合您的请求的配置位,我看到以下内容可能与路径匹配/myservice/backend/items/42
:
Alias /myservice "/var/www/myservice/frontend"
Alias /myservice/backend "/var/www/myservice/backend"
<Location /myservice/backend>
所有这些似乎都相当矛盾和令人困惑。要弄清楚哪些会起作用,就需要比您希望的更仔细地阅读处理规则。清理!
我建议您尝试安排以下事项:
- 没有必要知道 Alias 指令或 Location 指令是否首先生效。
- 最具体的 Alias 指令位于文件中的第一个位置。后者可能无效。
- 别名指令主要用于将请求映射到文档根目录之外的区域。在文档根目录中,我会使用 mod_rewrite。考虑将其设为客户端重定向,这样您就不会有多个 URL 指向同一内容。
- 阅读笔记关于使用位置块进行访问控制,并确保您没有这样做。我不熟悉 Mono,但我想它不应该使用文档根目录中的路径?
- 你的 webdav 内容是否应该使用
<Directory>
块而不是<Location>
?
在 URL 路径映射到目录后,您不希望有多个定义<Directory /var/www/myservice/backend>
。它们目前看起来是等效的,但随着时间的推移可能会出现分歧并造成混乱。
我不确定您的请求发生了什么,但您确定这两行日志匹配吗?一方面您收到错误,另一方面您收到状态200
。考虑使用 curl 而不是浏览器,这样您就可以避免触发子请求。
我怀疑,当你以某种方式整理好配置时,你的问题就会消失。也许你会一路理解它,也许它会消失,也许它从一开始就不存在(例如,它是来自不同请求的混乱日志条目的产物)。如果不是这些原因,那么错误可能来自你的 mono 应用程序吗?