We currently use the excellent WordFence plugin on almost all of the WordPress installations we host. Once a week or so, WordFence will email a list of IP addresses it’s detected that are attacking a given site — i.e. they’re trying to brute-force something on the server, guess passwords, take advantage of possible software vulnerabilities. Rather than block each of these individually using csf (not hard to do, but a chore with many IPs), I finally created this simple bash script that allows me to copy and paste the list of offending IPs into the command line, hit enter twice to initiate processing, and then it automatically bans every valid IP address it finds.
Feel free to use this yourself if it seems helpful! 🙂
ban_ips.sh
#!/bin/bash
# Script to bulk ban bad IPs that are copy/pasted
printf "Give me some IPs to ban using CSF! Use ctrl-d to cancel, or new line to process. \n"
ip_list=$(sed '/^$/q')
echo "Processing..."
echo "$ip_list" | while read -r line;
do
ip="$(grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' < << "$line")"
if [[ ! -z $ip ]]
then
geoip=`geoiplookup $ip`
echo "Found IP $ip"
echo "$geoip"
echo "Banning IP..."
csf -d $ip "Bulk banning IPs found by WordFence ($(tr '\n' ' ' <<< $geoip))"
fi
done
echo "Done!"
After yet another brute-force attack on our servers hosting WordPress sites today I finally decided it was time to take some drastic action.  There are a number of different approaches you can take, this is what I did to block literally over 75,000 attacks against wp-login.php today.
Step 2: Add this to /usr/local/apache/conf/includes/post_virtualhost_global.conf
# Whitelist countries allowed to access wp-login.php or wp-comments-post.php
<FilesMatch "(wp-login|wp-comments-post)\.php$">
SetEnvIf GEOIP_COUNTRY_CODE US AllowCountry
SetEnvIf GEOIP_COUNTRY_CODE CN AllowCountry
order deny,allow
Deny from all
Allow from env=AllowCountry
ErrorDocument 403 "Forbidden."
</FilesMatch>
(We have some clients in China who need to legitimately login to WordPress, so we included them in the whitelist). Adjust your whitelist / allowed country list appropriately.
Restart apache service httpd restart and start watching the attacks get served up “Forbidden.” messages instead of hitting WordPress and database. Server load way down, yay! Sorry rest of the world, you can’t have our wp-login.php anymore.
Chair and checkered tile floor at Cafe Helloakland
Since it’s almost my 36th birthday, I decided it was time to update the site theme for my personal site, www.gabrielserafini.com. I wanted the new design to focus on framing content in an aesthetically pleasing way. The background changes on each refresh, and uses CSS transformations and translucencies to create a lovely effect.
There are still a lot of rough edges to it, but it was important to me to get it out there.
We have 82 installations of WordPress on our servers and are excited for the new release of WordPress 3.1. There are a bunch of neat new features, but probably the thing that most of our clients will notice first is that there is a new admin bar that will show up for them. Should be fun managing the upgrades. 🙂
If you’re like me you’ve been using the excellent Twitter Tools plugin for WordPress for a while now. Recently a client noticed that there was a sporadic error being shown that was similar to this:
Warning: require_once() [function.require-once]: open_basedir restriction in effect. File(twitteroauth.php) is not within the allowed path(s): (/home/fern:/usr/lib/php:/usr/local/lib/php:/tmp) in /home/fern/public_html/wp-content/plugins/twitter-tools/twitter-tools.php on line 1516
Here is the fix that I figured out would work — add the absolute path of the file into the plugin code and it should clear this up. Obviously this isn’t an ideal long-term solution. Hopefully Alex will incorporate this simple fix into the next version of the plugin. Note that this fix applies to Twitter Tools version 2.4.
In twitter-tools/twitter-tools.php change line 1516 to: require_once(dirname (__FILE__) . '/twitteroauth.php');
And in twitter-tools/twitteroauth.php change line 10 to: require_once(dirname (__FILE__) . '/OAuth.php');
WordCamp San Francisco 2010 (#wcsf) was great. Â Lots of neat people sharing good ideas about WordPress, including a great “State of the Word” address by Matt Mullenweg, co-founder of WordPress.
During the presentations I learned about a couple of plugins that both seem worth trying out.
IntenseDebate — Basically a commenting system on turbo mode. Â It keeps a copy of all your WordPress comments in your database (your data is still your data) but adds come tasty improvements to the stock WordPress commenting system. Â These features include reputation management (up or downvote comments), commenter profile lookups, threaded comments, subscribe (and reply!) by email and more.
After the Deadline — This takes the concept of ‘spell check’ to a whole new level. Â It does grammar and style checking in addition to spell checking, and helps you to become a better writer. Â This is also activated in my comments now as well.
Anyways, while you’re waiting for WordPress 3.0 to ship (should be very soon now) go ahead and give those plugins a go, I think you might like them.
We’ll be upgrading most of our clients to the latest version of WordPress 2.9.1 now that they’ve resolved a number of the issues we were seeing with the 2.9 release. Â Good job guys on getting a quick fix out!
The current import script (as of WordPress 2.8.6) is broken when it comes to successfully importing images from WordPress.com. The error you see is something like
Remote file error: Remote file returned error response 301 Moved Permanently
Fixing this involves adding a couple of lines to a core WordPress file. Hopefully a future version of WordPress will include the working version.
Note that these instructions are for WordPress 2.8.6. Your version may be different, and you may need to play with this to get it to work for you. This worked for me, YMMV.
Open wp-includes/functions.php
Around line 1208 or so, you’ll find the wp_get_http function.
Right below where it says $headers['response'] = $response['response']['code'];, add the following code (around line 1227):
// added to fix 301 redirects for blog import code from WordPress.com
if ((string)$response['response']['code'] == '301') {
$response = wp_remote_request($headers['location'], $options);
$headers = wp_remote_retrieve_headers($response);
$headers['response'] = $response['response']['code'];
}
Save the functions.php file and copy it back to the server.
Re-run the import function (Tools > Import > WordPress). Don’t worry, it won’t make copies of the posts you’ve already imported, it will just download the images to your new blog.
To fix the references to the images so they’re being served off your new blog, you can either go through every post and manually correct them all, (not very fun), or better yet, download the Search and Replace plugin, activate it and do a search for all instances of the WordPress.com image server URL in all your posts (something like http://BLOGNAME.files.wordpress.com/ with your own new URL — http://BLOGNAME.com/wp-content/uploads/). Don’t forget to test the new URL structure before you do the search and replace, otherwise you’ll have to go back and fix it.
Question: Is the built-in WordPress automatic install / upgrade process compatible with a SVN deployment of WordPress?
Short answer: Yes.
Ever since WordPress came out with the automatic upgrade functionality in 2.7 I’ve hesitated to use it since the majority of our client installs are deployed using Subversion (svn) and I wasn’t sure how it would react with the .svn directories.
Today I finally decided to figure it out, and found that the WordPress team coded their upgrading functions exactly correctly (as far as not overwriting or deleting .svn directories goes). In addition, their script correctly removes old and unneeded files that might be present.
First, check to make sure that our svn checkout is clean:
$ svn st
Next, we begin the automatic upgrade process.
Step 1: Click the WordPress 2.8.5 “Please update now.” link: Step 2: Backup your files as suggested – http://codex.wordpress.org/WordPress_Backups Step 3: Enter your FTP connection details and click the Proceed button Step 4: Wait while the files are downloaded and unzipped. This can take a minute or two, so be patient.
Now we can check to see what files were changed:
$ svn st
M wp-app.php
M xmlrpc.php
M wp-includes/post-template.php
M wp-includes/version.php
M wp-includes/theme.php
M wp-includes/comment-template.php
M wp-includes/bookmark-template.php
M wp-includes/media.php
M wp-includes/formatting.php
M wp-includes/author-template.php
! wp-includes/images/swf.png
! wp-includes/images/audio.png
! wp-includes/images/zip.png
! wp-includes/images/html.png
! wp-includes/images/doc.png
! wp-includes/images/video.png
! wp-includes/images/pdf.png
! wp-includes/images/js.png
! wp-includes/images/exe.png
! wp-includes/images/text.png
! wp-includes/images/default.png
! wp-includes/images/tar.png
! wp-includes/images/css.png
M wp-includes/rewrite.php
M wp-includes/general-template.php
M wp-includes/capabilities.php
M wp-includes/classes.php
M wp-includes/category-template.php
? wp-content/plugins/hello.php
M wp-content/plugins/akismet/akismet.php
M wp-content/plugins/akismet/readme.txt
M wp-trackback.php
M readme.html
M wp-admin/includes/post.php
M wp-admin/includes/update-core.php
M wp-admin/post.php
! wp-admin/js/forms.js
! wp-admin/js/upload.js
M wp-admin/edit-attachment-rows.php
! wp-admin/import/btt.php
! wp-admin/import/jkw.php
M wp-admin/import/wordpress.php
! wp-admin/edit-form.php
! wp-admin/link-import.php
! wp-admin/images/media-button-gallery.gif
! wp-admin/images/tail.gif
! wp-admin/images/gear.png
! wp-admin/images/comment-stalk-classic.gif
! wp-admin/images/media-buttons.gif
! wp-admin/images/comment-stalk-rtl.gif
! wp-admin/images/tab.png
! wp-admin/images/comment-stalk-fresh.gif
! wp-admin/images/comment-pill.gif
! wp-admin/css/press-this-ie-rtl.css
! wp-admin/css/press-this-ie.css
! wp-admin/css/upload-rtl.css
M wp-admin/install.php
M wp-admin/page.php
Next we schedule old files to be removed from svn:
$ svn st | grep ! | sed 's/! *//' | xargs svn rm;
Next we commit the modified files and the removed files:
$ svn ci -m "Upgrading to the latest version of WordPress 2.8.5"
That’s it. The WordPress automatic upgrade process does not interfere with .svn directories, and is therefore compatible with maintaining a deploy from Subversion workflow.