FrankenPHP with Caddyfile: tls: client offered only unsupported versions: [301]

1. The problem I’m having:

I’m trying to use FrankenPHP on an Alma Linux 9 VPS.

I have /var/www/html/index.php, which just outputs phpinfo().

If I run FrankenPHP directly from the CLI, it works fine:

cd /var/www/html
frankenphp php_server

Browsing to the IP address yields the expected output.

However, when I try to do this with frankenphp running as a service, I get TLS errors

[Update:
I swear it was working from the CLI – I literally saw the output – but once I stopped the service and tried it again, I couldn’t get it to work

2. Error messages and/or full log output:


Aug  7 15:44:41 srv575029 frankenphp[1531]: {"level":"debug","ts":1723045481.267512,"logger":"events","msg":"event","name":"tls_get_certificate","id":"8ef56b65-a3cb-43cb-a7d6-0775428b932c","origin":"tls","data":{"client_hello":{"CipherSuites":[10794,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],"ServerName":"","SupportedCurves":[23130,29,23,24,25],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,515,2053,2053,1281,2054,1537,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[43690,772,771,770,769],"RemoteAddr":{"IP":"82.7.154.110","Port":61347,"Zone":""},"LocalAddr":{"IP":"82.180.154.41","Port":443,"Zone":""}}}}
Aug  7 15:44:41 srv575029 frankenphp[1531]: {"level":"debug","ts":1723045481.2675369,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"82.180.154.41"}
Aug  7 15:44:41 srv575029 frankenphp[1531]: {"level":"debug","ts":1723045481.267547,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"82.7.154.110","remote_port":"61347","server_name":"","remote":"82.7.154.110:61347","identifier":"82.180.154.41","cipher_suites":[10794,4865,4866,4867,49196,49195,52393,49200,49199,52392,49162,49161,49172,49171,157,156,53,47,49160,49170,10,22016],"cert_cache_fill":0,"load_or_obtain_if_necessary":true,"on_demand":false}
Aug  7 15:44:41 srv575029 frankenphp[1531]: {"level":"debug","ts":1723045481.2675824,"logger":"http.stdlib","msg":"http: TLS handshake error from 82.7.154.110:61347: no certificate available for '82.180.154.41'"}
Aug  7 15:44:41 srv575029 frankenphp[1531]: {"level":"debug","ts":1723045481.328796,"logger":"http.stdlib","msg":"http: TLS handshake error from 82.7.154.110:61348: tls: client offered only unsupported versions: [301]"}

[Update from CLI, errors now}

2024/08/07 16:06:55.465 WARN    admin   admin endpoint disabled
2024/08/07 16:06:55.465 WARN    http.auto_https server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server {"server_name": "php", "http_port": 80}
2024/08/07 16:06:55.465 INFO    tls.cache.maintenance   started background certificate maintenance      {"cache": "0xc000569600"}
2024/08/07 16:06:55.465 INFO    http.log        server running  {"name": "php", "protocols": ["h1", "h2", "h3"]}
2024/08/07 16:06:55.465 INFO    FrankenPHP started ⎻Ÿ˜ {"php_version": "8.3.10", "num_threads": 2}
2024/08/07 16:06:55.466 INFO    Caddy serving PHP app on :80
2024/08/07 16:06:55.473 INFO    tls     storage cleaning happened too recently; skipping for now        {"storage": "FileStorage:/root/.local/share/caddy", "instance": "ecf296da-98ea-4aeb-aa45-dae01d3e9a81", "try_again": "2024/08/08 16:06:55.473", "try_again_in": 86399.99999941}
2024/08/07 16:06:55.473 INFO    tls     finished cleaning storage units

from cURL

curl: (35) LibreSSL/3.3.6: error:1404B438:SSL routines:ST_CONNECT:tlsv1 alert internal error

3. Caddy version:

FrankenPHP v1.2.3 PHP 8.3.10 Caddy v2.8.4

4. How I installed and ran Caddy:

I installed the frankenphp binary

a. System environment:

Alma Linux 9 (x86_64)

b. Command:

systemctl start frankenphp

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

{
        # Enable FrankenPHP
        frankenphp

        #logging
        log {
                output stderr
                level DEBUG
        }
}

82.180.154.41 {   # I also tried `localhost`
        # Enable compression (optional)
        encode zstd br gzip

        root * /var/www/html/

        # Execute PHP files in the current directory and serve assets
        php_server
}

5. Links to relevant resources:

Bloody hell. I had to re-image the server to get it to work again.
Here’s proof of the CLI command working.

And I can confirm the same order of events happened this time around too. Once I enabled the service, it all stops working, and from that point onwards I cannot run it from the command line, even if I reboot stop the service and reboot the server, the CLI version still won’t work again.

That is TLS 1.0, which is broken and not supported. The client needs to use a more modern TLS version.

1 Like

Thanks for the quick reply!
However, I have no idea what that means. What do you mean by client? Do you mean the browser? If so I’ve tried 'em all, all at the latest versions. Also why would it work then not work?

I tried a third time - re-imaged the server. This time I couldn’t get it to work at all.

It looks like occasionally the redirect to https doesn’t work and then it serves the page via http, in which case I get to see the content. But this happens rarely and intermittently.

But I can’t think of what you mean by client… ChatGPT seems to think you mean browser… which is odd because browsers keep themselves updated these days, so how would it end up trying an old version of TLS? I also get the same issue via cURL, so I wouldn’t know how to change the TLS version being requested by any of those.

The client is whatever is making the connection to the server. It could be a proxy (if being proxied/MITM’ed/intercepted), or a browser, or a bot/script, etc.

What logs are printed if you turn on debug mode? (add debug to your global options)

1 Like

I think the problem may have been that I was trying to use TLS on an IP address? Not sure. Once I attached a domain to it, then I was able to get it to work. However, I’m still getting some flakiness:

frankenphp via CLI

  1. curl http://81.21.23.42 - result: PHP v8.3.10
  2. curl https://81.21.23.42 - timeout
  3. curl http://dev.my.domain - result: PHP v8.3.10
  4. curl https://dev.my.domain - timeout

frankenphp via systemctl

  1. curl http://81.21.23.42 - result: timeout
  2. curl https://81.21.23.42 - timeout
  3. curl http://dev.my.domain - redirect to https
  4. curl https://dev.my.domain - result: PHP v8.3.7

Why would the PHP version change?

Ok the php version thing is a red herring.

SO…

I guess the lesson here is: don’t try use Caddy without a domain pointing at it.

The last problem here with frankenphp is I can’t get the @hide to work:

me.my.domain {
    # Enable compression (optional)
    encode zstd br gzip

    root * /var/www/html/my-app

    # Define a route for handling requests
    route {
    
        # Execute PHP files
        php_server

        # Rewrite subfolder requests for screenscrapers
        rewrite /ladder/* /ladder/index.php
        rewrite /manager/* /manager/index.php


        # Security: Hide specific paths
        @hide path /.env
        respond @hide 404
    }
}

the .env file is still browsable.

This works fine though. I suspect something strange about the network or your system/infra.

Probably hitting a different PHP stack? I am not sure with redacted domains like that unfortunately since I can’t test it.

That’s because you put it after your php_server in a route (order matters in a route), so the PHP server will handle the request before Caddy even tries to hide the file.

4 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.