Recently encountered a puzzling scenario where HTTPS requests behave differently across tools:
# Success case
curl "https://example.com"
# Failure case
wget https://example.com
# Returns: "Unable to establish SSL connection"
The same issue manifests in PHP's file()
function when accessing HTTPS URLs. This behavior suddenly appeared over a weekend on a RHEL 6.4 system that previously worked fine.
Several technical factors could explain why cURL succeeds where wget fails:
- Default SSL/TLS versions differ between implementations
- Certificate verification handling varies
- Underlying SSL library differences (OpenSSL vs GnuTLS)
- Different default cipher suites
First, let's verify SSL/TLS capabilities with openssl
:
openssl s_client -connect example.com:443 -showcerts
For wget, we can increase verbosity:
wget --debug https://example.com
Compare with cURL's verbose output:
curl -v https://example.com
Based on similar cases I've encountered, these are the most likely culprits:
- SSL Protocol Version Mismatch: Older wget versions may default to SSLv3 while servers require TLS 1.2+
- Certificate Chain Issues: Intermediate certificates might not be properly installed
- Cipher Suite Incompatibility: Server may reject wget's default cipher suite
- System Time Drift: Certificate validation fails if system clock is incorrect
For wget:
# Force TLS 1.2
wget --secure-protocol=TLSv1_2 https://example.com
# Or try different SSL implementations
wget --no-check-certificate --https-only --secure-protocol=auto https://example.com
For PHP file():
// Context options for SSL
$context = stream_context_create([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
]
]);
$content = file('https://example.com', FILE_USE_INCLUDE_PATH, $context);
For system-wide resolution on RHEL 6.4:
- Update wget and OpenSSL packages:
- Adjust system-wide crypto policies:
- Add CA certificates to the trusted store:
yum update wget openssl
update-crypto-policies --set LEGACY
yum install ca-certificates
update-ca-trust force-enable
update-ca-trust extract
If the issue persists, try compiling wget with different SSL backends:
# Recompile with OpenSSL
./configure --with-ssl=openssl
make && make install
# Or with GnuTLS
./configure --with-ssl=gnutls
make && make install
Sometimes the issue stems from network configuration:
- Check for SSL inspection devices (firewalls, proxies)
- Verify MTU settings aren't causing packet fragmentation
- Test with different DNS resolvers
- Inspect TCP connections with tcpdump
tcpdump -nn -i eth0 'port 443 and host example.com'
When executing HTTPS requests on RHEL 6.4, we're seeing inconsistent behavior between different tools:
# Success case
curl "https://example.com"
# Failure case (times out during SSL handshake)
wget https://example.com
# Output: Unable to establish SSL connection
# HTTP works fine
wget http://example.com
- OS: Red Hat Enterprise Linux 6.4
- Affected tools: wget, PHP's file() function
- Working tool: cURL
- Protocol difference: HTTPS fails, HTTP succeeds
The root cause typically relates to SSL/TLS protocol version mismatches or cipher suite differences between client and server. Here's how to investigate:
# Check cURL's SSL details
curl -v https://example.com 2>&1 | grep -i "SSL"
# Check wget's SSL handshake attempt
wget --debug https://example.com 2>&1 | grep -i "SSL"
# Alternative using openssl client
openssl s_client -connect example.com:443 -showcerts
1. Outdated SSL/TLS Protocols
RHEL 6.4 ships with older SSL libraries by default. Try forcing modern protocols:
# For wget
wget --secure-protocol=TLSv1_2 https://example.com
# For curl comparison
curl --tlsv1.2 https://example.com
2. Certificate Verification Issues
While --no-check-certificate didn't help, try specifying CA bundles:
wget --ca-certificate=/etc/pki/tls/certs/ca-bundle.crt https://example.com
3. Cipher Suite Mismatches
Some servers reject connections with weak ciphers:
# For wget (requires newer versions)
wget --ciphers="HIGH:!aNULL:!MD5" https://example.com
The PHP issue stems from the same SSL configuration. Here are options:
// Option 1: Use curl instead
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
// Option 2: Update PHP stream context
$context = stream_context_create([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'ciphers' => 'HIGH:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1'
]
]);
file('https://example.com', false, $context);
- Update system CA certificates:
yum update ca-certificates
- Upgrade wget to a newer version that supports modern TLS
- Consider upgrading OpenSSL libraries if possible
- For PHP, update to a newer version with better SSL support
For deeper investigation, these commands help:
# Check installed SSL/TLS versions
openssl version
# Verify what protocols a server supports
nmap --script ssl-enum-ciphers -p 443 example.com
# Check current SSL configuration in PHP
php -i | grep -i ssl