浏览代码

HPCC-23036 DistributePKI and safe_pki
- creation of certs only on dali (admin) box
- pull certs, no middle man for private certs
- component certs only on nodes where declared

Signed-off-by: Michael Gardner <michael.gardner@lexisnexisrisk.com>

Michael Gardner 5 年之前
父节点
当前提交
cdbf9bb329

+ 2 - 0
CMakeLists.txt

@@ -500,6 +500,8 @@ if(PLATFORM OR CLIENTTOOLS OR REMBED)
     install(FILES ${HPCC_SOURCE_DIR}/${LICENSE_FILE} DESTINATION "." COMPONENT Runtime)
 endif()
 
+add_subdirectory(devel)
+
 #uninstall target
 configure_file(
     "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"

+ 31 - 0
devel/CMakeLists.txt

@@ -0,0 +1,31 @@
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2020 HPCC Systems.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+################################################################################
+
+################################################################################
+# Description:
+# ------------
+#     This directory is the last add_subdirectory and will be the last entry
+#     in the cmake_install.cmake file. This behavior is necessary for running
+#     setup scripts for a developers build and installation.
+################################################################################
+
+if(NOT "${DESTDIR}" STREQUAL "")
+  message(STATUS "Development build and installation")
+  message(STATUS "    DESTDIR:       ${DESTDIR}")
+  message(STATUS "    RUNTIME_USER:  ${RUNTIME_USER}")
+  message(STATUS "    RUNTIME_GROUP: ${RUNTIME_GROUP}")
+  include(pki_setup.cmake)
+endif()

+ 28 - 0
devel/pki_setup.cmake

@@ -0,0 +1,28 @@
+###############################################################################
+#    HPCC SYSTEMS software Copyright (C) 2020 HPCC Systems®.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+################################################################################
+
+################################################################################
+# Description:
+# ------------
+#     Setup PKI certificates for the development environment
+################################################################################
+
+install(CODE "
+if(EXISTS ${INSTALL_DIR}/etc/init.d/setupPKI)
+  message(STATUS \"Running pki setup for a local dev build\")
+  execute_process(COMMAND ${INSTALL_DIR}/etc/init.d/setupPKI)
+endif()
+") 

+ 2 - 1
initfiles/bash/etc/init.d/CMakeLists.txt

@@ -22,6 +22,8 @@ GENERATE_BASH(processor ${bash-vars} "hpcc-init.in" outFiles)
 GENERATE_BASH(processor ${bash-vars} "hpcc_common.in" outFiles)
 GENERATE_BASH(processor ${bash-vars} "uninstall-init.in" outFiles)
 GENERATE_BASH(processor ${bash-vars} "setupPKI.in" outFiles)
+GENERATE_BASH(processor ${bash-vars} "distributePKI.in" outFiles)
+GENERATE_BASH(processor ${bash-vars} "safe_copyPKI.in" outFiles)
 
 ADD_CUSTOM_TARGET(ProcessFiles-initfiles-bash-etc-init.d ALL DEPENDS ${outFiles})
 FOREACH( oFILES
@@ -39,4 +41,3 @@ if ( PLATFORM )
     install ( PROGRAMS hpcc-init.uninstall DESTINATION etc/init.d/uninstall COMPONENT Runtime )
 endif()
 
-install(CODE "execute_process (COMMAND bash -c \"${CMAKE_CURRENT_BINARY_DIR}/setupPKI\")" COMPONENT Runtime)

+ 165 - 0
initfiles/bash/etc/init.d/distributePKI.in

@@ -0,0 +1,165 @@
+#!/bin/bash
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2019 HPCC Systems®.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+################################################################################
+
+set -x
+exec 3>&2 2>./distributePKI.log
+
+###<REPLACE>###
+
+progname=distributePKI
+
+source ${INSTALL_DIR}/etc/init.d/hpcc_common
+source ${INSTALL_DIR}/etc/init.d/init-functions
+source ${INSTALL_DIR}/etc/init.d/export-path
+
+HPCC_CONFIG=${HPCC_CONFIG:-${CONFIG_DIR}/${ENV_CONF_FILE}}
+SECTION=${1:-DEFAULT}
+PATH_PREFIX=`cat ${HPCC_CONFIG} | sed -n "/\[${SECTION}\]/,/\[/p" | grep "^home *= *" | sed -e 's/^home *= *//'`
+USER_NAME=`cat ${HPCC_CONFIG} | sed -n "/\[${SECTION}\]/,/\[/p" | grep "^user *= *" | sed -e 's/^user *= *//'`
+homePath=${PATH_PREFIX}/${USER_NAME}
+
+certPath=${homePath}/certificate
+sbin_path="${INSTALL_DIR}/sbin"
+envfile="${CONFIG_DIR}/${ENV_XML_FILE}"
+
+source_file=certificates.tgz
+source_tar=${homePath}/${source_file}
+
+if [ "$(whoami)" != "root" ] && [ "$(whoami)" != "${USER_NAME}" ]; then
+   echo ""
+   echo "The script must run as root, $USER_NAME or sudo."
+   echo ""
+   exit 1
+fi
+
+createScriptFile() {
+
+  cat > $SCRIPT_FILE <<SCRIPTFILE
+#!/bin/bash
+IP=\$1
+
+if ping -c 1 -w 5 -n \$IP > /dev/null 2>&1; then
+  echo "\$IP: Host is alive."
+  CAN_SSH="\`ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP exit > /dev/null 2>&1; echo \$?\`"
+  if [ "\$CAN_SSH" -eq 255 ]; then
+    echo "\$IP: Cannot SSH to host.";
+  fi
+  
+  IS_LOCAL="\`ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP ls $SCRIPT_FILE > /dev/null 2>&1; echo \$?\`"
+  if [ "\$IS_LOCAL" -ne 0 ]; then
+    echo "\$IP: Fetching complist for \$IP"
+  else
+    echo "\$IP: running on local machine, nothing to do"
+    exit 0
+  fi
+  
+  ## get list of components on remote machine
+  OIFS=\$IFS
+  IFS=\$'\\n'
+  complist=(\$($sbin_path/configgen -env $envfile -ip \$IP -list | awk 'BEGIN { FS="=";} {print \$1;}'))
+  IFS=\$OIFS
+  
+  ## ensure certPath exists
+  ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP mkdir -p $certPath > /dev/null 2>&1
+
+  ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP rm -f $certPath/key.pem $certPath/certificate.pem > /dev/null 2>&1
+  scp -i $homePath/.ssh/id_rsa $certPath/key.pem $certPath/certificate.pem $USER_NAME@\$IP:$certPath
+
+  for i in \${complist[@]} ; do
+      ## allow for overwrite
+      ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP rm -rf $certPath/\$i > /dev/null 2>&1
+      echo "\$IP: scp -r $certPath/\$i $certPath";
+      scp -r -i $homePath/.ssh/id_rsa $certPath/\$i $USER_NAME@\$IP:$certPath
+  done
+
+else
+  echo "\$IP: Cannot Ping host? (Host Alive?)"
+  exit 1
+fi
+SCRIPTFILE
+
+chmod +x ${SCRIPT_FILE}
+}
+
+createRemoteToRemoteScriptFile() {
+
+  cat > $SCRIPT_FILE <<REMOTE_TO_REMOTE_SCRIPTFILE
+#!/bin/bash
+IP=\$1
+
+if ping -c 1 -w 5 -n \$IP > /dev/null 2>&1; then
+  echo "\$IP: Host is alive."
+  CAN_SSH="\`ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP exit > /dev/null 2>&1; echo \$?\`"
+  if [ "\$CAN_SSH" -eq 255 ]; then
+    echo "\$IP: Cannot SSH to host.";
+  fi
+ 
+  if [ "$dali_ip" == "\$IP" ]; then
+    echo "\$IP: On admin node, nothing to do"
+    exit 0
+  fi
+  
+  ## get list of components on remote machine
+  OIFS=\$IFS
+  IFS=\$'\\n'
+  complist=(\$($sbin_path/configgen -env $envfile -ip \$IP -list | awk 'BEGIN { FS="=";} {print \$1;}'))
+  IFS=\$OIFS
+  
+  ## ensure certPath exists
+  ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP mkdir -p $certPath > /dev/null 2>&1
+
+  ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP rm -f $certPath/key.pem $certPath/certificate.pem > /dev/null 2>&1
+  scp -i $homePath/.ssh/id_rsa $USER_NAME@$dali_ip:$certPath/key.pem $USER_NAME@\$IP:$certPath
+  scp -i $homePath/.ssh/id_rsa $USER_NAME@$dali_ip:$certPath/certificate.pem $USER_NAME@\$IP:$certPath
+
+  for i in \${complist[@]} ; do
+      ## allow for overwrite
+      ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@\$IP rm -rf $certPath/\$i > /dev/null 2>&1
+      echo "\$IP: scp -r $certPath/\$i $certPath";
+      scp -r -i $homePath/.ssh/id_rsa $USER_NAME@$dali_ip:$certPath/\$i $USER_NAME@\$IP:$certPath
+  done
+
+else
+  echo "\$IP: Cannot Ping host? (Host Alive?)"
+  exit 1
+fi
+REMOTE_TO_REMOTE_SCRIPTFILE
+
+chmod +x ${SCRIPT_FILE}
+}
+
+is_dali=$($sbin_path/configgen -env $envfile -list | grep dali )
+if [ -n "$is_dali" ]; then
+  SCRIPT_FILE=/tmp/distributePKI_$$
+  createScriptFile
+
+  ${INSTALL_DIR}/etc/init.d/setupPKI
+
+  OPTION="-e ${CONFIG_DIR}/${ENV_CONF_FILE} -s ${SECTION:-DEFAULT} -x"
+  eval ${INSTALL_DIR}/sbin/cluster_script.py -f ${SCRIPT_FILE} $OPTION
+  rm -rf ${SCRIPT_FILE}
+else
+  SCRIPT_FILE=/tmp/distributePKI_$$
+  dali_ip=$($sbin_path/configgen -env $envfile -listall | awk 'BEGIN {FS=",";} /^DaliServerProcess/ {print $3;}')
+  createRemoteToRemoteScriptFile
+  ssh -i $homePath/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER_NAME@$dali_ip $INSTALL_DIR/etc/init.d/setupPKI
+  OPTION="-e ${CONFIG_DIR}/${ENV_CONF_FILE} -s ${SECTION:-DEFAULT}"
+  eval ${INSTALL_DIR}/sbin/cluster_script.py -f ${SCRIPT_FILE} $OPTION
+  rm -rf ${SCRIPT_FILE}
+fi
+
+set +x

+ 29 - 27
initfiles/bash/etc/init.d/install-init.in

@@ -231,34 +231,36 @@ else
     log_success_msg
 fi
 
-if [ ! -d ${homePath}/certificate ]; then
-    mkdir -p ${homePath}/certificate
-fi
-
-if [ ! -e ${homePath}/certificate/key.pem ]; then
-    ssh-keygen -t rsa -N '' -f ${homePath}/certificate/key.pem \
-        1>/dev/null 2>&1
-    openssl rsa -in ${homePath}/certificate/key.pem -pubout \
-        -out ${homePath}/certificate/public.key.pem 
-    chmod 0644 ${homePath}/certificate/public.key.pem
-    rm -f ${homePath}/certificate/key.pem.pub
-    printf "RSA key installed for user %-28s ..." "$user"
-    log_success_msg
-else
-    printf "RSA keys are already installed for user %-15s ..." "$user"
-    log_success_msg
-fi
+## for now turn off certificate logic if we're switching to setupPKI and distributePKI
 
-if [ ! -e ${homePath}/certificate/certificate.pem ]; then
-    openssl req -new -key ${homePath}/certificate/key.pem -keyform PEM -x509 \
-        -days 365 -out ${homePath}/certificate/certificate.pem \
-        -batch 1>/dev/null 2>&1
-    printf "Self Signed Certificate installed for user %-12s ..." "$user"
-    log_success_msg
-else
-    printf "Self Signed Certificate already installed for %-9s ..." "$user"
-    log_success_msg
-fi
+#if [ ! -d ${homePath}/certificate ]; then
+#    mkdir -p ${homePath}/certificate
+#fi
+#
+#if [ ! -e ${homePath}/certificate/key.pem ]; then
+#    ssh-keygen -t rsa -N '' -f ${homePath}/certificate/key.pem \
+#        1>/dev/null 2>&1
+#    openssl rsa -in ${homePath}/certificate/key.pem -pubout \
+#        -out ${homePath}/certificate/public.key.pem 
+#    chmod 0644 ${homePath}/certificate/public.key.pem
+#    rm -f ${homePath}/certificate/key.pem.pub
+#    printf "RSA key installed for user %-28s ..." "$user"
+#    log_success_msg
+#else
+#    printf "RSA keys are already installed for user %-15s ..." "$user"
+#    log_success_msg
+#fi
+#
+#if [ ! -e ${homePath}/certificate/certificate.pem ]; then
+#    openssl req -new -key ${homePath}/certificate/key.pem -keyform PEM -x509 \
+#        -days 365 -out ${homePath}/certificate/certificate.pem \
+#        -batch 1>/dev/null 2>&1
+#    printf "Self Signed Certificate installed for user %-12s ..." "$user"
+#    log_success_msg
+#else
+#    printf "Self Signed Certificate already installed for %-9s ..." "$user"
+#    log_success_msg
+#fi
 
 # Added code to change environment.conf file user home directory location for key generation
 if [ "$homeBase" != "$home" ]; then

+ 126 - 0
initfiles/bash/etc/init.d/safe_copyPKI.in

@@ -0,0 +1,126 @@
+#!/bin/bash
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2019 HPCC Systems®.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+################################################################################
+
+set -x
+exec 3>&2 2>./safe_copyPKI.log
+
+INSTALL_DIR=/opt/HPCCSystems
+CONFIG_DIR=/etc/HPCCSystems
+ENV_XML_FILE=environment.xml
+ENV_CONF_FILE=environment.conf
+PID_DIR=/var/run/HPCCSystems
+LOCK_DIR=/var/lock/HPCCSystems
+LOG_DIR=/var/log/HPCCSystems
+INIT_PATH=/etc/init.d
+
+
+progname=safe_copyPKI
+
+source ${INSTALL_DIR}/etc/init.d/hpcc_common
+source ${INSTALL_DIR}/etc/init.d/init-functions
+source ${INSTALL_DIR}/etc/init.d/export-path
+
+HPCC_CONFIG=${HPCC_CONFIG:-${CONFIG_DIR}/${ENV_CONF_FILE}}
+SECTION=${1:-DEFAULT}
+PATH_PREFIX=`cat ${HPCC_CONFIG} | sed -n "/\[${SECTION}\]/,/\[/p" | grep "^home *= *" | sed -e 's/^home *= *//'`
+USER_NAME=`cat ${HPCC_CONFIG} | sed -n "/\[${SECTION}\]/,/\[/p" | grep "^user *= *" | sed -e 's/^user *= *//'`
+homePath=${PATH_PREFIX}/${USER_NAME}
+
+certPath=${homePath}/certificate
+sbin_path="${INSTALL_DIR}/sbin"
+envfile="${CONFIG_DIR}/${ENV_XML_FILE}"
+
+if [ "$(whoami)" != "${USER}" ]; then
+   echo ""
+   echo "The script must run as $USER."
+   echo ""
+   exit 1
+fi
+
+createScriptFile() {
+
+  cat > $SCRIPT_FILE <<SCRIPTFILE
+#!/bin/bash
+IP=\$1
+
+set -x
+exec 3>&2 2>./safe-\$(date -Ins).log
+
+if ping -c 1 -w 5 -n \$IP > /dev/null 2>&1; then
+  echo "\$IP: Host is alive."
+  CAN_SSH="\`ssh -i $HOME/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER@\$IP exit > /dev/null 2>&1; echo \$?\`"
+  if [ "\$CAN_SSH" -eq 255 ]; then
+    echo "\$IP: Cannot SSH to host.";
+  fi
+  
+  IS_LOCAL="\`ssh -i $HOME/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER@\$IP ls $SCRIPT_FILE > /dev/null 2>&1; echo \$?\`"
+  if [ "\$IS_LOCAL" -ne 0 ]; then
+    echo "\$IP: Fetching complist for \$IP"
+  else
+    echo "\$IP: running on local machine, nothing to do"
+    exit 0
+  fi
+  
+  ## get list of components on remote machine
+  OIFS=\$IFS
+  IFS=\$'\\n'
+  complist=(\$($sbin_path/configgen -env $envfile -ip \$IP -list | awk 'BEGIN { FS="=";} {print \$1;}'))
+  IFS=\$OIFS
+
+  mkdir -p $HOME/tmp_certs
+  for i in "" \${complist[@]} ; do
+    compName=""
+    if [ "\$i" != "" ]; then
+      compName=""\${i#*_}
+    fi
+    if [ -n "\$compName" ]; then
+      ## allow for overwrite
+      ssh -i $HOME/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER@\$IP sudo rm -rf $certPath/\$compName > /dev/null 2>&1
+      sudo cp -R $certPath/\$compName $HOME/tmp_certs
+    fi
+  done
+  
+  sudo chown -R $USER:$USER $HOME/tmp_certs
+  scp -r -i $HOME/.ssh/id_rsa $HOME/tmp_certs $USER@\$IP:$HOME
+  ## copy full directory over
+  ssh -i $HOME/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER@\$IP sudo cp -R $HOME/tmp_certs/ $certPath > /dev/null 2>&1
+  ## ensure $USER_NAME is owner
+  ssh -i $HOME/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER@\$IP sudo chown -R $USER_NAME:$USER_NAME $certPath > /dev/null 2>&1
+  ## cleanup
+  rm -rf $HOME/tmp_certs
+  ssh -i $HOME/.ssh/id_rsa -o BatchMode=yes -o LogLevel=QUIET -o StrictHostKeyChecking=no $USER@\$IP rm -rf $HOME/tmp_certs > /dev/null 2>&1
+
+else
+  echo "\$IP: Cannot Ping host? (Host Alive?)"
+  exit 1
+fi
+SCRIPTFILE
+
+chmod +x ${SCRIPT_FILE}
+}
+
+SCRIPT_FILE=/tmp/distributePKI_$$
+createScriptFile
+
+sudo ${INSTALL_DIR}/etc/init.d/setupPKI
+
+OPTION="-e ${CONFIG_DIR}/${ENV_CONF_FILE} -s ${SECTION:-DEFAULT} -x"
+eval sudo ${INSTALL_DIR}/sbin/cluster_script.py -f ${SCRIPT_FILE} $OPTION
+
+rm -rf ${SCRIPT_FILE}
+
+set +x

+ 8 - 13
initfiles/bash/etc/init.d/setupPKI.in

@@ -24,7 +24,7 @@ progname=setupPKI
 
 source ${INSTALL_DIR}/etc/init.d/hpcc_common
 source ${INSTALL_DIR}/etc/init.d/init-functions
-source  ${INSTALL_DIR}/etc/init.d/export-path
+source ${INSTALL_DIR}/etc/init.d/export-path
 
 HPCC_CONFIG=${HPCC_CONFIG:-${CONFIG_DIR}/${ENV_CONF_FILE}}
 SECTION=${1:-DEFAULT}
@@ -36,22 +36,17 @@ certPath=${homePath}/certificate
 sbin_path="${INSTALL_DIR}/sbin"
 envfile="${CONFIG_DIR}/${ENV_XML_FILE}"
 
-COMPS=$(${sbin_path}/configgen -env ${envfile} -list)
+OIFS=$IFS
+IFS=$'\n'
+compArray=($(${sbin_path}/configgen -env ${envfile} -listall | awk 'BEGIN { FS=",";} {print $2;}'))
+IFS=$OIFS
 
-if [[ ${rc} -ne 0 ]]; then
-    log "${progname}: failure to build COMPS from configgen call"
-    echo -e "\033[31merror\033[0m: ${progname} -> failure to build COMPS from configgen call"
+if [ ${#compArray[@]} -eq 0 ]; then
+    log "$progname: failure to build COMPS from configgen call"
+    echo -e "\033[31merror\033[0m: $progname -> failure to build COMPS from configgen call"
     exit 1
 fi
 
-comp.parser ${COMPS}
-
-if [ -z ${compArray} ];then
-   log  "There are no components configured to run on this node ..."
-   echo "There are no components configured to run on this node ..."
-   exit 3
-fi
-
 if [ ! -d ${certPath} ]; then
     mkdir -p ${certPath}
 fi