moode-player / moode

moOde sources and configs
GNU General Public License v3.0
1k stars 166 forks source link

Support for HTTPS via a self-signed certificate #585

Closed ReK42 closed 1 year ago

ReK42 commented 1 year ago

I saw the custom scripts feature for the restore process and wrote a script which will re-enable TLS on Nginx.

This should be fairly easy to adapt into the image itself as a first-run script. Note that it should be re-run whenever the hostname changes.

Potential future improvements:

#!/bin/bash
# Ensure this is running as root
if [ "$EUID" -ne 0 ]; then
    >&2 echo "Error: This script must be run as root"
    exit 1
fi

# Ensure OpenSSL is installed
OPENSSL=$(which openssl)
if [ "$OPENSSL" = "" ]; then
    >&2 echo "Error: Could not find openssl, ensure it is installed and in the PATH"
    exit 1
fi

# Initialize variables
FQDN="$HOSTNAME.local"
TLS_DIR="/etc/pki/tls"
CERT_DIR="$TLS_DIR/certs"
PRIV_DIR="$TLS_DIR/private"
CFG_FILE="$TLS_DIR/$FQDN.conf"
CSR_FILE="$TLS_DIR/$FQDN.csr"
CRT_FILE="$CERT_DIR/$FQDN.crt"
KEY_FILE="$PRIV_DIR/$FQDN.key"
NGINX_CFG_FILE="/etc/nginx/nginx.conf"

# Check for and create self-signed certificate if not present
#     NOTE: Does not check for certificate validity (hostname, expiry)
if [ ! -f "$CRT_FILE" ]; then
    # Create directories and files, set permissions
    mkdir --parents $CERT_DIR $PRIV_DIR
    touch $CFG_FILE $CSR_FILE $CRT_FILE $KEY_FILE
    chmod --recursive 755 "$TLS_DIR/.."
    chmod 700 $PRIV_DIR
    chmod 644 $CFG_FILE $CSR_FILE $CRT_FILE
    chmod 600 $KEY_FILE

    # Initialize OpenSSL config file
    cat >> $CFG_FILE <<EOF
[ req ]
default_bits            = 2048
encrypt_key             = no
default_md              = sha256
string_mask             = nombstr
prompt                  = no
distinguished_name      = req_dn
req_extensions          = req_ext

[ req_dn ]
commonName              = $FQDN

[ req_ext ]
basicConstraints        = critical, CA:FALSE
keyUsage                = digitalSignature, keyEncipherment, nonRepudiation
extendedKeyUsage        = clientAuth, serverAuth
subjectAltName          = @req_sans

[ req_sans ]
DNS.1                   = $FQDN
EOF

    # Create CSR, key and self-signed certificate
    $OPENSSL req -new -config $CFG_FILE -out $CSR_FILE -keyout $KEY_FILE
    $OPENSSL req -x509 -days 3650 -config $CFG_FILE -in $CSR_FILE -key $KEY_FILE -out $CRT_FILE -extensions req_ext
fi

# Check for a update Nginx TLS config if not present
#     NOTE: Does not check included config files (/etc/nginx/*.d)
TEST=$(grep "listen 443" $NGINX_CFG_FILE)
if [ "$TEST" = "" ]; then
    # Initialize Nginx config insert section
    if [ -f "/tmp/nginx_cfg_section" ]; then
        rm -f /tmp/nginx_cfg_section
    fi
    cat >> /tmp/nginx_cfg_section <<EOF
                listen 80 default_server;
                listen [::]:80 default_server;
                return 301 https://\$host\$request_uri;
        }

        server {
                listen 443 ssl http2;
                listen [::]:443 ssl http2;

                ssl_certificate $CRT_FILE;
                ssl_certificate_key $KEY_FILE;
                ssl_session_timeout 1d;
                ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
                ssl_session_tickets off;

                # modern configuration
                ssl_protocols TLSv1.3;
                ssl_prefer_server_ciphers off;
EOF

    # Reconfigure Nginx to use the new certificate
    if [ -f "/tmp/nginx_cfg_file" ]; then
        rm -f /tmp/nginx_cfg_file
    fi
    awk '/listen 80;/{system("cat /tmp/nginx_cfg_section");next}1' $NGINX_CFG_FILE > /tmp/nginx_cfg_file
    mv -f /tmp/nginx_cfg_file $NGINX_CFG_FILE
    rm -f /tmp/nginx_cfg_section
    systemctl restart nginx
fi
moodeaudio commented 1 year ago

Couple questions:

  1. Whats the usage scenario where https is needed to access moOde?
  2. Does user have to do anything in the Browser for example approve a security/certificate check warning?
ReK42 commented 1 year ago

HTTPS is a basic feature of modern web communication and should be turned on by default. Even with an untrusted certificate, such as a self-signed cert, it still provides numerous benefits. All major browsers require it for HTTP/2 connections and are moving towards requiring it for everything (https://www.eff.org/deeplinks/2021/09/https-actually-everywhere)

With a self-signed certificate, the user is prompted that the certificate is not trusted and they have to click accept to proceed. The UI is different depending on the client browser, but the behaviour is consistent across them. This is normal behaviour seen on many appliances which offer a web UI such as server infrastructure, IOT devices, etc.

moodeaudio commented 1 year ago

My understanding is that HTTPS-only mode will be optional in Browsers for the foreseeable future. If Browsers only accepted HTTPS there would I imagine be a lot of application breakage on LAN's.

The challenge in doing HTTPS for moOde is the messy process the user has to go through to just access the player. it's an even messier process to get the Browser to trust the self-signed cert so the warnings and dialogs go away.

In spite of this I'm in favor of your approach.

Some things to consider are:

  1. Many users have multiple Pi's and thus multiple different hostnames
  2. Users access moOde via hostname, hostname.local or IP_ADDRESS
  3. Access Point mode uses 172.24.1.1 or hostname.local
  4. Chromium-browser is used to render the UI on locally attached displays and it currently uses http://localhost
ReK42 commented 1 year ago
  1. In the case of multiple pis, I'd recommend ensuring each have a unique hostname and therefore unique certificate. Unless cross-trust is required for embeds, they should be able to be treated individually. This would be required even without certificates, as the nature of MDNS responses means if multiple devices share the same hostname, the user will have no way of knowing which device they're viewing when going to hostname.local and it can potentially change on each refresh.
  2. I'd recommend keeping the common name of the certificate as the FQDN, i.e. hostname.local, however the others can be added to the certificates as SANs. There is already a SAN for hostname.local so you can just add DNS.2 = <hostname>. Note that I'd recommend suggesting users don't load via IP address directly as the default is DHCP, meaning it can change at any time. It is possible to add IP addresses as SANs on a certificate but I don't recommend it for that reason.
  3. See previous, can be handled the same way.
  4. I'd recommend changing these references to use hostname. In linux, the local hostname is entered into /etc/hosts and will always resolve immediately to localhost without a DNS request. This means the name matches the already-existing certificate and therefore won't throw any errors. Modifying the script to also add the self-signed certificate to the ca trust list will cause the display to load headlessly without prompting the user, resulting in no change in application behaviour.
moodeaudio commented 1 year ago

I suppose what I meant to say in (1) was that users will be changing the hostname but you have already covered that scenario (rerun the script when user changes hostname) in your OP.

Wrt IP address, there are several scenarios.

  1. The AP mode IP address is fixed at 172.24.1.1 and so could be added to the cert.
  2. Users can configure either DHCP or Static IP address in moOde's Network Config and a certain segment of users configure static address and access using http://IP_address. In some cases it's because name resolution is somehow broken on their networks. I'm not sure about other cases where a static address or http://IP_ADDRESS is needed.
  3. There may still be the issue where Browsers on certain versions Android don't support .local (mDNS) and thus the only option for user is http://IP_ADDRESS

Does this mean no Browser warnings or dialogs that user has to deal with? Modifying the script to also add the self-signed certificate to the ca trust list will cause the display to load headlessly without prompting the user, resulting in no change in application behaviour.

ReK42 commented 1 year ago

Yes, as long as the issuing certificate (which is the certificate itself, hence self-signed) is trusted by the base OS and the name/address used to access the page matches the CN or one of the SANs, no errors will be presented to the user and the page will just load.

It may be worth extending the script so that if a static IP is configured or AP mode is enabled, it will be added to the certificate. I generally recommend avoiding adding IP addresses to certificates even in cases where it's static since some organizations view internal addressing as sensitive information and having it in the certificate can leak that, even when behind a reverse proxy/load balancer, but that really shouldn't matter for moode.

To handle things like DHCP reservations or regular DNS records the user configures externally to moode you could simply allow the user to upload a certificate/key file manually to overwrite whatever the script would normally generate. This has the added benefit of allowing the user to sign the certificate with an actual CA, either private or public.

moodeaudio commented 1 year ago
  1. This: It may be worth extending the script so that if a static IP is configured or AP mode is enabled, it will be added to the certificate. could work. AP mode address never changes so it could be default added to cert.
  2. This: `allow the user to upload a certificate/key file manually' is prolly too technical and complex for most users.
  3. Wrt script automatically add the self-signed certificate to the ca trust list only covers the AP mode access and chromium-browser access to local display, correct?
  4. There is still the mess of adding to root CA list on Mac, Windows, Linux clients. This could prolly be automated with some scripting but I have no expertise in Windows or MacOS scripting and their root CA stores.

I think this feature would need to be implemented as optional at first so that field usage can surface the failure modes.

ReK42 commented 1 year ago

Wrt script automatically add the self-signed certificate to the ca trust list only covers the AP mode access and chromium-browser access to local display, correct?

The OS CA trust is only used for clients on that OS. So the local display would be the only thing affected.

There is still the mess of adding to root CA list on Mac, Windows, Linux clients. This could prolly be automated with some scripting but I have no expertise in Windows or MacOS scripting and their root CA stores.

I would not do this. Adding certificates to the trust store can be a significant security issue and is not necessary. Browsers will remember it once the user has clicked accept once.

This: `allow the user to upload a certificate/key file manually' is prolly too technical and complex for most users.

Probably, but it's very little effort to add as a feature for those who do want to do it. You simply need to overwrite /etc/pki/tls/certs/<fqdn>.crt and /etc/pki/tls/private/<fqdn>.key with the files they upload.

moodeaudio commented 1 year ago

Is it this easy (one click) for user to add a self-signed cert to the store? Browsers will remember it once the user has clicked accept once.

Just to get a level-set what other Linux audio players are running over https on a local network?

ReK42 commented 1 year ago

That does not add the certificate to the store, it adds an exception for that specific certificate at that specific location. But yes, depending on the UI it may be two clicks: this user help page from a university includes screenshots of the process for all major browsers.

moodeaudio commented 1 year ago

Ok, thanks.

One possibility:

  1. Add an options to System Config to allow user to turn on/off "HTTPS-only mode".
  2. The NGINX conf file would maintain full port 80 and 443 server sections.
  3. Turning on/off HTTPS-only mode would simply sed the file to remove/add # to the line return 301 https://\$host\$request_uri; in the port 80 section.
  4. The cert check / create part of the script would be run during moOde startup (worker.php). This covers the case where user changes the hostname in System Config since this requires a restart for the change to take effect.

Script enhancements:

  1. Add a program header containing an Open Source License for example GPLv3 or MIT otherwise I would not be able to integrate and redistribute your code contrib.
  2. Add 172.24.1.1 to the cert to support HTTPS in AP mode.
  3. Not sure the static IP address case needs to be handled. User can just use port 80.

Let me know what you think.

ReK42 commented 1 year ago

I'd recommend restructuring the config files. I wrote the script to run as part of the backup restore operation for the current environment but it would be better to use proper configs if we can modify the base image.

Nginx can use include files inside config statements. The HTTP redirect and full HTTP serve config could be in two separate files, then the setting can just change the one line in the main config for which should be included.

Similarly, the openssl config file could be stored on filesystem with placeholder values, then the script can simply copy that file to /tmp, replace the values and add the IP.1=172.24.1.1 to the end of the file if necessary.

I included the hostname in the openssl and certificate file name out of habit, as that is best practice due to potentially needing multiple certificates, but that isn't true in this case. It would be easier to detect and work with these files if they were statically named.

moodeaudio commented 1 year ago

Makes sense. Prolly something similar to this https://gist.github.com/lon-io/443bbc7b1caa0b7c48bd3cfd0b89532a

I have a stub feature worked up and if you are able to do a Gulp build of moOde from the develop branch you could test it out after I post the commit later this week or just wait till 8.2.3 is released later this month. The feature can be unhidden for testing by updating the Feature Availability Bitmask via the moodeutl command.

Couple things:

  1. There are three instances in moOde where curl is used to send data to another PHP script. Will curl automatically handle the 301 redirect?
  2. The CamillaDSP feature includes a Pipeline editor GUI thats accessed via the URL below $_camillagui_url = 'http://'. $_SERVER['HTTP_HOST'] . ':15000'; where $_SERVER['HTTP_HOST'] is the hostname for example "moode". Camilla uses it's own built-in web server.
  3. If any of your code is used what License do you prefer?
moodeaudio commented 1 year ago

After some testing, the Browser warnings issue ends up being too messy. Have a look at the Chrome address bar after allowing the exception. It has "Not secure" with https crossed out. The other challenge is that exception process has to be repeated each time Browser is opened afresh.

Btw, the feature framework for HTTPS-Only has been committed. There are some additional files not in the commit that are needed to make it fully functions. Email me if you would like the files for testing.

Screen Shot 2022-12-07 at 6 45 33 AM

Screen Shot 2022-12-07 at 6 45 56 AM

ReK42 commented 1 year ago

That should not be the behaviour. Unless you're in private/incognito mode, the exception should be remembered and the only reason to reprompt is if the certificate changes, you access it via a different name, or there's a new error (e.g. it expired). I just tested using Chrome 108.0.5359.95, Firefox 107.0.1 and Edge 108.0.1462.42 and they all behave that way for me (Windows 10 21H2 client).

Here's what it looks like on Firefox:

image

bitkeeper commented 1 year ago

First great effort that you try to harding the security of moOde! Not sure if self signed certificates are a cure or a disease, especially with home networks ;-)

Some thoughts about it:

If something is eavesdropping on your local lan you will prob have other 'issues' as well. For example login with SSH to gain root access to the Pi will cause more harm (expect that most users never change the default password).

The camilladsp gui can be setup to be bound to http://localhost:15000. With a nginx conf you can redirect for example https://moode/camillagui to http://localhost:15000.

moodeaudio commented 1 year ago

@bitkeeper: Good to know re camillagui. What about curl? It's used in 3 scripts to send commands to other scripts. Can it handle the 301 redirect?

@ReK42: Chrome ver was 108.0.5359.94 on MacOS. Of course there could be bugs in my implementation. Have a look at the files.

gen-cert.sh

# Template
OPENSSL_CFG_FILE=/tmp/nginx-selfsigned.conf
cat >> $OPENSSL_CFG_FILE <<EOF
[ req ]
default_bits            = 2048
encrypt_key             = no
default_md              = sha256
string_mask             = nombstr
prompt                  = no
distinguished_name      = req_dn
req_extensions          = req_ext

[ req_dn ]
commonName              = $HOSTNAME.local

[ req_ext ]
basicConstraints        = critical, CA:FALSE
keyUsage                = digitalSignature, keyEncipherment, nonRepudiation
extendedKeyUsage        = clientAuth, serverAuth
subjectAltName          = @req_sans

[ req_sans ]
DNS.1                   = $HOSTNAME.local
DNS.2                   = $HOSTNAME
IP.1                    = 172.24.1.1
EOF

# Cert
SSL_CSR_FILE=/tmp/nginx-selfsigned.csr
SSL_CRT_FILE=/etc/ssl/certs/nginx-selfsigned.crt
SSL_KEY_FILE=/etc/ssl/private/nginx-selfsigned.key
openssl req -new -config $OPENSSL_CFG_FILE -out $SSL_CSR_FILE -keyout $SSL_KEY_FILE
openssl req -x509 -days 3650 -config $OPENSSL_CFG_FILE -in $SSL_CSR_FILE -key $SSL_KEY_FILE -out $SSL_CRT_FILE -extensions req_ext

# TEST
# Chromium-browser trust store
#sudo apt -y install libnss3-tools
#CERT_NICKNAME=NGINX Self-signed Cert
#certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n $CERT_NICKNAME -i $SSL_CRT_FILE

# TEST
# Debian trust store (needed?)
#sudo cp $SSL_CRT_FILE /usr/local/share/ca-certificates/
#sudo update-ca-certificates

nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        client_max_body_size 75M;

        ##
        # SSL Settings
        ##

        #ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        #ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log off;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        #include /etc/nginx/conf.d/*.conf;
        #include /etc/nginx/sites-enabled/*;

        ##
        # moOde UI server
        ##

        server {
                listen 80 default_server;
                #listen [::]:80 default_server;
                #return 301 https://$host$request_uri;

                location / {
                    root /var/www;
                    index index.html index.php;
                    try_files $uri $uri/ /coverart.php;
                }

                location /imagesw/ {
                    root /var/local/www;
                }

                # php-fpm
                location ~ \.php$ {
                    root /var/www;
                    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
                    fastcgi_index index.php;
                    fastcgi_param SCRIPT_FILENAME $request_filename;
                    include fastcgi_params;
                }
        }

        server {
                listen 443 ssl http2;
                #listen [::]:443 ssl http2;
                include snippets/self-signed.conf;
                include snippets/ssl-params.conf;

                location / {
                    root /var/www;
                    index index.html index.php;
                    try_files $uri $uri/ /coverart.php;
                }

                location /imagesw/ {
                    root /var/local/www;
                }

                # php-fpm
                location ~ \.php$ {
                    root /var/www;
                    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
                    fastcgi_index index.php;
                    fastcgi_param SCRIPT_FILENAME $request_filename;
                    include fastcgi_params;
                }
        }
}

snippets/self-signed.conf snippets/ssl-params.conf

# Self-signed
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

# SSL params
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_tickets off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ReK42 commented 1 year ago

@moodeaudio can you post the certificate details you're seeing in browser? Specifically looking for the common name and subject alternative names. For Chrome on Windows this looks like:

image

image

image

ReK42 commented 1 year ago

@bitkeeper

  • First issue is that not all home router have a correct working dhcp with dns integration. (Can not resolve devices based on name). Also assuming for the local domain can get you into trouble.

.local domains are resolved using MDNS and do not rely on your home router. As long as the client and the moode box are on the same subnet it should work. If you want to configure a regular unicast DNS name for the moode box that would be on the user to setup their DNS server correctly.

  • Not sure if a self signed certificate for 10 year is really a best security practice.
  • Without authentication signing/encrypting will not prevent abuse by just opening a webclient to it. For example start the web ssh terminal.

This is very true, but encryption is better than no encryption and a long-term self-signed certificate is a low-friction way to get that without requiring user configuration. Further security enhancements are worth discussing but I'd recommend keeping this issue about the low hanging fruit that is enabling encryption.

  • Next is the message Tim shows; if very scary for my other family members. Even if it is there only one time.
  • Certificate is signed and created by device; I prefer to have the choice to supply it my self. (Added one CA as trusted to often used home clients, devices will get a cert signed by the CA. In this way you will not get any warnings on new devices, while you can easy add more devices with https )

This would be possible if a UI were added to allow the user to upload a customer certificate/keypair. The user will need to know how to properly construct the certificate file, i.e. certificate chaining, but I think that's a reasonable assumption for anyone running their own CA. Another possible solution is Let's Encrypt via certbot, but that requires publicly-resolvable DNS records which Let's Encrypt can verify, a discussion for another day I think.

  • And what about other open ports from programs like mpd, upmpdcli ? Should for example mpd default be bound to localhost instead of 0.0.0.0 ?

Something I was going to bring up in a separate issue. A host firewall should absolutely be enabled but it will require some effort to understand exactly which services need to be allowed. A number of the protocols in use, like AirPlay and UPnP, are not as straightforward as HTTP/S.

If something is eavesdropping on your local lan you will prob have other 'issues' as well. For example login with SSH to gain root access to the Pi will cause more harm (expect that most users never change the default password).

True, but not a reason to not encrypt. What if the moode box is on an open guest network, or available publicly via port forwarding?

The camilladsp gui can be setup to be bound to http://localhost:15000. With a nginx conf you can redirect for example https://moode/camillagui to http://localhost:15000.

Yes, Nginx is perfect for this.

ReK42 commented 1 year ago

@moodeaudio I'd recommend keeping the /etc/pki/tks/certs and /etc/pki/tls/private paths, they are standard on many Linux distributions.

I'd also recommend structuring the Nginx configs as below. This means the setting only needs to comment/uncomment the redirect/include lines under the listen 80 section. I'd also recommend not disabling the IPv6 listen statement, MDNS responses can be for IPv6 and if both the moode box and the client have that enabled it will be used by default on many clients.

/etc/nginx/nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        client_max_body_size 75M;

        ##
        # SSL Settings
        ##

        #ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        #ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log off;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        #include /etc/nginx/conf.d/*.conf;
        #include /etc/nginx/sites-enabled/*;

        ##
        # moOde UI server
        ##

        server {
                listen 80 default_server;
                listen [::]:80 default_server;

                # Redirect HTTP to HTTPS
                #return 301 https://$host$request_uri;

                # moOde web server config
                include snippets/moode.conf;
        }

        server {
                listen 443 ssl http2;
                listen [::]:443 ssl http2;

                ssl_certificate /etc/pki/tls/certs/nginx-selfsigned.crt;
                ssl_certificate_key /etc/pki/tls/private/nginx-selfsigned.key;

                ssl_session_timeout 1d;
                ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
                ssl_session_tickets off;
                ssl_protocols TLSv1.3;
                ssl_prefer_server_ciphers off;

                # moOde web server config
                include snippets/moode.conf;
        }
}

/etc/nginx/snippets/moode.conf

location / {
    root /var/www;
    index index.html index.php;
    try_files $uri $uri/ /coverart.php;
}

location /imagesw/ {
    root /var/local/www;
}

# php-fpm
location ~ \.php$ {
    root /var/www;
    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    include fastcgi_params;
}
ReK42 commented 1 year ago

@moodeaudio I'd recommend placing a static OpenSSL config on the filesystem and then running it from the script, using an environment variable for the hostname. This is a lot cleaner in the script and doesn't use a temp file.

/etc/pki/tls/nginx-selfsigned.conf

[ req ]
default_bits            = 2048
encrypt_key             = no
default_md              = sha256
string_mask             = nombstr
prompt                  = no
distinguished_name      = req_dn
req_extensions          = req_ext
oid_section             = new_oids

[ req_dn ]
commonName              = ${ENV::MOODE_HOSTNAME}.local

[ req_ext ]
basicConstraints        = critical, CA:FALSE
keyUsage                = digitalSignature, keyEncipherment, nonRepudiation
extendedKeyUsage        = clientAuth, serverAuth
subjectAltName          = @req_sans

[ req_sans ]
DNS.1                   = ${ENV::MOODE_HOSTNAME}.local
DNS.2                   = ${ENV::MOODE_HOSTNAME}

Script

#!/bin/bash
export MOODE_HOSTNAME="testing"
openssl req -new -config /etc/pki/tls/nginx-selfsigned.conf -out /etc/pki/tls/nginx-selfsigned.csr -keyout /etc/pki/tls/private/nginx-selfsigned.key

You can check the results with openssl req -text -in /etc/pki/tls/nginx-selfsigned.csr

moodeaudio commented 1 year ago

Wrt the recent posts:

On RaspiOS the standard is /etc/ssl/ and so I'm not seeing a good reason to use something else.

Good points on the configs. I'll review.

Here's some screenies: Screen Shot 2022-12-07 at 5 38 41 PM

Screen Shot 2022-12-07 at 5 38 55 PM

Screen Shot 2022-12-07 at 5 40 59 PM

ReK42 commented 1 year ago

Ah, /etc/pki/tls is standard on EL-based distros, I didn't realize it was different for Debian-based distros.

I'm not sure why you're getting reprompted each time, the CN and SANs look correct. What is the error you see on the prompt page in Chrome?

image

moodeaudio commented 1 year ago

Similar to your pic

Screen Shot 2022-12-07 at 7 37 00 PM

ReK42 commented 1 year ago

Do you have the same problem if you go to https://moode.local ?

moodeaudio commented 1 year ago

That screenie was from direct entry of the the https url. It's same if http is directly entered and 301'd to https.

ReK42 commented 1 year ago

I meant trying the FQDN rather than just the hostname. It's possible there's special handling in Chrome for TLDs?

moodeaudio commented 1 year ago

Yes, I tested moode and moode.local. Same result.

I can make a test image available with the feature so you can attempt a repro. You would just need to add a few files to make it fully functional. Email tim at moodeaudio dot org and I'll send you a download link.

moodeaudio commented 1 year ago

Will reopen if there is a solution that does not impact the user.

Maybe Browser makers will come up with something for HTTPS for web applications on residential networks.