Connecting HTTP clients over Unix domain sockets using cURL keeps internal APIs bound to the local host and avoids exposing TCP ports on external interfaces. Many local daemons on Linux, such as container runtimes and reverse proxies, publish control-plane or status endpoints only on socket files. Using cURL against those sockets simplifies debugging, health checks, and automation for services that are not intended to be reachable over the network.

Unix domain sockets use filesystem paths like /var/run/docker.sock as addressing instead of IP and port pairs, while the higher-level protocol remains standard HTTP or HTTPS. When compiled with Unix socket support, cURL attaches a regular URL to a specific socket path via the --unix-socket option, so the URL continues to define scheme, host header, and request path while the bytes travel through the designated socket. On Linux, abstract namespace sockets can be reached with --abstract-unix-socket when services are configured with that style of endpoint.

Access to socket files is governed by standard Unix permissions, which often restrict powerful control-plane sockets to privileged users or groups such as docker. Reaching sensitive sockets like /var/run/docker.sock effectively grants full control over the associated service and may expose host-level operations or confidential data. The commands below assume Ubuntu 22.04 with a systemd-managed Docker daemon and a cURL build that advertises UnixSockets support in its feature list.

Steps to connect over Unix sockets with cURL:

  1. Open a terminal with access to a user account that can reach the socket file.
    $ whoami
    user
  2. Confirm that the installed cURL build includes Unix domain socket support.
    $ curl --version
    curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11
    Release-Date: 2022-01-05
    Protocols: dict file ftp ftps http https
    Features: AsynchDNS IPv6 Largefile SSL UnixSockets
    ##### snipped #####

    Unix domain socket support is available when the Features line lists UnixSockets; abstract namespace sockets on Linux can be reached with --abstract-unix-socket when required.

  3. Inspect the Unix socket file exposed by the target service to confirm its presence and permissions.
    $ ls -l /var/run/docker.sock
    srw-rw---- 1 root docker 0 Dec  6 10:32 /var/run/docker.sock

    Access to /var/run/docker.sock grants effective root-level control over the Docker daemon, so membership in the docker group or use of elevated privileges must be restricted.

  4. Send a basic HTTP request over the Unix socket using the --unix-socket option in cURL.
    $ curl --unix-socket /var/run/docker.sock http://localhost/_ping
    OK

    The host portion http://localhost supplies the HTTP scheme and Host header, while the actual transport occurs entirely through the Unix socket at /var/run/docker.sock.

  5. Query a JSON API endpoint over the Unix socket and print the response body for inspection.
    $ curl --unix-socket /var/run/docker.sock \
      --header 'Accept: application/json' \
      http://localhost/v1.41/info
    {"ID":"ABCDEFG12345","Containers":5,"ContainersRunning":3,"ContainersStopped":2,"ServerVersion":"24.0.5","OperatingSystem":"Ubuntu 22.04.3 LTS"}
    ##### snipped #####

    Adding --header 'Accept: application/json' encourages APIs to return structured JSON suitable for parsing with tools such as jq.

  6. Validate connectivity for automation by checking only the HTTP status code and cURL exit status.
    $ curl --unix-socket /var/run/docker.sock \
      --silent --show-error \
      --output /dev/null \
      --write-out '%{http_code}\n' \
      http://localhost/_ping
    200

    Successful Unix socket connectivity is indicated by an HTTP 2xx code, no error output on stderr, and a zero exit status; non-zero status or errors such as Permission denied usually indicate missing group membership or an inactive socket.

Discuss the article:

Comment anonymously. Login not required.