Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: open source

  • Why Does The WordPress Background Auto-Upgrade Work?

    Why Does The WordPress Background Auto-Upgrade Work?

    Way back in the stone ages I wrote an explanation as to why the WordPress Upgrade didn’t work all the time. In that post, I pointed out that servers and your installs are special snowflakes and not all the same, and that’s why an upgrade doesn’t work all the time. I’m amused that no one pointed out to me that stance (one which I still maintain by the way) seems contradictory to my proclamation that we should love the built-in updater as of WordPress 3.7.

    Allow me to challenge myself.

    Your server, with your install and your plugins and theme and tweaks, is still a special snowflake.

    The background updates for WordPress keep this in mind.

    Oh, I have to go further into this? Fine. The reason the updates are restricted to just minor, security/maintenance, updates is that, in general, they do not cause the problems people experienced 2010. It’s been three years. We’re smarter, we learned a lot, and most importantly, if the problem in 2010 showed up again, WordPress would not to install. I heard the sounds of brakes screeching. Let me explain. We want WordPress to not install itself if it can’t. We’re not defining that as a ‘failure’ because while your install did fail to upgrade, your site didn’t break.

    Let’s get the down low from the man himself:

    Those seem pretty straight forward. WordPress 3.7.1 was made so that a failure to update didn’t break your site, because if it couldn’t apply the install, it would rollback seamlessly to 3.7 without you noticing. Well, except for the email you got to say “Hey, this didn’t work, man. Sorry.”

    Why does this work and the major upgrade does not?

    That’s the real question, isn’t it? Why are we having such a monumental success for 3.7 to 3.7.1, where we didn’t from 3.6 to 3.7? Actually, we did, but you’re not comparing the right things.

    First of all, the 3.6 to 3.7 upgrade is one of the more stable ones we’ve had in a while. 2.9 to 3.0 was the birth of my OMGWTFBBQ!!! post in the forums (and the catalyst for why I’m working for DreamHost). It was a major overhaul, with a lot of changes, and a lot of complicated tweaks. Let’s be frank, it was a re-write of a crap-ton of modules, and it was just going to break things. WPMU folded into WordPress and changed to Multisite? Yikes! But as time has moved on, I’ve been reporting more and more “Everything’s okay in the forums.” This does not mean everyone is perfectly happy and perfectly safe, and the upgrades were a 100% success. We have the same type of complaints as we always have. Themes and plugins were not robustly tested enough with the new release, so they broke when the upgrade happened. This is (currently) unavoidable.

    So again, why is this working so well?

    Three Nacin MoonBecause the core team who wrote the update script learned from their mistakes in the past. The changes made in WordPress may be bold and large, but they’re also done carefully. Instead of just saying ‘What’s done gets into the new version,’ 3.7 took the ‘feature teams’ trend started a few releases back to the next level. Only if the feature was done-done did it get into 3.7. This meant that while we did not have a major ‘feature’ this release (like we did with the Media Release in 3.5), we had the opportunity to make each feature rock solid on it’s own. And this worked better than many expected because of “features as plugins.”

    While some aspects of core have to be developed in core, others begin their lives as plugins. Like the password-strength improvements and auto-upgrades were both plugins before they were added to core. Also if you look at 3.8, pretty much every major feature that can be a plugin is one. This means that one feature, a new post editor, didn’t make it because right now it’s not ready. Having things be plugins also lets more people test them, by installing the plugin without having to upgrade to a beta version of WordPress!

    Finally, and this is really important, not everyone gets upgraded at the same time. Within 24 hours of the release of WordPress 3.7.1, only 75% of English installs were updated. This was done to keep an eye out for load issues on WordPress.org’s boxes, but also on shared webservers. Which by the way are doing just fine. As we go forward, Nacin’s said he expects this to be sped up, especially for a 100% security release.

    How does it work? Glad you asked! The best explanation I got at this was over beer with Nacin, and sold me. At 7am and 7pm your site pings WordPress.org to see if there are updates. When this happens, your URL is hashed into MD5. Then the first three letters of that is converted to a base 10 number (MD5 being based on base 16, which doesn’t do you any good unless you have 6 extra fingers) and that’s used to decide if you get an update or not. The cool part of this is that it can be used to push to only one out of four thousand sites.

    I know this is all probably sounding like fan service. Like I can’t see anything wrong with this. Nothing is perfect. I’m well aware that things can break. I’m well aware there are possibilities like WP being DNS highjacked, or a plugin circumventing the updater. But. If the DNS is jacked, the API just won’t work unless the jacker has a duplicate that works. And the evil plugin would kind of have to do the same thing, or they would only be able to impact you when a natural upgrade occurred. And neither of those are actually related to background updates. They could have happened at any time in the past. They could happen tomorrow.

    Why do the upgrades work?

    Because WordPress grew up.

    And that’s pretty cool.

  • Give Back Or Die

    Give Back Or Die

    One of the things I hate in the world is people who don’t give back.

    USSR Socalism PosterI call myself a software socialist because I strongly believe in giving back to the things that make me successful.(This is, in no way, a blanket approval of everything Socalist. Snarky political comments may be deleted.) This is why I give back to WordPress, spend so much time on it, and so on and so forth. Thus, it’s logical (or at least internally consistant) when I say that the part about WordPress that I hate is people who take and never reciprocate. More than this just being a pet peeve, though, people who do this with Open Source code are biting the hands that feed them, and it’s terribly frustrating to watch.

    Look. You get this totally awesome software for free. People volunteer (sometimes we’re compensated, sometimes not) to make it better, safer, more secure. And we give these updates, again for free, back to you to make a living from. That gives all of us ownership in the software and a responsibility that I see a lot of people dropping the ball on.

    So let me state this for the record: If you use a product that is free that enables you to make your living, and you do not give back in some way, you annoy me.

    I’m going to use Mediawiki as an example here. I cut my teeth on it, which is something few of you know. I’ve been using it longer than WordPress, as a self-hosted Wiki install. I learned about caching tools not because of WP, but from Mediawiki. I learned about config files and extensions, and why you never edit core files, and theming all from Mediawiki. It’s safe to say that had it not been for my foray into that world, I’d never ever have been the WordPress Guru I am today.

    At the same time, I have never once given a single line of code back to Mediawiki. I’ve probably reported no more than 5 bugs in my lifetime, and it’s not because they don’t exist. I actually do know how to do more than just theme in Mediawiki, I know how to trace a bug and fix it, but given my use-case of it it’s been pretty rare that I’ve even had to report it, because every time I’ve found it already handled in the next release.

    By the way, the whole reason I mastered Git? Mediawiki. I needed an easy way to upgrade and keep up with a trunk release that fixed a critical bug for me.

    Wikimedia Foundation LogoBut if I don’t give back code, do I annoy myself? Nope! Much like WordPress has a WordPress Foundation, Mediawiki has a Wikimedia Foundation. And yes, I donate money.

    And this is my point. We’ve already proven that sponsored software can work. At the time I wrote this, Aaron Jorbin’s charge to raise money so he could work on Post Formats was a couple hundred from goal. I’m confident that by the time this is posted, it’ll be met. (I’m also confident the Indians will sweep the White Sox, so Aaron, you can do your ten support tickets for Post Formats if you want. If they lose, I’ll patch something for your plugin.)

    The point is simple. Giving back is not just code. I talked about this at WordCamp Portland, and I talk about it all the time. You don’t have to code, or file bug reports, all you have to do is be here and do something for the community at large. Heck, if you want to help clean up after a meetup? You gave back!

    So please, don’t be greedy. Give back to open source. Don’t just take and take and then complain it’s not everything and more. Do something, anything, that helps someone else. Even if you’re doing it altruistically, you’re not living in a vacuum.

  • To Fork Or Not To Fork

    To Fork Or Not To Fork

    ForkinRoad Sometimes the question you have to ask yourself is if you should fork. With a plugin, this is a fairly easy conversation. You want functionality, the original author doesn’t, you fork. But when you look at a theme, you start getting into messier territory.

    In many ways, a theme is ‘simpler’ than a plugin. Theme devs, don’t shoot me! What I mean is that a plugin can be or do anything, but a theme is always a theme. While it may change how your site looks in amazing ways (and I am constantly in envy of people who can visualize like that), it really is just a theme. This is why reviewing themes is easier to monitor and manage than plugins. But that’s another conversation. The point here is that when you want to extend a theme, you make a child theme. Done.

    What happens when you’re already using a child theme, though? StudioPress, a theme shop I love, makes child themes and sells those. This site is using a child theme, though it’s currently one of my own devising. Previously, it was using a child theme called Streamline, however, and it had a lot of changes.

    So when do you make a child theme, and when do you extend it in other ways? It really depends on what you’re doing. While I sat and tried to figure out where my personal breakpoints were, I realized that since the best themes know they are a theme, and not a plugin, it was really easy. A great theme lets you seamlessly use a plugin to add in functionality. They may even tell you what the best ones are. Recently, Coen Jacobs wrote about how good themes never bundle plugins and he’s right. A plugin is a plugin, a theme is a theme. Keep ’em separate, keep ’em safe.

    I’ve done it in three different ways for three different sites, and I’ll explain my rational below.

    The Simple

    Fork+in+the+roadOne site is simple. Every ounce of functionality I needed, and more, was in the core code of StudioPress, not even a child theme was needed. All I wanted was to change some colors and add in a couple CPTs and shortcodes. That was easily done via Jetpack, which has a CSS editor, and a couple plugins. Actually, 99% was the CSS, once I sat down and looked at it. All the weird stuff was normal plugins.

    Sometimes simple is a teeny bit complicated, and when that happens, I may make a custom mu-plugin or two, but in general, not so much needed unless I want a Custom Post Type. And anyway, I never put a CPT in my theme if I can help it.

    The Complicated

    On the other hand, one site is hella complex. I found a theme I really, really, liked. Almost. And worse, this was a child theme. It was exactly what I was afraid of. There was no way I would get what I wanted out of this theme unless I edited the functions.php file, a lot of the CSS, and a ton of the images. Could I still have done this via CSS and a couple plugins? No. Well, the CSS yes, but not the code. I had need for some crazy functions, a total re-write of comments, and the list went on.

    In this case, I forked. I ripped out the small amount I never wanted. I added in the medium amount I did want. I directly edited the theme’s CSS, added in a post template, and changed all the images to my chose color. I even added in a different font. Could I have re-written from scratch? Of course, but the theme had 90% of what I already wanted to do.

    There actually is a step before forking, and that would be using plugins. I know I mentioned plugins before, with the simple themes, but actually most theme frameworks are extra special. They often have custom plugins like Simple Hooks, which fundamentally lets me do everything I might do in a functions.php file for that theme. This means most of the time, I don’t fork. But. This theme really was so complex that I needed more than just the simple hooks. Genesis Complex Hooks may have done it, or another plugin to make a transient functions.php (ala CSS editing). And that would have done it except for when I wanted to change a lot of images, add in JS, and then a custom page template …

    Well you see how it goes. The point here, however, is that I sat and thought about it, studied my setup, and made a long term decision. Originally I was using the plugin way, but when it stopped being extendable, I decided to do this, and I regret nothing.

    Fork_In_The_Road

    The Original

    The last option I had was I theme I kind of liked, but it was old. It was pre-HTML5, it didn’t have microformats, but more-over, it wasn’t aging as well as I would have liked. I made a list of what I liked about it, what I didn’t, and what I really wanted. While the list was short, it was also clearly not going to just be CSS. I wanted a custom front page, an extra page template, images, and Genericons built in. In short, I wanted this theme to be something that could carry me onward, regardless of a plugin, even one I wrote.

    I have not made my own, 100% from scratch, child-theme in a long while, and this one may not really count since I was designing it to look like something else. This took me an afternoon to bang out the basics, and a couple days of minor fixes here and there to perfect them. Release and iterate, as they say. Certainly, I could have taken someone else’s theme, but it was going to be a surprising amount of work to do that. Instead, I made a list of my needed features and my desired options, and went to town. It’s still a pretty simple child-theme (which speaks well to the inherent extensibility of the parent), but now it’s mine, and it’s easy to extend it and expand it.

    The Rest…

    What about you? What do you think about when deciding how to handle a theme that needs changing?

  • Not RSS 2 Email

    Not RSS 2 Email

    37679586Back in 2011, I made an RSS powered email list using rss2email. The last new version was released that year, and while the last two years have worked perfectly well, there’s one small problem. The developer appears to be done with it. This happens, and the beauty of open source is that people can pick up the code, fork it, and carry on. The annoyance is that sometimes the new coders do things that break it all for you. In this case, the running fork of rss2email uses Python 3.2 or higher.

    If you’re using Python 3.2+, grab rss2email the new version and off you go! But if, like me, you’re on a server that doesn’t come with that version of Python, you can start swearing. This is not something you can just upgrade, either as Daniel Eriksson explains how to do this on CentOS 6 (my flavor). Many different flavors of Linux use the old 2.x branch of Python, and there are no plans I’ve seen to upgrade any time soon.

    Now I’m faced with a dilema. Do I mess around and upgrade on my own, or do I find another answer. You know I went with option B, right?

    I sat and thought really hard about what I, personally, needed this to do. This is a key component to any code you’re going to write. Make sure you know what you need. Let’s break things down:

    Needs

    • Email to be sent to a specific address automatically when there’s a new post.
    • No email sent on pages or CPTs
    • Post ‘excerpt’ is message content

    Wants

    • Change ‘to’ email on the fly.
    • Select full post or post excerpt in email
    • Customize ‘from’ email address

    Dream Future

    • Ability to say “no, not this post”
    • Customize email message
    • Allow options for different post types to get emailed

    That’s pretty simple, isn’t it? It’s clear cut what I need, what I want, and what I’d like to have if I have time. Not every project is this simple, but today it is.

    I actually knew how to do my ‘needs’ already, but as soon as I tested it I found I had to expand on what I meant by ‘when there’s a new post.’ If I hooked into the publish_post action, the email got sent every time a post was updated too. This lead me down to Notifly, which emails a list of people for every post and comment, but not post updates. That gave me the magic of transition_post_status, which solved that first problem.

    At this point, the question became “Why not just use Notifly?” The first problem I had was that it sent out emails for comments too, with no easy way to turn that off. I could have forked, and I started looking into that when I ran into problem two, which was I couldn’t change the ‘from’ email. This was something that became a bigger issue later, when I realized I needed to be able to change the from email to work better with restrictions on certain hosts and with certain mailing lists. I could still edit the plugin, but I looked at what that plugin did and what I needed and wanted. Editing Notifly to do what I wanted would mean overcomplicating it and adding a lot more options. I could fork it, but I’d be stripping everything out and rewriting if I did that, so I decided to carry forward with my own thing. I would say the plugins are similar, cousins, but approach the goal in different ways. Semantics, I know.

    Once I mastered only emailing on post publish, I had to tell it not to email on non-posts. No emails being sent on CPTs and pages was easy and I could have used is_post_type() and checked for posts, but I decided to use get_page(), because that let me expand on some other features later. This was new to me, but since I wanted to use the post excerpt, this was going to be, bar none, the fastest way to pull that in.

    While I love being able to read whole posts in my RSS reader, I lose a lot with it, in regards to formatting. For the site I desired to run this on, the layout is a huge thing. On top of that, thanks to some idiots, I had to turn on hotlink protection, lest they crash my server again. Also I use a lot of embedded media (HTML5 video, twitter, etc). That means the ‘whole’ post generally looks like crap. So for every single post, I custom craft an excerpt. And this is why get_page() was awesome, because I could use that to pull the excerpt.

    EmailsThe default WordPress emails are sent from ‘wordpress@yourdomain.com’ with the name ‘WordPress’ and while that’s great, I wanted mine to be sent from ‘Blogname’ (the email address was fine, I’ll just add it to the email list as a moderator). That changed my ‘want’ of being able to customize the from info into a ‘need’ but it was also pretty easy to do.

    If I was only going to use this code on one site forever and ever, I’d probably leave it at this. But … I know I’ll want to use this around other places. I started by looking at my ‘wants’ and put those in as well.

    So what did I end up with?

    Post2Email

    This is a simple WordPress plugin that lets you set a to email, a from email, and a from ‘name’. It uses the RSS settings to determine if your email body is the full text or the excerpt. It only emails on posts, not pages or CPTs, and not for private posts. You can only set one email because of reasons, first being I only need to send to one address, but second is that I really hate when people send me emails I don’t want or need. Limiting the number of emails you can send to will help that. It also helps you not piss off your webhost by spamming people. Seriously. You use my plugin to spam people, I will hurt you.

    What about my dream features? Handling the different post types means using get_post_types(), which isn’t horrible. In theory it’s just a check ‘If the option for that post type isn’t checked, fail out.’ It’s not something I need, and I really don’t feel like auto-emails for everything is a good idea (pages and CPTs are not posts!), so I’m going to wait and see if this is a need for people.

    Flagging per post I have no idea how to do, since I don’t yet know how to put a custom post option like that per-post and check it on publish. Yet. Since public posts are public, I think that it’s fine having it email on all public posts. Opting out like that is not for me, but if enough folks come up with it, I’ll consider it because it’s a good excuse to learn something new.

    Customizing the message is easy and when I went back in to fiddle with internationalization and proper content serialization, I added it in. I also went and used wp_parse_args to remove setting the defaults in the database, and make it easier for me to add more options in later.

  • Personal Version Control With Git

    Personal Version Control With Git

    Git RelationshipsOne thing I am personally bad at is version control. Oh, don’t get me wrong, I’m great decent at it for code at work, but I still have a tendency to cowboy code. Bad me.

    Part of why is that I don’t want to have my stuff public. At the same time, I don’t want to pay Github while I’m learning, and I want a GUI. Why not overcomplicate my life! I’ll add on one more, I want a website where I can look at my changes all pretty like. Last time I did this via SVN, hated it, never used it, and walked away. This time I decided to use Git, and once I started using it via the command line, I realized how freaking awesome this was. And since I’m using CLI, I ran git config --global color.ui true to get pretty colors.

    I should note that I use Coda2 by Panic and I love it. But. It doesn’t have an easy way to properly branch and tag in SVN or Git, which is something I’m used to having. And my master plan is this. Master will have the ‘live’ real code. The branches are releases. When a branch is ready to go live, I merge it with master.

    So let’s get started.

    Stage One: Install Git

    I followed Gits official directions for installing Git on my server, so once you’ve got things like that up and running, it’ll be time for the webpage.

    Cart comes after horse, though. I had a hell of a time getting my own SVN crap up and running, but git was way easier. There was far less to mess with to install, since I’d already done it before. With Git, I don’t need to mess with svnserve or daemons, since git isn’t the ‘server’ where my code is stored, it’s just another repository/clone. It breaks my head sometimes, but this is a case where it’s going to be easy. Install any Git dependencies (on CentOS that means I ran yum -y install zlib-devel openssl-devel cpio expat-devel gettext-devel ) and then install from command line:

    cd /usr/local/src
    wget http://git-core.googlecode.com/files/git-1.8.2.2.tar.gz
    tar xvzf git-1.8.2.2.tar.gz
    rm git-1.8.2.2.tar.gz
    cd git-1.8.2.2
    
    ./configure
    make
    make install
    

    Done, and now I’m on 1.8.2.2. Upgrading is as easy as doing the wget again.

    Stage Two: Make Repositories

    At this point, the official git directions say you should make a git account, but after some pondering, I decided to put my repos in /home/myuser/gitrepos/ so I can easily add my repositories to my local computer. Everything is locked down via RSA keys anyway, so I can secure connect from my computers and everything is basic and simple and safe. If I want to make more repositories for other accounts, I can do it as a one-by-one basis. Right now I have no need for group stuff, this is a me repository after all. If I did, I’d use git’s directions for making a git user instead.

    I made projects for my domains (ipstenu and jfo) and then one for my server (mothra). I hooked into them with Coda2, which is my app of choice, and I tested that I could get and push files. I’ll come back to this in a second.

    Stage Three: Webify it!

    Next up was webifying things. I want to do this, even though I’m putting it behind a password, because I’m visual and being able to see what I’ve got going on is helpful to me. I went with GitList because it looked nice. The drawback to these things is that if I used a shared repository (say /home/gituser/gitrepos/ for example) then I’d have to web-alias to the gituser instead of having it hosted as ‘Ipstenu’ … which is okay. If I was really making a full blown shared group, I’d probably buy gitstenu.org and point it there.

    My Gitlist

    Awesomesauce! It works! Except for this error Unnamed repository; edit this file ‘description’ to name the repository. That’s easily fixed on the server by editing the description file.

    Those initial repositories are for my non-public files, actually. That’s where I keep copies of the obscure shell scripts I run, stuff that isn’t web accessible. After I got those set up, I made repositories for my themes and my mu-plugins. This gave me folders like ipstenu-mu-plugins and jfogenesis-wp because I named the theme ‘jfogenesis’ for WordPress, MediaWiki, and ZenPhoto. Still this let me progress to …

    Stage Four: Control

    The whole reason I did all the rest of that was so I could do this, which seems redundant, but bear with me.

    1. I checked out all the code locally, edit it, and push it back up to the repos on my server
    2. On the webserver, I check out the code with a simple git clone to folder2 (trust me)
    3. switch folder and folder2 (you know how to move things)
    4. Checkout the new code with a git pull. If I want to checkout a specific version, it’s git checkout -b mysite-REL_1.0 origin/REL_1.0(It’s worth mentioning that I made a branch for everything at the start as REL_1.0 because reasons.)

    And that’s it.

    Stage Five: Updates

    Here’s my current process.

    Locally, I start work on my new version so I make a new branch: git checkout -b REL_2.0

    Edit my files and add and remove them as needed:

    git rm <filename>
    git add .
    

    Check them in when I’m done with the files: git commit -m "Editing foo and bar, replacing baz."

    When I’m ready with it to be tested, I push it: git push origin REL_2.0

    Everything tests well on the dev server(Just pretend there is one.)? Okay! Let’s merge!

    git checkout master
    git merge REL_2.0
    git push origin master

    Summary

    Since this is just me running stuff, it’s pretty easy to keep track of everything. Having the website makes it easy for me to see what’s I last did and what’s changed:

    Diff Screen

    Again, yes, I put the git website behind password protection. I may change this later, if I determine I never put anything secret up there. But right now, this is good for me. After a couple days of using it, I liked it a lot. Enough that, unlike my foray into SVN, I kept using it. It was easy for me to keep my code organized and up to date. If I had to update ‘live’ I could still use branches easily and roll things back painlessly. That’s pretty darn cool.

  • WordPress False Security

    WordPress False Security

    False Security
    Credit: Grafitti Verite
    I wrote this months before the botnet attack of April 2013, but I kept putting off posting it. Clearly now is the time! So since people often ask me if I do certain things to protect my site, here’s what I don’t and do do.

    What I don’t do

    • Hide the WP version in my HTML
    • Remove readme.html
    • Hide login error messages
    • IP blocking*
    • Use a different prefix for your DB
    • Move wp-config.php*

    I don’t bother with the readme or the WP version because it doesn’t matter. People don’t actually search for ‘Who’s using WP 3.4.2? I’ll attack them!’ They let slip their dogs of kiddie cracker war and bury us in traffic. I learned that lesson with the TimThumb debacle. My server got slaughtered by people not searching for TimThumb, but slinging attacks at me as if I had it installed! Even better? They didn’t bother to differentiate where my install where WP was in a subfolder (domain.com/wp/) and just attacked domain.com/wp-content/themes directly. The same thing happened with the recent botnet attacks. Basically people are going to attack me, assuming I’m vulnerable. It’s only when I’ve pissed someone off directly that I’d worry about having a specific version being an issue. And since I keep up to date with upgrades and patches, I don’t worry so much at all.

    The error messages thing stems from people worrying that failed logins to WP will tell you that you got the username or password wrong. So if I login as Lpstenu, it’ll say ‘ERROR: Incorrect username.’ That apparently spooks people, thinking that if you know that you’ve gotten a right username, you’ll hammer that. Do me a favor. Go to yourdomain.com/?author=1 and what happens?(This doesn’t work on this domain because I created it back when WP defaulted your first user to ‘admin.’ I made a second ID and deleted that one.) That’s how much effort it takes to find your username, folks. It’s even easier when you look at this post and see the author name, and a link to it, right there in front of you. Your username isn’t a secret. It’s dead easy to get. I’m not wasting time hiding something that easy to find.

    That’s not really a valid “security” improvement, anyway. It’s irrelevant whether the attacker knows what he got wrong, as it provides no extra information that would help him to get in. Furthermore, the usernames are exposed in dozens of other places already as I showed you before. I often argue that you can’t remove doors: everyone has to be able to get into a house, so we put locks on our doors as deterrents, and signs up to say we’re watched by ATD or whomever. All of those can be circumvented, and you still have a door. Most crime is prevented by deterrents, however (a sufficiently motivated and skilled person will work around anything), so really all we do is make things inconvenient enough that they go somewhere else.

    Locking CablesPart of security is knowing where to spend your time. Make a better mousetrap and you get smarter mice, true, but if you still want to get rid of the mice where do you start? I start with not hiding the obvious. Here’s my username, here’s my login location. They’re standard on most websites, because people have to be able to log in. Now when I really have a locked down site where I want no one but me to log in, I use .htaccess to limit login to just my IPs. This is a (minor) problem when I’m on the road, but I can always SSH in to fix that. Most of the time, though, I trust in my firewall, my server, and the basic security of WP to be enough.

    IP blocking is totally useless to me. With a caveat. I use CSF and ModSecurity on my server which will block by IP if you hit very specific abuse parameters, including my newer ModSec rules for protecting logins. However I don’t pay much attention to it, save to whitelist my commonly used IPs. The point of the firewall is not to stop people I know are bad, but to dynamically catch them in the act, block them on the fly, and then let that IP gracefully expire after a certain amount of time. Years ago I may have had to use .htaccess for that, manually updating it to block specific IPs, but software’s come a long way, and letting the right tool do that job is huge. If you only have .htaccess, well, you can use some .htaccess protection of logins, or you can use Perishable Press’s 5G Blacklist. As I tell people frequently, you never know where legit traffic is coming from, don’t be foolhardy.(True story. A customer at work insisted he did too know better, and blocked China and India traffic. Then he went there on vacation and was pissed he couldn’t log in. Yes, I mentioned I had warned him before.)

    Curiously controversially, I don’t mess with the DB prefix. I use wp_ much for the same reason I never move my wp-content folder unless I’m using CDN (and even then…) : Poorly written plugins and themes will kill me, and people can view my source code or use DB insertion calls in their code. They don’t have to know my prefix, and in fact, best coding practices are intended to work no matter where the folder is or what you use as a prefix. The other reason is I’m exceptionally lazy, and the less I have to remember that I did ‘differently’ in case of an emergency, the easier my life is. This is important when I’m ever hacked (yes, when), because I can restore faster from scratch if I didn’t go nuts reinventing the wheels or moving things around. Rebuilding a wp-config.php is very easy if I only have to change passwords and user IDs, after all.

    Similarly, I don’t move my wp-config.php in most cases. I do on my localhost instance (so I can wipe the folder and DB and start over easily), but really it’s impractical in other situations for me. I think it would be safer to move it out of a web-accessible folder, and when possible I do that (sometimes I have WP in a subfolder) but I have other things I can do to protect that file.

    What I Do

    Besides a massive amount of work keeping my server up to date and tuning my firewall, I do some things that anyone using WordPress can do:

    Stupid Security

    • .htaccess protect wp-config.php
    • Lock file permissions
    • Prevent plugins from writing to wp-config.php and .htaccess
    • Prevent folder content browsing (for images mostly, but also plugins)
    • Use strong passwords for WP/FTP/SQL accounts
    • Use one-time passwords for WP/SQL/FTP/SSH accounts

    I protect my wp-config.php from direct access with a really simple .htaccess directive:

    <files wp-config.php>
    order allow,deny
    deny from all
    </files>
    

    I think nginx is this:

    location ~* wp-config.php { 
        deny all; 
    }
    

    This means you can’t see https://halfelf.org/wp-config.php in your browser. It’s pretty minor, in so far as things go.

    I lock down my file permissions as tight as I possibly can. Nothing is set to 777, and my .htaccess isn’t writable. This means if I use a plugin that wants to edit my .htaccess (or wp-config), I have to do it manually. This is good, in my opinion. I always know exactly what I’m doing. In my .htaccess I also have Options -Indexes, which stops people from being able to browse empty folders (this is important for plugins that don’t have an index.php file). Since I’m using SVN and Git, I also prevent people from seeing those:

    	RewriteRule ^(.*/)?(\.svn|\.git)/ - [F,L]
    	ErrorDocument 403 "Access Forbidden"
    

    My passwords are stupid complex. I haven’t the foggiest idea what they are thanks to 1Password. I also don’t reuse passwords. This is very important for how my server is setup, as DSO requires you to enter in passwords to upgrade WordPress. While I can use my main account, I actually created an FTP only account for each and every website on my server, and then I hard coded that (and it’s password) into my wp-config file. So yes, I have a DB password (each account is used once for each DB) and an FTP password (again, one account for each account) in my config. And no, I’m not worried about that. Sometimes I have a generic SQL ID for all DBs under one account, though that’s a tiny bit more risky.

    But, most importantly, I try to cure myself of being stupid. I don’t log in to my site via non-secure ways (SSH & SFTP only). The passwords I use for my login (which is not SSL protected on WP) are one-account/one-use. I try never to log in on someone else’s computer. I don’t do admin work on potentially unsafe wifi. You see, the greatest security risk in the world isn’t the software you’re using, it’s you. You do stupid things, like recite your credit card info (or password) over your cellphone while on a train trying to get your host to reboot a server. You use Starbucks’s wifi to pay your bills. You talk about how your mother changed her name.

    Social engineering is way more dangerous than any server hack, and when it’s down to the wire, that’s what I’m more worried about. After all, I have good backups of my files.