Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wazuh-certs-tool.sh support for multiple IPs in server nodes #1770

Merged
merged 7 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 163 additions & 51 deletions unattended_installer/cert_tool/certFunctions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,22 +91,27 @@ function cert_generateCertificateconfiguration() {
IP.1 = cip
EOF


conf="$(awk '{sub("CN = cname", "CN = '"${1}"'")}1' "${cert_tmp_path}/${1}.conf")"
echo "${conf}" > "${cert_tmp_path}/${1}.conf"

isIP=$(echo "${2}" | grep -P "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$")
isDNS=$(echo "${2}" | grep -P "^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z-]{2,})+$" )

if [[ -n "${isIP}" ]]; then
conf="$(awk '{sub("IP.1 = cip", "IP.1 = '"${2}"'")}1' "${cert_tmp_path}/${1}.conf")"
echo "${conf}" > "${cert_tmp_path}/${1}.conf"
elif [[ -n "${isDNS}" ]]; then
conf="$(awk '{sub("CN = cname", "CN = '"${2}"'")}1' "${cert_tmp_path}/${1}.conf")"
echo "${conf}" > "${cert_tmp_path}/${1}.conf"
conf="$(awk '{sub("IP.1 = cip", "DNS.1 = '"${2}"'")}1' "${cert_tmp_path}/${1}.conf")"
echo "${conf}" > "${cert_tmp_path}/${1}.conf"
if [ "${#@}" -gt 1 ]; then
sed -i '/IP.1/d' "${cert_tmp_path}/${1}.conf"
for (( i=2; i<=${#@}; i++ )); do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't you use this same loop for all cases instead of testing it separately when there is only one IP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 4ea226d

isIP=$(echo "${!i}" | grep -P "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$")
isDNS=$(echo "${!i}" | grep -P "^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z-]{2,})+$" )
j=$((i-1))
if [ "${isIP}" ]; then
printf '%s\n' " IP.${j} = ${!i}" >> "${cert_tmp_path}/${1}.conf"
elif [ "${isDNS}" ]; then
printf '%s\n' " DNS.${j} = ${!i}" >> "${cert_tmp_path}/${1}.conf"
else
common_logger -e "Invalid IP or DNS ${!i}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use 2 different messages for the same error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 4ea226d

exit 1
fi
done
else
common_logger -e "The given information does not match with an IP address or a DNS."
common_logger -e "No IP or DNS specified"
exit 1
fi

Expand All @@ -118,9 +123,10 @@ function cert_generateIndexercertificates() {
common_logger -d "Creating the Wazuh indexer certificates."

for i in "${!indexer_node_names[@]}"; do
cert_generateCertificateconfiguration "${indexer_node_names[i]}" "${indexer_node_ips[i]}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/${indexer_node_names[i]}-key.pem -out ${cert_tmp_path}/${indexer_node_names[i]}.csr -config ${cert_tmp_path}/${indexer_node_names[i]}.conf -days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${indexer_node_names[i]}.csr -CA ${cert_tmp_path}/root-ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out ${cert_tmp_path}/${indexer_node_names[i]}.pem -extfile ${cert_tmp_path}/${indexer_node_names[i]}.conf -extensions v3_req -days 3650 ${debug}"
indexer_node_name=${indexer_node_names[$i]}
cert_generateCertificateconfiguration "${indexer_node_name}" "${indexer_node_ips[i]}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/${indexer_node_name}-key.pem -out ${cert_tmp_path}/${indexer_node_name}.csr -config ${cert_tmp_path}/${indexer_node_name}.conf -days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${indexer_node_name}.csr -CA ${cert_tmp_path}/root-ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out ${cert_tmp_path}/${indexer_node_name}.pem -extfile ${cert_tmp_path}/${indexer_node_name}.conf -extensions v3_req -days 3650 ${debug}"
done
else
return 1
Expand All @@ -134,9 +140,12 @@ function cert_generateFilebeatcertificates() {
common_logger -d "Creating the Wazuh server certificates."

for i in "${!server_node_names[@]}"; do
cert_generateCertificateconfiguration "${server_node_names[i]}" "${server_node_ips[i]}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/${server_node_names[i]}-key.pem -out ${cert_tmp_path}/${server_node_names[i]}.csr -config ${cert_tmp_path}/${server_node_names[i]}.conf -days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${server_node_names[i]}.csr -CA ${cert_tmp_path}/root-ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out ${cert_tmp_path}/${server_node_names[i]}.pem -extfile ${cert_tmp_path}/${server_node_names[i]}.conf -extensions v3_req -days 3650 ${debug}"
server_name="${server_node_names[i]}"
j=$((i+1))
declare -a server_ips=(server_node_ip_"$j"[@])
cert_generateCertificateconfiguration "${server_name}" "${!server_ips}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/${server_name}-key.pem -out ${cert_tmp_path}/${server_name}.csr -config ${cert_tmp_path}/${server_name}.conf -days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${server_name}.csr -CA ${cert_tmp_path}/root-ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out ${cert_tmp_path}/${server_name}.pem -extfile ${cert_tmp_path}/${server_name}.conf -extensions v3_req -days 3650 ${debug}"
done
else
return 1
Expand All @@ -150,9 +159,10 @@ function cert_generateDashboardcertificates() {
common_logger -d "Creating the Wazuh dashboard certificates."

for i in "${!dashboard_node_names[@]}"; do
cert_generateCertificateconfiguration "${dashboard_node_names[i]}" "${dashboard_node_ips[i]}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/${dashboard_node_names[i]}-key.pem -out ${cert_tmp_path}/${dashboard_node_names[i]}.csr -config ${cert_tmp_path}/${dashboard_node_names[i]}.conf -days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${dashboard_node_names[i]}.csr -CA ${cert_tmp_path}/root-ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out ${cert_tmp_path}/${dashboard_node_names[i]}.pem -extfile ${cert_tmp_path}/${dashboard_node_names[i]}.conf -extensions v3_req -days 3650 ${debug}"
dashboard_node_name="${dashboard_node_names[i]}"
cert_generateCertificateconfiguration "${dashboard_node_name}" "${dashboard_node_ips[i]}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/${dashboard_node_name}-key.pem -out ${cert_tmp_path}/${dashboard_node_name}.csr -config ${cert_tmp_path}/${dashboard_node_name}.conf -days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${dashboard_node_name}.csr -CA ${cert_tmp_path}/root-ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out ${cert_tmp_path}/${dashboard_node_name}.pem -extfile ${cert_tmp_path}/${dashboard_node_name}.conf -extensions v3_req -days 3650 ${debug}"
done
else
return 1
Expand All @@ -170,27 +180,120 @@ function cert_generateRootCAcertificate() {

function cert_parseYaml() {

local prefix=${2}
local s='[[:space:]]*'
local w='[a-zA-Z0-9_]*'
local fs
fs=$(echo @|tr @ '\034')
sed -re "s|^(\s+)-\s+name|\1 name|" "${1}" |
local prefix=$2
local separator=${3:-_}
local indexfix
# Detect awk flavor
if awk --version 2>&1 | grep -q "GNU Awk" ; then
# GNU Awk detected
indexfix=-1
elif awk -Wv 2>&1 | grep -q "mawk" ; then
# mawk detected
indexfix=0
fi

local s='[[:space:]]*' sm='[ \t]*' w='[a-zA-Z0-9_]*' fs=${fs:-$(echo @|tr @ '\034')} i=${i:- }
cat $1 2>/dev/null | \
awk -F$fs "{multi=0;
if(match(\$0,/$sm\|$sm$/)){multi=1; sub(/$sm\|$sm$/,\"\");}
if(match(\$0,/$sm>$sm$/)){multi=2; sub(/$sm>$sm$/,\"\");}
while(multi>0){
str=\$0; gsub(/^$sm/,\"\", str);
indent=index(\$0,str);
indentstr=substr(\$0, 0, indent+$indexfix) \"$i\";
obuf=\$0;
getline;
while(index(\$0,indentstr)){
obuf=obuf substr(\$0, length(indentstr)+1);
if (multi==1){obuf=obuf \"\\\\n\";}
if (multi==2){
if(match(\$0,/^$sm$/))
obuf=obuf \"\\\\n\";
else obuf=obuf \" \";
}
getline;
}
sub(/$sm$/,\"\",obuf);
print obuf;
multi=0;
if(match(\$0,/$sm\|$sm$/)){multi=1; sub(/$sm\|$sm$/,\"\");}
if(match(\$0,/$sm>$sm$/)){multi=2; sub(/$sm>$sm$/,\"\");}
}
print}" | \
sed -e "s|^\($s\)?|\1-|" \
-ne "s|^$s#.*||;s|$s#[^\"']*$||;s|^\([^\"'#]*\)#.*|\1|;t1;t;:1;s|^$s\$||;t2;p;:2;d" | \
sed -ne "s|,$s\]$s\$|]|" \
-e ":1;s|^\($s\)\($w\)$s:$s\(&$w\)\?$s\[$s\(.*\)$s,$s\(.*\)$s\]|\1\2: \3[\4]\n\1$i- \5|;t1" \
-e "s|^\($s\)\($w\)$s:$s\(&$w\)\?$s\[$s\(.*\)$s\]|\1\2: \3\n\1$i- \4|;" \
-e ":2;s|^\($s\)-$s\[$s\(.*\)$s,$s\(.*\)$s\]|\1- [\2]\n\1$i- \3|;t2" \
-e "s|^\($s\)-$s\[$s\(.*\)$s\]|\1-\n\1$i- \2|;p" | \
sed -ne "s|,$s}$s\$|}|" \
-e ":1;s|^\($s\)-$s{$s\(.*\)$s,$s\($w\)$s:$s\(.*\)$s}|\1- {\2}\n\1$i\3: \4|;t1" \
-e "s|^\($s\)-$s{$s\(.*\)$s}|\1-\n\1$i\2|;" \
-e ":2;s|^\($s\)\($w\)$s:$s\(&$w\)\?$s{$s\(.*\)$s,$s\($w\)$s:$s\(.*\)$s}|\1\2: \3 {\4}\n\1$i\5: \6|;t2" \
-e "s|^\($s\)\($w\)$s:$s\(&$w\)\?$s{$s\(.*\)$s}|\1\2: \3\n\1$i\4|;p" | \
sed -e "s|^\($s\)\($w\)$s:$s\(&$w\)\(.*\)|\1\2:\4\n\3|" \
-e "s|^\($s\)-$s\(&$w\)\(.*\)|\1- \3\n\2|" | \
sed -ne "s|^\($s\):|\1|" \
-e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" |
awk -F"$fs" '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s=%s\n", "'$prefix'",vn, $2, $3);
-e "s|^\($s\)\(---\)\($s\)||" \
-e "s|^\($s\)\(\.\.\.\)\($s\)||" \
-e "s|^\($s\)-$s[\"']\(.*\)[\"']$s\$|\1$fs$fs\2|p;t" \
-e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p;t" \
-e "s|^\($s\)-$s\(.*\)$s\$|\1$fs$fs\2|" \
-e "s|^\($s\)\($w\)$s:$s[\"']\?\(.*\)$s\$|\1$fs\2$fs\3|" \
-e "s|^\($s\)[\"']\?\([^&][^$fs]\+\)[\"']$s\$|\1$fs$fs$fs\2|" \
-e "s|^\($s\)[\"']\?\([^&][^$fs]\+\)$s\$|\1$fs$fs$fs\2|" \
-e "s|$s\$||p" | \
awk -F$fs "{
gsub(/\t/,\" \",\$1);
gsub(\"name: \", \"\");
if(NF>3){if(value!=\"\"){value = value \" \";}value = value \$4;}
else {
if(match(\$1,/^&/)){anchor[substr(\$1,2)]=full_vn;getline};
indent = length(\$1)/length(\"$i\");
vname[indent] = \$2;
value= \$3;
for (i in vname) {if (i > indent) {delete vname[i]; idx[i]=0}}
if(length(\$2)== 0){ vname[indent]= ++idx[indent] };
vn=\"\"; for (i=0; i<indent; i++) { vn=(vn)(vname[i])(\"$separator\")}
vn=\"$prefix\" vn;
full_vn=vn vname[indent];
if(vn==\"$prefix\")vn=\"$prefix$separator\";
if(vn==\"_\")vn=\"__\";
}
assignment[full_vn]=value;
if(!match(assignment[vn], full_vn))assignment[vn]=assignment[vn] \" \" full_vn;
if(match(value,/^\*/)){
ref=anchor[substr(value,2)];
if(length(ref)==0){
printf(\"%s=\\\"%s\\\"\n\", full_vn, value);
} else {
for(val in assignment){
if((length(ref)>0)&&index(val, ref)==1){
tmpval=assignment[val];
sub(ref,full_vn,val);
if(match(val,\"$separator\$\")){
gsub(ref,full_vn,tmpval);
} else if (length(tmpval) > 0) {
printf(\"%s=\\\"%s\\\"\n\", val, tmpval);
}
assignment[val]=tmpval;
}
}
}
}'
} else if (length(value) > 0) {
printf(\"%s=\\\"%s\\\"\n\", full_vn, value);
}
}END{
for(val in assignment){
if(match(val,\"$separator\$\"))
printf(\"%s=\\\"%s\\\"\n\", val, assignment[val]);
}
}"

}


function cert_readConfig() {

if [ -f "${config_file}" ]; then
Expand All @@ -199,17 +302,31 @@ function cert_readConfig() {
exit 1
fi
eval "$(cert_convertCRLFtoLF "${config_file}")"
common_checkWazuhConfigYaml
eval "$(cert_parseYaml "${config_file}")"
eval "indexer_node_names=( $(cert_parseYaml "${config_file}" | grep nodes_indexer__name | sed 's/nodes_indexer__name=//' | sed -r 's/\s+//g') )"
eval "server_node_names=( $(cert_parseYaml "${config_file}" | grep nodes_server__name | sed 's/nodes_server__name=//' | sed -r 's/\s+//g') )"
eval "dashboard_node_names=( $(cert_parseYaml "${config_file}" | grep nodes_dashboard__name | sed 's/nodes_dashboard__name=//' | sed -r 's/\s+//g') )"

eval "indexer_node_ips=( $(cert_parseYaml "${config_file}" | grep nodes_indexer__ip | sed 's/nodes_indexer__ip=//' | sed -r 's/\s+//g') )"
eval "server_node_ips=( $(cert_parseYaml "${config_file}" | grep nodes_server__ip | sed 's/nodes_server__ip=//' | sed -r 's/\s+//g') )"
eval "dashboard_node_ips=( $(cert_parseYaml "${config_file}" | grep nodes_dashboard__ip | sed 's/nodes_dashboard__ip=//' | sed -r 's/\s+//g') )"
if [ -n "${AIO}" ] || [ -n "${indexer}" ] || [ -n "${wazuh}" ] || [ -n "${dashboard}" ]; then
eval "indexer_node_names=( $(cert_parseYaml "${config_file}" | grep "nodes__indexer__[0-9]=" | cut -d = -f 2 ) )"
eval "server_node_names=( $(cert_parseYaml "${config_file}" | grep "nodes__server__[0-9]=" | cut -d = -f 2 ) )"
eval "dashboard_node_names=( $(cert_parseYaml "${config_file}" | grep "nodes__dashboard__[0-9]=" | cut -d = -f 2) )"
eval "indexer_node_ips=( $(cert_parseYaml "${config_file}" | grep "nodes__indexer__[0-9]__ip=" | cut -d = -f 2) )"
eval "server_node_ips=( $(cert_parseYaml "${config_file}" | grep "nodes__server__[0-9]__ip=" | cut -d = -f 2) )"
eval "dashboard_node_ips=( $(cert_parseYaml "${config_file}" | grep "nodes__dashboard__[0-9]__ip=" | cut -d = -f 2 ) )"
eval "server_node_types=( $(cert_parseYaml "${config_file}" | grep "nodes__server__[0-9]__node_type=" | cut -d = -f 2 ) )"
eval "number_server_ips=( $(cert_parseYaml "${config_file}" | grep -o -E 'nodes__server__[0-9]__ip' | sort -u | wc -l) )"
else
eval "indexer_node_names=( $(cert_parseYaml "${config_file}" | grep "nodes_indexer_[0-9]=" | cut -d = -f 2 ) )"
eval "server_node_names=( $(cert_parseYaml "${config_file}" | grep "nodes_server_[0-9]=" | cut -d = -f 2 ) )"
eval "dashboard_node_names=( $(cert_parseYaml "${config_file}" | grep "nodes_dashboard_[0-9]=" | cut -d = -f 2) )"
eval "indexer_node_ips=( $(cert_parseYaml "${config_file}" | grep "nodes_indexer_[0-9]_ip=" | cut -d = -f 2) )"
eval "server_node_ips=( $(cert_parseYaml "${config_file}" | grep "nodes_server_[0-9]_ip=" | cut -d = -f 2) )"
eval "dashboard_node_ips=( $(cert_parseYaml "${config_file}" | grep "nodes_dashboard_[0-9]_ip=" | cut -d = -f 2 ) )"
eval "server_node_types=( $(cert_parseYaml "${config_file}" | grep "nodes_server_[0-9]_node_type=" | cut -d = -f 2 ) )"
eval "number_server_ips=( $(cert_parseYaml "${config_file}" | grep -o -E 'nodes_server_[0-9]_ip' | sort -u | wc -l) )"
fi

eval "server_node_types=( $(cert_parseYaml "${config_file}" | grep nodes_server__node_type | sed 's/nodes_server__node_type=//' | sed -r 's/\s+//g') )"
for i in $(seq 1 "${number_server_ips}"); do
nodes_server=nodes__server__"${i}"__ip
eval "server_node_ip_$i=( $( cert_parseYaml "${config_file}" | grep "${nodes_server}" | sed '/\./!d' | cut -d = -f 2 | sed -r 's/\s+//g') )"
done

unique_names=($(echo "${indexer_node_names[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
if [ "${#unique_names[@]}" -ne "${#indexer_node_names[@]}" ]; then
Expand Down Expand Up @@ -247,11 +364,6 @@ function cert_readConfig() {
exit 1
fi

if [ "${#server_node_names[@]}" -ne "${#server_node_ips[@]}" ]; then
common_logger -e "Different number of Wazuh server node names and IPs."
exit 1
fi

for i in "${server_node_types[@]}"; do
if ! echo "$i" | grep -ioq master && ! echo "$i" | grep -ioq worker; then
common_logger -e "Incorrect node_type $i must be master or worker"
Expand Down
4 changes: 2 additions & 2 deletions unattended_installer/passwords_tool/passwordsFunctions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

function passwords_changePassword() {

eval "mkdir /etc/wazuh-indexer/backup/"
eval "cp /etc/wazuh-indexer/opensearch-security/* /etc/wazuh-indexer/backup/"
eval "mkdir /etc/wazuh-indexer/backup/ 2>/dev/null"
eval "cp /etc/wazuh-indexer/opensearch-security/* /etc/wazuh-indexer/backup/ 2>/dev/null"

if [ -n "${changeall}" ]; then
for i in "${!passwords[@]}"
Expand Down