We know that in the APM architecture diagram:
Any application may transfer data to the APM Server if security is not set up. If it’s malicious software, then we might get the wrong data. So how do we guarantee our secure transmission?
The answer is to use secret Token at transfer time.
What is a Secret Token?
You can configure a Secret Token to authorize requests to the APM server. This ensures that only your Agent can send data to your APM server. Both the proxy and APM servers must be configured with the same Secret Toke, and the SCecret token provides security only when used in conjunction with SSL/TLS.
To use Secret token to secure communication between APM proxy and APM server:
- Enable SSL/TLS in APM server
- Set the Secret Token on the Agent and server
- Enable HTTPS on the APM Agent
Actual practice
Next, let’s follow the steps above to demonstrate how this is done.
Follow Elasticsearch, Kibana and APM Server
If you don’t already have your Own Elasticsearch, Kibana, and APM servers installed, you can refer to my previous article “Solutions: Application Performance Monitoring/Management (APM) Practices” to do so.
Generate a certificate
To install the above requirements, we need to enable SSL/TLS. We must have our own certificates. Insert the following command into the root directory of the Elasticsearch installation:
./bin/elasticsearch-certutil ca --pem
Copy the code
$PWD/Users/liuxg/elastic3 / elasticsearch - 7.6.2 $. / bin/elasticsearch - certutil ca - pem This tool assists you in the generation of X.509 certificates and certificate signing requests for use with SSL/TLS in the Elastic stack. The 'ca' mode generates a new 'certificate authority' This will create a new X.509 certificate and private key that can be used to sign certificate when running in 'cert' mode. Use the 'ca-dn' option if you wish to configure the 'distinguished name' of the certificate authority By default the 'ca' mode produces a single PKCS#12 output file which holds: * The CA certificate * The CA's private key If you elect to generate PEM format certificates (the -pem option), then the output will be a zip file containing individual files for the CA certificate and private key Please enter the desired output file [elastic-stack-ca.zip]:Copy the code
As shown above, the command above will generate a file called elastice-stack-ca.zip. We then unzip the file using the following command:
unzip elastic-stack-ca.zip
Copy the code
$PWD/Users/liuxg/elastic3 / elasticsearch - 7.6.2 liuxg: elasticsearch - 7.6.2 liuxg $unzip elastic - stack - ca. Zip Archive: elastic-stack-ca.zip creating: ca/ inflating: ca/ca.crt inflating: ca/ca.keyCopy the code
Above, we can see that a new directory ca has been created under the current directory. It contains two files: ca.crt and ca.key. Please note that the ca.crt certificate will be used in our agent below. Next, we generate the certificate as follows:
./bin/elasticsearch-certutil cert --ca-cert ./ca/ca.crt --ca-key ./ca/ca.key --pem --name localhost
Copy the code
$PWD/Users/liuxg/elastic3 / elasticsearch - 7.6.2 $. / bin/elasticsearch - certutil cert - ca - cert. / ca/ca. The CRT - ca - key ./ca/ca.key --pem --name localhost This tool assists you in the generation of X.509 certificates and certificate signing requests for use with SSL/TLS in the Elastic stack. The 'cert' mode generates X.509 certificate and private keys. * By default, this generates a single certificate and key for use on a single instance. * The '-multiple' option will prompt you to enter details for multiple instances and will generate a certificate and key for each one * The '-in' option allows for the certificate generation to be automated by describing the details of each instance in a YAML file * An instance is any piece of the Elastic Stack that requires an SSL certificate. Depending on your configuration, Elasticsearch, Logstash, Kibana, and Beats may all require a certificate and private key. * The minimum required value for each instance is a name. This can simply be the hostname, which will be used as the Common Name of the certificate. A full distinguished name may also be used. * A filename value may be required for each instance. This is necessary when the name would result in an invalid file or directory name. The name provided here is used as the directory name (within the zip) and the prefix for the key and certificate files. The filename is required if you are prompted and the name is not displayed in the prompt. * IP addresses and DNS names are optional. Multiple values can be specified as a comma separated string. If no IP addresses or DNS names are provided, you may disable hostname verification in your SSL configuration. * All certificates generated by this tool will be signed by a certificate authority (CA). * The tool can automatically generate a new CA for you, or you can provide your own with the -ca or -ca-cert command line options. By default the 'cert' mode produces a single PKCS#12 output file which holds: * The instance certificate * The private key for the instance certificate * The CA certificate If you specify any of the following options: * -pem (PEM formatted output) * -keep-ca-key (retain generated CA key) * -multiple (generate multiple certificates) * -in (generate certificates from an input file) then the output will be be a zip file containing individual certificate/key files Please enter the desired output file [certificate-bundle.zip]: Certificates written to/Users/liuxg/elastic3 / elasticsearch 7.6.2 / certificate - bundle. Zip This file should be properly secured as it contains the private key for your instance. After unzipping the file, there will be a directory for each instance. Each instance has a certificate and private key. For each Elastic product that you wish to configure, you should copy the certificate, key, and CA certificate to the relevant configuration directory and then follow the SSL configuration instructions in the product guide. For client applications, you may only need to copy the CA certificate and configure the client to trust this certificate.Copy the code
In the above command, we produce a certificate bound to localhost, which means that the certificate can only be used in the current localhost. As shown above, it produces a file called certificate-bundle.zip in the current directory. This file contains the certificate information we need. We use the following command to unzip the file:
unzip certificate-bundle.zip
Copy the code
$PWD/Users/liuxg/elastic3 / elasticsearch - 7.6.2 liuxg: elasticsearch - 7.6.2 liuxg $unzip certificate - bundle. Zip Archive: certificate-bundle.zip creating: localhost/ inflating: localhost/localhost.crt inflating: localhost/localhost.keyCopy the code
CRT and localhoset.key in localhost. We copied these two files into the root directory of our APM server installation. In the APM server installation directory, I can see:
$PWD/Users/liuxg/elastic3 / apm - server - 7.6.2 - Darwin - x86_64 liuxg: apm - server - 7.6.2 - Darwin - x86_64 liuxg $ls LICENSE. TXT apm-server data key.pem localhost.key NOTICE.txt apm-server.yml fields.yml kibana README.md certificate.pem ingest localhost.crtCopy the code
Note: We can convert a. CRT certificate to a. Pem certificate using the following command:
openssl x509 -in mycert.crt -out mycert.pem -outform PEM
Copy the code
Configure the APM server
We need to configure SSL/TLS for our APM server in this step. Using one of our favorite editors, we opened the apm-server.yml file and added the following configuration to the end of the file:
apm-server.ssl.enabled: true
apm-server.secret_token: "123456"
apm-server.ssl.key: "localhost.key"
apm-server.ssl.certificate: "localhost.crt"
Copy the code
Above, we open, set the token to 123456, and add the certificate.
After the above configuration, we restart our APM server:
./apm-server -e
Copy the code
If you configure it correctly, you should see something like this:
If your certificate is incorrect, you will see a lot of messages in this output saying the certificate is incorrect.
Test the APM agent
In today’s test, we will use my previous example “Solutions: APM functionality for Nodejs microservices”. We downloaded the test application using the following method:
git clone https://github.com/liu-xiao-guo/apm-zipcode-microservice
Copy the code
We modify this part of the server.js file as follows:
// Add this to the VERY top of the first file loaded in your app
var apm = require('elastic-apm-node').start({
// Override service name from package.json
// Allowed characters: a-z, A-Z, 0-9, -, _, and space
serviceName: 'zipcode service',
// Use if APM Server requires a token
secretToken: '1234561',
// Set custom APM Server URL (default: http://localhost:8200)
serverUrl: 'http://localhost:8200'
verifyServerCert: true,
serverCaCertFile: "ca.crt"
})
Copy the code
Above, we have also added the following two lines:
verifyServerCert: true,
serverCaCertFile: "ca.crt"
Copy the code
See the links for a detailed description of the two configurations above. As shown above, we need to copy the previously generated ca.crt certificate to the root directory of the application:
$ pwd
/Users/liuxg/nodejs/apm/zipcode-microservice-node
liuxg:zipcode-microservice-node liuxg$ ls
LICENSE ca.crt package.json
README.md node_modules server.js
api package-lock.json service
Copy the code
After that, we can restart our nodejs application:
npm start
Copy the code
If our certificate is configured correctly, we should see the following screen:
If our certificate is not set up correctly, we will see a connection error and so on.
Type the following address in our browser:
http://localhost:3000/distance/84010/97229
Copy the code
We can see this in the APM application in Kibana:
From the above we can see the invocation of our microservice.
To verify that our Secret token has worked, we can use a Secret token that does not match, such as 1234561111:
// Add this to the VERY top of the first file loaded in your app
var apm = require('elastic-apm-node').start({
// Override service name from package.json
// Allowed characters: a-z, A-Z, 0-9, -, _, and space
serviceName: 'zipcode service',
// Use if APM Server requires a token
secretToken: '1234561111',
// Set custom APM Server URL (default: http://localhost:8200)
serverUrl: 'https://localhost:8200',
verifyServerCert: true,
serverCaCertFile: "/Users/liuxg/nodejs/apm/zipcode-microservice-node/ca.crt"
})
Copy the code
So restart our NodeJS application and I should see something like this:
It says our Secret Token works.
Reference:
【 1 】 www.elastic.co/guide/en/el…
(2) www.elastic.co/guide/en/ap…