Multiuser

是否有可用於 linux 的多使用者 webdav 伺服器?

  • September 26, 2021

我希望完全停用我的 SMBA 服務並用 WebDav 服務替換它。

到目前為止,所有Google搜尋都指向我使用 Apache / Webdav。這接近我所需要的,但據我所知,它要求 Apache 能夠訪問我使用者的文件,甚至更糟;如果它創建一個文件,則新文件將歸 Apache(而不是使用者)所有。 請注意,具有正確 Unix 所有權和權限的文件是必需的,因為某些使用者具有直接 SSH 訪問權限。

所以我很簡單地尋找一種方法來使 Apache / Webdav 與多使用者“正確”工作(即在嘗試提供文件之前將 unix 使用者更改為登錄使用者)或找到一個完整的替代 Apache /網路影片。

到目前為止,搜尋還沒有出現任何結果。

找了好久,就是沒找到。有許多多使用者伺服器,但我找不到以系統使用者身份執行的伺服器。

所以我自己寫了一個。這僅在我自己可以測試的範圍內進行測試。但是對於它的價值,原始碼在這裡:

https://github.com/couling/WebDAV-Daemon

如果你有使用者名和/或 uid,你可以使用 nginx + lua + luarocks ljsyscall

在 debian 系統上,配置為:

apt-get -y install nginx libnginx-mod-http-dav-ext libnginx-mod-http-lua luarocks
luarocks install ljsyscall

而nginx配置如下:

user  root;
worker_processes  1;

load_module modules/ngx_http_dav_ext_module.so;
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_lua_module.so;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
   worker_connections  1024;
}


http {
   sendfile        on;
   keepalive_timeout  65;
   gzip  on;

   server {
       listen      80;
       listen [::]:80;

       location / {
           rewrite ^ http://$host$request_uri?; # permanent;
       }
   }

   server {
       listen      443           ssl http2;
       listen [::]:443           ssl http2;

       ssl                       on;    
       # [ SSL Sections Omitted ]

       # Set the maximum size of uploads
       client_max_body_size 200m;

       # Default is 60, May need to be increased for very large uploads
       client_body_timeout 120s; 

       # other configs
       location /webdav/ {
           autoindex              on;
           alias                  /data/www/;
           client_body_temp_path  /data/client_temp;

           dav_methods PUT DELETE MKCOL COPY MOVE;
           dav_ext_methods PROPFIND OPTIONS;

           create_full_put_path   on;
           # Not sure if you want to tweak this
           # dav_access             group:rw  all:r;

           # Let's assume you have an auth subrequest that can set X-UID
           auth_request  /auth
           auth_request_set $auth_status $upstream_status;
           auth_request_set $saved_remote_user $upstream_http_REMOTE_USER;
           auth_request_set $saved_remote_uid $upstream_http_X_UID;

           # Per-Request Impersonation
           access_by_lua_block {
               # Boilerplate because ljsyscall doesn't have setfsuid implemented directly
               local syscall_api = require 'syscall'
               local ffi = require "ffi"
               local nr = require("syscall.linux.nr")
               local sys = nr.SYS
               local uint = ffi.typeof("unsigned int")
               local syscall_long = ffi.C.syscall -- returns long
               local function syscall(...) return tonumber(syscall_long(...)) end 
               local function setfsuid(id) return syscall(sys.setfsuid, uint(id)) end
               -- If you only have ngx.var.saved_remote_user, install luaposix and do this ...
               -- local pwd = require 'posix.pwd'
               -- local new_uid = pwd.getpwnam(ngx.saved_remote_user).pw_uid
               local new_uid = tonumber(ngx.var.saved_remote_uid)
               ngx.log(ngx.NOTICE, "[Impersonating User #" .. new_uid .. "]")
               local previous = setfsuid(new_uid)
               local actual = setfsuid(new_uid)
               if actual ~= new_uid then
                   ngx.log(ngx.CRIT, "Unable to impersonate users")
                   ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
               end
           }
       }

       location = /auth {
           internal;
           proxy_pass              http://localhost:8080/auth;
           proxy_pass_request_body off;
           proxy_set_header        Content-Length "";
           proxy_set_header        X-Original-URI $request_uri;
           proxy_set_header        X-Original-Method $request_method;
       }
   }
}

這將對 nginx worker 服務的每個請求執行 setfsuid。不幸的是,您似乎必須以 root 身份執行 nginx 才能使其目前正常工作。我相信它可以與不同的使用者一起工作,前提是程序以 root 身份啟動,刪除到不同的使用者,保留 CAP_SETUID(請參閱文件capsh),並且usernginx 配置文件中不存在該指令。

您可能還需要設置組 ID。

請參閱http://man7.org/linux/man-pages/man7/capabilities.7.html中的“使用者 ID 更改對功能的影響”

引用自:https://unix.stackexchange.com/questions/123001