В реалиях сегодняшнего мира, файлы хочется хранить там, где они будут доступны для всех устройств, желательно с возможностью подключать это пространство как диск или как облачную папку. Конечно есть Dropbox и другие сервисы, но как на счет чего-то своего? Ну, тогда есть Seafile или OwnCloud, но и то и другое требует и базы данных и детальной настройки, плюс это все работает на разных языках и прочее. Долго. А хочется просто и со вкусом. Тогда-то к нам на помощь и приходит WebDAV. Не так давно я «пересел» на MacOS и для меня стало проблемой например подключить диск по sftp например. Есть конечно сторонний софт который позволяет это делать, такой как Mountain Duck, например. Но хочется доступ со всяких операционных систем, при этом, возможно даже без лишнего софта.
Напомню немного читателю, что такое WebDAV:
WebDAV (Web Distributed Authoring and Versioning) или просто DAV — набор расширений и дополнений к протоколу HTTP, поддерживающих совместную работу пользователей над редактированием файлов и управление файлами на удаленных веб-серверах.
Отлично, значит для работы всего этого мне просто нужен веб сервер? В документации к nginx сказано, это это модуль ngx_http_dav_module, значит все что нам нужно это добавить модуль к nginx. Сделать это можно либо собрав его из исходных кодов с этим модулем, как например для FreeBSD, так и установив пакет nginx-extras в Ubuntu или Debian-like дистрибутивах. В любом случае, я рекомендую ознакомиться с документацией: http://nginx.org/en/docs/http/ngx_http_dav_module.html Хорошо, мы все установили, теперь нам необходимо сконфигурировать сервер, для этого создаем файл виртуального хоста и вносим туда следующее:
server {
charset UTF-8;
server_name file.yakunin.dev;
listen 10.100.2.6:80;
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.webdav_htpasswd;
try_files $uri $uri/ =404;
root /data;
autoindex on;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS;
dav_access user:rw group:r all:r;
client_max_body_size 10G;
create_full_put_path on;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.webdav_htpasswd;
}
}
Обратите внимание, что обязательно необходимо закрыть сервер паролем, если конечно не хотите чтобы вашим сервером пользовался кто-то ещё 🙂 И разместить файл паролей не в той же папке которую вы будете использовать для хранения файлов. Так же нужно прикрутить к этому SSL сертификат чтобы передача файлов была безопасной. Я настоятельно рекомендую использовать очень длинный и стойкий пароль, так как это всего лишь basic auth, она подвержена логике подбора, поэтому не делайте легкий пароль, это в ваших же интересах. Далее мы можем посмотреть что лежит на нашем сервере:
curl -s -u "username:strongpassword" https://file.yakunin.dev | grep -oP '(?<=href=").*(?=")'
# Output:
../
webdav_client.py
Отлично, у нас корень и в моем случае скрипт для командной строки для управления файлами, об этом позже, но как видите и обычный curl для этого подойдет. Попробуем загрузить файл на сервер:
curl -s -u "username:strongpassword" -T "/path/to/file/file.dat" https://file.yakunin.dev
Теперь вы можете проверить файлы на сервере либо с помощью команды выше, либо зайти на веб-сервер и убедиться что файл там есть. А что если надо удалить файл?
curl -u "username:strongpassword" -X DELETE https://file.yakunin.dev/file.dat
Заходим и убеждаемся что файла нет. Почитайте о других методах в документации о WebDAV.
Я решил быстро написать небольшой скрипт на питоне, чтобы облегчить себе жизнь.
from webdav3.client import Client
import argparse
webdav_options = {
'webdav_hostname': "https://file.yakunin.dev",
'webdav_login': "username",
'webdav_password': "strongpassword"
}
webdav_client = Client(webdav_options)
parser = argparse.ArgumentParser()
parser.add_argument("-l", "--list", help="Get file list", action="store_true")
parser.add_argument("-u", "--upload", help="Upload file to server", action="store")
parser.add_argument("-d", "--download", help="Download file from server", action="store")
parser.add_argument("-r", "--remove", help="Remove file from server", action="store")
args = parser.parse_args()
def get_file_list():
my_file_list = webdav_client.list()
for my_file in my_file_list:
print(my_file)
def upload_file(upload_filename):
if '\\' in upload_filename:
remote_filename = upload_filename.split('\\')[-1]
webdav_client.upload_sync(remote_path=remote_filename, local_path=upload_filename)
elif '/' in upload_filename:
remote_filename = upload_filename.split('/')[-1]
webdav_client.upload_sync(remote_path=remote_filename, local_path=upload_filename)
def download_file(download_filename):
webdav_client.download_sync(remote_path=download_filename, local_path=download_filename)
def delete_file(delete_filename):
webdav_client.clean(delete_filename)
if args.list:
get_file_list()
if args.download:
download_file(args.download)
if args.upload:
upload_file(args.upload)
if args.remove:
delete_file(args.remove)
Перед использованием нужно поставить необходимую для работы библиотеку, сделать это просто: pip install webdavclient3
аргументы для запуска простые: -l или --list
выведет список файлов, -u --upload
загрузит файл и т.д., полную справку можно увидеть в листинге скрипта или вызвать: webdav_client.py --help
Есть так же online сервисы, но доверять кому-то пароль, такое. Но, если файлы скажем не конфиденциальные, то почему нет: https://www.filestash.app/webdav-client.html
А также, есть клиенты для подключения сервера как сетевого ресурса для изменений «налету»:
- Linux:
- Вы можете монтировать диск через Connect to… в любом файловом менеджере
- Windows:
- FileZilla
- SmartFTP
- BitKinex
- MacOS:
- Cyberduck
- Transmit
Теперь у вас есть свое облако, которое, работает только на одном nginx и больше для этого ничего не нужно, что крайне удобно. Конечно, есть традиционные FTP сервера, но кажется они уже остались где-то в прошлом.