# webdav [](https://github.com/hacdias/webdav/releases/latest) [](https://hub.docker.com/r/hacdias/webdav) A simple and standalone [WebDAV](https://en.wikipedia.org/wiki/WebDAV) server. ## Install For a manual install, please refer to the [releases](https://github.com/hacdias/webdav/releases) page and download the correct binary for your system. Alternatively, you can build or install it from source using the Go toolchain. You can either clone the repository and execute `go build`, or directly install it, using: ``` go install github.com/hacdias/webdav/v5@latest ``` ### Homebrew If you have Homebrew available on your system, you can also install `webdav` using it: ``` brew install webdav ``` ### Docker Docker images are provided on both [GitHub's registry](https://github.com/hacdias/webdav/pkgs/container/webdav) and [Docker Hub](https://hub.docker.com/r/hacdias/webdav). You can pull the images using one of the following two commands. Note that this commands pull the latest released version. You can use specific tags to pin specific versions, or use `main` for the development branch. ```bash # GitHub Registry docker pull ghcr.io/hacdias/webdav:latest # Docker Hub docker pull hacdias/webdav:latest ``` ## Usage For usage information regarding the CLI, run `webdav --help`. ### Container To run the container, you can refer to the `compose.yml` file which provides a minimal setup. Additionally, you also need to create a configuration file, as [explained below](#configuration). The equivalent Docker command to the aforementioned compose file would be as follows: ```bash docker run \ -p 6065:6065 \ -v ./config.yml:/config.yml:ro \ -v ./data:/data \ ghcr.io/hacdias/webdav -c /config.yml ``` If you are using [fail2ban](#fail2ban-setup), it would be helpful to add the parameters listed below. They will assist in analyzing the log. ```bash --log-driver journald \ --name webdav \ ``` ### Partial updates This server supports partial file updates compatible with SabreDAV's `PATCH` extension. This is not an official WebDAV specification. Requests must use the `application/x-sabredav-partialupdate` content type, include `Content-Length`, and provide the target range in `X-Update-Range`. Supported `X-Update-Range` values are: - `bytes=start-end` - `bytes=start-` - `bytes=-N` - `append` For clients that use it, the server also supports partial `PUT` requests with `Content-Range`, for example `Content-Range: bytes 6-8/*`. This is an extra compatibility path and should be treated as a client/server agreement. ## Configuration The configuration can be provided as a YAML, JSON or TOML file. Below is an example of a YAML configuration file with all the options available, as well as what they mean. ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### Rules Rules are matched against the request path after dot segments have been resolved, so `/public/../secret/file` is matched as `/secret/file`. The last rule that matches wins. A `path` rule is a prefix match. A rule written with a trailing slash also covers the collection it names, so `path: /secret/` applies to a request for `/secret` as well. Such a rule can only restrict that collection: acting on the collection itself also requires the permissions that apply outside the rule, since the operation takes place in the parent collection. A `regex` rule is matched literally against the path, and gets none of the above handling. In particular `regex: "^/secret/"` does **not** match a request for `/secret` itself. Write `regex: "^/secret(/|$)"` if you want to cover the collection too. ### CORS The `allowed_*` properties are optional, the default value for each of them will be `*`. `exposed_headers` is optional as well, but is not set if not defined. Setting `credentials` to `true` will allow you to: 1. Use `withCredentials = true` in javascript. 2. Use the `username:password@host` syntax. ## Caveats ### Reverse Proxy Service When using a reverse proxy implementation, like Caddy, Nginx, or Apache, note that you need to forward the correct headers in order to avoid 502 errors. #### Nginx Configuration Example ```nginx location / { proxy_pass http://127.0.0.1:8080; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; # Ensure COPY and MOVE commands work. Change https://example.com to the # correct address where the WebDAV server will be deployed at. set $dest $http_destination; if ($http_destination ~ "^https://example.com(?(.+))") { set $dest /$path; } proxy_set_header Destination $dest; } ``` #### Caddy Configuration Example ```Caddyfile example.com { tls internal # for local development # tls name@email.com # so that Caddy gets certs for you via Letsencrypt # Rewrites destination to remove host and include only the path e.g. /test.txt @hasDest header_regexp dest ^https?://[^/]+(.*)$ header @hasDest Destination {re.dest.1} # if running on the same network in docker you can just point to the service name e.g. webdav:6065 reverse_proxy 127.0.0.1:6065 { header_up X-Real-IP {remote_host} header_up REMOTE-HOST {remote_host} } } ``` ## Examples ### Systemd Example configuration of a [`systemd`](https://en.wikipedia.org/wiki/Systemd) service: ```conf [Unit] Description=WebDAV After=network.target [Service] Type=simple User=root ExecStart=/usr/bin/webdav --config /opt/webdav.yml Restart=on-failure [Install] WantedBy=multi-user.target ``` ### Fail2Ban Setup To add security against brute-force attacks in your WebDAV server, you can configure Fail2Ban to ban IP addresses after a set number of failed login attempts. #### Filter Configuration Create a new filter rule under `filter.d/webdav.conf`: ```ini [INCLUDES] before = common.conf [Definition] # Failregex to match "invalid password" and extract remote_address only failregex = ^.*invalid password\s*\{.*"remote_address":\s*":\d+"\s*\} ^.*invalid username\s*\{.*"remote_address":\s*":\d+"\s*\} ignoreregex = ``` This configuration will capture invalid login attempts and extract the IP address to ban. #### Jail Configuration In `jail.d/webdav.conf`, define the jail that monitors your WebDAV log for failed login attempts: ```ini [webdav] enabled = true port = [your_port] filter = webdav logpath = [your_log_path] banaction = iptables-allports ignoreself = false ``` - Replace `[your_port]` with the port your WebDAV server is running on. - Replace `[your_log_path]` with the path to your WebDAV log file. If you use it with Docker and `--log-driver journald`, replace `logpath` with `journalmatch = CONTAINER_NAME=[your_container_name]` #### Final Steps 1. Restart Fail2Ban to apply these configurations: ```bash sudo systemctl restart fail2ban ``` 2. Verify that Fail2Ban is running and monitoring your WebDAV logs: ```bash sudo fail2ban-client status webdav ``` With this setup, Fail2Ban will automatically block IP addresses that exceed the allowed number of failed login attempts. ## Contributing Feel free to open an issue or a pull request. ## License [MIT License](LICENSE) © [Henrique Dias](https://hacdias.com)