[Tests] Add packaging tests for SSL/TLS communication (elastic/x-pack-elasticsearch#2556)

This commit adds a packaging test that uses the certgen tool
to set up a two nodes cluster that uses encrypted communication.

relates elastic/x-pack-elasticsearch#2485

Original commit: elastic/x-pack-elasticsearch@6d2e3c5cd0
This commit is contained in:
Tanguy Leroux 2017-09-21 10:12:07 +02:00 committed by GitHub
parent 34bd72e69b
commit 70687fbef3
4 changed files with 400 additions and 1 deletions

View File

@ -0,0 +1 @@
certgen.bash

View File

@ -0,0 +1 @@
certgen.bash

View File

@ -0,0 +1,395 @@
#!/usr/bin/env bats
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License;
# you may not use this file except in compliance with the Elastic License.
load $BATS_UTILS/utils.bash
load $BATS_UTILS/plugins.bash
load $BATS_UTILS/xpack.bash
# Description of the nodes instances
instances="/tmp/instances.yml"
# Destination for generated certificates
certificates="/tmp/certificates.zip"
setup() {
if [ $BATS_TEST_NUMBER == 1 ]; then
clean_before_test
fi
}
DEFAULT_ARCHIVE_USER=elasticsearch
DEFAULT_ARCHIVE_ESHOME="/tmp/elasticsearch"
DEFAULT_ARCHIVE_UTILS=$BATS_UTILS/tar.bash
DEFAULT_PACKAGE_USER=root
DEFAULT_PACKAGE_ESHOME="/usr/share/elasticsearch"
DEFAULT_PACKAGE_UTILS=$BATS_UTILS/packages.bash
if [[ "$BATS_TEST_FILENAME" =~ 60_tar_certgen.bats$ ]]; then
GROUP='TAR CERTGEN'
MASTER_USER=$DEFAULT_ARCHIVE_USER
MASTER_HOME=$DEFAULT_ARCHIVE_ESHOME
MASTER_UTILS=$DEFAULT_ARCHIVE_UTILS
DATA_USER=$DEFAULT_PACKAGE_USER
DATA_HOME=$DEFAULT_PACKAGE_ESHOME
DATA_UTILS=$DEFAULT_PACKAGE_UTILS
install_master_node() {
install_node_using_archive
}
start_master_node() {
start_node_using_archive
}
install_data_node() {
install_node_using_package
}
start_data_node() {
start_node_using_package
}
else
if is_rpm; then
GROUP='RPM CERTGEN'
elif is_dpkg; then
GROUP='DEB CERTGEN'
fi
MASTER_USER=$DEFAULT_PACKAGE_USER
MASTER_HOME=$DEFAULT_PACKAGE_ESHOME
MASTER_UTILS=$DEFAULT_PACKAGE_UTILS
DATA_USER=$DEFAULT_ARCHIVE_USER
DATA_HOME=$DEFAULT_ARCHIVE_ESHOME
DATA_UTILS=$DEFAULT_ARCHIVE_UTILS
install_master_node() {
install_node_using_package
}
start_master_node() {
start_node_using_package
}
install_data_node() {
install_node_using_archive
}
start_data_node() {
start_node_using_archive
}
fi
# Install a node with x-pack using the archive file
install_node_using_archive() {
load $BATS_UTILS/tar.bash
export ESHOME="$DEFAULT_ARCHIVE_ESHOME"
export_elasticsearch_paths
install_archive
verify_archive_installation
export ESPLUGIN_COMMAND_USER=$DEFAULT_ARCHIVE_USER
install_and_check_plugin x pack x-pack-*.jar
verify_xpack_installation
}
# Starts a node installed using the archive
start_node_using_archive() {
load $BATS_UTILS/tar.bash
export ESHOME="$DEFAULT_ARCHIVE_ESHOME"
export_elasticsearch_paths
run sudo -u $DEFAULT_ARCHIVE_USER "$ESHOME/bin/elasticsearch" -d -p $ESHOME/elasticsearch.pid
[ "$status" -eq "0" ] || {
echo "Failed to start node using archive: $output"
false
}
}
# Install a node with x-pack using a package file
install_node_using_package() {
load $BATS_UTILS/packages.bash
export ESHOME="$DEFAULT_PACKAGE_ESHOME"
export_elasticsearch_paths
install_package
verify_package_installation
export ESPLUGIN_COMMAND_USER=$DEFAULT_PACKAGE_USER
install_and_check_plugin x pack x-pack-*.jar
verify_xpack_installation
}
# Starts a node installed using a package
start_node_using_package() {
if is_systemd; then
run systemctl daemon-reload
[ "$status" -eq 0 ]
run sudo systemctl start elasticsearch.service
[ "$status" -eq "0" ]
elif is_sysvinit; then
run sudo service elasticsearch start
[ "$status" -eq "0" ]
fi
}
@test "[$GROUP] install master node" {
install_master_node
}
@test "[$GROUP] add bootstrap password" {
load $MASTER_UTILS
export ESHOME="$MASTER_HOME"
export_elasticsearch_paths
# For the sake of simplicity we use a bootstrap password in this test.
# The alternative would be to start the master node, use setup-passwords
# and restart the node once ssl/tls is configured. Or use setup-passwords over
# HTTPS with the right cacerts imported into a Java keystore.
run sudo -E -u $MASTER_USER sh <<"NEW_PASS"
echo "changeme" | $ESHOME/bin/elasticsearch-keystore add --stdin bootstrap.password
NEW_PASS
[ "$status" -eq 0 ] || {
echo "Expected elasticsearch-keystore tool exit code to be zero"
echo "$output"
false
}
}
@test "[$GROUP] create instances file" {
run sudo -E -u $MASTER_USER sh <<"CREATE_INSTANCES_FILE"
cat > /tmp/instances.yml <<- EOF
instances:
- name: "node-master"
ip:
- "127.0.0.1"
- name: "node-data"
ip:
- "127.0.0.1"
EOF
CREATE_INSTANCES_FILE
[ "$status" -eq 0 ] || {
echo "Failed to create instances file [$instances]: $output"
false
}
}
@test "[$GROUP] create certificates" {
if [[ -f "$certificates" ]]; then
sudo rm -f "$certificates"
fi
run sudo -E -u $MASTER_USER "$MASTER_HOME/bin/x-pack/certgen" --in "$instances" --out "$certificates"
[ "$status" -eq 0 ] || {
echo "Expected certgen tool exit code to be zero"
echo "$output"
false
}
echo "$output" | grep "Certificates written to $certificates"
assert_file "$certificates" f $MASTER_USER $MASTER_USER 600
}
@test "[$GROUP] install certificates on master node" {
load $MASTER_UTILS
export ESHOME="$MASTER_HOME"
export_elasticsearch_paths
certs="$ESCONFIG/x-pack/certs"
if [[ -d "$certs" ]]; then
sudo rm -rf "$certs"
fi
run sudo -E -u $MASTER_USER "unzip" $certificates -d $certs
[ "$status" -eq 0 ] || {
echo "Failed to unzip certificates in $certs: $output"
false
}
assert_file "$certs/ca/ca.key" f $MASTER_USER $MASTER_USER 644
assert_file "$certs/ca/ca.crt" f $MASTER_USER $MASTER_USER 644
assert_file "$certs/node-master" d $MASTER_USER $MASTER_USER 755
assert_file "$certs/node-master/node-master.key" f $MASTER_USER $MASTER_USER 644
assert_file "$certs/node-master/node-master.crt" f $MASTER_USER $MASTER_USER 644
assert_file "$certs/node-data" d $MASTER_USER $MASTER_USER 755
assert_file "$certs/node-data/node-data.key" f $MASTER_USER $MASTER_USER 644
assert_file "$certs/node-data/node-data.crt" f $MASTER_USER $MASTER_USER 644
}
@test "[$GROUP] update master node settings" {
load $MASTER_UTILS
export ESHOME="$MASTER_HOME"
export_elasticsearch_paths
run sudo -E -u $MASTER_USER sh <<"MASTER_SETTINGS"
cat >> $ESCONFIG/elasticsearch.yml <<- EOF
node.name: "node-master"
node.master: true
node.data: false
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301"]
xpack.ssl.key: $ESCONFIG/x-pack/certs/node-master/node-master.key
xpack.ssl.certificate: $ESCONFIG/x-pack/certs/node-master/node-master.crt
xpack.ssl.certificate_authorities: ["$ESCONFIG/x-pack/certs/ca/ca.crt"]
xpack.security.transport.ssl.enabled: true
transport.tcp.port: 9300
xpack.security.http.ssl.enabled: true
http.port: 9200
EOF
MASTER_SETTINGS
start_master_node
wait_for_xpack 127.0.0.1 9200
}
@test "[$GROUP] test connection to master node using HTTPS" {
load $MASTER_UTILS
export ESHOME="$MASTER_HOME"
export_elasticsearch_paths
run sudo -E -u $MASTER_USER curl -u "elastic:changeme" --cacert "$ESCONFIG/x-pack/certs/ca/ca.crt" -XGET "https://127.0.0.1:9200"
[ "$status" -eq 0 ] || {
echo "Failed to connect to master node using HTTPS:"
echo "$output"
false
}
echo "$output" | grep "node-master"
}
@test "[$GROUP] install data node" {
install_data_node
}
@test "[$GROUP] install certificates on data node" {
load $DATA_UTILS
export ESHOME="$DATA_HOME"
export_elasticsearch_paths
sudo chown $DATA_USER:$DATA_USER "$certificates"
[ -f "$certificates" ] || {
echo "Could not find certificates: $certificates"
false
}
certs="$ESCONFIG/x-pack/certs"
if [[ -d "$certs" ]]; then
sudo rm -rf "$certs"
fi
run sudo -E -u $DATA_USER "unzip" $certificates -d $certs
[ "$status" -eq 0 ] || {
echo "Failed to unzip certificates in $certs: $output"
false
}
assert_file "$certs/ca" d $DATA_USER $DATA_USER
assert_file "$certs/ca/ca.key" f $DATA_USER $DATA_USER 644
assert_file "$certs/ca/ca.crt" f $DATA_USER $DATA_USER 644
assert_file "$certs/node-master" d $DATA_USER $DATA_USER
assert_file "$certs/node-master/node-master.key" f $DATA_USER $DATA_USER 644
assert_file "$certs/node-master/node-master.crt" f $DATA_USER $DATA_USER 644
assert_file "$certs/node-data" d $DATA_USER $DATA_USER
assert_file "$certs/node-data/node-data.key" f $DATA_USER $DATA_USER 644
assert_file "$certs/node-data/node-data.crt" f $DATA_USER $DATA_USER 644
}
@test "[$GROUP] update data node settings" {
load $DATA_UTILS
export ESHOME="$DATA_HOME"
export_elasticsearch_paths
run sudo -E -u $DATA_USER sh <<"DATA_SETTINGS"
cat >> $ESCONFIG/elasticsearch.yml <<- EOF
node.name: "node-data"
node.master: false
node.data: true
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300"]
xpack.ssl.key: $ESCONFIG/x-pack/certs/node-data/node-data.key
xpack.ssl.certificate: $ESCONFIG/x-pack/certs/node-data/node-data.crt
xpack.ssl.certificate_authorities: ["$ESCONFIG/x-pack/certs/ca/ca.crt"]
xpack.security.transport.ssl.enabled: true
transport.tcp.port: 9301
xpack.security.http.ssl.enabled: true
http.port: 9201
EOF
DATA_SETTINGS
start_data_node
wait_for_xpack 127.0.0.1 9201
}
@test "[$GROUP] test connection to data node using HTTPS" {
load $DATA_UTILS
export ESHOME="$DATA_HOME"
export_elasticsearch_paths
run sudo -E -u $DATA_USER curl --cacert "$ESCONFIG/x-pack/certs/ca/ca.crt" -XGET "https://127.0.0.1:9201"
[ "$status" -eq 0 ] || {
echo "Failed to connect to data node using HTTPS:"
echo "$output"
false
}
echo "$output" | grep "missing authentication token"
}
@test "[$GROUP] test node to node communication" {
load $MASTER_UTILS
export ESHOME="$MASTER_HOME"
export_elasticsearch_paths
testIndex=$(sudo curl -u "elastic:changeme" \
-H "Content-Type: application/json" \
--cacert "$ESCONFIG/x-pack/certs/ca/ca.crt" \
-XPOST "https://127.0.0.1:9200/books/book/0?refresh" \
-d '{"title": "Elasticsearch The Definitive Guide"}')
echo "$testIndex" | grep '"result":"created"'
masterSettings=$(sudo curl -u "elastic:changeme" \
-H "Content-Type: application/json" \
--cacert "$ESCONFIG/x-pack/certs/ca/ca.crt" \
-XGET "https://127.0.0.1:9200/_nodes/node-master?filter_path=nodes.*.settings.xpack")
echo "$masterSettings" | grep '"http":{"ssl":{"enabled":"true"}'
echo "$masterSettings" | grep '"transport":{"ssl":{"enabled":"true"}'
echo "$masterSettings" | grep "\"certificate_authorities\":\[\"$ESCONFIG/x-pack/certs/ca/ca.crt\"\]"
load $DATA_UTILS
export ESHOME="$DATA_HOME"
export_elasticsearch_paths
dataSettings=$(curl -u "elastic:changeme" \
-H "Content-Type: application/json" \
--cacert "$ESCONFIG/x-pack/certs/ca/ca.crt" \
-XGET "https://127.0.0.1:9200/_nodes/node-data?filter_path=nodes.*.settings.xpack")
echo "$dataSettings" | grep '"http":{"ssl":{"enabled":"true"}'
echo "$dataSettings" | grep '"transport":{"ssl":{"enabled":"true"}'
echo "$dataSettings" | grep "\"certificate_authorities\":\[\"$ESCONFIG/x-pack/certs/ca/ca.crt\"\]"
testSearch=$(curl -u "elastic:changeme" \
-H "Content-Type: application/json" \
--cacert "$ESCONFIG/x-pack/certs/ca/ca.crt" \
-XGET "https://127.0.0.1:9200/_search?q=title:guide")
echo "$testSearch" | grep '"_index":"books"'
echo "$testSearch" | grep '"_id":"0"'
}

View File

@ -42,7 +42,9 @@ assert_number_of_files() {
}
wait_for_xpack() {
local host=${1:-localhost}
local port=${1:-9200}
for i in {1..30}; do
echo "GET / HTTP/1.0" > /dev/tcp/localhost/9200 && break || sleep 1;
echo "GET / HTTP/1.0" > /dev/tcp/$host/$port && break || sleep 1;
done
}