crazywhalecc / static-php-cli

Build standalone PHP binary on Linux, macOS, FreeBSD, Windows, with PHP project together, with popular extensions included.
https://static-php.dev
MIT License
1.34k stars 234 forks source link

SSL operation failed with code 5 #421

Closed ywisax closed 6 months ago

ywisax commented 7 months ago

Create a new Linux machine, create a test script:

<?php

file_get_contents('https://www.baidu.com');

Current static php cli version:

./php -v
PHP 8.1.27 (cli) (built: Mar 15 2024 05:47:55) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.27, Copyright (c) Zend Technologies

output:

Warning: file_get_contents(): SSL operation failed with code 5. OpenSSL Error messages:
error:80000002:system library::No such file or directory
error:80000002:system library::No such file or directory
error:80000002:system library::No such file or directory
error:80000002:system library::No such file or directory
error:80000002:system library::No such file or directory
error:0A000086:SSL routines::certificate verify failed in /data/test.php on line 3

Warning: file_get_contents(): Failed to enable crypto in /data/test.php on line 3

Warning: file_get_contents(https://xxxx.com): Failed to open stream: operation failed in /data/test.php on line 3
crazywhalecc commented 7 months ago

Related issue: https://github.com/beyondcode/expose/issues/391#issuecomment-1866184348

Generally it's caused by openssl conf. Just set system default config.

ywisax commented 7 months ago

No working.

wget https://curl.se/ca/cacert.pem

=======

cat test.php 
<?php

ini_set('curl.cainfo', __DIR__ . '/cacert.pem');
ini_set('openssl.cafile', __DIR__ . '/cacert.pem');

file_get_contents('https://www.baidu.com');

=======

./php test.php 

Warning: file_get_contents(): SSL operation failed with code 5. OpenSSL Error messages:
error:80000002:system library::No such file or directory
error:80000002:system library::No such file or directory
error:80000002:system library::No such file or directory
error:80000002:system library::No such file or directory
error:0A000086:SSL routines::certificate verify failed in /data/test.php on line 6

Warning: file_get_contents(): Failed to enable crypto in /data/test.php on line 6

Warning: file_get_contents(https://www.baidu.com): Failed to open stream: operation failed in /data/test.php on line 6
crazywhalecc commented 7 months ago

Do you have /etc/ssl/openssl.cnf?

ywisax commented 7 months ago

Do you have /etc/ssl/openssl.cnf?

Yes.

# wc -c /etc/ssl/openssl.cnf
11118 /etc/ssl/openssl.cnf

# openssl help
Standard commands
asn1parse         ca                ciphers           cms               
crl               crl2pkcs7         dgst              dhparam           
dsa               dsaparam          ec                ecparam           
enc               engine            errstr            gendsa            
genpkey           genrsa            help              list              
nseq              ocsp              passwd            pkcs12            
pkcs7             pkcs8             pkey              pkeyparam         
pkeyutl           prime             rand              rehash            
req               rsa               rsautl            s_client          
s_server          s_time            sess_id           smime             
speed             spkac             srp               storeutl          
ts                verify            version           x509              

Message Digest commands (see the `dgst' command for more details)
blake2b512        blake2s256        gost              md4               
md5               rmd160            sha1              sha224            
sha256            sha3-224          sha3-256          sha3-384          
sha3-512          sha384            sha512            sha512-224        
sha512-256        shake128          shake256          sm3               

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb      
aria-128-cfb1     aria-128-cfb8     aria-128-ctr      aria-128-ecb      
aria-128-ofb      aria-192-cbc      aria-192-cfb      aria-192-cfb1     
aria-192-cfb8     aria-192-ctr      aria-192-ecb      aria-192-ofb      
aria-256-cbc      aria-256-cfb      aria-256-cfb1     aria-256-cfb8     
aria-256-ctr      aria-256-ecb      aria-256-ofb      base64            
bf                bf-cbc            bf-cfb            bf-ecb            
bf-ofb            camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  
camellia-192-ecb  camellia-256-cbc  camellia-256-ecb  cast              
cast-cbc          cast5-cbc         cast5-cfb         cast5-ecb         
cast5-ofb         des               des-cbc           des-cfb           
des-ecb           des-ede           des-ede-cbc       des-ede-cfb       
des-ede-ofb       des-ede3          des-ede3-cbc      des-ede3-cfb      
des-ede3-ofb      des-ofb           des3              desx              
rc2               rc2-40-cbc        rc2-64-cbc        rc2-cbc           
rc2-cfb           rc2-ecb           rc2-ofb           rc4               
rc4-40            seed              seed-cbc          seed-cfb          
seed-ecb          seed-ofb          sm4-cbc           sm4-cfb           
sm4-ctr           sm4-ecb           sm4-ofb

# curl -v https://www.baidu.com
*   Trying 103.235.46.40:443...
* Connected to www.baidu.com (103.235.46.40) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=CN; ST=beijing; L=beijing; O=Beijing Baidu Netcom Science Technology Co., Ltd; CN=baidu.com
*  start date: Jul  6 01:51:06 2023 GMT
*  expire date: Aug  6 01:51:05 2024 GMT
*  subjectAltName: host "www.baidu.com" matched cert's "*.baidu.com"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host: www.baidu.com
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 25 Apr 2024 05:13:17 GMT
< Content-Length: 0
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host www.baidu.com left intact

All other binary is ok except static-php-cli.

ywisax commented 7 months ago

I try https://www.swoole.com/download, it was ok with the test script below.

crazywhalecc commented 7 months ago

php openssl ini config cannot be set with ini_set(). You can consider using ./php -d "openssl.cafile=/etc/ssl/certs/ca-certificates.crt" or using single php.ini file.

crazywhalecc commented 7 months ago

From stack exchange, this is where Go looks for public root certificates:

"/etc/ssl/certs/ca-certificates.crt",                // Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt",                  // Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem",                            // OpenSUSE
"/etc/pki/tls/cacert.pem",                           // OpenELEC
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
"/etc/ssl/cert.pem",                                 // Alpine Linux
ywisax commented 7 months ago

You are right, run ./php -d "openssl.cafile=/etc/ssl/certs/ca-certificates.crt" test.php and response correct. Is it possible to make it out-of-box in static-php-cli ? I think not so much people could realize the cert file problem.

crazywhalecc commented 7 months ago

I thought about this, but different linux distributions still use different locations for root certificates. We currently only support hard-coding the specified ini, but supporting different distributions obviously requires a dynamic search method.

It would be great if you have better advice on this.

2colours commented 6 months ago

@crazywhalecc this probably doesn't have very high priority but still, considering that the doctor command can somehow account for environmental peculiarities, it would make sense that spc does something similar for this as well.