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 13:14]
– [Важно] 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 212: Line 212:
  
  
-===== Проблема 5 - OPTIONS корня =====+===== Проблема 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 корня =====
 Клиент запрашивает опции не у той папки которую мы хотим чтобы он подключил а у корня сервера.\\ Клиент запрашивает опции не у той папки которую мы хотим чтобы он подключил а у корня сервера.\\
  
-**Фикс 5**:+**Фикс 6**:
 <code>location / { <code>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 228: Line 255:
  
  
-===== Проблема - виндовый клиент не может подключится =====+===== Проблема - виндовый клиент не может подключится =====
 Соединение происходит но в логах nginx ничего нет, а клиент сообщает об ошибке.\\ Соединение происходит но в логах nginx ничего нет, а клиент сообщает об ошибке.\\
 В логах с включённым дебагом ssl видно что рукопожатие не проходит.\\ В логах с включённым дебагом ssl видно что рукопожатие не проходит.\\
Line 234: Line 261:
 При этом IE и другие браузеры могут авторизоваться по этому URL и отобразить листинг директории.\\ При этом IE и другие браузеры могут авторизоваться по этому URL и отобразить листинг директории.\\
  
-**Фикс 6**:+**Фикс 7**:
 Заменить OpenSSL на LibreSSL и пересобрать nginx. Заменить OpenSSL на LibreSSL и пересобрать nginx.
 Возможно OpenSSL уже исправили. Возможно OpenSSL уже исправили.
Line 250: 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 267: 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 286: 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 309: Line 371:
  
 open_file_cache off; - нужно потому что мы меняем файлы, если кеширование включено то можно будет долго гадать почему не видно файлы которые мы только что закинули на сервер.\\ open_file_cache off; - нужно потому что мы меняем файлы, если кеширование включено то можно будет долго гадать почему не видно файлы которые мы только что закинули на сервер.\\
 +Также в самом начале локейшена есть требование использовать SSL и если SSL используется то запрашивается BASIC авторизация.
 ==== Важно ==== ==== Важно ====
-  - set $webdav_root "/mnt/WebDav_folder"; - **полный путь** на диске к папке которую мы расшариваем.+  - set $webdav_root "/mnt/WebDav_folder"; - **полный путь** на диске к папке которую мы расшариваем. Папка должна существовать и на неё должны быть выставлены права доступа которые позволят nginx получить доступ к содержимому, читать и записывать файлы. 
 +  - в папке "/mnt/WebDav_folder" должна существовать папка Family
   - location ^~ **/Family** - означает что клиент должен использовать URL: https://SERVER_ADDRESS**/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 339: 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.1434546850.txt.gz · Last modified: 2015/06/17 13:14 by root