Directing cURL traffic through a specific network interface keeps HTTP requests pinned to a predictable source address on multi-homed systems. This approach simplifies testing of firewalls and load balancers, enforces VPN-only egress for sensitive APIs, and avoids surprises when multiple outbound links exist.

Underneath the command-line flags, cURL exposes the libcurl option CURLOPT_INTERFACE, which binds the outgoing socket to an interface name, local IPv4 address, or local IPv6 address before connecting. When an interface such as eth0 or wlp2s0 is used, the kernel chooses an appropriate address from that device; when a literal address is provided, the kernel binds exactly that source IP and uses standard routing to reach the target.

Binding succeeds only when the selected interface is up, configured with the requested address, and part of a route capable of reaching the remote host. Attempts to bind to an absent or mismatched address typically fail immediately with errors such as curl: (45) bind failed with errno 99: Cannot assign requested address, and elevated privileges may be needed when experimenting with low-level or policy-restricted interfaces on Linux.

Steps to bind cURL to a network interface:

  1. Display available network interfaces and their assigned IP addresses on the host where cURL runs.
    $ ip -brief addr
    lo               UNKNOWN        127.0.0.1/8 ::1/128
    eth0             UP             192.0.2.10/24 fe80::1a2b:3c4d:5e6f:1/64
    eth1             UP             198.51.100.20/24 fe80::1a2b:3c4d:5e6f:2/64

    Interface names such as eth0, enp3s0, or wlp2s0 work as values for --interface when binding cURL traffic to a device.

  2. Send an HTTPS request bound to a specific interface name to confirm that outbound connectivity works over that path.
    $ curl --interface eth0 https://example.com/
    <!doctype html>
    <html>
    <head>
        <title>Example Domain</title>
    ##### snipped #####

    Binding to an interface name allows the kernel to select whichever address on that device has a valid route to the remote server.

  3. Send an HTTPS request bound to a specific local IP address to force traffic from a single source address.
    $ curl --interface 192.0.2.10 https://example.com/
    <!doctype html>
    <html>
    <head>
        <title>Example Domain</title>
    ##### snipped #####

    Binding to an IP address that is not configured locally results in an immediate failure such as curl: (45) bind failed with errno 99: Cannot assign requested address and prevents the connection from being established.

  4. Verify the external IP address seen by a remote diagnostic service while binding traffic to the chosen interface.
    $ curl --interface eth0 https://ifconfig.io/ip
    192.0.2.10

    Success signal: the response matches the IP address assigned to the selected interface in the interface listing.

  5. Compare the reported source IP when repeating the request without an interface binding or with a different interface to confirm isolation between paths.
    $ curl https://ifconfig.io/ip
    198.51.100.20

    Different source IP values between bound and unbound requests confirm that routing policies and multi-homed configuration behave as intended.

Discuss the article:

Comment anonymously. Login not required.