Routing HTTP and other application traffic through a proxy server enables controlled access to external resources, compliance with network policies, and testing from different egress points. Using cURL with HTTP and SOCKS proxies makes it possible to reproduce browser behavior, verify access rules, or simulate client requests from a specific location or network segment.
When proxy options are supplied, cURL sends connection requests to the proxy instead of directly to the origin server. For HTTP and HTTPS traffic, the --proxy option selects an HTTP or HTTPS proxy, while SOCKS support is available through dedicated options such as --socks5-hostname, --socks5, and --socks4. Environment variables and the ~/.curlrc configuration file provide convenient defaults so repeated commands automatically reuse the desired proxy settings.
Incorrect proxy configuration can leak DNS queries, expose credentials to untrusted intermediaries, or unexpectedly route sensitive traffic through external infrastructure. Reliable usage requires a reachable proxy host and port, the correct scheme (http://, https://, or socks5://), and any authentication details defined by the network administrator. Verification against diagnostic endpoints confirms that traffic actually exits via the proxy rather than the local host.
Steps to use HTTP and SOCKS proxies with cURL:
- Open a terminal in an environment where cURL can reach the network and confirm proxy support in the build.
$ curl --version curl 8.5.0 (aarch64-unknown-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libidn2/2.3.7 libpsl/0.21.2 (+libidn2/2.3.7) libssh/0.10.6/openssl/zlib nghttp2/1.59.0 librtmp/2.3 OpenLDAP/2.6.7 Release-Date: 2023-12-06, security patched: 8.5.0-2ubuntu10.6 Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
Entries such as HTTPS-proxy and SOCKS5 in the feature list indicate native support for encrypted proxying and SOCKS tunneling.
- Route a single request through an HTTP proxy using the --proxy option with an http:// proxy URL.
$ curl --silent --proxy "http://user:password@proxy.example.net:3128" --cacert /work/docker/certs/ca.crt "https://api.example.net/" <!doctype html><html><title>Mock API</title><h1>OK</h1></html>
Including the http:// scheme in the proxy URL ensures cURL negotiates an HTTP-style proxy connection instead of assuming a different proxy type.
- Authenticate to an HTTP proxy that requires credentials using --proxy-user.
$ curl --silent --proxy "http://proxy.example.net:3128" --proxy-user "user:password" --cacert /work/docker/certs/ca.crt "https://api.example.net/" <!doctype html><html><title>Mock API</title><h1>OK</h1></html>
Proxy credentials are sent to the proxy host and may appear in logs, so unique passwords and restricted administrative access are essential.
- Send traffic through a SOCKS5 proxy while resolving hostnames on the proxy using --socks5-hostname.
$ curl --silent --socks5-hostname "socks.example.net:1080" --proxy-user "user:password" "http://api.example.net/" <!doctype html><html><title>Mock API</title><h1>OK</h1></html>
--socks5-hostname keeps DNS lookups and HTTP traffic inside the SOCKS tunnel so origin servers and local resolvers do not see direct hostname queries.
- Use SOCKS5 with local DNS resolution when the proxy expects IP addresses rather than hostnames, via --socks5.
$ curl --silent --socks5 "socks.example.net:1080" --proxy-user "user:password" "http://api.example.net/" <!doctype html><html><title>Mock API</title><h1>OK</h1></html>
Local DNS resolution through --socks5 can leak requested hostnames to the local resolver even though the TCP connection itself traverses the SOCKS proxy.
- Fall back to a SOCKS4 proxy when only that protocol is available in the environment.
$ curl --silent --show-error --socks4 "socks.example.net:1080" "http://api.example.net/" curl: (97) Can't complete SOCKS4 connection to 127.0.0.1:80. (91), request rejected or failed.
SOCKS4 does not include DNS forwarding, so hostnames are always resolved locally before establishing the proxy tunnel.
- Export temporary proxy environment variables so multiple cURL commands and other tools reuse the same proxy within one shell session.
$ export http_proxy="http://user:password@proxy.example.net:3128" $ export https_proxy="http://user:password@proxy.example.net:3128" $ curl --silent --cacert /work/docker/certs/ca.crt "https://api.example.net/" <!doctype html><html><title>Mock API</title><h1>OK</h1></html>
Any application honoring http_proxy or https_proxy in this shell uses the proxy, which can unintentionally route unrelated or sensitive traffic through the proxy infrastructure.
- Configure a persistent default proxy for cURL in the user configuration file ~/.curlrc.
$ printf '%s\n' 'proxy = http://user:password@proxy.example.net:3128' 'cacert = /work/docker/certs/ca.crt' >> ~/.curlrc $ curl --silent "https://api.example.net/" <!doctype html><html><title>Mock API</title><h1>OK</h1></html>
A permanent proxy setting in ~/.curlrc affects every cURL invocation for that user until removed, which can hide connectivity issues when the proxy is offline or misconfigured.
- Exclude specific hosts or domains from proxy usage with --noproxy for individual commands or via the NO_PROXY environment variable for broader rules.
$ curl --proxy "http://proxy.example.net:3128" --noproxy "api.example.net" "http://api.example.net/status/200" OK $ export NO_PROXY="localhost,127.0.0.1,api.example.net" $ curl --silent "http://api.example.net/" <!doctype html><html><title>Mock API</title><h1>OK</h1></html>
NO_PROXY accepts literal hostnames, domain suffixes with a leading dot, and IP addresses, enabling granular bypass policies for local or security-sensitive endpoints.
- Confirm that requests traverse the proxy by querying a diagnostic endpoint that reports the apparent client IP address.
$ curl --silent --proxy "http://user:password@proxy.example.net:3128" --cacert /work/docker/certs/ca.crt "https://api.example.net/ip" { "origin": "203.0.113.10" }Successful proxy use is indicated when the reported origin address or X-Forwarded-For header matches the proxy’s egress IP instead of the local machine.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
