使用 apache 和 rewrite 模块以及 webdav 进行两次重写

使用 apache 和 rewrite 模块以及 webdav 进行两次重写

我正在尝试设置一个 WebDAV 服务器,该服务器使用用户名重定向到私有 DAV 目录。每个私有目录中还有一个名为共享文件夹

这个想法是,当用户登录时,他首先会被重定向到他的私人目录。使用重写模块,URL 中不会显示任何路径,只有主机名,这可以防止用户进入另一个私人目录。当用户打开名为共享文件夹,mod_rewrite 将在匹配的 RewriteCond 文件夹名称上触发,并重定向到 RewriteMap 中指定的相应共享文件夹。

我的虚拟主机配置:

LoadModule dbd_module modules/mod_dbd.so
LoadModule authn_dbd_module modules/mod_authn_dbd.so
DBDriver mysql
DBDParams "host=db.example.com user=username pass=password dbname=webdav"

<VirtualHost *:80>
    Servername webdav.example.com

    DocumentRoot /var/www

    Options +FollowSymlinks
    RewriteLog "/var/log/httpd/rewrite.log"
    RewriteLogLevel 5
    RewriteEngine on

    RewriteRule ^(.*) /webdav/%{LA-U:REMOTE_USER}$1

    RewriteMap usergroup txt:/etc/httpd/usersingroups
    RewriteCond %{REQUEST_URI} ^/SharedFolder/ [NC]
    RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}} [L]

    <Directory "/var/www">
        DAV on
        Options +Indexes
                AuthName "example.com"
                AuthType Digest
                AuthDigestDomain /

                AuthDigestProvider dbd
                AuthDBDUserRealmQuery "SELECT digest FROM users WHERE username = %s AND unix_timestamp() < (ts+900) "

                Require valid-user
    </Directory>
</VirtualHost>

的内容重写映射如下:

fred sales/indoor/
bob sales/outdoor/
alice production/warehouse

文件系统的布局都在文档根目录/var/www。/var/www 中有两个文件夹。一个名为 /var/www/webdav,其中包含所有私有目录。另一个文件夹名为 /var/www/sharedfolders,其中包含属于不同组的目录。通过在重写映射我可以确定用户中显示哪个组目录共享文件夹

我面临的问题是,重定向到 SharedFolder 无法正常工作。用户私有目录中的每个文件或文件夹都可以访问和使用。除了共享文件夹。当我打开它共享文件夹,我可以看到它的内容(一个 txt 文件和一个文件夹),但我无法打开该文件(我的桌面上就是这么显示的)。重写日志显示:

[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) rewrite '/webdav/fred/SharedFolder/Readme.txt/' -> '/sharedfolders/sales/indoor/'
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) local path result: /sharedfolders/sales/indoor/
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (2) prefixed with document_root to /var/www/sharedfolders/sales/indoor/
[webdav.example.com/sid#8ffd998][rid#9043870/initial] (1) go-ahead with /var/www/sharedfolders/sales/indoor/ [OK]

当我阅读重写日志时,它告诉我该文件(Readme.txt)最终没有被重写而无法打开。

另一个问题是打开共享文件夹.我不断看到的内容共享文件夹在其内部。来自 WebDAV 磁盘:SharedFolder/folder a/folder a/folder a/folder a等等。在每个“文件夹 a”内,我还会看到文件“Readme.txt”。以下是重写日志对此的说明:

[webdav.example.com/sid#8ffd998][rid#905d898/initial] (2) rewrite '/SharedFolder/bla/bla/bla/' -> '/webdav/fred/SharedFolder/bla/bla/bla/'
[webdav.example.com/sid#8ffd998][rid#904b850/subreq] (2) init rewrite engine with requested uri /webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) init rewrite engine with requested uri /webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) rewrite '/webdav/fred/SharedFolder/bla/bla/bla/' -> '/webdav//webdav/fred/SharedFolder/bla/bla/bla/'
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) local path result: /webdav//webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (2) prefixed with document_root to /var/www/webdav/webdav/fred/SharedFolder/bla/bla/bla/
[webdav.example.com/sid#8ffd998][rid#904d858/subreq] (1) go-ahead with /var/www/webdav/webdav/fred/SharedFolder/bla/bla/bla/ [OK]

我相信我已经向前迈出了几步,但还不够:-)

一些背景信息:我最初尝试使用符号链接通过 SharedFolder 实现相同的目标,但是与启用的 WebDAV 结合似乎是不可能的(我无法使其工作)。

操作系统:RHEL5.8 Apache 版本:2.2.3

提前致谢

更新 根据 @Jenny_D 的建议,我做了一些更改。我已在code本问题的部分中更新了我当前的配置。我已更改的内容:

  1. 删除了末尾的 $1RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}}
  2. 添加[L]到同一行的末尾。
  3. 将其更改<Directory "/var/www/webdav"><Directory "/var/www">,以便重写路径 (/var/www/sharedfolders) 也支持 DAV。

最后一个变化(第 3 个变化)带来了很大的变化:我现在可以看到共享文件夹我之前放置过(没有 WebDAV)。

答案1

问题在于:

RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}}$1

您要做的是捕获 URL 中使用的目录,将其存储在 $1 中,然后将 $1 附加到行尾。如果您不知道附加的 URL 部分是什么,只需删除末尾的 $1 即可。

要在共享文件夹规则后停止重写,请在末尾添加标志 [L]。

因此规则最终应如下所示:

RewriteRule ^(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}} [L]

答案2

我找到了一个可行的配置。我现在使用以下内容:

LoadModule dbd_module modules/mod_dbd.so
LoadModule authn_dbd_module modules/mod_authn_dbd.so
DBDriver mysql
DBDParams "host=db.example.com user=username pass=password dbname=webdav"

<VirtualHost *:80>

Servername webdav.example.com

DocumentRoot /var/www

Options +FollowSymlinks
RewriteLog "/var/log/httpd/rewrite.log"
RewriteLogLevel 2
RewriteEngine on

RewriteMap usergroup txt:/etc/httpd/usersingroups
RewriteCond %{REQUEST_URI} !^/SharedFolder [NC]
RewriteRule .? - [S=2]
RewriteRule ^/SharedFolder/(.*)$ /sharedfolders/${usergroup:%{LA-U:REMOTE_USER}}$1
RewriteRule .? - [S=2]

RewriteCond %{REQUEST_URI} !^/SharedFolder [NC]
RewriteRule ^(.*)$ /webdav/%{LA-U:REMOTE_USER}$1

<Directory "/var/www">
    DAV on
    Options +Indexes
            AuthName "example.com"
            AuthType Digest
            AuthDigestDomain /

            AuthDigestProvider dbd
            AuthDBDUserRealmQuery "SELECT digest FROM users WHERE username = %s AND unix_timestamp() < (ts+900) "

            Require valid-user
</Directory>
</VirtualHost>

我创建了一个 if-then-else 结构,如果满足某个条件,则跳过相应行。除此之外,我还制作了重写规则为了共享文件夹更具体一点。这基本上奏效了。之后,我被流量管理器(反向代理)搞得一团糟,它把 SSL 卸载到这个主机(因此:80<VirtualHost *:80>。查看、上传和删除都很好,除了重命名。事实证明,当您在 WebDAV 中重命名文件或文件夹时,全部的上传或删除文件或文件夹时,会发送目标标头,而不仅仅是路径。因此,在执行某种形式的 SSL 卸载时,请记住这一点。

相关内容