Site Tools


software:nginx:webdav

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
software:nginx:webdav [2015/06/17 12:34]
– [Конфиг nginx для WebDav] root
software:nginx:webdav [2022/02/05 04:30] (current)
root
Line 5: Line 5:
 SAMB-у в принципе тоже без VPN можно пробросить, но это из области поиска приключений с последствиями.\\ SAMB-у в принципе тоже без VPN можно пробросить, но это из области поиска приключений с последствиями.\\
  
-Nginx в базовом функционале имеет не полную поддержку WebDav: PUT DELETE MKCOL COPY MOVE.\\ +Nginx в базовом функционале имеет не полную поддержку [[http://nginx.org/ru/docs/http/ngx_http_dav_module.html|Dav]]: PUT DELETE MKCOL COPY MOVE.\\ 
-Расширить его ещё двумя: PROPFIND и OPTIONS можно с помощью плагина: [[https://github.com/arut/nginx-dav-ext-module|dav-ext]]\\+Расширить его ещё двумя: PROPFIND и OPTIONS можно с помощью модуля: [[https://github.com/arut/nginx-dav-ext-module|dav-ext]]\\
  
  
-Для работы потребуется Nginx собранный с поддержкой WebDav, dav-ext модулем и rewrite.\\+Для работы потребуется Nginx собранный с поддержкой [[http://nginx.org/ru/docs/http/ngx_http_dav_module.html|Dav]][[https://github.com/arut/nginx-dav-ext-module|dav-ext]], [[http://nginx.org/ru/docs/http/ngx_http_rewrite_module.html|rewrite]] и [[http://wiki.nginx.org/HttpHeadersMoreModule|headers_more]].\\
 <code>[x] HTTP_DAV              Enable http_webdav module <code>[x] HTTP_DAV              Enable http_webdav module
 [x] HTTP_DAV_EXT          3rd party webdav_ext module [x] HTTP_DAV_EXT          3rd party webdav_ext module
-[x] HTTP_REWRITE          Enable http_rewrite module</code>+[x] HTTP_REWRITE          Enable http_rewrite module 
 +[x] HEADERS_MORE          3rd party headers_more module</code>
  
  
  
 ===== Проблема 1 - Майкрософт нарушает стандарты и свои обещания ===== ===== Проблема 1 - Майкрософт нарушает стандарты и свои обещания =====
-{{:ru:software:nginx:webdav1.png|}}+{{:software:nginx:webdav1.png|}}
  
 Перед тем как создать файл WebDav клиент проверяет наличие файла посылая запрос: Перед тем как создать файл WebDav клиент проверяет наличие файла посылая запрос:
Line 92: Line 93:
  
 ===== Проблема 2 - PROPPATCH отсутствует в nginx ===== ===== Проблема 2 - PROPPATCH отсутствует в nginx =====
-{{:ru:software:nginx:webdav2.png|}} \\+{{:software:nginx:webdav2.png|}} \\
 WebDav от мс очень хочет метод PROPPATCH, которого в Nginx и расширениях нет. Совсем нет.\\ WebDav от мс очень хочет метод PROPPATCH, которого в Nginx и расширениях нет. Совсем нет.\\
 Я рассматривал два варианта решения:\\ Я рассматривал два варианта решения:\\
Line 136: Line 137:
  
 ===== Проблема 3 - создание папок ===== ===== Проблема 3 - создание папок =====
-{{:ru:software:nginx:webdav3.png|}} \\+{{:software:nginx:webdav3.png|}} \\
 См п1 :) См п1 :)
  
Line 182: Line 183:
 **Фикс 3**: **Фикс 3**:
 <code>if ($request_method = MKCOL) { # Microsoft specific handle: add trailing slash. <code>if ($request_method = MKCOL) { # Microsoft specific handle: add trailing slash.
- rewrite ^(.*[^/])$ $1/;+ rewrite ^(.*[^/])$ $1/ break;
 }</code> }</code>
 Вот для этого пустяка и потребовался REWRITE плагин.\\ Вот для этого пустяка и потребовался REWRITE плагин.\\
Line 189: Line 190:
 ===== Проблема 4 - удаление папок ===== ===== Проблема 4 - удаление папок =====
 Ноги тут те же что и в п3: отсутствие слеша на конце урла.\\ Ноги тут те же что и в п3: отсутствие слеша на конце урла.\\
-Однако я столкнулся с тем, что nginx тоже ведёт себя несколько странно.\\ +Однако я столкнулся с тем, что nginx тоже ведёт себя несколько странно: если слеш на конце отсутствует, то nginx считает что его просят удалить файл, и получает ошибку: 21: Is a directory при попытке удалить.\\ 
-1. Если слеш на конце отсутствует, то nginx считает что его просят удалить файл, и получает ошибку: 21: Is a directory при попытке удалить.\\ +
-2. Если слеш добавить то папку он почему то так и не удаляет. Подозреваю тут где то баг самого nginx.\\+
  
 **Фикс 4**: **Фикс 4**:
Line 204: Line 204:
  open_file_cache off;  open_file_cache off;
  if (-d $webdav_root/$uri) { # Add trailing slash to dirs.  if (-d $webdav_root/$uri) { # Add trailing slash to dirs.
- rewrite ^(.*[^/])$ $1/;+ rewrite ^(.*[^/])$ $1/ break;
  }  }
  root $webdav_root;  root $webdav_root;
Line 210: Line 210:
 }</code> }</code>
 Если кратко, то переносим обработку DELETE в отдельный локейшин (процедуру), дальше проверяем, если удаляется папка то добавляем слеш.\\ Если кратко, то переносим обработку DELETE в отдельный локейшин (процедуру), дальше проверяем, если удаляется папка то добавляем слеш.\\
 +
 +
 +===== Проблема 5 - копирование и переименование =====
 +Ноги тут те же что и в п4: отсутствие слеша на конце урла и в Destination заголовке.\\
 +Для решения проблемы с добавлением "/" в заголовок Destinaton нам потребуется модуль headers_more.\\
 +
 +**Фикс 6**:
 +<code>error_page 597 = @copy_move_handler;
 +if ($request_method = COPY) {
 + return 597;
 +}
 +if ($request_method = MOVE) {
 + return 597;
 +}
 +
 +location @copy_move_handler {
 + internal;
 +
 + open_file_cache off;
 + if (-d $webdav_root/$uri) { # Add trailing slash to dirs.
 + more_set_input_headers 'Destination: $http_destination/';
 + rewrite ^(.*[^/])$ $1/ break;
 + }
 + root $webdav_root;
 + dav_methods COPY MOVE;
 +}</code>
 +
 +
 +
 +===== Проблема 6 - OPTIONS корня =====
 +Клиент запрашивает опции не у той папки которую мы хотим чтобы он подключил а у корня сервера.\\
 +
 +**Фикс 6**:
 +<code>location / {
 + if ($request_method = OPTIONS) {
 + add_header Allow 'OPTIONS, GET, HEAD, POST, PUT, MKCOL, MOVE, COPY, DELETE, PROPFIND, PROPPATCH';
 + add_header DAV '1, 2';
 + return 200;
 + }
 +}
 +</code>
 +Возвращаем ему статический список.\\
 +Можно было просто разрешить: dav_ext_methods OPTIONS;\\
 +
 +
 +===== Проблема 7 - виндовый клиент не может подключится =====
 +Соединение происходит но в логах nginx ничего нет, а клиент сообщает об ошибке.\\
 +В логах с включённым дебагом ssl видно что рукопожатие не проходит.\\
 +Проблема у меня проявилась не так давно, после обновления OpenSSL.\\
 +При этом IE и другие браузеры могут авторизоваться по этому URL и отобразить листинг директории.\\
 +
 +**Фикс 7**:
 +Заменить OpenSSL на LibreSSL и пересобрать nginx.
 +Возможно OpenSSL уже исправили.
  
  
Line 223: Line 277:
 set $webdav_root "/mnt/WebDav_folder"; set $webdav_root "/mnt/WebDav_folder";
 location ^~ /Family { location ^~ /Family {
 + if ($ssl_protocol = "") { # Block non ssl/tls connections.
 + add_header Strict-Transport-Security 'max-age=600';
 + return 403;
 + }
 + auth_basic "Private site";
 + auth_basic_user_file /usr/local/etc/nginx/secure/authbasic.htpasswd;
  
- root $webdav_root; + root $webdav_root; 
- error_page 599 = @propfind_handler; + error_page 599 = @propfind_handler; 
- error_page 598 = @delete_handler; + error_page 598 = @delete_handler; 
- chunked_transfer_encoding on+ error_page 597 = @copy_move_handler
- open_file_cache off; + open_file_cache off; 
- client_max_body_size 50m+ client_max_body_size 50m;
- add_header Allow 'OPTIONS, GET, HEAD, DELETE, PUT, COPY, MOVE, PROPFIND';+
  
  if ($request_method = PROPFIND) {  if ($request_method = PROPFIND) {
Line 240: Line 299:
  }  }
  if ($request_method = MKCOL) { # Microsoft specific handle: add trailing slash.  if ($request_method = MKCOL) { # Microsoft specific handle: add trailing slash.
- rewrite ^(.*[^/])$ $1/;+ rewrite ^(.*[^/])$ $1/ break;
  }  }
  if ($request_method = DELETE) {  if ($request_method = DELETE) {
  return 598;  return 598;
 + }
 + if ($request_method = COPY) {
 + return 597;
 + }
 + if ($request_method = MOVE) {
 + return 597;
  }  }
  
- dav_methods PUT MKCOL COPY MOVE# + dav_methods PUT MKCOL; 
- dav_ext_methods OPTIONS;+ dav_ext_methods OPTIONS;
  create_full_put_path on;  create_full_put_path on;
  min_delete_depth 0;  min_delete_depth 0;
- dav_access user:rw group:rw all:rw;+ dav_access user:rw group:rw all:rw
 + 
 + autoindex on; 
 + autoindex_exact_size on; 
 + autoindex_localtime on;
 } }
 location @propfind_handler { location @propfind_handler {
  internal;  internal;
 +
 + auth_basic "Private site";
 + auth_basic_user_file /usr/local/etc/nginx/secure/authbasic.htpasswd;
  
  open_file_cache off;  open_file_cache off;
Line 259: Line 331:
  return 404;  return 404;
  }  }
- root $webdav_root; + root $webdav_root; 
- dav_ext_methods PROPFIND;+ dav_ext_methods PROPFIND;
 } }
 location @delete_handler { location @delete_handler {
  internal;  internal;
 +
 + auth_basic "Private site";
 + auth_basic_user_file /usr/local/etc/nginx/secure/authbasic.htpasswd;
  
  open_file_cache off;  open_file_cache off;
- if (-d $webdav_root/$uri) { # Add trailing slash to dirs. + if (-d $webdav_root/$uri) { # Microsoft specific handle: Add trailing slash to dirs. 
- rewrite ^(.*[^/])$ $1/;+ rewrite ^(.*[^/])$ $1/ break;
  }  }
- root $webdav_root; + root $webdav_root; 
- dav_methods DELETE;+ dav_methods DELETE
 +
 +location @copy_move_handler { 
 + internal; 
 + 
 + auth_basic "Private site"; 
 + auth_basic_user_file /usr/local/etc/nginx/secure/authbasic.htpasswd; 
 + 
 + open_file_cache off; 
 + if (-d $webdav_root/$uri) { # Microsoft specific handle: Add trailing slash to dirs. 
 + more_set_input_headers 'Destination: $http_destination/'; 
 + rewrite ^(.*[^/])$ $1/ break; 
 +
 + root $webdav_root; 
 + dav_methods COPY MOVE;
 } }
 location / { location / {
  if ($request_method = OPTIONS) {  if ($request_method = OPTIONS) {
- add_header Allow 'OPTIONS, GET, HEAD, POST, PUT, MKCOL, DELETE, PROPFIND, PROPPATCH';+ add_header Allow 'OPTIONS, GET, HEAD, POST, PUT, MKCOL, MOVE, COPY, DELETE, PROPFIND, PROPPATCH';
  add_header DAV '1, 2';  add_header DAV '1, 2';
  return 200;  return 200;
Line 282: Line 371:
  
 open_file_cache off; - нужно потому что мы меняем файлы, если кеширование включено то можно будет долго гадать почему не видно файлы которые мы только что закинули на сервер.\\ open_file_cache off; - нужно потому что мы меняем файлы, если кеширование включено то можно будет долго гадать почему не видно файлы которые мы только что закинули на сервер.\\
 +Также в самом начале локейшена есть требование использовать SSL и если SSL используется то запрашивается BASIC авторизация.
 +==== Важно ====
 +  - set $webdav_root "/mnt/WebDav_folder"; - **полный путь** на диске к папке которую мы расшариваем. Папка должна существовать и на неё должны быть выставлены права доступа которые позволят nginx получить доступ к содержимому, читать и записывать файлы.
 +  - в папке "/mnt/WebDav_folder" должна существовать папка Family
 +  - location ^~ **/Family** - означает что клиент должен использовать URL: https://SERVER_ADDRESS**/Family**
 +  - директивы **auth_basic** и **auth_basic_user_file** должны быть в каждом **location** который осуществляет обработку запросов, см [[https://github.com/dgraziotin/docker-nginx-webdav-nononsense/issues/15|DELETE requests work unauthenticated]]
  
  
Line 308: Line 403:
  
  
 +===== Полезное =====
 +  * Дальнейшая разработка решения происходит тут: [[https://github.com/dgraziotin/docker-nginx-webdav-nononsense|docker-nginx-webdav-nononsense]] - настоятельно рекомендую хотя бы посмотреть все решения которые там применены
 +  * Патч [[https://github.com/arut/nginx-dav-ext-module/pull/56|Fix PROPFIND fail with 500 on simlinks to non exist file/dir.]]
 +
 +
 +
 +{{tag>software howto windows net nginx WebDAV}}
software/nginx/webdav.1434544454.txt.gz · Last modified: 2015/06/17 12:34 by root