Вопрос или проблема
Я застрял уже два дня, потому что не могу правильно настроить мой WebDAV сервер в Docker, чтобы пользователи могли получить доступ к хранимым данным.
Контекст в том, что у меня есть сервер Nginx, работающий как сервер WebDAV в Docker. У меня есть Traefik с Authelia в качестве промежуточного программного обеспечения, который использует мой LDAP для аутентификации пользователей перед перенаправлением их на запрашиваемый сервис.
Дело в том, что корневая директория WebDAV подключена в виде тома. Насколько я понимаю, это файловая система, которая управляет правами на файлы в томах, но здесь у меня проблема. Пользователь на моем хосте – bob, и он владеет папкой, которая монтируется как том, но я не знаю, что делать в контейнере Docker, чтобы каждый пользователь, подключенный к серверу WebDAV, имел root-доступ (с точки зрения хоста) для доступа к папке. Я пытался указать USER root в моем Dockerfile, но это не работает. Есть ли способ предоставить пользователю из моего LDAP права на папку?
Я получаю эту ошибку, когда пытаюсь добавить файл в папку из Windows:
172.18.0.5 - toto [04/Feb/2025:21:56:13 +0000] "PROPFIND / HTTP/1.1" 207 424 "-" "Microsoft-WebDAV-MiniRedir/10.0.26100"
2025/02/04 21:56:13 [crit] 20#20: *3 open() "/media/data/Database - Copie.kdbx.0000000006" failed (13: Permission denied), client: 172.18.0.5, server: , request: "PUT /Database%20-%20Copie.kdbx HTTP/1.1", host: "storage.example.com"
172.18.0.5 - toto [04/Feb/2025:21:56:13 +0000] "PUT /Database%20-%20Copie.kdbx HTTP/1.1" 500 177 "-" "Microsoft-WebDAV-MiniRedir/10.0.26100"
Вот мой Dockerfile и конфигурация Nginx. Если нужно больше, я с удовольствием предоставлю дополнительную информацию 🙂
FROM nginx:1.22.1
# Установка необходимых зависимостей
RUN apt-get update \
&& apt-get install -y apt-utils \
&& apt-get install -y nginx-extras apache2-utils \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Удаление стандартных сайтов nginx
RUN rm -rf /etc/nginx/sites-enabled/*
# Настройка директории данных
RUN mkdir -p "/media/data" &&\
chown -R root:root /media/data/ &&\
chmod -R 755 /media/data/
# Определить точку входа и запустить nginx от имени root
USER root
# Определить точку входа и запустить nginx
CMD ["nginx", "-g", "daemon off;"]
server {
listen 80;
access_log /dev/stdout;
error_log /dev/stdout info;
client_max_body_size 100M;
location / {
create_full_put_path on;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS;
dav_access user:rw group:rw all:rw;
root /media/data/;
}
}
После множества неисправностей, я почти у цели! Я изменил мой Dockerfile, чтобы назначить www-data (пользователь nginx) UID владельца тома. Однако я столкнулся с еще одной ошибкой. На моем ПК я пытаюсь создать новый документ, чтобы проверить разрешение на запись, и получаю ошибку 405. Я добавил метод LOCK и UNLOCK в мой файл конфигурации, но всё еще получаю ошибку. Тем не менее, файлы создаются, так что, предположительно, проблема с разрешениями файлов решена. Однако я не могу переименовывать файлы, так как получаю ошибку 400 на методе MOVE.
Вот мои изменения и новые ошибки:
server {
listen 80;
access_log /dev/stdout;
error_log /dev/stdout info;
client_max_body_size 100M;
location / {
create_full_put_path on;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK;
dav_access user:rw group:rw all:rw;
root /media/data/;
}
}
FROM nginx:1.22.1
# Установка необходимых зависимостей
RUN apt-get update \
&& apt-get install -y apt-utils \
&& apt-get install -y nginx-extras apache2-utils \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Удаление стандартных сайтов nginx
RUN rm -rf /etc/nginx/sites-enabled/*
# Изменение www-data на использование UID 1000
RUN usermod -u 1000 www-data &&\
groupmod -g 1000 www-data
# Настройка директории данных
RUN mkdir -p /media/data &&\
chown -R www-data:www-data /media/data/ &&\
chmod -R 775 /media/data/
# Определить точку входа и запустить nginx от имени root
USER root
# Определить точку входа и запустить nginx
CMD ["nginx", "-g", "daemon off;"]
172.18.0.7 - toto [15/Feb/2025:17:01:11 +0000] "MOVE /Nouveau%20Document%20texte.txt HTTP/1.1" 400 157 "-" "Microsoft-WebDAV-MiniRedir/10.0.26100"
172.18.0.7 - toto [15/Feb/2025:17:01:18 +0000] "PROPFIND /Nouveau%20Document%20texte%20(6).txt HTTP/1.1" 404 125 "-" "Microsoft-WebDAV-MiniRedir/10.0.26100"
172.18.0.7 - toto [15/Feb/2025:17:01:18 +0000] "PROPFIND / HTTP/1.1" 207 424 "-" "Microsoft-WebDAV-MiniRedir/10.0.26100"
172.18.0.7 - toto [15/Feb/2025:17:01:18 +0000] "PUT /Nouveau%20Document%20texte%20(6).txt HTTP/1.1" 201 0 "-" "Microsoft-WebDAV-MiniRedir/10.0.26100"
172.18.0.7 - toto [15/Feb/2025:17:01:18 +0000] "LOCK /Nouveau%20Document%20texte%20(6).txt HTTP/1.1" 405 157 "-" "Microsoft-WebDAV-MiniRedir/10.0.26100"
EDIT:
Мне удалось решить оставшиеся проблемы. По поводу проблемы с блокировкой, см. здесь: https://github.com/arut/nginx-dav-ext-module
Для ошибки 400 с MOVE решение заключается в переписывании заголовка назначения.
Итоговая конфигурация ниже:
server {
listen 80;
access_log /dev/stdout;
error_log /dev/stdout info;
client_max_body_size 100M;
location / {
create_full_put_path on;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
charset utf-8;
# Убрать хост и сделать относительным путь для заголовка 'Destination'
set $destination $http_destination;
# Проверить, является ли заголовок Destination полным URL, затем убрать хост и сделать относительным
if ($destination ~* "^https?://[^/]+(.*)$") {
# Переписать заголовок Destination только на относительный путь
set $destination /$1;
more_set_input_headers "Destination: $destination"; # Переписать заголовок Destination
}
# модуль dav
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_access user:rw group:rw all:rw;
# ngx_http_dav_ext_module
dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK;
# Использовать зону блокировки, определенную в nginx.conf
dav_ext_lock zone=webdav_locks;
# корневая директория
root /media/data/;
}
}
Ответ или решение
Запуск WebDAV сервера на Docker с использованием монтированных томов может стать сложной задачей, особенно если на пути возникают ошибки, связанные с правами доступа к файлам. Рассмотрим, как правильно настроить эту систему, учитывая предоставленное описание и возможные ошибки.
Теория
WebDAV – это протокол, который предоставляет возможность пользователям управлять файлами и папками на веб-серверах, в более расширенной форме, чем это позволяет стандартный протокол HTTP. Проблема, связанная с правами доступа в среде Docker, часто связана с разницей в механизмах управления правами доступа на хосте и внутри контейнера. Каждый том, используемый в Docker, имеет свои собственные настройки владельца и группы, которые могут не совпадать с теми, что ожидает сервер, работающий внутри контейнера.
Когда вы монтируете директорию хоста в контейнер Docker, важно учесть, что пользовательские и групповая метаданные не транслируются автоматически в Docker-контейнер. Это может привести к ошибкам при попытках доступа к файлам с разных уровней разрешений.
Пример
В предоставленной конфигурации Nginx используется как сервер WebDAV, и вы уже сделали несколько шагов для решения проблемы с правами доступа, изменив UID пользователя www-data
таким образом, чтобы он совпадал с владельцем монтированной директории на хосте. Это важный шаг, который помогает синхронизировать права на доступ к файлам между хостом и контейнером.
Также важно обратить внимание на использование методов, таких как LOCK и UNLOCK, которые необходимы для полноценной работы WebDAV, чтобы обеспечить возможность редактирования и перемещения файлов.
Применение
-
Права доступа и пользователи: После определения общего механизма работы, следующим шагом является корректировка самой конфигурации и проверки привязок пользователей. Команда
usermod
вDockerfile
была использована для переназначения UID/GID, и это уже в значительной степени решило проблемы с доступом к файлам из WebDAV. -
Конфигурация Nginx: Убедитесь, что в вашей Nginx-конфигурации поддерживаются все необходимые методы WebDAV, такие как PUT, DELETE, MKCOL, COPY и MOVE, которые уже добавлены в вашей конфигурации. Это позволит полноценно использовать функционал WebDAV.
-
Проблемы с мутирующими операциями: Добавление поддержки PROPFIND, OPTIONS, LOCK и UNLOCK в
dav_ext_methods
также помогает устранить ошибки 405 и другие, возникающие при попытке работы с этими методами. Увеличение логирования Nginx поможет более подробно изучить проблемы и понять их происхождение. -
Проблемы с заголовками: Как вы уже отметили, проблема с MOVE может быть связана с заголовками. Переписывание заголовка
Destination
представляет собой один из подходов к решению этой проблемы. Это особенно критично, когда клиент, такой как Microsoft-WebDAV, может отправлять полный URL, даже если это не требуется сервером. -
Логрование: Реализация хорошего логирования доступа и ошибок в Nginx позволит более точно отследить, какие запросы вызывают ошибки, и какое состояние сервера наблюдается в момент возникновения проблем. Это можно сделать с помощью конфигурации access_log и error_log.
-
Тестирование и Развертывание: После того как все конфигурационные изменения внесены, важно тестировать систему с различными пользователями WebDAV, моделируя сценарии, такие как создание, удаление, перемещение и изменение файлов. Это поможет выявить возможные остальные узкие места.
Таким образом, успешная настройка WebDAV на Docker с монтированными томами требует продуманного подхода к конфигурации прав доступа и начальных мер по согласованию UID/GID между хостом и контейнером. Делая это, можно устранить многие из проблем, которые могут возникнуть при доступе к файлам через WebDAV, обеспечивая при этом эффективную и безопасную работу.