jens-maus / RaspberryMatic

:house: A feature-rich but lightweight, buildroot-based Linux operating system alternative for your CloudFree CCU3/ELV-Charly 'homematicIP CCU' IoT smarthome central. Running as a pure virtual appliance (ProxmoxVE, Home Assistant, LXC, Docker/OCI, Kubernetes/K8s, etc.) on a dedicated embedded device (RaspberryPi, etc.) or generic x86/ARM hardware.
https://raspberrymatic.de
Apache License 2.0
1.55k stars 192 forks source link

lighttpd ignores the basic auth configuration #1982

Closed Shaker1978 closed 1 year ago

Shaker1978 commented 2 years ago

Describe the issue you are experiencing

I have an additional configuration in /usr/local/etc/config/lighttpd/auth.conf looking like this:

auth.backend = "plain"
auth.backend.plain.userfile = "/some/path/.users"
auth.require = (
  "/addons/xmlapi" =>
  (
    "method" => "basic",
    "realm" => "External access protection",
    "require" => "user=SomeUser"
  )
)

It is read and evaluated on lighttpd startup (temporarily introduced syntax errors prevent a successful start), but the execution is being ignored, i.e. I can access /addons/xmlapi without being asked for authentication!

Describe the behavior you expected

I expect the browser to popup basic auth window for username and password and that the webserver does not deliver content, when no credentials or the wrong credentials are entered.

Steps to reproduce the issue

  1. Install the XML-API addon
  2. Add an additional configuration in /usr/local/etc/config/lighttpd/ that restricts the access to /addons/xmlapi with basic authentication.
  3. Restart lighttpd with the command. /etc/init.d/S50lighttpd restart
  4. Try to access /addons/xmlapi ...

What is the version this bug report is based on?

3.65.8.20220831

Which base platform are you running?

rpi3 (RaspberryPi3)

Which HomeMatic/homematicIP radio module are you using?

HM-MOD-RPI-PCB

Anything in the logs that might be useful for us?

Additional information

I think, it's the version of lighttpd 1.4.65 that introduced this problem. I tested firmware 3.63.8.20220330 which acts normal. And firmware 3.65.6.20220723 already has this issue. I have not yet tested the firmwares in between, but I guess, it starts with 3.63.9.20220625, because lighttpd 1.4.65 is new here.

skettler commented 2 years ago

Try this as /usr/local/etc/config/lighttpd/auth.conf:

$HTTP["url"] == "/addons/xmlapi/update-check.cgi" {
    # Whitelist XMLAPI update check
}
else $HTTP["url"] =^ "/addons/xmlapi/" {
    # All other XMLAPI urls require authentication

    auth.backend = "plain"
    auth.backend.plain.userfile = "/usr/local/etc/.users"
    auth.require = (
        "/" => (
            "method"  => "basic",
            "realm"   => "External access protection",
            "require" => "user=ExternalUser",
        ),
    )
}
Shaker1978 commented 2 years ago

Try this as /usr/local/etc/config/lighttpd/auth.conf:

$HTTP["url"] == "/addons/xmlapi/update-check.cgi" {
    # Whitelist XMLAPI update check
}
else $HTTP["url"] =^ "/addons/xmlapi/" {
    # All other XMLAPI urls require authentication

    auth.backend = "plain"
    auth.backend.plain.userfile = "/usr/local/etc/.users"
    auth.require = (
        "/" => (
            "method"  => "basic",
            "realm"   => "External access protection",
            "require" => "user=ExternalUser",
        ),
    )
}

Why do you think, whitelisting a URL will help, wenn NO authentication is requested at all whith this version?

skettler commented 2 years ago

The lighttpd configuration changed a bit, so we basically have to create conditional configuration for different parts of the site (https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_Configuration).

The snippet defines a whitelist for "/addons/xmlapi/update-check.cgi" (safe, used in web interface) and a password requirement for everything else that starts with "/addons/xmlapi/". This is the configuration I use in my setup.

Shaker1978 commented 1 year ago

Sorry for my late reply. I have just tried it, because 3.67.10.20230114 is the first update I have done since then. Taking the chance to spend some time with this problem again.

Thank you very much for pointing out this detail! I wonder why I got this incredibly small response and why this is so badly documented. Or isn't it? You still can find this (https://redmine.lighttpd.net/projects/lighttpd/wiki/Mod_auth) and this (https://redmine.lighttpd.net/projects/1/wiki/HowToBasicAuth), the last one only via google. Shouldn't there be a better way of publishing this kind of braking changes in a configuration syntax? How and where did you find this information?

And can I ask for more details? Is it possible to combine entries that start with the same path, while not using RegularExpressions? When I tried to block /addons/xmlapi/... and /addons/email/..., this didn't work:

$HTTP["url"] =^ "/addons/" {
    auth.backend = "plain"
    auth.backend.plain.userfile = "/some/path/.users"
    auth.require = (
        "/xmlapi/" =>
        (
            "method" => "basic",
            "realm" => "External access protection",
            "require" => "user=SomeUser"
        ),
        "/email/" =>
        (
            "method" => "basic",
            "realm" => "External access protection",
            "require" => "user=SomeUser"
        )
    )
}

I'd like to get rid of some redundant information in such config files and at least avoid repeating auth.backend and auth.backend.plain.userfile: Even cooler, if I didn't have to repeat method, realm and require.

Shaker1978 commented 1 year ago

Found a way:

auth.backend = "plain"
auth.backend.plain.userfile = "/some/path/.users"

$HTTP["url"] =$ "update-check.cgi" {
    # Addon update checks are allowed.
}
else $HTTP["url"] =^ "/config/xmlapi/" {
    # /config/xmlapi/... requires basic auth.
    auth.require = (
        "/" =>
        (
            "method" => "basic",
            "realm" => "External access protection",
            "require" => "user=SomeUser"
        )
    )
}
else $HTTP["url"] =^ "/addons/" {
    auth.require = (
        "/" =>
        (
            "method" => "basic",
            "realm" => "External access protection",
            "require" => "user=SomeUser"
        )
    )
}

So, still the "auth.require" assignments are repetitive, but at least the "auth.backend" assignments could be pulled outside in front of the conditional blocks.

When the URL ends with "update-check.cgi", the request is allowed (regardless of the query string that follows the URL after the "?").

Everything that starts with "/config/xmlapi/" or "/addons/" requires authentication.

Closing this...