Archives for January 2008

Why cloud services rock

Earlier this month I went away for a week. Two big things broke while I was gone:

In each case, software or hardware that I maintain went badly off the rails. I try pretty hard to lock down my WordPress. I protect my /wp-admin/ so that only certain IP addresses can access that directory. But this was a weird vulnerability. If I had hosted my blog with WordPress as a web service, I wouldn’t have had to patch things up myself. And I’m pretty sure that at least a few of my draft blog posts leaked to folks who exploited the security hole on my blog.

My NAS box was even more painful. I have a Buffalo TeraStation, and it’s worked well for over a year. But they don’t always cope well with power outages. And the version that I have required me to undo 22 screws to replace the bad hard drive. Then I had to wait for five nervous hours to see whether the NAS could repair my RAID array. No data was lost, but suffice it to say that I’ve got much better backups now, plus an uninterruptible power supply (UPS) as well. Again, if I had storage somewhere in the cloud, it would probably be more reliable than my ham-handed attempts at backing up my data.

So there you go: I went on vacation for a week and came back to two scary reminders why hosted services and storing data “in the cloud” (on someone else’s servers) can be better than doing it yourself. In general, a well-run cloud service is going to be much more reliable than any average person would be.

Three tips to protect your WordPress installation

Here are three easy but important ways to protect yourself if you run a WordPress blog:

  1. Secure your /wp-admin/ directory. What I’ve done is lock down /wp-admin/ so that only certain IP addresses can access that directory. I use an .htaccess file, which you can place directly at /wp-admin/.htaccess . This is what mine looks like:

    AuthUserFile /dev/null
    AuthGroupFile /dev/null
    AuthName “Access Control”
    AuthType Basic
    order deny,allow
    deny from all
    # whitelist home IP address
    allow from 64.233.169.99
    # whitelist work IP address
    allow from 69.147.114.210
    allow from 199.239.136.200
    # IP while in Kentucky; delete when back
    allow from 128.163.2.27

    I’ve changed the IP addresses, but otherwise that’s what I use. This file says that the IP address 64.233.169.99 (and the other IP addresses that I’ve whitelisted) are allowed to access /wp-admin/, but all other IP addresses are denied access. Has this saved me from being hacked before? Yes.

  2. Make an empty wp-content/plugins/index.html file. Otherwise you leak information on which plug-ins you run. If someone wanted to hack your blog, they might be able to do it by discovering that you run an out-of-date plugin on your blog and then they could exploit that.
  3. Subscribe to the WordPress Development blog at http://wordpress.org/development/feed/ . When WordPress patches a security hole or releases a new version, they announce it on that blog. If you see a security patch released, you need to upgrade or apply the patch. You leave yourself open to being hacked if you don’t upgrade.

And here’s a bonus tip: in the header.php file for your theme, you might want to check for a line like

<meta name=”generator” content=”WordPress <?php bloginfo(’version’); ?>” /> <!-– leave this for stats please -->

I’d just go ahead and delete that line or at least the bloginfo(‘version’). If you’re running an older version of WordPress, anyone can view source to see what attacks might work against your blog.

Hat tip to Reuben Yau and Shoe.

Update: In the comments, Joshua Slive pointed out that the .htaccess file shouldn’t have a <LIMIT GET> around the IP addresses. That would have allowed IP addresses to POST, for example. Joshua, thanks for the pointer to the Apache docs on this point.

How to subscribe to just my Google/SEO posts

I’ve got some pent-up techie/gadget blogging in me, and I know that not everyone wants to read that. I’ve mentioned before how to get just my Google/SEO posts, but I’ll repeat in case you didn’t see it the first time.

The short answer is to subscribe to

http://www.mattcutts.com/blog/type/googleseo/feed/

instead of my main blog feed at

http://www.mattcutts.com/blog/feed/

This trick works with any category, so you could (for example) subscribe to my Movies/Videos category by clicking on the “Movies/Videos” category over on the right-hand side of my blog and then adding “feed” to get http://www.mattcutts.com/blog/type/movies/feed/ . (This trick works with lots of WordPress blogs, by the way. Ain’t WordPress great?)

Now that you know how to get only the SEO/Google posts, I refuse to be guilt-tripped about doing some non-SEO posts, especially when my top-two traffic posts in 2007 were geek/Linux/iPhone posts instead of SEO posts. 🙂

Formatting USB hard drives for Ubuntu (Gutsy Gibbon)

Recently my home Network Attached Storage (NAS) started acting flaky, so I wanted to back up my data. I picked up a 750 gigabyte Seagate Free Agent Pro drive. Here’s how I fixed a couple annoyances:

1. The drive is formatted with ntfs.

That’s great for Windows computers, but I preferred to format into a native Linux filesystem like ext3 or ext2. Rather than typing commands like mk2efs myself, I installed a wonderful utility called gparted. GParted lets you format and partition hard drives. Type the following:

sudo apt-get install gparted
sudo gparted

GParted is pretty intuitive, and it looks something like this:

Gparted screenshot

If you’ve just plugged your drive into the computer, unmount the drive by selecting the external drive (under GParted->Devices) and then doing Partition->Unmount. Then make sure the correct drive is selected (under GParted->Devices again). Once the right device is selected, click on the partition you want to format. You’ll see a dashed box appear around the partition that you clicked (see the picture above where “/dev/sdf1” has been clicked). Now click Partition->Format to . I recommend “ext3” because it’s a very stable file system. Finally, click “Apply” on the menu bar and just wait 3-4 minutes. GParted will do all the formatting for you.

2. Give the partition a label

It’s nice if you plug in an external hard drive and you see something more descriptive than “disk” or “usbdisk”. If you formatted the drive as ext3 in step 1, you can use e2label (from the e2fsprogs set of utilities) to give your drive a persistent name. Each time you plug in that drive, you’ll see the same label for that drive. Attach the USB drive to the computer and use the “mount” command to identify the partition to add a label to. Normally you’ll see something like “/media/disk” mapping to a device like “/dev/sdX” where X is a letter like a, b, or c. Suppose the disk partition that you want to label is /dev/sdf1 and you want to call the hard drive “M1”. Here’s how to do it:

mount
sudo apt-get install e2fsprogs
sudo e2label /dev/sdf1
sudo e2label /dev/sdf1 “M1”
sudo e2label /dev/sdf1

The command “sudo e2label /dev/sdf1” will query /dev/sdf1 to see what label it has. If there is no label, you will get back a blank line. The above command makes the label be “M1”. The final command reads the label back. If everything worked correctly, the final command should return the word “M1”. I’d stick with a short and simple label (under 16 characters, and nothing fancy schmancy like punctuation/spaces).

3. The Seagate Free Agent Pro drive can spin down under Linux when you don’t want it to.

There’s a setting in the hard drive that you can easily modify with the “sdparm” program. Install sdparm with “sudo apt-get install sdparm”. Then imagine that your device is /dev/sdX (again, X will normally be a letter like ‘b’ or ‘c’). Here’s what I typed to see the setting and modify it:

mount
sdparm -al /dev/sdX
sudo sdparm --clear STANDBY -6 /dev/sdX
sdparm -al /dev/sdX

You should see a line that looks like “STANDBY 1 [cha: y, def: 1, sav: 1] Standby timer active” change to “STANDBY 0 [cha: n, def: 1, sav: 0] Standby timer active“. If the drive has already spun down, you can unplug it, reboot everything, and plug it back in. Or the handy command “sudo sdparm --command=start /dev/sdX” might also wake it up.

The “-6” is a fallback for some older types of drives and I think it’s pretty safe to include on sdparm commands.

Further reading on how the Seagate Free Agent Pro spins down:
http://alienghic.livejournal.com/382903.html
http://hardware.slashdot.org/article.pl?sid=07/12/09/0651200

How to dynamically adjust an iframe’s height

Suppose you want to include a child iframe on your page. You’d like to resize the height of the child iframe so that it doesn’t show a scrollbar. That is, you want something that looks like this:

Dynamic i-frame height example

Here’s one way you can do it. First, make the iframe that you want to include. I made a file “child-frame.html” that looks like this:

<html>
<head> <title>Child frame</title> </head>
<body bgcolor=”#000000″>

<font color=”#ffffff”>
<p>Child frame.</p>
<p>Child frame.</p>
<p>Child frame.</p>
<p>Child frame.</p>
<p>Child frame.</p>
<p>Child frame.</p>
<p>Child frame.</p>
<p>Child frame.</p>
</font>

</body>
</html>

Now in the parent frame, you can make code like this:

<html>
<head> <title>Parent frame</title> </head>

<body onload=”resizeFrame(document.getElementById(‘childframe’))” bgcolor=”#cccccc”>

<script type=”text/javascript”>
// Firefox worked fine. Internet Explorer shows scrollbar because of frameborder
function resizeFrame(f) {
f.style.height = f.contentWindow.document.body.scrollHeight + “px”;
}
</script>

<p>Parent frame.</p>
<p>Parent frame.</p>
<p>Parent frame.</p>
<p>Parent frame.</p>

<p>
<iframe frameborder=0 border=0 src=”./child-frame.html” name=”childframe” id=”childframe”>
</iframe>
</p>

</body>
</html>

You can also see a live example of resizing an iframe height dynamically.

What does this code do? When the body of the parent frame loads, it looks up the document element “childframe” which corresponds to the iframe. Then the page calls a function resizeFrame(). The function sets the height of the frame to be the scrollHeight, which effectively removes the scrollbar.

The only tricky bit is the “frameborder=0 border=0” attributes on the frame. If you leave off the frameborder attribute, Internet Explorer will assume that the frame should have a nonzero border, but it won’t include the frame border in the value it returns for scrollHeight. The net effect is that IE will show a scrollbar unless you add “frameborder=0”.

It always annoys me to dive into cross-browser development when it feels like things should be standardized. Looks like it annoys other people too.

Anyway, feel free to rip on my code in the comments, but I was looking for a simple, working example of setting an iframe’s height so that the iframe wouldn’t have a scrollbar.

css.php