Improve prepare_nginx script

Proposers

  • Jorge Moratinos Salcines (Telefonica)

Description

Fix prepare_nginx.sh script in order to check if values are previously stored at vault. This makes nginx service stateless, and prevent mismatch between values when pods restarts.

Acknowledgements

This work is funded by the European Commission through the HORIZON-JU-SNS-2022 6G-VERSUS project with Grant Agreement number 101192633.

Edited by Jorge Moratinos

Merge request reports

Loading
+88 −19
Changes for services/nginx/nginx_prepare.sh: 88 added lines, 19 removed lines.
Original line number Diff line number Diff line
@@ -14,7 +14,11 @@ ATTEMPT=0
# Success check
SUCCES_OPERATION=false

# Variable to store CCF_ID retrieved from Helper
CCF_ID=""

fetch_ca_root_cert_from_vault() {
    if [ ! -f $CERTS_FOLDER/ca.crt ]; then
        ###############################################################
        # 1) FETCH CA ROOT CERTIFICATE FROM VAULT
        ###############################################################
@@ -50,24 +54,29 @@ if [ "$SUCCES_OPERATION" = false ]; then
            echo "[ERROR] Unable to retrieve CA certificate from Vault after $MAX_RETRIES attempts"
            exit 1
        fi
    else
        echo "CA certificate already exists. Skipping retrieval from Vault."
    fi
}



generate_server_key_if_missing() {
    ###############################################################
    # 2) GENERATE SERVER KEY IF MISSING
    ###############################################################
if [ ! -f server.key ]; then
    if [ ! -f $CERTS_FOLDER/server.key ]; then
        echo "server.key not found. Generating new private key..."
    openssl genrsa -out server.key 2048
        openssl genrsa -out $CERTS_FOLDER/server.key 2048
    else
        echo "server.key already exists. Skipping generation."
    fi
}


generate_server_key_and_sign() {
    ###############################################################
    # 3) IF NO SERVER CERT → GENERATE CSR + REQUEST SIGNING IN VAULT
    ###############################################################
if [ ! -f server.crt ]; then
    if [ ! -f $CERTS_FOLDER/server.crt ]; then
        SUCCESS_OPERATION=false
        
        echo "[STEP 3] Server certificate not found"
@@ -75,13 +84,13 @@ if [ ! -f server.crt ]; then
        echo "[INFO] Common Name (CN): $CAPIF_HOSTNAME"

        # Generate CSR using the previously generated server.key
    openssl req -new -key server.key \
        openssl req -new -key $CERTS_FOLDER/server.key \
            -subj "/CN=$CAPIF_HOSTNAME" \
            -addext "subjectAltName=DNS:$CAPIF_HOSTNAME" \
        -out server.csr
            -out $CERTS_FOLDER/server.csr

        # Convert the CSR to a single line with \n so it can be sent in the body of the request to Vault (which expects JSON)
    CSR_CONTENT=$(sed ':a;N;$!ba;s/\n/\\n/g' server.csr)
        CSR_CONTENT=$(sed ':a;N;$!ba;s/\n/\\n/g' $CERTS_FOLDER/server.csr)

        echo "[STEP 3] CSR generated successfully"
        echo "[STEP 3] Requesting certificate signing from Vault"
@@ -105,7 +114,7 @@ if [ ! -f server.crt ]; then
            CERT=$(printf '%s' "$SIGN_RESPONSE" | jq -er '.data.certificate')

            if [ -n "$CERT" ] && [ "$CERT" != "null" ]; then
            echo "$CERT" > server.crt
                echo "$CERT" > $CERTS_FOLDER/server.crt
                echo "Server certificate successfully signed and saved."
                SUCCESS_OPERATION=true
                break
@@ -120,21 +129,28 @@ if [ ! -f server.crt ]; then
            exit 1
        fi
    else
    echo "[STEP 3] server.crt already exists – skipping certificate signing"
        echo "[STEP 3] $CERTS_FOLDER/server.crt already exists – skipping certificate signing"
    fi
}


extract_public_key() {
    if [ ! -f $CERTS_FOLDER/server_pub.pem ]; then
        ###############################################################
# 4) Extract the public key from server.crt
        # 4) Extract the public key from server.crt and save it as server_pub.pem
        ###############################################################
openssl x509 -pubkey -noout -in server.crt > server_pub.pem
        openssl x509 -pubkey -noout -in $CERTS_FOLDER/server.crt > $CERTS_FOLDER/server_pub.pem
    else
        echo "Public key already extracted. Skipping extraction."
    fi
}

get_ccf_id_from_helper() {
    ###############################################################
    # 5) CCF_ID RETRIEVAL (from helper, inside docker network)
    ###############################################################
    HELPER_URL="http://helper:8080/helper/api/getCcfId"
    ATTEMPT_CCFID=0
CCF_ID=""
    

    echo "[STEP] Fetching CCF_ID from Helper: $HELPER_URL"

@@ -161,18 +177,19 @@ if [ -z "$CCF_ID" ]; then
    echo "[ERROR] Unable to retrieve CCF_ID from Helper after $MAX_RETRIES attempts"
    exit 1
    fi
}



store_certs_in_vault() {
    ###############################################################
    # 6) STORE CERTIFICATES IN VAULT UNDER capif/<ccf_id>
    ###############################################################
    echo "Storing CAPIF certificates in Vault..."

SERVER_CRT_ESCAPED=$(sed ':a;N;$!ba;s/\n/\\n/g' server.crt)
SERVER_KEY_ESCAPED=$(sed ':a;N;$!ba;s/\n/\\n/g' server.key)
SERVER_PUB_ESCAPED=$(sed ':a;N;$!ba;s/\n/\\n/g' server_pub.pem)
CA_ESCAPED=$(sed ':a;N;$!ba;s/\n/\\n/g' ca.crt)
    SERVER_CRT_ESCAPED=$(sed ':a;N;$!ba;s/\n/\\n/g' $CERTS_FOLDER/server.crt)
    SERVER_KEY_ESCAPED=$(sed ':a;N;$!ba;s/\n/\\n/g' $CERTS_FOLDER/server.key)
    SERVER_PUB_ESCAPED=$(sed ':a;N;$!ba;s/\n/\\n/g' $CERTS_FOLDER/server_pub.pem)
    CA_ESCAPED=$(sed ':a;N;$!ba;s/\n/\\n/g' $CERTS_FOLDER/ca.crt)

    # Store the server certificate, private key and CA certificate in Vault under secret/data/capif/<ccf_id>/nginx
    VAULT_RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/vault_resp.json \
@@ -196,6 +213,58 @@ if [ "$VAULT_RESPONSE" != "200" ] && [ "$VAULT_RESPONSE" != "204" ]; then
    fi

    echo "Certificates successfully stored in Vault namespace: secret/capif/$CCF_ID"
}

check_value_and_store(){
    INPUT_VALUE=$1
    OUTPUT_FILE=$2
    if [ -n "$INPUT_VALUE" ] && [ "$INPUT_VALUE" != "null" ]; then
        echo "$INPUT_VALUE" > $OUTPUT_FILE
        echo "Value successfully saved to $OUTPUT_FILE."
    else
        echo "Invalid value for $OUTPUT_FILE ('null' or empty)."
        exit 1
    fi
}


get_ccf_id_from_helper
echo "Retrieved CCF_ID from Helper: $CCF_ID"

# Make the request to Vault and store the response in a variable

HTTP_STATUS=$(curl -s -k \
  --connect-timeout 5 \
  --max-time 10 \
  --header "X-Vault-Token: $VAULT_TOKEN" \
  --request GET "$VAULT_ADDR/v1/secret/data/capif/${CCF_ID}/nginx" \
  -o $CERTS_FOLDER/response.json \
  -w "%{http_code}")

echo "HTTP STATUS: $HTTP_STATUS"

RESPONSE=$(cat $CERTS_FOLDER/response.json)
if [ -n "$RESPONSE" ] && [ "$RESPONSE" != "null" ] && [ "$HTTP_STATUS" -eq 200 ] ; then
    echo "RESPONSE is valid, proceeding with certificate extraction and storage"
    CA_CERT=$(jq -r '.data.data.ca' $CERTS_FOLDER/response.json)
    SERVER_CRT=$(jq -r '.data.data.server_crt' $CERTS_FOLDER/response.json)
    SERVER_KEY=$(jq -r '.data.data.server_key' $CERTS_FOLDER/response.json)
    SERVER_PUB=$(jq -r '.data.data.server_pub' $CERTS_FOLDER/response.json)

    check_value_and_store "$SERVER_CRT" "$CERTS_FOLDER/server.crt"
    check_value_and_store "$SERVER_KEY" "$CERTS_FOLDER/server.key"
    check_value_and_store "$SERVER_PUB" "$CERTS_FOLDER/server_pub.pem"
    check_value_and_store "$CA_CERT" "$CERTS_FOLDER/ca.crt"

else
    echo "Data not previously stored at Vault. Initialize information"
    fetch_ca_root_cert_from_vault
    generate_server_key_if_missing
    generate_server_key_and_sign
    extract_public_key
    store_certs_in_vault
    echo "Certificate information successfully stored in Vault for CCF_ID=$CCF_ID"
fi


###############################################################
Loading