CHG-2018-02-05 migrate osemain to hetzner2: Difference between revisions
No edit summary |
|||
Line 3: | Line 3: | ||
==2018-03-01 20:00 UTC== | ==2018-03-01 20:00 UTC== | ||
Pausing this change until tomorrow. It's 90% done. All that remains is to actually remove the old files on hetzner1, but the system-wide backup I kicked-off at the start of this CHG is still running. I'll resume this tomorrow after the backup has been verified on our dreamhost server. Then I'll remove the files & get validation from Marcin. In the meantime, my own spotchecks for both the wiki & osemain show that | Pausing this change until tomorrow. It's 90% done. All that remains is to actually remove the old files on hetzner1, but the system-wide backup I kicked-off at the start of this CHG is still running. I'll resume this tomorrow after the backup has been verified on our dreamhost server. Then I'll remove the files & get validation from Marcin. In the meantime, my own spotchecks for both the wiki & osemain show that both sites are fully functional. | ||
==2018-03-01 15:00 UTC== | ==2018-03-01 15:00 UTC== |
Revision as of 20:03, 1 March 2018
Status
2018-03-01 20:00 UTC
Pausing this change until tomorrow. It's 90% done. All that remains is to actually remove the old files on hetzner1, but the system-wide backup I kicked-off at the start of this CHG is still running. I'll resume this tomorrow after the backup has been verified on our dreamhost server. Then I'll remove the files & get validation from Marcin. In the meantime, my own spotchecks for both the wiki & osemain show that both sites are fully functional.
2018-03-01 15:00 UTC
Started this change.
2018-02-28 02:32 UTC
Marcin confirmed that all outstanding issues are fixed, and that we can proceed with migration. The new migration time is 2018-03-01 15:00 UTC
2018-02-20
Marcin confirmed that enabling 2FA opened up his account, but he got a Forbidden issue when attempting to update or create *blog* posts (as opposed to pages). I fixed this by whitelisting the modsec rule id = 973337, xss.
2018-02-14
Marcin confirmed that all issues were fixed, but couldn't edit. The result was that his account was locked in a demoted state as the Subscriber role because he didn't enable 2FA. I added documentation to 2FA to clarify.
2018-02-12
Last week we discovered issues with several pages. Critical issues were fixed. Minor issues were agreed to be non-blocking of the migration.
- /
- /contributors/
- /community/
- /community-true-fans/
- /history-timeline/
- /cnc-torch-table-workshop/
- /about-videos-3/
For more info, see my log from 2018-02-07 Maltfield_log_2018#Wed_Feb_07.2C_2018
2018-02-05 15:11 UTC
I had emailed Marcin yesterday asking for re-validation after I updated some plugins & found some issues with the staging site. I haven't heard back from Marcin, so I'm delaying this migration until I do.
2018-02-04 06:02 UTC
Marcin finished validation of the staging site on hetzner2 & gave the green-light for cutover on Monday, February 5th at 10:00 EST, follwed by a 1-week content freeze.
Purpose
This change does the following for osemain
- entirely migrate the 'osemain' wordpress site from hetzner1 (shared hosting) to hetzner2 (dedicated hosting)
- changes the domain from 'http://opensourceecology.org/' to 'https://www..opensourceecology.org'
- update core wp from v4.7.9 to v4.9.2
- changes the docroot to a subversion repo of the wp codebase, making it easier to update in the future without sacrificing security (ie: permitting wordpress to update itself) for ease-of-use
- updates the vhost config to block access to svn files, and more generally: ".*\.(svn|git|hg|bzr|cvs|ht)/.*"
- update plugin 'akismet' from v3.3 to v4.0.2
- update plugin 'cyclone-slider-2' from v2.12.4 to v3.2.0
- update plugin 'duplicate-post' from v3.1.2 to v3.2.1
- update plugin 'jetpack' from v4.7.1 to v5.7.1
- update plugin 'ml-slider' from v3.5 to v3.6.8
- update plugin 'ml-slider-pro' from v2.6.6 to v2.7.1
- update plugin 'recent-tweets-widget' from v1.6.6 to v 1.6.8
- install & activate plugin 'google-authenticator' to provide 2FA
- install & activate plugin 'google-authenticator-encourage-user-activation' to require users to use 2FA
- install & activate plugin 'force-strong-passwords' to prevent users from using a poor password, as determined by the built-in wp core password strength feature
- install & activate plugin 'rename-wp-login' to obfuscate the wordpress login page (reduces server load & alert emails from HIDS blocking brute force attempts)
- install & activate plugin 'vcaching' so wordpress & varnish communicate to clear the cache when needed
- updates the vhost config to block all access to ".*wp-login.php"
- enable https via nginx
- enable cache via varnish
Points of Contact
Change being performed by: Michael Altfield
Service owners: Catarina Mota & Marcin Jakubowski
Apply to Production
#################### # run on hetzner1 # #################### # STEP 0: CREATE BACKUPS source /usr/home/osemain/backups/backup.settings /usr/home/osemain/backups/backup.sh # when finished, SSH into the dreamhost server to verify that the whole system backup was successful before proceeding bash -c 'source /usr/home/osemain/backups/backup.settings; ssh $RSYNC_USER@$RSYNC_HOST du -sh backups/hetzner1/*' # DECLARE VARIABLES source /usr/home/osemain/backups/backup.settings stamp=`date +%Y%m%d` backupDir_hetzner1="/usr/home/osemain/tmp/backups_for_migration_to_hetzner2/osemain_${stamp}" backupFileName_db_hetzner1="mysqldump_osemain.${stamp}.sql.bz2" backupFileName_files_hetzner1="osemain_files.${stamp}.tar.gz" vhostDir_hetzner1='/usr/www/users/osemain/' dbName_hetzner1='ose_osemain' dbUser_hetzner1="${mysqlUser_osemain}" dbPass_hetzner1="${mysqlPass_osemain}" # STEP 1: BACKUP DB mkdir -p ${backupDir_hetzner1}/{current,old} pushd ${backupDir_hetzner1}/current/ mv ${backupDir_hetzner1}/current/* ${backupDir_hetzner1}/old/ time nice mysqldump -u"${dbUser_hetzner1}" -p"${dbPass_hetzner1}" --all-databases | bzip2 -c > ${backupDir_hetzner1}/current/${backupFileName_db_hetzner1} # STEP 2: BACKUP FILES time nice tar -czvf ${backupDir_hetzner1}/current/${backupFileName_files_hetzner1} --exclude="${vhostDir_hetzner1}logs" --exclude="${vhostDir_hetzner1}w" --exclude="${vhostDir_hetzner1}archive" --exclude="${vhostDir_hetzner1}mediawiki-1.24.2.extra" ${vhostDir_hetzner1} #################### # run on hetzner2 # #################### sudo su - # STEP 0: CREATE BACKUPS # for good measure, trigger a backup of the entire system's database & files: time /bin/nice /root/backups/backup.sh &>> /var/log/backups/backup.log # when finished, SSH into the dreamhost server to verify that the whole system backup was successful before proceeding bash -c 'source /root/backups/backup.settings; ssh $RSYNC_USER@$RSYNC_HOST du -sh backups/hetzner2/*' # DECLARE VARIABLES source /root/backups/backup.settings stamp=`date +%Y%m%d` backupDir_hetzner1="/usr/home/osemain/tmp/backups_for_migration_to_hetzner2/osemain_${stamp}" backupDir_hetzner2="/var/tmp/backups_for_migration_from_hetzner1/osemain_${stamp}" backupFileName_db_hetzner1="mysqldump_osemain.${stamp}.sql.bz2" backupFileName_files_hetzner1="osemain_files.${stamp}.tar.gz" dbName_hetzner1='ose_osemain' dbName_hetzner2='osemain_db' dbUser_hetzner2="osemain_user" dbPass_hetzner2="CHANGEME" vhostDir_hetzner2="/var/www/html/www.opensourceecology.org" docrootDir_hetzner2="${vhostDir_hetzner2}/htdocs" # STEP 1: COPY FROM HETZNER1 mkdir -p ${backupDir_hetzner2}/{current,old} mv ${backupDir_hetzner2}/current/* ${backupDir_hetzner2}/old/ scp -P 222 osemain@dedi978.your-server.de:${backupDir_hetzner1}/current/* ${backupDir_hetzner2}/current/ # STEP 2: ADD DB # create backup before we start changing the sql file pushd ${backupDir_hetzner2}/current cp ${backupFileName_db_hetzner1} ${backupFileName_db_hetzner1}.orig # extract .sql.bz2 -> .sql bzip2 -dc ${backupFileName_db_hetzner1} > db.sql # verify the first 2 (non-comment) occurances of $dbName meet the naming convention of "<siteName>_db vim db.sql time nice mysql -uroot -p${mysqlPass} -sNe "DROP DATABASE IF EXISTS ${dbName_hetzner2};" time nice mysql -uroot -p${mysqlPass} -sNe "CREATE DATABASE ${dbName_hetzner2}; USE ${dbName_hetzner2};" time nice mysql -uroot -p${mysqlPass} < "db.sql" time nice mysql -uroot -p${mysqlPass} -sNe "GRANT ALL ON ${dbName_hetzner2}.* TO '${dbUser_hetzner2}'@'localhost' IDENTIFIED BY '${dbPass_hetzner2}'; FLUSH PRIVILEGES;" # STEP 3: Add vhost files mv ${vhostDir_hetzner2}/* ${backupDir_hetzner2}/old/ tar -xzvf ${backupFileName_files_hetzner1} content_dir=`find ${backupFileName_db_hetzner2} -name wp-content -type d | sort | head -n1` htaccess_file=`find ${backupFileName_db_hetzner2} -name '.htaccess' -type f | sort | head -n1` wp_config_file=`find ${backupFileName_db_hetzner2} -name 'wp-config.php' -type f | sort | head -n1` mkdir -p ${docrootDir_hetzner2} pushd ${docrootDir_hetzner2} currentWpVersion=`curl -i https://core.svn.wordpress.org/tags/ | grep '<li>' | tail -n1 | cut -d\" -f2` svn co https://core.svn.wordpress.org/tags/${currentWpVersion}/ ${docrootDir_hetzner2} popd rsync -av --progress ${wp_config_file} ${vhostDir_hetzner2}/ rsync -av --progress ${htaccess_file} ${docrootDir_hetzner2}/ rsync -av --progress ${content_dir} ${docrootDir_hetzner2}/ # make sure this is sudomain, not subdir now vim ${docrootDir_hetzner2}/.htaccess # update WP_HOME/WP_SITEURL/DB_NAME/DB_USER/DB_PASSWORD/DB_HOST/ # add/replace salts https://api.wordpress.org/secret-key/1.1/salt/ vim ${vhostDir_hetzner2}/wp-config.php # SET PERMISSIONS chown -R not-apache:apache "${vhostDir_hetzner2}" find "${vhostDir_hetzner2}" -type d -exec chmod 0050 {} \; find "${vhostDir_hetzner2}" -type f -exec chmod 0040 {} \; chown not-apache:apache-admins "${vhostDir_hetzner2}/wp-config.php" chmod 0040 "${vhostDir_hetzner2}/wp-config.php" [ -d "${docrootDir_hetzner2}/wp-content/uploads" ] || mkdir "${docrootDir_hetzner2}/wp-content/uploads" chown -R apache:apache "${docrootDir_hetzner2}/wp-content/uploads" find "${docrootDir_hetzner2}/wp-content/uploads" -type f -exec chmod 0660 {} \; find "${docrootDir_hetzner2}/wp-content/uploads" -type d -exec chmod 0770 {} \; # UPDATE EXISTING PLUGINS sudo -u wp -i wp --path=${docrootDir_hetzner2} plugin update --all # UPDATE EXISTING THEMES sudo -u wp -i wp --path=${docrootDir_hetzner2} theme update --all # INSTALL PLUGINS # install & configure 2FA plugins sudo -u wp -i wp --path=${docrootDir_hetzner2} plugin install google-authenticator --activate sudo -u wp -i wp --path=${docrootDir_hetzner2} plugin install google-authenticator-encourage-user-activation --activate defaultOtpAccountDescription="`basename ${vhostDir_hetzner2}` wp" pushd ${docrootDir_hetzner2}/wp-content/plugins/google-authenticator sed -i "s^\$GA_description\s=\s__(\s[\"'].*[\"']^\$GA_description = __( '$defaultOtpAccountDescription'^" google-authenticator.php popd # install 'force-strong-passwords' plugin sudo -u wp -i wp --path=${docrootDir_hetzner2} plugin install force-strong-passwords --activate # install rename-wp-login plugin sudo -u wp -i wp --path=${docrootDir_hetzner2} plugin install rename-wp-login --activate # install "SSL Insecure Content Fixer" pugin sudo -u wp -i wp --path=${docrootDir_hetzner2} plugin install ssl-insecure-content-fixer --activate # install "Varnish Caching" pugin sudo -u wp -i wp --path=${docrootDir_hetzner2} plugin install vcaching --activate # SET PERMISSIONS AGAIN chown -R not-apache:apache "${vhostDir_hetzner2}" find "${vhostDir_hetzner2}" -type d -exec chmod 0050 {} \; find "${vhostDir_hetzner2}" -type f -exec chmod 0040 {} \; chown not-apache:apache-admins "${vhostDir_hetzner2}/wp-config.php" chmod 0040 "${vhostDir_hetzner2}/wp-config.php" [ -d "${docrootDir_hetzner2}/wp-content/uploads" ] || mkdir "${docrootDir_hetzner2}/wp-content/uploads" chown -R apache:apache "${docrootDir_hetzner2}/wp-content/uploads" find "${docrootDir_hetzner2}/wp-content/uploads" -type f -exec chmod 0660 {} \; find "${docrootDir_hetzner2}/wp-content/uploads" -type d -exec chmod 0770 {} \; # 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" # 3. "Settings" -> "SSL Insecure Content" and then [a] uncheck the "WooCOmmerce" checkbox and [b] change the HTTPS detection from the default "standard WordPress function" to "HTTP_X_FORWARDED_PROTO" # 4. "Varnish Caching" and then [a] check the "Enable" checkbox, [b] enter "86400" for the "Homepage cache TTL", [c] enter "86400" for the "Cache TTL", [d] enter "127.0.0.1:6081" for "IPs", [e] check the "Dynamic host" checkbox
Finally, update the various content as needed:
- /contributors/, /community-true-fans/, /history-timeline/
- update iframes to knigtlab.com time sliders to be https instead of http
- /cnc-torch-table-workshop/, /eco-tractor_workshop/, /3d-printer-construction-set-workshop-3/
- update the widgets to use new "Custom HTML" widgets instead of "Text" widgets to prevent the eventbright's height from being truncated