couling / WebDAV-Daemon

MIT License
34 stars 7 forks source link

broken tls support on Arch Linux #7

Closed p5n closed 3 years ago

p5n commented 4 years ago

http works well, but https:

$ cadaver https://10.0.1.140:443
....
Username: user
Password:
Could not open collection:
Could not read status line: connection was closed by server

The same with nautilus and dolphin webdav clients.

Distro: ArchLinux

Versions: webdav-daemon v1.1.r1.bc88ec6-2 libmicrohttpd 0.9.70-3

Config:

<?xml version="1.0" encoding="utf-8" ?>
<server-config xmlns="http://couling.me/webdavd">
    <server>
        <rap-binary>/usr/bin/rap</rap-binary>
        <static-response-dir>/usr/share/webdavd</static-response-dir>
        <chroot-path>~</chroot-path>
        <listen>
            <port>80</port>
            <encryption>none</encryption>
        </listen>
        <listen>
            <port>443</port>
            <encryption>ssl</encryption>
        </listen>
        <ssl-cert>
            <certificate>/etc/letsencrypt/live/.../cert.pem</certificate>
            <key>/etc/letsencrypt/live/.../privkey.pem</key>
        </ssl-cert>
    </server>
</server-config>
couling commented 4 years ago

Thanks for your interest.

Different software has different requirements but you must always use either of:

Using just chain.pem on it's own is likely to fail because it doesn't contain the intermediate certificate required by clients. Different server software has different requirements so you must always check which you need.

For webdavd you need cert.pem with chain.pem:

<ssl-cert>
    <certificate>/etc/letsencrypt/live/.../cert.pem</certificate>
    <chain>/etc/letsencrypt/live/.../chain.pem</chain>
    <key>/etc/letsencrypt/live/.../privkey.pem</key>
</ssl-cert>

I'll close this issue for now. If you still can't get it working, you can re-open and comment again.

p5n commented 4 years ago

I tried all variants with the same result. According to wireshark it connects TLSv1.3 successfully and exchanges 4 application data packets after "Change Cipher Spec" one.

p5n commented 4 years ago

(I used wildcard let's encrypt cert if it can matter somehow)

couling commented 4 years ago

Okay I've never tested it on Arch Linux. I'm wondering about dependency trouble with the SSL library.

What Arch Linux version are you running?

How did you install WebDAV-Daemon?

I'll see if I can recreate your issue.

p5n commented 4 years ago

current version of ArchLinux x86_64 (it is rolling release distro) webdav installed from https://aur.archlinux.org/packages/webdav-daemon/

make package files: https://aur.archlinux.org/cgit/aur.git/tree/?h=webdav-daemon

main file: https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=webdav-daemon

p5n commented 4 years ago

full output just in case:

$ cadaver http://10.0.1.140:1080
Authentication required for My Server on server `10.0.1.140':
Username: ...
Password: 
dav:/> ls
Listing collection `/': succeeded.
Coll:   test                                   0  мая 23 18:04
        qwe.txt                                0  мая 23 18:02
dav:/> 
Connection to `10.0.1.140' closed.

$ cadaver https://10.0.1.140:1443
WARNING: Untrusted server certificate presented for `*.mydomain.com':
Certificate was issued to hostname `*.mydomain.com' rather than `10.0.1.140'
This connection could have been intercepted.
Issued to: mydomain.com
Issued by: Let's Encrypt, US
Certificate is valid from Fri, 10 Apr 2020 10:04:51 GMT to Thu, 09 Jul 2020 10:04:51 GMT
Do you wish to accept the certificate? (y/n) y
Authentication required for My Server on server `10.0.1.140':
Username: .....
Password: 
Could not open collection:
Could not read status line: connection was closed by server
dav:/? 
couling commented 4 years ago

Thanks for your patience.

I have managed to confirm the bug but not yet found the cause. I've used a docker container. Attached zip contains everything required for the docker image except letsencrypt certs. arch-test.zip

Something really strange is happening. Some responses are returning just fine, such as the 401 response . I can GET files if I know the exact URL. But some dynamically generated responses such as indexing a directory are failing. It's clearly logging the access requests so somehow it's failing to write the response.

It's really weird that this would be a problem triggered by adding a layer of SSL. If it was blocking everything it would be less surprising.

I'll keep investigating as I get the time. Apologies that this may take a while.


@p5n I see it's your name as the maintainer for Arch Linux.

Firstly: Thanks!

May I suggest a couple of tweaks. The server uses mine-types and I believe gnutls. These ought to be dependencies as my first docker image fell over without them.

I've also noted there's a patch file to fix a minor logging bug. If you wanted to raise a PR for it I'll gladly merge it in upstream. If not I'll silently patch it.

couling commented 4 years ago

This looks like a bug in a supporting library. Probably libmicrohttpd 9.70-3. It specifically only affects sending data with TransferEncoding: chunked.

I've confirmed my code is behaving identically regardless of SSL or not. With listing a directory, exactly the same calls to createFdResponse and subsiquently fdContentReader yield exactly the same results. These are the last point in my code responsible for responding to requests, so my code appears to be responding correctly.

After my code has put the data on a buffer to send and passed it back to libmicrohttpd, somehow it's getting lost / truncated.

Testing with wget https://username@example.com/some-dir/ --ask-password I get the curious error:

Read error at byte 122488 (Success).Giving up

When testing it's HTTP (not HTTPS) equivalent with wget http://username@example.com/some-dir/ --ask-password I get a HTML index correctly which is exactly 122488 bytes long. So it looks like libmicrohttpd is not cleanly terminating the chunked encoding when using gnutls.

I'll check to see if this is all still working on Ubuntu which uses a slightly different version.

montvid commented 3 years ago

So does this code work with https? I am looking for a webdav solution that has two users one with read access only and the other with all access serving on the internet on port 443.

couling commented 3 years ago

@montvid Yes it supports SSL/TLS. This issue was with building it for Arch Linux - a newer version of a supporting library (libmicrohttpd) broke the code. As far as I'm aware this only affects Arch Linux

couling commented 3 years ago

For reference I reported this as a bug against libmicrohttpd here with response here.

Unfortunately I then lost all my free time and couldn't get back to it.

It's possible that they fixed the issue already. Hopefully I'll be able to figure this out before the next release.

p5n commented 3 years ago

It looks fixed with libmicrohttpd 0.9.73-1 and latest webdav-daemon. Thank you!