Giter Site home page Giter Site logo

dave's Introduction

Build Status Go Report

dave - The simple WebDAV server

Sorry, this project is unmaintained 😢

Thanks to all contributors for your incredible work!

Introduction

dave is a simple WebDAV server that provides the following features:

  • Single binary that runs under Windows, Linux and OSX.
  • Authentication via HTTP-Basic.
  • TLS support - if needed.
  • A simple user management which allows user-directory-jails as well as full admin access to all subdirectories.
  • Live config reload to allow editing of users without downtime.
  • A cli tool to generate BCrypt password hashes.

It perfectly fits if you would like to give some people the possibility to upload, download or share files with common tools like the OSX Finder, Windows Explorer or Nautilus under Linux (or many other tools).

The project name dave is an abbreviation for: Distributed Authoring and Versioning made easy.

Table of Contents

Configuration

The configuration is done in form of a yaml file. dave will scan the following locations for the presence of a config.yaml in the following order:

  • The directory ./config
  • The directory $HOME/.swd (swd was the initial project name of dave)
  • The directory $HOME/.dave
  • The current working directory .

Alternatively, the path to a configuration file can be specified on the command-line:

dave --config /path/to/config.yaml

First steps

Here an example of a very simple but functional configuration:

address: "127.0.0.1"    # the bind address
port: "8000"            # the listening port
dir: "/home/webdav"     # the provided base dir
prefix: "/webdav"       # the url-prefix of the original url
users:
  user:                 # with password 'foo' and jailed access to '/home/webdav/user'
    password: "$2a$10$yITzSSNJZAdDZs8iVBQzkuZCzZ49PyjTiPIrmBUKUpB0pwX7eySvW"
    subdir: "/user"
  admin:                # with password 'foo' and access to '/home/webdav'
    password: "$2a$10$DaWhagZaxWnWAOXY0a55.eaYccgtMOL3lGlqI3spqIBGyM0MD.EN6"

With this configuration you'll grant access for two users and the WebDAV server is available under http://127.0.0.1:8000/webdav.

TLS

At first, use your favorite toolchain to obtain a SSL certificate and keyfile (if you don't already have some).

Here an example with openssl:

# Generate a keypair
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
# Remove the passphrase from the key file
openssl rsa -in key.pem -out clean_key.pem

Now you can reference your keypair in the configuration via:

address: "127.0.0.1"    # the bind address
port: "8000"            # the listening port
dir: "/home/webdav"     # the provided base directory
tls:
  keyFile: clean_key.pem
  certFile: cert.pem
users:
...

The presence of the tls section is completely enough to let the server start with a TLS secured HTTPS connection.

In the current release version you must take care, that the private key doesn't need a passphrase. Otherwise starting the server will fail.

Cross Origin Resource Sharing (CORS)

In case you intend to operate this server from a web browser based application, you might need to allow CORS access. To achieve that, you can configure the host you want to grant access to:

cors:
  origin: "*"        # the origin to allow, or '*' for all
  credentials: true  # whether to allow credentials via CORS

Note however that this has security implications, so be careful in production environments.

Behind a proxy

dave will also work behind a reverse proxy. Here is an example configuration with apache2 httpd's mod_proxy:

<Location /webdav>
  ProxyPass           https://webdav-host:8000/
  ProxyPassReverse    https://webdav-host:8000/
</Location>

User management

User management in dave is very simple, but optional. You don't have to add users if it's not necessary for your use case. But if you do, each user in the config.yaml must have a password and can have a subdirectory.

The password must be in form of a BCrypt hash. You can generate one calling the shipped cli tool davecli passwd.

If a subdirectory is configured for a user, the user is jailed within it and can't see anything that exists outside of this directory. If no subdirectory is configured for an user, the user can see and modify all files within the base directory.

Logging

You can enable / disable logging for the following operations:

  • Creation of files or directories
  • Reading of files or directories
  • Updating of files or directories
  • Deletion of files or directories

You can also enable or disable the error log.

All file-operation logs are disabled per default until you will turn it on via the following config entries:

address: "127.0.0.1"    # the bind address
port: "8000"            # the listening port
dir: "/home/webdav"     # the provided base directory
log:
  error: true
  create: true
  read: true
  update: true
  delete: true
...

Be aware, that the log pattern of an attached tty differs from the log pattern of a detached tty.

Example of an attached tty:

INFO[0000] Server is starting and listening              address=0.0.0.0 port=8000 security=none

Example of a detached tty:

time="2018-04-14T20:46:00+02:00" level=info msg="Server is starting and listening" address=0.0.0.0 port=8000 security=none

Live reload

There is no need to restart the server itself, if you're editing the user or log section of the configuration. The config file will be re-read and the application will update it's own configuration silently in background.

Installation

Binary installation

You can check out the releases page for the latest precompiled binaries.

Otherwise you can use the binary installation via go get:

go get github.com/micromata/dave/cmd/...

Build from sources

Setup

  1. Ensure you've set up Go. Take a look at the installation guide and how you set up your path
  2. Create a source directory and change your working directory
mkdir -p $GOPATH/src/github.com/micromata/ && cd $GOPATH/src/github.com/micromata
  1. Clone the repository (or your fork)
git clone https://github.com/micromata/dave.git

To build and install from sources you have two major possibilites:

go install

You can use the plain go toolchain and install the project to your $GOPATH via:

cd $GOPATH/src/github.com/micromata/dave && go install ./...

magefile

You can also use mage to build the project.

Please ensure you've got mage installed. This can be done with the following steps:

git clone https://github.com/magefile/mage
cd mage
go run bootstrap.go

The golint utility is also required for mage check:

go install golang.org/x/lint/golint

Now you can call mage install to build and install the binaries. If you just call mage, you'll get a list of possible targets:

Targets:
  build            Builds dave and davecli and moves it to the dist directory
  buildReleases    Builds dave and davecli for different OS and package them to a zip file for each os
  check            Runs golint and go tool vet on each .go file.
  clean            Removes the dist directory
  fmt              Formats the code via gofmt
  install          Installs dave and davecli to your $GOPATH/bin folder
  installDeps      Runs dep ensure and installs additional dependencies.

Build and run with Docker

The image of dave is available on Docker Hub as micromata/dave.

If you like to build it for your own, just execute the following lines:

git clone https://github.com/micromata/dave.git
cd dave
docker build -t micromata/dave:latest .

You can run dave with the following lines:

# create webdav home
mkdir webdav-home

docker run -d \
	-p 8000:8000 \
	-v $(pwd)/examples/config-sample.yaml:/config.yaml:ro \
	-v $(pwd)/webdav-home:/tmp:rw \
	micromata/dave:latest

Connecting

You could simply connect to the WebDAV server with an HTTP(S) connection and a tool that allows the WebDAV protocol.

For example: Under OSX you can use the default file management tool Finder. Press CMD+K, enter the server address (e.g. http://localhost:8000) and choose connect.

Contributing

Everyone is welcome to create pull requests for this project. If you're new to github, take a look here to get an idea of it.

If you'd like to contribute, please make sure to use the magefile and execute and check the following commands before starting a PR:

mage fmt
mage check

If you've got an idea of a function that should find it's way into this project, but you won't implement it by yourself, please create a new issue.

License

Please be aware of the licenses of the components we use in this project. Everything else that has been developed by the contributions to this project is under the Apache 2 License.

dave's People

Contributors

chclaus avatar dependabot[bot] avatar divinity76 avatar lingej avatar mpizala avatar pataquets avatar samhocevar avatar sergiobenitez avatar tyler71 avatar zonque avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dave's Issues

write access?

currently dave works excellently for mostly read-only access, but when I try to write to the DAV directory, it says that there is insufficient space.
Is write support possible?

curl and listing files

Hello,

i wonder how it is possiblt to use curl with dave?

I read everywhere that simple GET request should work, but with dave i see "method not allowed".
so interested - how it would be possible to get list of files?

Feature: file blacklist

First, thanks for an excellent project!

As the title says, I would like to see a blacklist function in the application. My primary goal for this is to hinder pollution of the filesystem and repositories, in regards to various garbage different OS-s leave behind, like macOS's infamous .DS_Store and ._* files.

I have experimented with the code, and got a proof of concept working. So this issue is more a request if you want this feature, then I can improve my PoC and request a merge.

Enable brute force detection?

If you were to log "User x failed to login" I could use fail2ban to stop evil users from brute forcing me. I could use a proxy, but was curios what you thought about adding this security feature?

Mime types

I noticed that shares hosted with dave does not correctly identify tif files as an image. Is there a place to configure mime types for the server?

Error 207 Multistatus - Apache2 proxy

The given Apache example does not work for me.

<VirtualHost *:443>
  ServerName localhost

  SSLEngine On
  SSLProxyEngine On
  SSLProxyCheckPeerCN Off
  SSLCertificateFile    /data/cert.pem
  SSLCertificateKeyFile /data/key.pem

  ProxyRequests Off
  ProxyPreserveHost On

  RewriteEngine On
  RewriteRule ^/webdav$ /webdav/ [R,L]
  RewriteRule ^/radicale$ /radicale/ [R,L]

  <Location /webdav/>
  ProxyPass           http://localhost:8081/
  ProxyPassReverse    http://localhost:8081/
  </Location>

  <Location "/radicale/">
    ProxyPass        http://localhost:5232/ retry=0
    ProxyPassReverse http://localhost:5232/
    RequestHeader    set X-Script-Name /radicale/
  </Location>

</VirtualHost>
address: "127.0.0.1"    # the bind address
port: "8081"            # the listening port
dir: "/data/webdav/data"     # the provided base dir
#prefix: "/webdav"       # the url-prefix of the original url
users:
  user:
    password:

Docker image build fails

Running the docker build as documented fails:

Step 3/9 : RUN go get -u github.com/micromata/dave/cmd/...
 ---> Running in 38f7d68dee7f
package github.com/micromata/dave/cmd/...: github.com/micromata/dave/cmd/...: invalid import path: malformed import path "github.com/micromata/dave/cmd/...": double dot
The command '/bin/sh -c go get -u github.com/micromata/dave/cmd/...' returned a non-zero code: 1                                                               

enabling update log has no effect

Hello team,
I'm currently testing dave to store buttercup vaults.
I configured a couple of users and enabled all the logs.

I was expecting to see a log every time a user updates the vault but looks like only the "read" operations are logged.

here's the log

time="2023-03-25T08:24:22Z" level=info msg="Server is starting and listening" address=0.0.0.0 port=8000 security=none
time="2023-03-25T08:24:52Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:25:10Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:25:10Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:25:10Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:25:16Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:25:16Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:25:17Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:26:00Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:27:18Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:27:18Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:27:19Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:27:32Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:27:32Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:27:32Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele
time="2023-03-25T08:46:56Z" level=info msg="Opened file" path=/data/test-vault.bcup user=michele

and the file

~/dave$ ls -ln data/
total 4
-rw-r--r-- 1 100 65533 2720 Mar 25 08:27 test-vault.bcup

As you can see file has been updated at 08:27 but there's no evidence of it in the logs

Am I missing something?

Add logrus as http server logger

Currently the http.Server uses the default log implementation. This breaks the logfile pattern and makes it hard for automatic log-processing.

I think we should refactor the http.Server generation part and inject a io.Writer of the logrus logger to solve this problem.

Allow configuration without users

Currently, when you omit a user configuration the server will start up, but there is no possibility to establish a connection.

We should provide a way of anonymous connections when there is no user configuration.

http: multiple response.WriteHeader calls

Hi Christian
running swd behind a haproxy sometimes result in an error

swd[15065]: 2018/04/24 07:38:32 http: multiple response.WriteHeader calls

This happens on permission errors.
swd is running as user www-data and www-data has not permission on .gitignore file

Apr 24 08:02:08 het71 swd[15065]: 2018/04/24 08:02:08 http: multiple response.WriteHeader calls
Apr 24 08:02:08 het71 swd[15065]: time="2018-04-24T08:02:08+02:00" level=error msg="open /www/aaa.bbb.de/.gitignore: permission denied"

Jörg

Clients expecting response/propstat/prop/creationdate

Would it be possible to implement the creationdate prop element? Its a peer element to getlastmodified, and apparently suggested RFC4437.
Not a huge deal (and I actually don't see it in the RFC) but I'm working with an older client that crashed because it was missing (I patched this particular client, but others may have trouble.)

Thanks for building this, its awesome!

"Fatal error config file: While parsing config: yaml: line [nn]: did not find expected hexdecimal number"

I am trying to use the standalone binary on a Windows 10 host. However with config.yaml that is made directly from config-sample.yaml except for a change of the dir-directive I get the following error when launching dave:

C:\Users\user\Downloads\dave-0.4.0-windows-amd64>dave
time="2021-07-04T17:14:02+02:00" level=fatal msg="Fatal error config file: While parsing config: yaml: line 26: did not find expected hexdecimal number"

C:\Users\user\Downloads\dave-0.4.0-windows-amd64>

The line number (26) is the dir-directive

I have tried with the following two dir-directive, where I have tried the following two:

dir: "c:\Users\user\Downloads"

and

dir: "c:\\\Users\\\user\\\Downloads"

I can't find anything in the documentation, that might indicate, that it should be written otherwise :(

Moving the line with the dir around, makes the error change to that line, so I am certain it is related to dir...

Support authentication by upstream proxy

It would be nice to be able to let a proxy in front of dave handle the user authentication and just accept the username from a HTTP Header. This would open the possibility to use alternative authentication method (LDAP, custom, database, etc.) without adding much complexity to dave.

And example setup is Traefik configured to use forward auth with pinepain/ldap-auth-proxy. When a request hit dave, a user has already been authenticated and it's username is stored in the X-Auth-User header.

Related issue: #10

Windows 10 explorer.exe insist credentials are wrong

when trying to mount with windows 10 explorer.exe client with the default admin:foo it insist the credentials are wrong🤔
screenshot:
image

strangely at #37 someone else get a different error from windows 10, i wonder if it's related

Dockerify dave :)

We need a Dockerfile to:

  • build the project
  • run the project

There must be a possibility to pass some basic config settings like address, port, etc. via environment variables.

BCrypt is slow by design

And it makes each request to Dave slow as well. Even reducing the cost of our bcrypt hash to 4, there's still 10ms or so more time spent on each request than we'd like! Maybe it's not the ideal hash for this app!

Usermanagement bei puredb of pureftp

Is there any chance to alternate the user management to a puredb file by pure ftp. Therefore, the config.yml should be obsolete.

The case-scenario is a docker-container, which conclude pureftp and dave to a simple data storage especial for document-scanning.

Docker Hub

Hi! First of all, thanks for this software! 😃

It would be great to have the image in the Docker Hub, so one can do a docker pull without building it manually every time. Thanks in advance for your attention

Windows Explorer Issue

I tried now dave over docker local and over https (k8s nginx ingress)

WebDav clients like filestash online demo can connect without issues,
but Windows 10 Explorer is reporting an error after user-credentials

"The folder you entered does not appear to be valid. Please choose abother"

image

Question] Can I avoid the "code=503" response when uploading a file to Dave

Hello,

I'm trying to make an app on Android of a client for WebDAV.
I faced the problem when uploading a file larger than about 1.5MB to Dave.

Response message is below:
Response{protocol=http/1.1, code=503, message=Service Unavailable,

Using OkHttp3 Lib,
RequestBody requestBody = RequestBody.create(MediaType.parse(mediaType), file);
Request request = new Request.Builder().url(urlToUpload).put(requestBody).build;
Response response = client.newCall(request).execute();

This works finewhen uploading a file smaller than 1.5MB, but I faved 503 response for files larger than 1.5MB.

How can I avoid this situation ?

LDAP support

Many companies use LDAP as role/authentication managment system.
It would be nice if DAVE could provide an ldap integration.

Add a --config argument

It would be nice to have the ability to explicitly specify a config location using a command line argument e.g. dave --config dave-config.yaml. This would make it easier for instance to use dave as a system service. Alternatively/additionally dave could look for a config location in an absolute location that does not depend on environment variables e.g. /etc/dave/config.yaml.

Willing to help maintain Dave

Hi, we use Dave in production and are quite happy with it. I’d be willing to help maintain the software. I have decent Go experience, having ported the runtime to multiple platforms, and a pretty good software engineering experience.

A few disclaimers:

  • I would start working on smaller bugs / features that I think are worth working on: #29, #17, #13; you can see that I have already submitted a PR for #36.
  • I would probably not work on #10/#30 because the multiple possible LDAP binding scenarios make it difficult to get right. We successfully use Apache and nginx as authenticating (and caching) frontends for Dave instead.
  • I would get rid of the vendor directory, that’s 70 MiB of source data that probably no one needs; go build can fetch it.
  • I may consider removing the magefile in the long term, as its complexity seems to surpass its usefulness.

I’m happy to discuss this further. Let me know what you think!

Webdav Error

I'm using Windows, but I can't visit the folder contain the folder cannot access.

Responce

<?xml version="1.0" encoding="UTF-8"?><D:multistatus xmlns:D="DAV:"><D:response><D:href>/</D:href><D:propstat><D:prop><D:getlastmodified>Tue, 19 Oct 2021 06:01:48 GMT</D:getlastmodified><D:resourcetype><D:collection xmlns:D="DAV:"/></D:resourcetype><D:displayname></D:displayname><D:supportedlock><D:lockentry xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response><D:response><D:href>/$360Section/</D:href><D:propstat><D:prop><D:getlastmodified>Sat, 28 Jan 2017 06:21:50 GMT</D:getlastmodified><D:resourcetype><D:collection xmlns:D="DAV:"/></D:resourcetype><D:displayname>$360Section</D:displayname><D:supportedlock><D:lockentry xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response><D:response><D:href>/$360Section/360SD/</D:href><D:propstat><D:prop><D:getlastmodified>Sun, 02 Jul 2017 23:46:11 GMT</D:getlastmodified><D:resourcetype><D:collection xmlns:D="DAV:"/></D:resourcetype><D:displayname>360SD</D:displayname><D:supportedlock><D:lockentry xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response><D:response><D:href>/$RECYCLE.BIN/</D:href><D:propstat><D:prop><D:supportedlock><D:lockentry xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock><D:getlastmodified>Wed, 11 Aug 2021 08:26:23 GMT</D:getlastmodified><D:resourcetype><D:collection xmlns:D="DAV:"/></D:resourcetype><D:displayname>$RECYCLE.BIN</D:displayname></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response></D:multistatus>Internal Server Error

log

time="2021-10-19T14:11:38+08:00" level=info msg="2021/10/19 14:11:38 http: superfluous response.WriteHeader call from golang.org/x/net/webdav.(*Handler).ServeHTTP (webdav.go:74)"
time="2021-10-19T14:11:38+08:00" level=error msg="open F:\\$RECYCLE.BIN\\S-1-5-18: Access is denied."

Enable different log formats

The used logging implementation is logrus. logrus allows a lot of different log formatters (including third party libs).

I think we should support at least the two default log formats:

  • text
  • json

To allow further log processing with tools like logstash, etc.

The feature should be placed in the config section without capabilities of config live reloading and text as default log output.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.