Download and insert salt string inside wordpress wp-config.php with Bash

How can I insert the content of the variable $SALT in a specific point (line or string) of a file like wp-contet.php from wordpress using Bash script?

SALT=$(curl -L https://api.wordpress.org/secret-key/1.1/salt/)

Related posts

Leave a Reply

12 comments

  1. I’m not an expert at parsing text files in bash but you should delete the lines that define the things you’re downloading from the wordpress salt and then insert the variable at the end… something like:

    #!/bin/sh
    
    SALT=$(curl -L https://api.wordpress.org/secret-key/1.1/salt/)
    STRING='put your unique phrase here'
    printf '%sn' "g/$STRING/d" a "$SALT" . w | ed -s wp-config.php
    

    OK, now it’s fixed… it should look for where the salt is supposed to go and it will replace it with the info retrieved from https://api.wordpress.org/secret-key/1.1/salt/

  2. This version defines new keys if none exist, and also replaces existing keys:

    #!/bin/bash
    find . -name wp-config.php -print | while read line
    do 
        curl http://api.wordpress.org/secret-key/1.1/salt/ > wp_keys.txt
        sed -i.bak -e '/put your unique phrase here/d' -e 
        '/AUTH_KEY/d' -e '/SECURE_AUTH_KEY/d' -e '/LOGGED_IN_KEY/d' -e '/NONCE_KEY/d' -e 
        '/AUTH_SALT/d' -e '/SECURE_AUTH_SALT/d' -e '/LOGGED_IN_SALT/d' -e '/NONCE_SALT/d' $line
        cat wp_keys.txt >> $line
        rm wp_keys.txt
    done
    
  3. If you have csplit available, you can split the original wp-config.php file either side of the salt definitions, download new salts, then cat back together. This keeps the PHP define() statements at the same location in wp-config.php instead of than moving them to a different location within the file:

    # Download new salts
    curl "https://api.wordpress.org/secret-key/1.1/salt/" -o salts
    
    # Split wp-config.php into 3 on the first and last definition statements
    csplit wp-config.php '/AUTH_KEY/' '/NONCE_SALT/+1'
    
    # Recombine the first part, the new salts and the last part
    cat xx00 salts xx02 > wp-config.php
    
    # Tidy up
    rm salts xx00 xx01 xx02
    
  4. I think I got this one! its a bash script using only commands normally available at the command prompt and it does -everything- (assuming httpd is your web user) except create the databases. here you go.

    #!/bin/bash
    
    # wordpress latest auto-install script, by alienation 24 jan 2013. run as root.
    # usage: ~/wp-install alien /hsphere/local/home/alien/nettrip.org alien_wpdbname alien_wpdbusername p@sSw0rd
    # ( wp-install shell-user folder db-name db-user-name db-user-pw )
    
    # download wordpress to temporary area
    cd /tmp
    rm -rf tmpwp
    mkdir tmpwp
    cd tmpwp
    wget http://wordpress.org/latest.tar.gz
    tar -xvzpf latest.tar.gz
    
    # copy wordpress to where it will live, and go there, removing index placeholder if there is one
    mv wordpress/* $2
    cd $2
    rm index.html
    
    # create config from sample, replacing salt example lines with a real salt from online generator
    grep -A 1 -B 50 'since 2.6.0' wp-config-sample.php > wp-config.php
    wget -O - https://api.wordpress.org/secret-key/1.1/salt/ >> wp-config.php
    grep -A 50 -B 3 'Table prefix' wp-config-sample.php >> wp-config.php
    
    # put the appropriate db info in place of placeholders in our new config file
    replace 'database_name_here' $3 -- wp-config.php
    replace 'username_here' $4 -- wp-config.php
    replace 'password_here' $5 -- wp-config.php
    
    # change file ownership and permissions according to ideal at http://codex.wordpress.org/Hardening_WordPress#File_Permissions
    touch .htaccess
    chown $1:httpd .htaccess
    chown -R $1:httpd *
    find . -type d -exec chmod 755 {} ;
    find . -type f -exec chmod 644 {} ;
    chmod -R 770 wp-content
    chmod -R g-w wp-admin wp-includes wp-content/plugins
    chmod g+w .htaccess
    
    # thats it!
    echo ALL DONE
    
  5. I built a simple CLI for just that. Try it out. It’s called [WP-Salts-Update-CLI][1].

    WP-Salts-Update-CLI

    WPSUCLI downloads new salts from the WP API and replaces them with the ones in your wp-config.php file for every site on your server.

    ⚡️ Installation

    Open command line terminal (I prefer iTerm2) and run the following command.

    bash
    sudo wget -qO wpsucli https://git.io/vykgu && sudo chmod +x ./wpsucli && sudo install ./wpsucli /usr/local/bin/wpsucli

    This command will perform the following actions:

    • Use sudo permissions
    • Use wget to download WPSUCLI and rename it to wpsucli
    • Make the wpsucli executable
    • Install wpsucli inside /usr/local/bin/ folder.

    🙌 Usage

    Just run wpsucli and it will update the salts for every wp-config.php file on your server or PC.

  6. This is the bash script that I came up with that works on my Ubuntu server. I modified the examples from above.

    Its a bit of brute force in that it will only replace the 8 keys that currently are required and expects the server to return exactly the same length key every time. The script works well for my use case so I thought I would share it.

    CONFIG_FILE=wp-config.php
    SALT=$(curl -L https://api.wordpress.org/secret-key/1.1/salt/)
    SRC="define('AUTH_KEY'"; DST=$(echo $SALT|cat|grep -o define('AUTH_KEY'.\{70\}); sed -i "/$SRC/c$DST" $CONFIG_FILE
    SRC="define('SECURE_AUTH_KEY'"; DST=$(echo $SALT|cat|grep -o define('SECURE_AUTH_KEY'.\{70\}); sed -i "/$SRC/c$DST" $CONFIG_FILE
    SRC="define('LOGGED_IN_KEY'"; DST=$(echo $SALT|cat|grep -o define('LOGGED_IN_KEY'.\{70\}); sed -i "/$SRC/c$DST" $CONFIG_FILE
    SRC="define('NONCE_KEY'"; DST=$(echo $SALT|cat|grep -o define('NONCE_KEY'.\{70\}); sed -i "/$SRC/c$DST" $CONFIG_FILE
    SRC="define('AUTH_SALT'"; DST=$(echo $SALT|cat|grep -o define('AUTH_SALT'.\{70\}); sed -i "/$SRC/c$DST" $CONFIG_FILE
    SRC="define('SECURE_AUTH_SALT'"; DST=$(echo $SALT|cat|grep -o define('SECURE_AUTH_SALT'.\{70\}); sed -i "/$SRC/c$DST" $CONFIG_FILE
    SRC="define('LOGGED_IN_SALT'"; DST=$(echo $SALT|cat|grep -o define('LOGGED_IN_SALT'.\{70\}); sed -i "/$SRC/c$DST" $CONFIG_FILE
    SRC="define('NONCE_SALT'"; DST=$(echo $SALT|cat|grep -o define('NONCE_SALT'.\{70\}); sed -i "/$SRC/c$DST" $CONFIG_FILE
    
  7. I tried the accepted solution:

    #!/bin/sh
    SALT=$(curl -L https://api.wordpress.org/secret-key/1.1/salt/)
    STRING='put your unique phrase here'
    printf '%sn' "g/$STRING/d" a "$SALT" . w | ed -s wp-config.php
    

    However it does not work perfectly as for some reason it induces the SALTS to “move down” 1 line in the wp-config.php file each time it is used… it is not ideal if you are going to change SALTS automatically like every week, months with cron for example…

    A better solution for me was to create a little function that I call in my script.
    This function creates a file with the SALTS (deletes it at the end), deletes every lines containing one of the SALTS then just inserts the SALTS contained in the file in place of the initial SALTS.
    This works perfectly.

    fct_update_salts() {
        # Requires website name as target
    
        curl http://api.wordpress.org/secret-key/1.1/salt/ > ~/SALTS.txt
    
        var_initial_path1=`pwd`
        cd ~ #going to home directory
    
        # This scripts eliminates successively all SALT entries, replaces the last one by XXX as a marker, places SALTS.txt, below XXX and deletes XXX
        sudo sed -i "/SECURE_AUTH_KEY/d" $1/wp-config.php
        sudo sed -i "/LOGGED_IN_KEY/d" $1/wp-config.php
        sudo sed -i "/NONCE_KEY/d" $1/wp-config.php
        sudo sed -i "/AUTH_SALT/d" $1/wp-config.php
        sudo sed -i "/SECURE_AUTH_SALT/d" $1/wp-config.php
        sudo sed -i "/LOGGED_IN_SALT/d" $1/wp-config.php
        sudo sed -i "/NONCE_SALT/d" $1/wp-config.php
        sudo sed -i "/AUTH_KEY/cXXX" $1/wp-config.php
        sudo sed -i '/XXX/r SALTS.txt' $1/wp-config.php
        sudo sed -i "/XXX/d" $1/wp-config.php
        echo "SALTS REPLACED BY:"
        echo "====================="
        cat ~/SALTS.txt
        sudo rm -rf ~/SALTS.txt
        cd $var_initial_path1
    }
    

    The function is to be called in the script like this:

    # Reset SALTS
    fct_update_salts $SITE_PATH
    

    Where $SITE_PATH=”/var/www/html/YOUR_WEBSITE” or whatever path works for you.

  8. I was challenged with the same issue. Here is the script I wrote to replace the salts and keys from ones downloaded from WordPress. You can use it at any time to replace them if/when needed. I run it as sudo, and the script tests for that. If you use an account that can download to the directory and make updates to the wp-config.php file, then you can delete that part of the script.

    #!/bin/sh
    # update-WordPress-Salts: Updates WordPress Salts
    # written by Wayne Woodward 2017
    
    if [ $# -lt 1 ]; then
        echo "Usage: update-WordPress-Salts directory"
        exit
    fi
    
    if [ "$(whoami)" != "root" ]; then
      echo "Please run as root (sudo)"
      exit
    fi
    
    WPPATH=$1
    
    # Update the salts in the config file
    
    # Download salts from WordPress and save them locally
    curl http://api.wordpress.org/secret-key/1.1/salt/ > /var/www/$WPPATH/wp-keys.txt
    
    # Iterate through each "Saltname" and append 1 to it
    # For a couple names that may match twice like "AUTH_KEY" adds extra 1s to the end
    # But that is OK as when this deletes the lines, it uses the same matching pattern
    # (Smarter people may fix this)
    for SALTNAME in AUTH_KEY SECURE_AUTH_KEY LOGGED_IN_KEY NONCE_KEY AUTH_SALT SECURE_AUTH_SALT LOGGED_IN_SALT NONCE_SALT
    do
       sed -i -e "s/$SALTNAME/${SALTNAME}1/g" /var/www/$WPPATH/wp-config.php
    done
    
    # Find the line that has the updated AUTH_KEY1 name
    # This is so we can insert the file in the same area
    line=$(sed -n '/AUTH_KEY1/{=;q}' /var/www/$WPPATH/wp-config.php)
    
    # Insert the file from the WordPress API that we saved into the configuration
    sed -i -e "${line}r /var/www/$WPPATH/wp-keys.txt" /var/www/$WPPATH/wp-config.php
    
    # Itererate through the old keys and remove them from the file
    for SALTNAME in AUTH_KEY SECURE_AUTH_KEY LOGGED_IN_KEY NONCE_KEY AUTH_SALT SECURE_AUTH_SALT LOGGED_IN_SALT NONCE_SALT
    do
       sed -i -e "/${SALTNAME}1/d" /var/www/$WPPATH/wp-config.php
    done
    
    # Delete the file downloaded from WordPress
    rm /var/www/$WPPATH/wp-keys.txt
    
  9. Many of the answers rely on the phrase 'put your unique phrase here' being present in the file, so they do not work when you want to change salts after the first time. There are also some that remove the old definitions and append the new ones at the end. While that does work, it’s nice to keep the definitions where you would expect them, right after the comment documenting them. My solution addresses those issues.

    I made a few attempts with sed, perl and regex, but there are special characters in the salts and the rest of the config file that tend to mess things up. I ended up using grep to search the document for the unique comment structure that opens and closes the salt definition block, which has the following format:

    /**#@+
     <comment documentation>
     */
    <salt definitions>
    
    /**#@-*/
    

    Note that if that comment structure is removed or altered, this will no longer work. Here’s the script:

    #!/bin/bash -e
    
    # Set Default Settings:
    file='wp-config.php'
    
    # set up temporary files with automatic removal:
    trap "rm -f $file_start $file_end $salt" 0 1 2 3 15
    file_start=$(mktemp) || exit 1
    file_end=$(mktemp) || exit 1
    salt=$(mktemp) || exit 1
    
    function find_line {
    # returns the first line number in the file which contains the text
    # program exits if text is not found
    # $1 : text to search for
    # $2 : file in which to search
    # $3 (optional) : line at which to start the search
    line=$(tail -n +${3:-1} $2 | grep -nm 1 $1 | cut -f1 -d:)
    [ -z "$line" ] && exit 1
    echo $(($line + ${3:-1} - 1))
    }
    
    line=$(find_line "/**#@+" "$file")
    line=$(find_line "*/" "$file" "$line")
    head -n $line $file > $file_start
    line=$(find_line "/**#@-*/" "$file" "$line")
    tail -n +$line $file > $file_end
    curl -Ls https://api.wordpress.org/secret-key/1.1/salt/ > $salt
    (cat $file_start $salt; echo; cat $file_end) > $file
    
    exit 0
    

    Strings containing single asterisks, such as "*/" and "/**#@-*/" want to expand to directory lists, so that is why those asterisks are escaped.

  10. Here’s a pure bash approach. This does not depend on wordpress.org.

    I converted the original wp_generate_password() function used by WordPress to generate salt.

        #!/bin/bash
        
        set -e
        
        #
        # Generates a random password drawn from the defined set of characters.
        # Inspired by WordPress function https://developer.wordpress.org/reference/functions/wp_generate_password/
        #
        # Parameters
        # ----------
        # $length
        #   (ing) (Optional) Length of password to generate.
        #   Default value: 12
        # $special_chars
        #   (bool) (Optional) Whether to include standard special characters.
        #   Default value: true
        # $extra_special_chars
        #   (bool) (Optional) Whether to include other special characters. Used when generating secret keys and salts.
        #   Default value: false
        #
        function wp_generate_password() {
          # Args
          length="$(test $1 && echo $1 || echo 12 )"
          special_chars="$(test $2 && echo $2 || echo 1 )"
          extra_special_chars="$(test $3 && echo $3 || echo 0 )"
        
          chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
          [[ $special_chars != 0 ]] && chars="$chars"'!@#$%^&*()'
          [[ $extra_special_chars != 0 ]] && chars="$chars"'-_ []{}<>~`+=,.;:/?|'
        
          password='';
          for i in $(seq 1 $length); do
            password="${password}${chars:$(( RANDOM % ${#chars} )):1}"
          done
        
          echo "$password"
        }
    

    You can then just run SALT="$(wp_generate_password 64 1 1)".

    Update

    I just published a standalone script to generate WP salt values. You can generate the salt values by running ./wp-generate-salt.sh.

  11. If the wordpress.org API generated SALT values are not necessary for your use case, you can use the pwgen to generate keys on the server and insert those into wp-config.php.

    for i in {1..8} ;do unique_key="`pwgen -1 -s 64`";sudo sed -i "0,/put your unique phrase here/s/put your unique phrase here/$unique_key/" /srv/www/wordpress/wp-config.php; done
    

    You may need to fix the ownership of the file after using sudo. You can use a command similar to this for changing the ownership.

    chown www-data:www-data /srv/www/wordpress/wp-config.php