SpringBoot e-Commerce project mall (39K + STAR) address: github.com/macrozheng/…

Abstract

Before many friends mentioned, when using docker-Maven-plugin package SpringBoot application docker image, the server needs to open port 2375. Because the port is opened without any security protection, it will cause security loopholes, intrusion, mining, CPU surge and other situations happen. Today we are going to talk about how to solve this problem.

The cause of the problem

First we have to understand the cause of the problem, in order to better solve the problem!

Docker provides a port for remote management in order to achieve cluster management. The Docker Daemon runs in the background as a Daemon and can execute Docker commands sent to the management port.

When we modify the docker.service file and modify the startup command to add -h TCP ://0.0.0.0:2375, port 2375 will be opened without any encryption or authentication process. This method is generally used in the Intranet test environment. It’s scary to think that if your server is deployed on a public network, anyone who knows your IP can manage containers and images on that host.

solution

This problem occurs when the remote management port is opened without any security protection. We just use the Secure Transport Layer protocol (TLS) for transmission and use CA authentication.

Make certificates and secret keys

We need to use OpenSSL to make CA certificates, server certificates, and client certificates. The following operations are performed on the Linux server with Docker installed.

  • First, create a directory to store the generated certificates and keys.
mkdir /mydata/docker-ca && cd /mydata/docker-ca
Copy the code
  • When creating a CA certificate private key, enter the user name and password twice. The generated file is ca-key.pem.
openssl genrsa -aes256 -out ca-key.pem 4096
Copy the code
  • When creating a CA certificate based on the private key, enter the private key password set in the previous step. The generated file is ca.pem.
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem
Copy the code
  • Create a server private key. The generated file is server-key.pem.
openssl genrsa -out server-key.pem 4096
Copy the code
  • Create a server certificate signing request file for the CA certificate to sign the server certificate and generate a file server.csr.
openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
Copy the code
  • When creating a server certificate signed by the CA certificate, you need to enter the CA certificate private key password. The generated file is server-cert.pem.
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
Copy the code
  • Create a client private key. The generated file is key.pem.
openssl genrsa -out key.pem 4096
Copy the code
  • Create a client certificate signing request file for the CA certificate to sign the client certificate and generate a client.csr file.
openssl req -subj "/CN=client" -new -key key.pem -out client.csr
Copy the code
  • To make the secret key suitable for client authentication, create an extension configuration file extfile-client.cnf;
echo extendedKeyUsage = clientAuth > extfile-client.cnf
Copy the code
  • When creating a client certificate signed by the CA certificate, you need to enter the CA certificate private key password. The generated file is cert.pem.
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf
Copy the code
  • Delete unnecessary files during creation.
rm -rf ca.srl server.csr client.csr extfile-client.cnf
Copy the code
  • The resulting files are as follows, and with them we can perform secure access over TLS.
Pem Ca certificate ca-key.pem CA certificate private key server-cert.pem Server certificate private key cert.pem client certificate key.pem Client certificate private keyCopy the code

Configure Docker to support TLS

  • Modify docker.service file with vim editor;
vi /usr/lib/systemd/system/docker.service
Copy the code
  • Modify the configuration starting with ExecStart, enable TLS authentication, and configure the CA certificate, server certificate, and server private key as follows:
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.pemCopy the code
  • Restart Docker service, so that our Docker service support TLS remote access!
systemctl daemon-reload && systemctl restart docker
Copy the code

Client access

Next we will use the Docker-Maven-plugin to package the Docker image using the original mall-tiny-Docker example.

  • Try packaging directly with docker-Maven-plugin. Since the version of our plug-in is a little low, the following problems will occur when using a new version of Docker. Upgrade to version 1.2.2 to solve the problem.
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.1.0:build (build-image) on project mall-tiny-docker: Exception caught: com.spotify.docker.client.shaded.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.spotify.docker.client.messages.RegistryAuth` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('desktop')
[ERROR] at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: java.util.LinkedHashMap["credsStore"])
[ERROR] -> [Help 1]
Copy the code
  • TLS does not support HTTP anymore, so you need to change

    to HTTPS.
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.2.2:build (build-image) on project mall-tiny-docker: Exception caught: Request error: GET http://192.168.3.101:2375/version: 400, body: Client sent an HTTP request to an HTTPS server. HTTP 400 Bad Request -> [Help 1]
Copy the code
  • After the modification is complete, the package fails again. You need to add the corresponding client certificate for access.
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.2.2:build (build-image) on project mall-tiny-docker: Exception caught: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target -> [Help 1]
Copy the code
  • Copy the following files to the specified directory, in this case to I:\developer\env\docker-ca;
Pem CA certificate cert.pem Client certificate key.pem Client certificate private keyCopy the code
  • This directory is then configured under the

    node of the plug-in. The final plug-in configuration is as follows.
< plugin > < groupId > com. The company < / 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>Copy the code
  • Pack the image again and find that the image can be packed successfully. From now on, our port 2375 can be used safely!
[INFO] Building image mall-tiny/mall-tiny-docker:0.0.1 -snapshot Step 1/3: FROM Java :8 --> d23bdf5b1b1b Step 2/3: ADD /mall-tiny-docker-0.0.1- snapshot. jar // --> 5cb5a64ccedd Step 3/3: ENTRYPOINT ["java", "-jar","/ mall-tiny-docker-0.0.1-snapshot.jar "] --> Running in 5f3ceefdd974 Removing Intermediate Container 5f3ceefdd974  ---> ee9d0e2b0114ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, ProgressDetail =null} Successfully built ee9d0e2b0114Successfully tagged mall-tiny/mall-tiny-docker:0.0.1-SNAPSHOT [INFO] Built mall - tiny/mall - tiny - docker: 0.0.1 - the SNAPSHOT [INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- [INFO] Total time: 20.550 s [INFO] Finished at: 2020-07-31T15:02:15+08:00 [INFO] Final Memory: 50M/490M [INFO] ------------------------------------------------------------------------Copy the code

The resources

The official document: docs.docker.com/engine/secu…

Project source code address

Github.com/macrozheng/…