Wordpress: Difference between revisions
No edit summary |
|||
Line 12: | Line 12: | ||
==Force Strong Passwords== | ==Force Strong Passwords== | ||
The wp core software includes a Javascript-powered password strength indicator (based on the [https://github.com/dropbox/zxcvbn zxcvbn Password Strength Estimator by Dropbox], but | The wp core software includes a Javascript-powered password strength indicator (based on the [https://github.com/dropbox/zxcvbn zxcvbn Password Strength Estimator by Dropbox], but it does not have a way to enforce passwords to meet the recommended strength. | ||
We use the [https://wordpress.org/plugins/force-strong-passwords/ "Force Strong Passwords plugin by Jason Cosper] plugin, | We use the [https://wordpress.org/plugins/force-strong-passwords/ "Force Strong Passwords plugin by Jason Cosper] plugin, which simply leverages the already-built-in zxcvbn Password Strength Estimator, and makes it actually _require_ strong passwords when users (with publish_posts, upload_files and/or edit_published_posts) attempt to create or update their password. | ||
==Rename wp-login.php== | ==Rename wp-login.php== |
Revision as of 19:20, 3 October 2017
Wordpress Plugins
2FA
We use the following two plugins to achieve 2FA auth in Wordpress:
# "Google Authenticator" plugin by Henrik Schack # "Google Authenticator – Encourage User Activation" plugin by Ian Dunn
For more information, see 2FA
Force Strong Passwords
The wp core software includes a Javascript-powered password strength indicator (based on the zxcvbn Password Strength Estimator by Dropbox, but it does not have a way to enforce passwords to meet the recommended strength.
We use the "Force Strong Passwords plugin by Jason Cosper plugin, which simply leverages the already-built-in zxcvbn Password Strength Estimator, and makes it actually _require_ strong passwords when users (with publish_posts, upload_files and/or edit_published_posts) attempt to create or update their password.
Rename wp-login.php
Other
- No Self Pings - remove self pings
- Contact Form 7 - easy to maintain contact form
- Efficient Related Posts - shows related posts by tags
- Enhanced Recent Posts - shows recent posts, can exclude posts from categories
- Like - Facebook like button for posts
- MailChimp Widget - easy and free newsletter by Mailchimp
- Really Simple CAPTCHA - needed for Contact Form 7
- Semisecure Login Reimagined - for more secure login into your Wordpress
- Social Media Widget - Adds links to all of your social media and sharing site as a widget
- W3 Total Cache - for caching (performance)
- XCloner - Backup and Restore - schedule backups with cron jobs
OSE Website - Known Bugs
Proper File/Directory Ownership & Permissions
This section will describe how the file permissions should be set on an OSE wordpress site.
For the purposes of this documentation, let's assume:
- vhost dir = /var/www/html/osemain
- wp docroot = /var/www/html/osemain/htdocs
Then the ideal permissions are:
- Files containing passwords (ie: wp-config.php) should be located outside the wp docroot with apache:apache-admins 0440
- Files in the wp-content dir should be apache:apache 0660
- Directories in the wp-content dir should be apache:apache 0770
- All other files in the vhost dir should be apache:apache 0640
- All other directories in the vhost dir should be apache:apache 0750
This is achievable with the following idempotent commands:
vhostDir="/var/www/html/osemain" wpDocroot="${vhostDir}/htdocs" chown -R apache:apache "${vhostDir}" find "${vhostDir}" -type d -exec chmod 0750 {} \; find "${vhostDir}" -type f -exec chmod 0640 {} \; find "${wpDocroot}/wp-content" -type f -exec chmod 0660 {} \; find "${wpDocroot}/wp-content" -type d -exec chmod 0770 {} \; chown apache:apache-admins "${vhostDir}/wp-config.php" chmod 0440 "${vhostDir}/wp-config.php"
Updating Wordpress
First of all, it is not uncommon for an attempt to update wordpress to result in an entirely broken site. If you do not have linux and bash literacy, do not attempt to update wordpress. Moreover, you should be well-versed in how to work with mysqldump, tar, rsync, chmod, chown, & sudo. If you are not confident in how all of these commands work, do not proceed. Hire someone with sysops experience to follow this guide; it should take them less than a couple hours to update and/or revert if the update fails.
Step 0: Trigger Backup Scripts for System-Wide backup
For good measure, trigger a backup of the entire system's database & files:
sudo 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
sudo bash -c 'source /root/backups/backup.settings; ssh $RSYNC_USER@$RSYNC_HOST du -sh backups/hetzner2/*'
Step 1: Set variables
Type these commands to set some variables, which will be used by the commands in the sections below. Replace 'osemain' with the corresponding directory for the wp site you're updating.
export vhostDir=/var/www/html/osemain
Step 2: Make Vhost-specific backups
The backups made in the previous step are huge. Because it's easier to work with vhost-specific backups, let's make a redundant copy available in /var/tmp/:
sudo su - dbName=osemain_db dbUser=osemain_user dbPass=CHANGEME rootDbPass=CHANGEME stamp=`date +%Y%m%d_%T` tmpDir=/var/tmp/dbChange.$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/"
Step 3: Permissions
TODO link to other section
Step 4: SVN Update
TODO update with svn
Step 5: Update Plugins and Themes
Run the following commands to have wp-cli update your plugins & themes.
# update wp plugins sudo -u wp -i wp --path=${vhostDir}/htdocs plugin update --all # update wp themes sudo -u wp -i wp --path=${vhostDir}/htdocs theme update --all
Step 6: Database Upgrade
TODO: login to wp & update (or is it upgrade?)
Step 7: Validate
TODO describe a test for sanity of successful upgrade
Revert
TODO restore procedure
WP-CLI
Wordpress has been officially developing a tool for managing their software over CLI called wp-cli. This has been around since 2011, it's funded by big hosting companies that offer cheap wordpress shared hosting plans, and is actively developed (as of 2017-08-26, at the time of writing, the last commit was a few days ago, and releases come out every few months).
Unfortunately, wp-cli expects php to be more open than our hardened config allows, so we can't use it for updating the wp core software (instead we use svn), but it works great for most plugins & themes.
Here's how we install wp-cli on our server:
useradd wp gpasswd -a wp apache gpasswd -a wp apache-admins su - wp mkdir -p $HOME/.wp-cli cd $HOME/.wp-cli curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar mkdir -p $HOME/bin ln -s $HOME/.wp-cli/wp-cli.phar $HOME/bin/wp chown wp:wp -R /$HOME/.wp-cli find $HOME/.wp-cli -type d -exec chmod 0700 {} \; find $HOME/.wp-cli -type f -exec chmod 0600 {} \; chmod 0700 $HOME/.wp-cli/wp-cli.phar
Note that we should *not* be running wp as root. Doing so may allow a wp site that's been owned (which is very common) to escalate itself to having root privileges. This is why we use a special user 'wp', and all documentation on this wiki for `wp` command is preceded with `sudo -u wp -i wp ...`, so that someone following this guide doesn't accidentally run `wp` as root.
Here are some example wp-cli commands:
sudo -u wp -i wp --path=/var/www/html/osemain/htdocs theme list sudo -u wp -i wp --path=/var/www/html/osemain/htdocs theme update --all sudo -u wp -i wp --path=/var/www/html/osemain/htdocs plugin list sudo -u wp -i wp --path=/var/www/html/osemain/htdocs plugin update --all
CLI guides
This section will provide commands to achieve certain actions for managing wordpress
replace strings everywhere in wp database backend
Use these commands to safely backup & do a string replacement for all occurrences from a given $fromString to $toString. This was used to replace links in the wordpress posts/pages to the ip address instead of using the domain name (which creates migration issues & https issues)
dbName=obi_db dbUser=obi_user dbPass=CHANGEME rootDbPass=CHANGEME fromString=138.201.84.223 toString=openbuildinginstitute.org stamp=`date +%Y%m%d_%T` tmpDir=/var/tmp/dbChange.$stamp mkdir $tmpDir chown root:root $tmpDir chmod 0700 $tmpDir pushd $tmpDir service httpd stop # create backup of everything for good measure time nice mysqldump -uroot -p$rootDbPass --all-databases | gzip -c > preBackup.all_databases.$stamp.sql.gz # dump obi wordpress db contents time nice mysqldump -u$dbUser -p$dbPass --database $dbName > $dbName.$stamp.sql # make backup cp $dbName.$stamp.sql $dbName.$stamp.sql.orig # sed sed -i "s/$fromString/$toString/g" $dbName.$stamp.sql # verify grep "$fromString" $dbName.$stamp.sql | less grep "$toString" obi_db.$stamp.sql | less # delete db tables mysql -u$dbUser -p$dbPass $dbName -sNe 'show tables' | while read table; do mysql -u$dbUser -p$dbPass -sNe "DROP TABLE $dbName.$table;"; done # verify mysql -u$dbUser -p$dbPass $dbName -sNe 'show tables' # import mysql -u$dbUser -p$dbPass < obi_db.$stamp.sql # verify mysql -u$dbUser -p$dbPass $dbName -sNe 'show tables' service httpd start
Changes
As of 2017-09, we have no ticket tracking or change control process. For now, everything is on the wiki as there's higher priorities. Hence, here's some articles used to track production changes:
- CHG-2017-09-25 - first major obi production change by Michael Altfield