Project

General

Profile

[Solved] lighttpd stopped reading apparently valid/complete self-signed x509 SSLcertificates for TLS

Added by alizardx 2 months ago

intended application: IoT web app on lighttpd webserve
problem: lighttpd stopped reading apparently valid/complete self-signed x509 SSL certificates for TLS a few weeks ago. Before then, they worked in lighttpd, firefox, brave (chromium), desktop, Android

this has held up major project for weeks. tried debugging config, rebuilding TLS on earlier version. looking at mkcert, building latest lighttpd from source, apparently build ok but didn't run.
using service lighttpd restart to check. oops...

www-data@DietPi:~$ sudo service lighttpd restart
Job for lighttpd.service failed because the control process exited with error code.
See "systemctl status lghttpd.service" and "journalctl -xeu lighttpd.service" for details.
www-data@DietPi:~$ sudo systemctl status lighttpd.service
 lighttpd.service - Lighttpd Daemon
     Loaded: loaded (/lib/systemd/system/lighttpd.service; enabled; preset: enabled)
     Active: activating (start-pre) since Wed 2024-07-03 21:49:45 UTC; 888ms ago
Cntrl PID: 8841 (lighttpd)
      Tasks: 3 (limit: 990)
        CPU: 666ms
     CGroup: /system.slice/lighttpd.service
             ├─8841 /usr/sbin/lighttpd -tt -f /etc/lighttpd/lighttpd.conf
             ├─8844 /bin/sh -c /usr/share/lighttpd/create-mime.conf.pl
             └─8845 /usr/bin/perl -w /usr/share/lighttpd/create-mime.conf.pl

www-data@DietPi:~$ sudo journalctl -xeu lighttpd.service

Jul 03 21:49:45 DietPi systemd[1]: Starting lighttpd.service - Lighttpd Daemon...
www-data@DietPi:~$ ^C
www-data@DietPi:~$  The unit lighttpd.service completed and consumed the indicated resources.
Jul 03 21:51:40 DietPi systemd[1]: Starting lighttpd.service - Lighttpd Daemon...
░ Subject: A start job for unit lighttplpd.service has begun execution
░░ Defined-By: systemd
░░ Support: https://www.debian.org/support
░░
░░ A start job for unit lighttpd.service has begun execution.
░░ pl
░░ The job identifier is 2505875.
Jul 03 21:51:44 DietPi lighttpd[8970]: 2024-07-03 21:51:40: (mod_openssl.c.1335) SSL: inactive/expired X509 certificate '/etc/lighttpd/certs/telens+1.pem'
Jul 03 21:51:44 DietPi lighttpd[8970]: 2024-07-03 21:51:40: (mod_openssl.c.1367) SSL: couldn't read private key from '/etc/lighttpd/certs/telens+1.pem'
Jul 03 21:51:44 DietPi lighttpd[8970]: 2024-07-03 21:51:40: (server.c.1454) Initialization of plugins failed. Going down.
Jul 03 21:51:44 DietPi systemd[1]: lighttpd.service: Control process exited, code=exited, status=255/EXCEPTION
░░ Subject: Unit process exited
░░ Defined-By: systemd
░░ Support: https://www.debian.org/support
░░
░░ An ExecStartPre= process belonging to unit lighttpd.service has exited.
░░
░░ The process' exit code is 'exited' and its exit status is 255.

www-data@DietPi:~$ sudo lighttpd -tt -f /etc/lighttpd/lighttpd.conf
2024-07-03 07:04:39: (mod_openssl.c.1335) SSL: inactive/expired X509 certificate '/etc/lighttpd/certs/telens+1.pem'
2024-07-03 07:04:39: (mod_openssl.c.1367) SSL: couldn't read private key from '/etc/lighttpd/certs/telens+1.pem'
2024-07-03 07:04:39: (server.c.1454) Initialization of plugins failed. Going down.

mkcert is a simple tool for making locally-trusted development  certificates. It requires no configuration. (includes Certificate Authority)

self-signed SSL x509 certificates used for IoT development, e.g. microcomputer webserver controlling relays and switches across a LAN, NOT the public Internet.

https://github.com/FiloSottile/mkcert

OS - DietPi variant of raspberry pi OS based on debian bookworm
 DietPi v9.5.1

www-data@DietPi:~$ uname -a
Linux DietPi 6.1.21+ #1642 Mon Apr  3 17:19:14 BST 2023 armv6l GNU/Linux

installed mkcert, openssl, lighttpd, lighttpd-mod-openssl from distro
lighty-enable-mod cgi , lighty-ensble-mod userdir
current versions from distro repository

lighttpd/1.4.69 (ssl) - a light and fast webserver
www-data@DietPi:~$

www-data@DietPi:~$ mkcert -version
1.4.4

www-data@DietPi~$ openssl version
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)

hardware: raspberry pi 0w  32 bit BCM2835 Architecture -  armv6l

https://www.raspberrypi.com/documentation/computers/processors.html

X509 SSL certificate info:

www-data@DietPi:~$ mkcert -install
Created a new local CA 
The local CA is now installed in the system trust store! 

www-data@DietPi:~$ mkcert telens 10.0.0.210
]]
Created a new certificate valid for the following names 
 - "telens" 
 - "10.0.0.210" 

The certificate is at "./telens+1.pem" and the key at "./telens+1-key.pem" 

It will expire on 3 October 2026 

www-data@DietPi:~$ mkcert -version
1.4.4

www-data@DietPi~$ openssl version
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
www-data@DietPi:~$ openssl x509 -in ./telens+1.pem -text -noout
Certificate:
hex code blocks omitted
    Data:
        Version: 3 (0x2)
        Serial Number:
            ca:e3:c0:10:9d:25:8c:83:03:f5:f7:8b:70:ba:a4:e6
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: O = mkcert development CA, OU = www-data@DietPi, CN = mkcert www-data@DietPi
        Validity
            Not Before: Jul  3 03:28:56 2024 GMT
            Not After : Oct  3 03:28:56 2026 GMT
        Subject: O = mkcert development certificate, OU = www-data@DietPi
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:

            Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Authority Key Identifier:
                EC:5C:AF:8B:E3:CD:5D:D6:E1:F7:94:78:9A:07:04:B0:FB:B3:C1:99
            X509v3 Subject Alternative Name:
                DNS:telens, IP Address:10.0.0.210

lighttpd setup:
lighttpd.conf

www-data@DietPi:~$ cat /etc/lighttpd/lighttpd.conf
server.modules = (
        "mod_indexfile",
        "mod_access",
        "mod_alias",
        "mod_redirect",
        "mod_openssl",
)

server.document-root        = "/var/www/html" 
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log" 
server.pid-file             = "/run/lighttpd.pid" 
server.username             = "www-data" 
server.groupname            = "www-data" 
server.port                 = 80

# features
#https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_feature-flagsDetails
server.feature-flags       += ("server.h2proto" => "enable")
server.feature-flags       += ("server.h2c"     => "enable")
server.feature-flags       += ("server.graceful-shutdown-timeout" => 5)
#server.feature-flags       += ("server.graceful-restart-bg" => "enable")

# strict parsing and normalization of URL for consistency and security
# https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_http-parseoptsDetails
# (might need to explicitly set "url-path-2f-decode" = "disable" 
#  if a specific application is encoding URLs inside url-path)
server.http-parseopts = (
  "header-strict"           => "enable",# default
  "host-strict"             => "enable",# default
  "host-normalize"          => "enable",# default
  "url-normalize-unreserved"=> "enable",# recommended highly
  "url-normalize-required"  => "enable",# recommended
  "url-ctrls-reject"        => "enable",# recommended
  "url-path-2f-decode"      => "enable",# recommended highly (unless breaks app)
 #"url-path-2f-reject"      => "enable",
  "url-path-dotseg-remove"  => "enable",# recommended highly (unless breaks app)
 #"url-path-dotseg-reject"  => "enable",
 #"url-query-20-plus"       => "enable",# consistency in query string
)

index-file.names            = ( "index.php", "index.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi", ".js" )
]
# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.conf.pl" 
include "/etc/lighttpd/conf-enabled/*.conf" 

#server.compat-module-load   = "disable" 
server.modules += (
        "mod_dirlisting",
        "mod_staticfile",
)

$SERVER["socket"] == ":443" {
    ssl.engine = "enable" 
    ssl.pemfile = "/etc/lighttpd/certs/telens+1.
server.modules += (pem" 
#    ssl.privkey = "/etc/lighttpd/certs/telens+1-key.pem" 
    server.name = "telens" 
#    server.document-root = "/var/www/html/" 
}

www-data@DietPi:~$ cat /etc/lighttpd/conf-enabled/10-cgi.conf
# 10-cgi.conf v1.2
# /usr/share/doc/lighttpd/cgi.txt

server.modules += ( "mod_cgi" )

$HTTP["url"] =~ "^/cgi-bin/" {
        cgi.assign = ( ".sh" => "/usr/bin/bash" )
        alias.url += ( "/cgi-bin/" => "/var/www/html/cgi-bin/" )
}

# Add this line to allow direct access to .js files in cgi-bin
# static-file.exclude-extensions -= ( ".js" )

## Warning this represents a security risk, as it allow to execute any file
## with a .pl/.py even outside of /usr/lib/cgi-bin.
#
#cgi.assign      = (
#       ".pl"  => "/usr/bin/perl",
#       ".py"  => "/usr/bin/python",
#)

.

www-data@DietPi:~$ sudo lighttpd -p -f /etc/lighttpd/lighttpd.conf
config {
    var.CWD                        = "/home/www-data" 
    var.PID                        = 15591

mimetypes omitted

    server.document-root           = "/var/www/html" 
    server.upload-dirs             = ("/var/cache/lighttpd/uploads")
    server.errorlog                = "/var/log/lighttpd/error.log" 
    server.pid-file                = "/run/lighttpd.pid" 
    server.username                = "www-data" 
    server.groupname               = "www-data" 
    server.port                    = 80
    server.feature-flags           = (
        "server.h2proto"                   => "enable",
        "server.h2c"                       => "enable",
        "server.graceful-shutdown-timeout" => 5,
    )
    server.http-parseopts          = (
        "header-strict"            => "enable",
        "host-strict"              => "enable",
        "host-normalize"           => "enable",
        "url-normalize-unreserved" => "enable",
        "url-normalize-required"   => "enable",
        "url-ctrls-reject"         => "enable",
        "url-path-2f-decode"       => "enable",
        "url-path-dotseg-remove"   => "enable",
    )
    index-file.names               = ("index.php", "index.html", "index.lighttpd.html")
    url.access-deny                = ("~", ".inc")
    static-file.exclude-extensions = (".php", ".pl", ".fcgi", ".js")
    userdir.exclude-user           = ("root", "postmaster")
    userdir.path                   = "public_html" 
    server.modules                 = (
        "mod_indexfile",
        "mod_access",
        "mod_alias",
        "mod_redirect",
        "mod_openssl",
        "mod_cgi",
        "mod_userdir",
        "mod_dirlisting",
        "mod_staticfile",
    )

    $SERVER["socket"] == "[::]:80" {
        # block 1

    } # end of $SERVER["socket"] == "[::]:80" 

    $HTTP["url"] =^ "/cgi-bin/" {
        # block 2
        cgi.assign = (
            ".sh" => "/usr/bin/bash",
        )
        alias.url  = (
            "/cgi-bin/" => "/var/www/html/cgi-bin/",
        )

    } # end of $HTTP["url"] =^ "/cgi-bin/" 

    $SERVER["socket"] == ":443" {
        # block 3
        ssl.engine  = "enable" 
        ssl.pemfile = "/etc/lighttpd/certs/telens+1.pem" 
        server.name = "telens" 

    } # end of $SERVER["socket"] == ":443" 
}
www-data@DietPi:~$


Replies (7)

RE: lighttpd stopped reading apparently valid/complete self-signed x509 SSLcertificates for TLS - Added by avij 2 months ago

The config you pasted is somewhat garbled. Please try posting it as preformatted text.

In any case, do note that you must have either ssl.pemfile pointing to a file that has both the certificate and the private key, or ssl.pemfile pointing to the certificate and ssl.privkey pointing to the private key. The .pem files are just text, so have a look at what they contain. Search for BEGIN PRIVATE KEY and BEGIN CERTIFICATE sections.

RE: lighttpd stopped reading apparently valid/complete self-signed x509 SSLcertificates for TLS - Added by gstrauss 2 months ago

I reformatted the original post.

This looks like a cut-n-paste error in the post above, or else it is broken lighttpd.conf syntax

    ssl.pemfile = "/etc/lighttpd/certs/telens+1.
server.modules += (pem" 

As for the errors:

www-data@DietPi:~$ sudo lighttpd -tt -f /etc/lighttpd/lighttpd.conf
2024-07-03 07:04:39: (mod_openssl.c.1335) SSL: inactive/expired X509 certificate '/etc/lighttpd/certs/telens+1.pem'
2024-07-03 07:04:39: (mod_openssl.c.1367) SSL: couldn't read private key from '/etc/lighttpd/certs/telens+1.pem'
2024-07-03 07:04:39: (server.c.1454) Initialization of plugins failed. Going down.

The first warning is due to time64 on your 32-bit system where lighttpd is using 64-bit time, but your openssl library is not. There is a workaround in lighttpd 1.4.75. (See #3244)

As avij noted: the second is an error and is your issue. SSL: couldn't read private key from '/etc/lighttpd/certs/telens+1.pem'

The key is probably missing from '/etc/lighttpd/certs/telens+1.pem' if you did not manually add the key to the cert file.

Please see lighttpd TLS docs and use ssl.privkey to specify the path to the private key instead of having both certificate and key in the same file.

If you still have issues, please try a different set of instructions to generate a self-signed cert: HowToSimpleSSL and test with that certificate.

https://github.com/FiloSottile/mkcert README states:
The certificate is at "./example.com+5.pem" and the key at "./example.com+5-key.pem"
so your lighttpd.conf should use

ssl.pemfile = "/path/to/example.com+5.pem" 
ssl.privkey = "/path/to/example.com+5-key.pem" 

Note the -key.pem suffix on the privkey file.

RE: lighttpd stopped reading apparently valid/complete self-signed x509 SSLcertificates for TLS - Added by alizardx 2 months ago

    ssl.pemfile = "/etc/lighttpd/certs/telens+1.
server.modules += (pem" 

sorry, that was indeed a copy/paste error. ssl.pemfile correct in actual lighttpd.conf:
$SERVER["socket"] == ":443" {
    ssl.engine = "enable" 
    ssl.pemfile = "/etc/lighttpd/certs/telens+1.pem" 
    ssl.privkey = "/etc/lighttpd/certs/telens+1-key.pem" 
    server.name = "telens" 
#    server.document-root = "/var/www/html/" 

i corrected ssl.privkey by uncommenting it. verified telens+1.pem contains certificate, telens+1-key contains key, ssl.pemfile and ssl.privkey appear correct.
result:
www-data@DietPi:~$ sudo lighttpd -tt -f  /etc/lighttpd/lighttpd.conf 
2024-07-05 08:36:33: (mod_openssl.c.1335) SSL: inactive/expired X509 certificate '/etc/lighttpd/certs/telens+1.pem'
www-data@DietPi:~$

will try how to simple ssl.
thanks

RE: lighttpd stopped reading apparently valid/complete self-signed x509 SSLcertificates for TLS - Added by alizardx 2 months ago

lighttpd.conf updated as specified in
Setting up a simple SSL configuration with a self-signed certificate¶

$SERVER["socket"] == ":443" {
  ssl.engine = "enable" 
  ssl.pemfile = "/etc/lighttpd/certs/lighttpd.pem" 
}

www-data@DietPi:~$ openssl req -new -x509 -keyout lighttpd.pem -out lighttpd.pem -days 365 -nodes
....+.....+......+.+......+...............+.....+....+.....+.+...+.........+...+...
.+..+....+.....+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:REPTILELABS
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:telens
Email Address []:
www-data@DietPi:~$ ls
lighttpd.pem  telens+1-key.pem  telens+1.pem
www-data@DietPi:~$ sudo cp ./lighttpd.pem /etc/lighttpd/certs/
[sudo] password for www-data:
www-data@DietPi:~$ sudo chmod 0400 /etc/lighttpd/certs/lighttpd.pem
www-data@DietPi:~$ sudo chown root:root  /etc/lighttpd/certs/lighttpd.pem
www-data@DietPi:~$ sudo nano /etc/lighttpd/lighttpd.conf
www-data@DietPi:~$ sudo lighttpd -tt -f /etc/lighttpd//lighttpd.conf
2024-07-05 10:04:42: (mod_openssl.c.1335) SSL: inactive/expired X509 certificate '/etc/lighttpd/certs/lighttpd.pem'

RE: [Solved] lighttpd stopped reading apparently valid/complete self-signed x509 SSLcertificates for TLS - Added by gstrauss 2 months ago

Please use <pre> tags around the information in your posts. I have corrected them.

2024-07-05 10:04:42: (mod_openssl.c.1335) SSL: inactive/expired X509 certificate '/etc/lighttpd/certs/lighttpd.pem'

The warning is due to time64 on your 32-bit system where lighttpd is using 64-bit time, but your openssl library is not. There is a workaround in lighttpd 1.4.75. (See #3244)

    (1-7/7)