When testing SSL connections on servers behind load balancers or using non-standard ports, developers often face this situation:
curl --resolve 'example.com:8090:192.168.1.100' 'https://example.com:8090'
Despite explicitly specifying port 8090, curl stubbornly defaults to 443, making it impossible to test the actual service endpoint.
The issue stems from how curl handles HTTPS URLs. When you specify https://
, curl automatically assumes port 443 unless you override both the connection and the Host header behavior.
To properly test SSL on custom ports, you need two critical modifications:
curl --resolve 'example.com:8090:192.168.1.100' \
--connect-to 'example.com:443:example.com:8090' \
'https://example.com'
Or alternatively:
curl --resolve 'example.com:8090:192.168.1.100' \
--header 'Host: example.com' \
'https://example.com:8090'
For complex testing scenarios, consider these additional parameters:
curl -v \
--resolve 'api.dev.example.com:8443:10.0.0.42' \
--connect-to 'api.dev.example.com:443:api.dev.example.com:8443' \
--cacert ./custom_ca.pem \
--tlsv1.2 \
'https://api.dev.example.com/ping'
Remember that the --connect-to
option was introduced in curl 7.49.0. For older versions, you'll need to use the host header approach.
Always use -v
flag to verify the actual connection:
curl -v --resolve 'test.example:9090:127.0.0.1' \
--connect-to 'test.example:443:test.example:9090' \
'https://test.example'
Look for these key lines in verbose output:
* Connecting to test.example (127.0.0.1) port 9090
* Using HTTP/2 over SSL
* Server certificate: test.example
When testing SSL connections to servers behind load balancers, developers often encounter situations where the standard port 443 isn't available. In this specific case, the server listens on port 8090, but cURL stubbornly defaults to 443 despite explicit port specifications.
The issue occurs because cURL handles port specification differently when combined with the --resolve
option. While you might expect:
curl --resolve 'myservice.com:8090:2.2.2.2' 'https://myservice.com:8090'
to connect to port 8090, cURL actually separates the DNS resolution from the connection port logic.
Here are three working approaches to force cURL to use your custom SSL port:
1. Explicit URL Port with Resolve
curl --resolve 'myservice.com:8090:2.2.2.2' https://myservice.com:8090
2. Using --connect-to Instead
curl --connect-to myservice.com:8090:2.2.2.2:8090 https://myservice.com
3. Combining URL Port and Host Header
curl -H "Host: myservice.com" https://2.2.2.2:8090
The key insight is that --resolve
only affects DNS resolution, not the actual connection port. The first solution works because:
--resolve
creates a DNS cache entry for port 8090- The URL explicitly specifies port 8090 in the connection
Add these flags to verify your connection:
curl -v --resolve 'myservice.com:8090:2.2.2.2' https://myservice.com:8090
Look for these key lines in output:
* Connecting to myservice.com (2.2.2.2) port 8090
* SSL connection using TLSv1.3
When testing SSL on non-standard ports, consider adding:
curl --tlsv1.2 --cacert /path/to/cert.pem \
--resolve 'myservice.com:8090:2.2.2.2' \
https://myservice.com:8090