CHG-2017-09-25 migrate obi to hetzner2: Difference between revisions
Jump to navigation
Jump to search
(Created page with "test") |
No edit summary |
||
Line 1: | Line 1: | ||
test | =Apply to Production= | ||
<pre> | |||
sudo su - | |||
################# | |||
# set variables # | |||
################# | |||
vhostDir=/var/www/html/obi | |||
dbName=obi_db | |||
dbUser=obi_db_user | |||
dbPass=CHANGEME | |||
rootDbPass=CHANGEME | |||
stamp=`date +%Y%m%d_%T` | |||
vhostDirMovedTo="${vhostDir}.${stamp}.bak" | |||
################ | |||
# make backups # | |||
################ | |||
# SYSTEM-SIDE BACKUPS | |||
time /bin/nice /root/backups/backup.sh &>> /var/log/backups/backup.log | |||
source /root/backups/backup.settings | |||
# validate | |||
ssh $RSYNC_USER@$RSYNC_HOST du -sh backups/hetzner2/* | |||
# LOCAL BACKUPS | |||
tmpDir=/var/tmp/chg.$stamp | |||
mkdir $tmpDir | |||
chown root:root $tmpDir | |||
chmod 0700 $tmpDir | |||
pushd $tmpDir | |||
service httpd stop | |||
# create backup of all DBs for good measure | |||
time nice mysqldump -uroot -p$rootDbPass --all-databases | gzip -c > preBackup.all_databases.$stamp.sql.gz | |||
# dump wp DB contents | |||
time nice mysqldump -u$dbUser -p$dbPass --database $dbName > $dbName.$stamp.sql | |||
# files backup | |||
rsync -av --progress "${vhostDir}" "vhostDir.${stamp}.bak/" | |||
############# | |||
# update db # | |||
############# | |||
# verify the first 2 (non-comment) occurances of $dbName meet the naming convention of "<siteName>_db" | |||
vim $dbName.$stamp.sql | |||
# update links for 3Dmodels, which we're moving to the 'wp-content' dir | |||
sed -i 's^/3Dmodels/^/wp-content/3Dmodels/^g' "$dbName.$stamp.sql" | |||
time nice mysql -uroot -p$rootDbPass -sNe "DROP DATABASE IF EXISTS $dbName;" | |||
time nice mysql -uroot -p$rootDbPass -sNe "CREATE DATABASE $bName; USE $dbName;" | |||
time nice mysql -uroot -p$rootDbPass < "$dbName.$stamp.sql" | |||
time nice mysql -uroot -p$rootDbPass -sNe "GRANT ALL ON $dbName.* TO '$dbUser'@'localhost' IDENTIFIED BY '$dbPass'; FLUSH PRIVILEGES;" | |||
popd | |||
################ | |||
# update files # | |||
################ | |||
mv "${vhostDir}" "${vhostDirMovedTo}" | |||
mkdir -p "${vhostDir}/htdocs" | |||
pushd $newVhostDir/htdocs | |||
yum install subversion | |||
svn co https://core.svn.wordpress.org/tags/4.8.1 . | |||
find $vhostDir -type d -exec chmod 750 {} \; | |||
find $vhostDIr -type f -exec chmod 640 {} \; | |||
chown -R apache:apache ${vhostDir} | |||
rsync -av --progress ${vhostDirMovedTo}/wp-config.php ${vhostDir}/ | |||
chown apache:apache-admins ${vhostDir}/wp-config.php | |||
chmod 440 ${vhostDir}/wp-config.php | |||
# change WP_HOME, WP_SITEURL, DB_NAME, DB_USER, & DB_PASSWORD as needed | |||
vim ${vhostDir}/wp-config.php | |||
# we want to copy files that don't exist yet in our new install dir. if a file exists in both, don't overwrite the new from the old | |||
rsync -av --progress --ignore-existing "${vhostDirMovedTo}/htdocs/wp-content/" "$vhostDir/htdocs/wp-content/" | |||
# delete unnecessary & empty upgrade dir | |||
rm -rf "${vhostDir}/htdocs/wp-content/upgrade" | |||
# delete unnecessary plugins | |||
rm -rf "${vhostDir}/htdocs/wp-content/plugins/hello.php" | |||
rm -rf "${vhostDir}/htdocs/wp-content/plugins/password-protected" | |||
rm -rf "${vhostDir}/htdocs/wp-content/plugins/simple-301-redirects" | |||
# migrate '3Dmodels' dir, but put it in 'wp-content' for future migrations (the wp upgrade docs migrate this dir already) | |||
rsync -av --progress "${vhostDirMovedTo}/htdocs/3Dmodels" "${vhostDir}/htdocs/wp-content/" | |||
# take the old .htaccess; overwrite existing if needed | |||
rsync -av --progress "${vhostDirMovedTo}/htdocs/.htaccess" "${vhostDir}/htdocs/" | |||
# set permissions, final pass | |||
chown -R apache:apache "${vhostDir}" | |||
find "${vhostDir}" -type d -exec chmod 0750 {} \; | |||
find "${vhostDir}" -type f -exec chmod 0640 {} \; | |||
find "${vhostDir}/htdocs/wp-content" -type f -exec chmod 0660 {} \; | |||
find "${vhostDir}/htdocs/wp-content" -type d -exec chmod 0770 {} \; | |||
chown apache:apache-admins "${newVhostDir}/wp-config.php" | |||
chmod 0440 "${vhostDir}/wp-config.php" | |||
# update wp plugins | |||
sudo -u wp -i wp --path="${vhostDir}/htdocs" plugin update --all | |||
# update wp themes | |||
#(we skip this in obi's oshine, since it caused issues) | |||
#sudo -u wp -i wp --path="${vhostDir}/htdocs" theme update --all | |||
# install & configure 2FA plugins | |||
sudo -u wp -i wp --path=${vhostDir}/htdocs plugin install google-authenticator --activate | |||
sudo -u wp -i wp --path=${vhostDir}/htdocs plugin install google-authenticator-encourage-user-activation --activate | |||
defaultOtpAccountDescription="`basename ${vhostDir}` wp" | |||
cd "${vhostDir}/htdocs/wp-content/plugins/google-authenticator" | |||
sed -i "s^\$GA_description\s=\s__(\s[\"'].*[\"']^\$GA_description = __( '$defaultOtpAccountDescription'^" google-authenticator.php | |||
# install 'force-strong-passwords' plugin | |||
sudo -u wp -i wp --path="${vhostDir}/htdocs" plugin install force-strong-passwords --activate | |||
# install rename-wp-login plugin | |||
sudo -u wp -i wp --path="${vhostDir}/htdocs" plugin install rename-wp-login --activate | |||
# add deny for 'wp-login.php' _inside_ the VirtualHosts block of the vhost config file | |||
#<LocationMatch .*wp-login.php> | |||
# Deny From All | |||
#</LocationMatch> | |||
vim /etc/httpd/conf.d/TODO | |||
# test apache config | |||
httpd -t | |||
# if OK, apply apache configs | |||
service httpd reload | |||
# finally, log into the new wordpress site (use '/login' instead of '/wp-login.php'. After authenticating, wp will ask you to update, if necessary. Then update settings: | |||
# 1. "Settings" -> "Permalinks" -> "Rename wp-login.php" -> "Login url" = 'ose-hidden-login' | |||
# 2. "Settings" -> "General" -> "Google Authenticator - Encourage User Activation" = "Force the user" | |||
</pre> | |||
=Build Ephemeral Staging= | |||
These commands were used to migrate the existing & outdated wordpress installs to a subversion-backed, ephemeral clone of the site. Changes were iterated to these commands documented here as validation by the site owners exposed issues with the upgrades, missing content, etc. Once the clone was validated entirely, the live site could be brought down & confidently updated per the findings with the ephemeral clone. | |||
==obi== | |||
<pre> | |||
oldVhostDir=/var/www/html/obi | |||
newVhostDir=/var/www/html/obi2 | |||
oldDbName=obi_db | |||
newDbName=obi2_db | |||
newDbUser=obi2_user | |||
newDbPass=CHANGEME | |||
rootDbPass=CHANGEME | |||
cd | |||
rm -rf $newVhostDir | |||
mkdir -p $newVhostDir/htdocs | |||
pushd $newVhostDir/htdocs | |||
yum install subversion | |||
svn co https://core.svn.wordpress.org/tags/4.8.1 . | |||
find $newVhostDir -type d -exec chmod 750 {} \; | |||
find $newVhostDIr -type f -exec chmod 640 {} \; | |||
chown -R apache:apache $newVhostDir | |||
stamp=`date +%Y%m%d_%T` | |||
tmpDir=/var/tmp/dbChange.$stamp | |||
mkdir $tmpDir | |||
chown root:root $tmpDir | |||
chmod 0700 $tmpDir | |||
pushd $tmpDir | |||
time nice mysqldump -uroot -p$rootDbPass --all-databases | gzip -c > preBackup.all_databases.$stamp.sql.gz | |||
time nice mysqldump -uroot -p$rootDbPass --databases $oldDbName > $oldDbName.$stamp.sql | |||
cp $oldDbName.$stamp.sql $newDbName.$stamp.sql | |||
# replace the first 2 (non-comment) occurances of $OldDbName with $newDbName | |||
vim $newDbName.$stamp.sql | |||
# update links for 3Dmodels, which we're moving to the 'wp-content' dir | |||
sed -i 's^/3Dmodels/^/wp-content/3Dmodels/^g' "$newDbName.$stamp.sql" | |||
time nice mysql -uroot -p$rootDbPass -sNe "DROP DATABASE IF EXISTS $newDbName;" | |||
time nice mysql -uroot -p$rootDbPass -sNe "CREATE DATABASE $newDbName; USE $newDbName;" | |||
time nice mysql -uroot -p$rootDbPass < "$newDbName.$stamp.sql" | |||
time nice mysql -uroot -p$rootDbPass -sNe "GRANT ALL ON $newDbName.* TO '$newDbUser'@'localhost' IDENTIFIED BY '$newDbPass'; FLUSH PRIVILEGES;" | |||
popd | |||
rsync -av --progress $oldVhostDir/wp-config.php $newVhostDir/ | |||
chown apache:apache $newVhostDir/wp-config.php | |||
chmod 400 $newVhostDir/wp-config.php | |||
# change WP_HOME, WP_SITEURL, DB_NAME, DB_USER, & DB_PASSWORD | |||
vim $newVhostDir/wp-config.php | |||
# we want to copy files that don't exist yet in our new install dir. if a file exists in both, don't overwrite the new from the old | |||
rsync -av --progress --ignore-existing $oldVhostDir/htdocs/wp-content/ $newVhostDir/htdocs/wp-content/ | |||
# delete unnecessary & empty upgrade dir | |||
rm -rf $newVhostDir/htdocs/wp-content/upgrade | |||
# delete unnecessary plugins | |||
rm -rf $newVhostDir/htdocs/wp-content/plugins/hello.php | |||
rm -rf $newVhostDir/htdocs/wp-content/plugins/password-protected | |||
rm -rf $newVhostDir/htdocs/wp-content/plugins/simple-301-redirects | |||
# migrate '3Dmodels' dir, but put it in 'wp-content' for future migrations (the wp upgrade docs migrate this dir already) | |||
rsync -av --progress $oldVhostDir/htdocs/3Dmodels $newVhostDir/htdocs/wp-content/ | |||
# take the old .htaccess; overwrite existing if needed | |||
rsync -av --progress $oldVhostDir/htdocs/.htaccess $newVhostDir/htdocs/ | |||
# set permissions | |||
chown -R apache:apache "${newVhostDir}" | |||
find "${newVhostDir}" -type d -exec chmod 0750 {} \; | |||
find "${newVhostDir}" -type f -exec chmod 0640 {} \; | |||
find "${newVhostDir}/htdocs/wp-content" -type f -exec chmod 0660 {} \; | |||
find "${newVhostDir}/htdocs/wp-content" -type d -exec chmod 0770 {} \; | |||
chown apache:apache-admins "${newVhostDir}/wp-config.php" | |||
chmod 0440 "${newVhostDir}/wp-config.php" | |||
# update wp plugins | |||
sudo -u wp -i wp --path=$newVhostDir/htdocs plugin update --all | |||
# update wp themes | |||
#sudo -u wp -i wp --path=$newVhostDir/htdocs theme update --all | |||
# install & configure 2FA plugins | |||
sudo -u wp -i wp --path=$newVhostDir/htdocs plugin install google-authenticator --activate | |||
sudo -u wp -i wp --path=$newVhostDir/htdocs plugin install google-authenticator-encourage-user-activation --activate | |||
defaultOtpAccountDescription="`basename $newVhostDir` wp" | |||
cd $newVhostDir/htdocs/wp-content/plugins/google-authenticator | |||
sed -i "s^\$GA_description\s=\s__(\s[\"'].*[\"']^\$GA_description = __( '$defaultOtpAccountDescription'^" google-authenticator.php | |||
# install 'force-strong-passwords' plugin | |||
sudo -u wp -i wp --path=$newVhostDir/htdocs plugin install force-strong-passwords --activate | |||
# install rename-wp-login plugin | |||
sudo -u wp -i wp --path=$newVhostDir/htdocs plugin install rename-wp-login --activate | |||
# add vhosts dir to php.ini 'open_basedir' | |||
vim /etc/php.ini | |||
# create vhosts apache conf file w/ deny for 'wp-login.php' | |||
#<LocationMatch .*wp-login.php> | |||
# Deny From All | |||
#</LocationMatch> | |||
vim /etc/httpd/conf.d/TODO | |||
# apply apache configs | |||
service httpd reload | |||
# finally, log into the new wordpress site (use '/login' instead of '/wp-login.php'. After authenticating, wp will ask you to update, if necessary. Then update settings: | |||
# 1. "Settings" -> "Permalinks" -> "Rename wp-login.php" -> "Login url" = 'ose-hidden-login' | |||
# 2. "Settings" -> "General" -> "Google Authenticator - Encourage User Activation" = "Force the user" | |||
</pre> |
Revision as of 19:19, 25 September 2017
Apply to Production
sudo su - ################# # set variables # ################# vhostDir=/var/www/html/obi dbName=obi_db dbUser=obi_db_user dbPass=CHANGEME rootDbPass=CHANGEME stamp=`date +%Y%m%d_%T` vhostDirMovedTo="${vhostDir}.${stamp}.bak" ################ # make backups # ################ # SYSTEM-SIDE BACKUPS time /bin/nice /root/backups/backup.sh &>> /var/log/backups/backup.log source /root/backups/backup.settings # validate ssh $RSYNC_USER@$RSYNC_HOST du -sh backups/hetzner2/* # LOCAL BACKUPS tmpDir=/var/tmp/chg.$stamp mkdir $tmpDir chown root:root $tmpDir chmod 0700 $tmpDir pushd $tmpDir service httpd stop # create backup of all DBs for good measure time nice mysqldump -uroot -p$rootDbPass --all-databases | gzip -c > preBackup.all_databases.$stamp.sql.gz # dump wp DB contents time nice mysqldump -u$dbUser -p$dbPass --database $dbName > $dbName.$stamp.sql # files backup rsync -av --progress "${vhostDir}" "vhostDir.${stamp}.bak/" ############# # update db # ############# # verify the first 2 (non-comment) occurances of $dbName meet the naming convention of "<siteName>_db" vim $dbName.$stamp.sql # update links for 3Dmodels, which we're moving to the 'wp-content' dir sed -i 's^/3Dmodels/^/wp-content/3Dmodels/^g' "$dbName.$stamp.sql" time nice mysql -uroot -p$rootDbPass -sNe "DROP DATABASE IF EXISTS $dbName;" time nice mysql -uroot -p$rootDbPass -sNe "CREATE DATABASE $bName; USE $dbName;" time nice mysql -uroot -p$rootDbPass < "$dbName.$stamp.sql" time nice mysql -uroot -p$rootDbPass -sNe "GRANT ALL ON $dbName.* TO '$dbUser'@'localhost' IDENTIFIED BY '$dbPass'; FLUSH PRIVILEGES;" popd ################ # update files # ################ mv "${vhostDir}" "${vhostDirMovedTo}" mkdir -p "${vhostDir}/htdocs" pushd $newVhostDir/htdocs yum install subversion svn co https://core.svn.wordpress.org/tags/4.8.1 . find $vhostDir -type d -exec chmod 750 {} \; find $vhostDIr -type f -exec chmod 640 {} \; chown -R apache:apache ${vhostDir} rsync -av --progress ${vhostDirMovedTo}/wp-config.php ${vhostDir}/ chown apache:apache-admins ${vhostDir}/wp-config.php chmod 440 ${vhostDir}/wp-config.php # change WP_HOME, WP_SITEURL, DB_NAME, DB_USER, & DB_PASSWORD as needed vim ${vhostDir}/wp-config.php # we want to copy files that don't exist yet in our new install dir. if a file exists in both, don't overwrite the new from the old rsync -av --progress --ignore-existing "${vhostDirMovedTo}/htdocs/wp-content/" "$vhostDir/htdocs/wp-content/" # delete unnecessary & empty upgrade dir rm -rf "${vhostDir}/htdocs/wp-content/upgrade" # delete unnecessary plugins rm -rf "${vhostDir}/htdocs/wp-content/plugins/hello.php" rm -rf "${vhostDir}/htdocs/wp-content/plugins/password-protected" rm -rf "${vhostDir}/htdocs/wp-content/plugins/simple-301-redirects" # migrate '3Dmodels' dir, but put it in 'wp-content' for future migrations (the wp upgrade docs migrate this dir already) rsync -av --progress "${vhostDirMovedTo}/htdocs/3Dmodels" "${vhostDir}/htdocs/wp-content/" # take the old .htaccess; overwrite existing if needed rsync -av --progress "${vhostDirMovedTo}/htdocs/.htaccess" "${vhostDir}/htdocs/" # set permissions, final pass chown -R apache:apache "${vhostDir}" find "${vhostDir}" -type d -exec chmod 0750 {} \; find "${vhostDir}" -type f -exec chmod 0640 {} \; find "${vhostDir}/htdocs/wp-content" -type f -exec chmod 0660 {} \; find "${vhostDir}/htdocs/wp-content" -type d -exec chmod 0770 {} \; chown apache:apache-admins "${newVhostDir}/wp-config.php" chmod 0440 "${vhostDir}/wp-config.php" # update wp plugins sudo -u wp -i wp --path="${vhostDir}/htdocs" plugin update --all # update wp themes #(we skip this in obi's oshine, since it caused issues) #sudo -u wp -i wp --path="${vhostDir}/htdocs" theme update --all # install & configure 2FA plugins sudo -u wp -i wp --path=${vhostDir}/htdocs plugin install google-authenticator --activate sudo -u wp -i wp --path=${vhostDir}/htdocs plugin install google-authenticator-encourage-user-activation --activate defaultOtpAccountDescription="`basename ${vhostDir}` wp" cd "${vhostDir}/htdocs/wp-content/plugins/google-authenticator" sed -i "s^\$GA_description\s=\s__(\s[\"'].*[\"']^\$GA_description = __( '$defaultOtpAccountDescription'^" google-authenticator.php # install 'force-strong-passwords' plugin sudo -u wp -i wp --path="${vhostDir}/htdocs" plugin install force-strong-passwords --activate # install rename-wp-login plugin sudo -u wp -i wp --path="${vhostDir}/htdocs" plugin install rename-wp-login --activate # add deny for 'wp-login.php' _inside_ the VirtualHosts block of the vhost config file #<LocationMatch .*wp-login.php> # Deny From All #</LocationMatch> vim /etc/httpd/conf.d/TODO # test apache config httpd -t # if OK, apply apache configs service httpd reload # finally, log into the new wordpress site (use '/login' instead of '/wp-login.php'. After authenticating, wp will ask you to update, if necessary. Then update settings: # 1. "Settings" -> "Permalinks" -> "Rename wp-login.php" -> "Login url" = 'ose-hidden-login' # 2. "Settings" -> "General" -> "Google Authenticator - Encourage User Activation" = "Force the user"
Build Ephemeral Staging
These commands were used to migrate the existing & outdated wordpress installs to a subversion-backed, ephemeral clone of the site. Changes were iterated to these commands documented here as validation by the site owners exposed issues with the upgrades, missing content, etc. Once the clone was validated entirely, the live site could be brought down & confidently updated per the findings with the ephemeral clone.
obi
oldVhostDir=/var/www/html/obi newVhostDir=/var/www/html/obi2 oldDbName=obi_db newDbName=obi2_db newDbUser=obi2_user newDbPass=CHANGEME rootDbPass=CHANGEME cd rm -rf $newVhostDir mkdir -p $newVhostDir/htdocs pushd $newVhostDir/htdocs yum install subversion svn co https://core.svn.wordpress.org/tags/4.8.1 . find $newVhostDir -type d -exec chmod 750 {} \; find $newVhostDIr -type f -exec chmod 640 {} \; chown -R apache:apache $newVhostDir stamp=`date +%Y%m%d_%T` tmpDir=/var/tmp/dbChange.$stamp mkdir $tmpDir chown root:root $tmpDir chmod 0700 $tmpDir pushd $tmpDir time nice mysqldump -uroot -p$rootDbPass --all-databases | gzip -c > preBackup.all_databases.$stamp.sql.gz time nice mysqldump -uroot -p$rootDbPass --databases $oldDbName > $oldDbName.$stamp.sql cp $oldDbName.$stamp.sql $newDbName.$stamp.sql # replace the first 2 (non-comment) occurances of $OldDbName with $newDbName vim $newDbName.$stamp.sql # update links for 3Dmodels, which we're moving to the 'wp-content' dir sed -i 's^/3Dmodels/^/wp-content/3Dmodels/^g' "$newDbName.$stamp.sql" time nice mysql -uroot -p$rootDbPass -sNe "DROP DATABASE IF EXISTS $newDbName;" time nice mysql -uroot -p$rootDbPass -sNe "CREATE DATABASE $newDbName; USE $newDbName;" time nice mysql -uroot -p$rootDbPass < "$newDbName.$stamp.sql" time nice mysql -uroot -p$rootDbPass -sNe "GRANT ALL ON $newDbName.* TO '$newDbUser'@'localhost' IDENTIFIED BY '$newDbPass'; FLUSH PRIVILEGES;" popd rsync -av --progress $oldVhostDir/wp-config.php $newVhostDir/ chown apache:apache $newVhostDir/wp-config.php chmod 400 $newVhostDir/wp-config.php # change WP_HOME, WP_SITEURL, DB_NAME, DB_USER, & DB_PASSWORD vim $newVhostDir/wp-config.php # we want to copy files that don't exist yet in our new install dir. if a file exists in both, don't overwrite the new from the old rsync -av --progress --ignore-existing $oldVhostDir/htdocs/wp-content/ $newVhostDir/htdocs/wp-content/ # delete unnecessary & empty upgrade dir rm -rf $newVhostDir/htdocs/wp-content/upgrade # delete unnecessary plugins rm -rf $newVhostDir/htdocs/wp-content/plugins/hello.php rm -rf $newVhostDir/htdocs/wp-content/plugins/password-protected rm -rf $newVhostDir/htdocs/wp-content/plugins/simple-301-redirects # migrate '3Dmodels' dir, but put it in 'wp-content' for future migrations (the wp upgrade docs migrate this dir already) rsync -av --progress $oldVhostDir/htdocs/3Dmodels $newVhostDir/htdocs/wp-content/ # take the old .htaccess; overwrite existing if needed rsync -av --progress $oldVhostDir/htdocs/.htaccess $newVhostDir/htdocs/ # set permissions chown -R apache:apache "${newVhostDir}" find "${newVhostDir}" -type d -exec chmod 0750 {} \; find "${newVhostDir}" -type f -exec chmod 0640 {} \; find "${newVhostDir}/htdocs/wp-content" -type f -exec chmod 0660 {} \; find "${newVhostDir}/htdocs/wp-content" -type d -exec chmod 0770 {} \; chown apache:apache-admins "${newVhostDir}/wp-config.php" chmod 0440 "${newVhostDir}/wp-config.php" # update wp plugins sudo -u wp -i wp --path=$newVhostDir/htdocs plugin update --all # update wp themes #sudo -u wp -i wp --path=$newVhostDir/htdocs theme update --all # install & configure 2FA plugins sudo -u wp -i wp --path=$newVhostDir/htdocs plugin install google-authenticator --activate sudo -u wp -i wp --path=$newVhostDir/htdocs plugin install google-authenticator-encourage-user-activation --activate defaultOtpAccountDescription="`basename $newVhostDir` wp" cd $newVhostDir/htdocs/wp-content/plugins/google-authenticator sed -i "s^\$GA_description\s=\s__(\s[\"'].*[\"']^\$GA_description = __( '$defaultOtpAccountDescription'^" google-authenticator.php # install 'force-strong-passwords' plugin sudo -u wp -i wp --path=$newVhostDir/htdocs plugin install force-strong-passwords --activate # install rename-wp-login plugin sudo -u wp -i wp --path=$newVhostDir/htdocs plugin install rename-wp-login --activate # add vhosts dir to php.ini 'open_basedir' vim /etc/php.ini # create vhosts apache conf file w/ deny for 'wp-login.php' #<LocationMatch .*wp-login.php> # Deny From All #</LocationMatch> vim /etc/httpd/conf.d/TODO # apply apache configs service httpd reload # finally, log into the new wordpress site (use '/login' instead of '/wp-login.php'. After authenticating, wp will ask you to update, if necessary. Then update settings: # 1. "Settings" -> "Permalinks" -> "Rename wp-login.php" -> "Login url" = 'ose-hidden-login' # 2. "Settings" -> "General" -> "Google Authenticator - Encourage User Activation" = "Force the user"