From 8628a89cb2f6f03fa7242390422e845283622391 Mon Sep 17 00:00:00 2001 From: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> Date: Wed, 27 Sep 2023 09:08:18 -0400 Subject: [PATCH] Demo configuration script requires admin password (#3329) This change requires an alternative to the default credentials for the admin user. The credentials can be provided to the script via: - `initialAdminPassword` environment variable - a file with a single line that contains the password. The admin password for the cluster will be printed to the console output of the `tools/install_demo_configuration.(bat|sh)` Signed-off-by: Stephen Crawford Signed-off-by: Peter Nied Co-authored-by: Peter Nied --- .../action.yml | 13 ++++- .github/workflows/plugin_install.yml | 6 ++- tools/install_demo_configuration.bat | 52 +++++++++++++++++++ tools/install_demo_configuration.sh | 38 ++++++++++++++ 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/.github/actions/start-opensearch-with-one-plugin/action.yml b/.github/actions/start-opensearch-with-one-plugin/action.yml index fa5681c422..642264f4ec 100644 --- a/.github/actions/start-opensearch-with-one-plugin/action.yml +++ b/.github/actions/start-opensearch-with-one-plugin/action.yml @@ -14,6 +14,10 @@ inputs: description: 'The name of the setup script you want to run i.e. "setup" (do not include file extension). Leave empty to indicate one should not be run.' required: false + admin-password: + description: 'The admin password uses for the cluster' + required: true + runs: using: "composite" steps: @@ -67,6 +71,11 @@ runs: 'y' | .\opensearch-${{ inputs.opensearch-version }}-SNAPSHOT\bin\opensearch-plugin.bat install file:$(pwd)\${{ inputs.plugin-name }}.zip shell: pwsh + - name: Write password to initialAdminPassword location + run: + echo ${{ inputs.admin-password }} >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/initialAdminPassword.txt + shell: bash + # Run any configuration scripts - name: Run Setup Script for Linux if: ${{ runner.os == 'Linux' && inputs.setup-script-name != '' }} @@ -101,13 +110,13 @@ runs: # Verify that the server is operational - name: Check OpenSearch Running on Linux if: ${{ runner.os != 'Windows'}} - run: curl https://localhost:9200/_cat/plugins -u 'admin:admin' -k -v + run: curl https://localhost:9200/_cat/plugins -u 'admin:${{ inputs.admin-password }}' -k -v --fail-with-body shell: bash - name: Check OpenSearch Running on Windows if: ${{ runner.os == 'Windows'}} run: | - $credentialBytes = [Text.Encoding]::ASCII.GetBytes("admin:admin") + $credentialBytes = [Text.Encoding]::ASCII.GetBytes("admin:${{ inputs.admin-password }}") $encodedCredentials = [Convert]::ToBase64String($credentialBytes) $baseCredentials = "Basic $encodedCredentials" $Headers = @{ Authorization = $baseCredentials } diff --git a/.github/workflows/plugin_install.yml b/.github/workflows/plugin_install.yml index 5bfce0248b..39901689be 100644 --- a/.github/workflows/plugin_install.yml +++ b/.github/workflows/plugin_install.yml @@ -16,6 +16,9 @@ jobs: runs-on: ${{ matrix.os }} steps: + - id: random-password + uses: peternied/random-name@v1 + - name: Set up JDK uses: actions/setup-java@v3 with: @@ -57,9 +60,10 @@ jobs: opensearch-version: ${{ env.OPENSEARCH_VERSION }} plugin-name: ${{ env.PLUGIN_NAME }} setup-script-name: setup + admin-password: ${{ steps.random-password.outputs.generated_name }} - name: Run sanity tests uses: gradle/gradle-build-action@v2 with: cache-disabled: true - arguments: integTestRemote -Dtests.rest.cluster=localhost:9200 -Dtests.cluster=localhost:9200 -Dtests.clustername="opensearch" -Dhttps=true -Duser=admin -Dpassword=admin + arguments: integTestRemote -Dtests.rest.cluster=localhost:9200 -Dtests.cluster=localhost:9200 -Dtests.clustername="opensearch" -Dhttps=true -Duser=admin -Dpassword=${{ steps.random-password.outputs.generated_name }} -i diff --git a/tools/install_demo_configuration.bat b/tools/install_demo_configuration.bat index b08c3bdfae..d9d30fea2b 100755 --- a/tools/install_demo_configuration.bat +++ b/tools/install_demo_configuration.bat @@ -75,6 +75,7 @@ cd %CUR% echo Basedir: %BASE_DIR% set "OPENSEARCH_CONF_FILE=%BASE_DIR%config\opensearch.yml" +set "INTERNAL_USERS_FILE"=%BASE_DIR%config\opensearch-security\internal_users.yml" set "OPENSEARCH_CONF_DIR=%BASE_DIR%config\" set "OPENSEARCH_BIN_DIR=%BASE_DIR%bin\" set "OPENSEARCH_PLUGINS_DIR=%BASE_DIR%plugins\" @@ -319,6 +320,57 @@ echo plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_a echo plugins.security.system_indices.enabled: true >> "%OPENSEARCH_CONF_FILE%" echo plugins.security.system_indices.indices: [".plugins-ml-config", ".plugins-ml-connector", ".plugins-ml-model-group", ".plugins-ml-model", ".plugins-ml-task", ".plugins-ml-conversation-meta", ".plugins-ml-conversation-interactions", ".opendistro-alerting-config", ".opendistro-alerting-alert*", ".opendistro-anomaly-results*", ".opendistro-anomaly-detector*", ".opendistro-anomaly-checkpoints", ".opendistro-anomaly-detection-state", ".opendistro-reports-*", ".opensearch-notifications-*", ".opensearch-notebooks", ".opensearch-observability", ".ql-datasources", ".opendistro-asynchronous-search-response*", ".replication-metadata-store", ".opensearch-knn-models", ".geospatial-ip2geo-data*"] >> "%OPENSEARCH_CONF_FILE%" +setlocal enabledelayedexpansion + +set "ADMIN_PASSWORD_FILE=%OPENSEARCH_CONF_DIR%initialAdminPassword.txt" +set "INTERNAL_USERS_FILE=%OPENSEARCH_CONF_DIR%opensearch-security\internal_users.yml" + +echo "what is in the config directory" +dir %OPENSEARCH_CONF_DIR% + +echo "what is in the password file" +type "%ADMIN_PASSWORD_FILE%" + + +if "%initialAdminPassword%" NEQ "" ( + set "ADMIN_PASSWORD=!initialAdminPassword!" +) else ( + for /f %%a in ('type "%ADMIN_PASSWORD_FILE%"') do set "ADMIN_PASSWORD=%%a" +) + +if not defined ADMIN_PASSWORD ( + echo Unable to find the admin password for the cluster. Please set initialAdminPassword or create a file %ADMIN_PASSWORD_FILE% with a single line that contains the password. + exit /b 1 +) + +echo " ***************************************************" +echo " *** ADMIN PASSWORD SET TO: %ADMIN_PASSWORD% ***" +echo " ***************************************************" + +set "HASH_SCRIPT=%OPENSEARCH_PLUGINS_DIR%\opensearch-security\tools\hash.bat" + +REM Run the command and capture its output +for /f %%a in ('%HASH_SCRIPT% -p !ADMIN_PASSWORD!') do ( + set "HASHED_ADMIN_PASSWORD=%%a" +) + +if errorlevel 1 ( + echo Failed to hash the admin password + exit /b 1 +) + +set "default_line= hash: "$2a$12$VcCDgh2NDk07JGN0rjGbM.Ad41qVR/YFJcgHp0UGns5JDymv..TOG"" +set "search=%default_line%" +set "replace= hash: "%HASHED_ADMIN_PASSWORD%"" + +setlocal enableextensions +for /f "delims=" %%i in ('type "%INTERNAL_USERS_FILE%" ^& break ^> "%INTERNAL_USERS_FILE%" ') do ( + set "line=%%i" + setlocal enabledelayedexpansion + >>"%INTERNAL_USERS_FILE%" echo(!line:%search%=%replace%! + endlocal +) + :: network.host >nul findstr /b /c:"network.host" "%OPENSEARCH_CONF_FILE%" && ( echo network.host already present diff --git a/tools/install_demo_configuration.sh b/tools/install_demo_configuration.sh index 9fce14aee9..01bc1bfed1 100755 --- a/tools/install_demo_configuration.sh +++ b/tools/install_demo_configuration.sh @@ -108,6 +108,7 @@ if [ -d "$BASE_DIR" ]; then else echo "DEBUG: basedir does not exist" fi + OPENSEARCH_CONF_FILE="$BASE_DIR/config/opensearch.yml" OPENSEARCH_BIN_DIR="$BASE_DIR/bin" OPENSEARCH_PLUGINS_DIR="$BASE_DIR/plugins" @@ -387,6 +388,43 @@ echo 'plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_ echo 'plugins.security.system_indices.enabled: true' | $SUDO_CMD tee -a "$OPENSEARCH_CONF_FILE" > /dev/null echo 'plugins.security.system_indices.indices: [".plugins-ml-config", ".plugins-ml-connector", ".plugins-ml-model-group", ".plugins-ml-model", ".plugins-ml-task", ".plugins-ml-conversation-meta", ".plugins-ml-conversation-interactions", ".opendistro-alerting-config", ".opendistro-alerting-alert*", ".opendistro-anomaly-results*", ".opendistro-anomaly-detector*", ".opendistro-anomaly-checkpoints", ".opendistro-anomaly-detection-state", ".opendistro-reports-*", ".opensearch-notifications-*", ".opensearch-notebooks", ".opensearch-observability", ".ql-datasources", ".opendistro-asynchronous-search-response*", ".replication-metadata-store", ".opensearch-knn-models", ".geospatial-ip2geo-data*"]' | $SUDO_CMD tee -a "$OPENSEARCH_CONF_FILE" > /dev/null +## Read the admin password from the file or use the initialAdminPassword if set +ADMIN_PASSWORD_FILE="$OPENSEARCH_CONF_DIR/initialAdminPassword.txt" +INTERNAL_USERS_FILE="$OPENSEARCH_CONF_DIR/opensearch-security/internal_users.yml" + +if [[ -n "$initialAdminPassword" ]]; then + ADMIN_PASSWORD="$initialAdminPassword" +elif [[ -f "$ADMIN_PASSWORD_FILE" && -s "$ADMIN_PASSWORD_FILE" ]]; then + ADMIN_PASSWORD=$(head -n 1 "$ADMIN_PASSWORD_FILE") +else + echo "Unable to find the admin password for the cluster. Please run 'export initialAdminPassword=' or create a file $ADMIN_PASSWORD_FILE with a single line that contains the password." + exit 1 +fi + +echo " ***************************************************" +echo " *** ADMIN PASSWORD SET TO: $ADMIN_PASSWORD ***" +echo " ***************************************************" + +$SUDO_CMD chmod +x "$OPENSEARCH_PLUGINS_DIR/opensearch-security/tools/hash.sh" + +# Use the Hasher script to hash the admin password +HASHED_ADMIN_PASSWORD=$($OPENSEARCH_PLUGINS_DIR/opensearch-security/tools/hash.sh -p "$ADMIN_PASSWORD" | tail -n 1) + +if [ $? -ne 0 ]; then + echo "Hash the admin password failure, see console for details" + exit 1 +fi + +# Find the line number containing 'admin:' in the internal_users.yml file +ADMIN_HASH_LINE=$(grep -n 'admin:' "$INTERNAL_USERS_FILE" | cut -f1 -d:) + +awk -v hashed_admin_password="$HASHED_ADMIN_PASSWORD" ' + /^ *hash: *"\$2a\$12\$VcCDgh2NDk07JGN0rjGbM.Ad41qVR\/YFJcgHp0UGns5JDymv..TOG"/ { + sub(/"\$2a\$12\$VcCDgh2NDk07JGN0rjGbM.Ad41qVR\/YFJcgHp0UGns5JDymv..TOG"/, "\"" hashed_admin_password "\""); + } + { print } +' "$INTERNAL_USERS_FILE" > temp_file && mv temp_file "$INTERNAL_USERS_FILE" + #network.host if $SUDO_CMD grep --quiet -i "^network.host" "$OPENSEARCH_CONF_FILE"; then : #already present