How to Secure Docker’s Remote API (Port 2375) with TLS and OpenSSL

Learn how to protect Docker’s exposed remote management port 2375 by generating CA, server, and client certificates with OpenSSL, configuring Docker daemon for TLS verification, and adjusting docker-maven-plugin settings to safely build and push images without exposing insecure endpoints.

macrozheng
macrozheng
macrozheng
How to Secure Docker’s Remote API (Port 2375) with TLS and OpenSSL
Many users encounter security issues when the docker-maven-plugin opens Docker’s remote management port 2375 without any protection, leading to potential attacks such as unauthorized access, mining, or CPU spikes.

Reason for the issue

Docker provides a remote management port (2375) for cluster control. Adding -H tcp://0.0.0.0:2375 to docker.service opens this port without encryption or authentication, which is acceptable only for internal testing. Exposing it on a public server allows anyone who knows the IP to control containers and images.

Solution approach

Secure the remote management port by using TLS for transport and CA‑based authentication.

Generate certificates and keys

Use OpenSSL on the Docker host to create a CA, server, and client certificates.

Create a directory for the certificates: mkdir /mydata/docker-ca && cd /mydata/docker-ca Create the CA private key: openssl genrsa -aes256 -out ca-key.pem 4096 Create the CA certificate:

openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem

Create the server private key: openssl genrsa -out server-key.pem 4096 Create the server CSR:

openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr

Sign the server certificate with the CA:

openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem

Create the client private key: openssl genrsa -out key.pem 4096 Create the client CSR:

openssl req -subj "/CN=client" -new -key key.pem -out client.csr

Create an extension file for client authentication:

echo extendedKeyUsage = clientAuth > extfile-client.cnf

Sign the client certificate with the CA:

openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf

Remove temporary files:

rm -rf ca.srl server.csr client.csr extfile-client.cnf

Resulting files:

ca.pem          # CA certificate
ca-key.pem      # CA private key
server-cert.pem # Server certificate
server-key.pem  # Server private key
cert.pem        # Client certificate
key.pem         # Client private key

Configure Docker to support TLS

Edit docker.service with vim:

Replace the ExecStart line to enable TLS verification and point to the generated certificates:

ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --tlsverify --tlscacert=/mydata/docker-ca/ca.pem --tlscert=/mydata/docker-ca/server-cert.pem --tlskey=/mydata/docker-ca/server-key.pem

Reload the systemd daemon and restart Docker:

systemctl daemon-reload && systemctl restart docker

Client access

Use docker-maven-plugin to build Docker images, now pointing to the secured endpoint.

Upgrade the plugin to version 1.2.2 to avoid compatibility issues.

Change the <dockerHost> configuration from http to https:

<dockerHost>https://192.168.3.101:2375</dockerHost>

Copy the CA, client certificate, and client key to a local directory (e.g., I:\developer\env\docker-ca) and reference it in the plugin configuration:

<dockerCertPath>I:\developer\env\docker-ca</dockerCertPath>

Full plugin configuration example:

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.2.2</version>
    <executions>
        <execution>
            <id>build-image</id>
            <phase>package</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <imageName>mall-tiny/${project.artifactId}:${project.version}</imageName>
        <dockerHost>https://192.168.3.101:2375</dockerHost>
        <baseImage>java:8</baseImage>
        <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
        <dockerCertPath>I:\developer\env\docker-ca</dockerCertPath>
        <resources>
            <resource>
                <targetPath>/</targetPath>
                <directory>${project.build.directory}</directory>
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
    </configuration>
</plugin>

After these changes, the image builds successfully and the 2375 port can be used safely over TLS.

Reference

Official Docker security documentation: https://docs.docker.com/engine/security/https/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DockerOpenSSLTLScertificatesdocker-maven-pluginremote API
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.