Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • Cookie Free Domains and CDNs

    Cookie Free Domains and CDNs

    After I dropped Cloudflare I went back looking at other ways to speed up my site and what could I optimize things. As I mentioned in Static Content Subdomain, one of the benefits of that mess was to allow me to have a cookie free domain and, in having a cookie free domain, I basically made a domain that could be used as a CDN for my (mostly) static files.

    It was noted then that, if you’re a non-www person, you have to actually use a separate domain. I do. I hate www in URLs. So I picked up a free domain for the site where I’m doing all this: ex-static.com. I probably could have gotten it even shorter if I’d tried sitecdn.net but that was short enough for me.

    Since I already had everything over at /home/user/public_html/static I created an add-on domain in cPanel and told it to use that as its home.

    Then I ran a search/replace on WordPress:
    wp search-replace static.example.com/wordpress ex-static.com/wp-content/uploads
    wp option set upload_path /home/example/public_html/static/wp-content/uploads

    Since I’d already changed my media settings, that was all I needed to really run a replace. It changed my media settings too! Since I was planning to move my static content, not just images, I changed the path too, so I had to go back and change upload_path as well, but wp-cli is my friend.

    Next up, because of the static content move, I copied my wp-content folder over and added this to my wp-config.php:

    define('WP_CONTENT_DIR', $_SERVER['DOCUMENT_ROOT'] . '/static/wp-content');
    define('WP_CONTENT_URL', 'http://ex-static.com/wp-content');
    

    Boom. Everything’s where I want it.

    Sadly, it got messy for MediaWiki and ZenPhoto. The later doesn’t allow you to move your themes folder at all so I made a symlink to /home/example/public_html/static/themes/themename/ and called that a day. MediaWiki was a damn dirty lie.

    Supposedly you can set this:

    $wgStylePath        = "http://ex-static.com/wiki/skins";
    $wgStyleDirectory   = "/home/example/public_html/static/wiki/skins";
    

    As soon as I did that, I got errors all over the place and had to change the directory path back:

    $wgStyleDirectory   = "$IP/skins";
    

    Weirdly named, $IP is set as follows:

    $IP = "/home/example/public_html/wiki";
    

    I did the same thing as with ZenPhoto and made a symlink then I could change the style directory.

    Lastly (and this was last for a reason) I changed my .htaccess rule:

    # CDN
    <If "%{HTTP_HOST} == 'example.com' ">
            RedirectMatch ^/static/(.*)$ http://ex-static.com/$1
    </If>
    

    This was last so that I could not break things mid-flight. And I added in this:

    # CDN
    <If "%{HTTP_HOST} == 'static.example.com' ">
            RedirectMatch ^(.*)$ http://ex-static.com/$1
    </If>
    

    Everything works as expected. And? I have cookie free domains and I’m ready to move all my data off to a CDN whenever I’m ready for that step. The CDN would only have to cover the ex-static.com domain, to boot!

  • CloudFlare Experiment Ends Weirdly

    CloudFlare Experiment Ends Weirdly

    I ended up turning it all off for one reason only.

    I keep getting a 522 error on cloudflare.com.

    Now. I have a working theory that it happens when I’m hitting my own site a lot (be it for development or as recently, a lot of traffic I need to reply to), but what would happen is I got an error 522 on my sites. So I’d go to cloudflare.com to whitelist my IP, since their explanation of “This means your site is down” was wrong (site was up, I was ssh’d in at the time), and I’d get a 522 on cloudflare.com.

    Let me roll back to August 1st.

    That night I went to make some changes on my site to the CSS and, instead of turning on Dev Mode in CloudFlare, I did my thing with Git, pushed my changes, dumped the cache of that CSS file, and was prepared to smile at my glory. Nope! I got a 522. This was odd, since I was currently on the server via SSH and the load on the box was 0.3. Naturally I went to support.cloudflare.com to try and see if I’d missed some directions only to get a 522 there as well.

    Track that for a second. I got a 522 on CloudFlare’s domain.

    The possible answers I could come up with, since I couldn’t read any of their documentation, as either my IP was blocked or the cache server I was proxying through was down. Since I could log into the dashboard for my accounts, I went in and tried to guess how to whitelist my IP. I couldn’t find that, so I opened a support request:

    I can’t access support.cloudflare.com because of 522s. My IP is 172.249.156.169 – Is there any way I can get whitelisted?

    I got reply that it was the wrong place to ask, which I don’t think was correct. One of the solutions (per a Google cache of the support page I couldn’t access, hello) said that you could whitelist your IP to see if that helped. Cool. Except I couldn’t get the part of the page to load that told me where and how that was set.

    So I asked for support with the dashboard via the dashboard support panel. Instead I got someone telling me I had to open a new ticket. And he was incapable of transferring my ticket or saying “Hey, you can’t access the right support place, let me make a ticket for you! Sorry about that.” It was akin to telling me to email them to tell them my email was down.

    I fumed. And then I kept clicking until I found the place to enter my IP. I did and magically CloudFlare started working for me! I quickly went and opened a ticket to complain that I couldn’t have a ticket transferred (or made for me), and suggested this:

    If someone’s logged in via the dashboard and they’re getting a 522 on ALL Cloudflare sites, it’s a logical assumption that something blocked them. But if I can log in, the odds are I’m really me, so that should get an auto-whitelist. If that isn’t possible, can it be detected and alerted? “Hey, we noticed your IP is blocked. Would you like to white list it, since you’ve logged in we can be reasonably sure you’re not an asshat?”

    They replied with a standard ‘A 522 means…’ and told me to whitelist their servers on my server firewall. For some reason the email didn’t get to me, so I made a new ticket.

    In this ticket, I had to wait until I got another 522 (end of August) and when I sent in my error ID and a screenshot, I was told this:

    This was a timeout between our cache server and the origin server that hosts support.cloudflare.com.

    I think he actually meant “Our cache server was down.” because at that time I couldn’t get to any CF hosted site until I rebooted my router and got a new IP.

    I don’t really buy this, though, and I think their IP block is too aggressive. I would run into it all the time when I was at a hotel. I’d be reading comments on my own sites and get blocked. And every single time I got blocked, it was from all of my domains and cloudflare.com. Sketchy as hell to me.

    When I added in the problem that ‘always up’ actually meant if your site was down they’d put up a CloudFlare page to apologize for the site being down, I decided to turn it off. It clearly wasn’t helping me as much as I’d hoped.

    This isn’t to say CloudFlare is terrible and you should never use it, just that it proved to be too frustrating for me to want to use.

  • Mailbag: Chocolate Cake is a Need

    Mailbag: Chocolate Cake is a Need

    Adrian in Florida has a long one! I’m going to break it up.

    I watched your presentation about “don’t use WP MU” have decided I shouldn’t use it but wanted to ask your advice on some other things. First I want to start by pointing out re the presentation:

    • I noticed that for the Wordpress.com network sites I noticed the WP toolbar does show on the sites giving them away as network sites except for one, Gigaom (perhaps there is a way to remove it?)

    • For some of us chocolate cake is a need, not a want.

    No, the cake is a want. And I use that example for a reason. We can joke all we want about how we need the cake, but fact is this: We need food. We want treats. If we can be clear in our hearts about needs versus wants, webdev is much simpler. I don’t need coffee. I like it. I can live without it. I don’t want to and choose not to. I can blog without WordPress. I don’t want to. I choose not to. It’s very important to be clear on needs and wants and choices in life in general.

    As for turning off the .com toolbar on Gigaom, I noticed when I visit there’s a blip where it shows the space for the toolbar and then it’s gone. So that suggests it’s CSS fixing itself. But the answer is “They’re a VIP customer and probably paid out the nose for that.”

    1. I just want to learn one theme/framework to make websites with and not change. I had already paid for Elegant Themes to get Divi which is supposed to be customizable and seems to have good video tutorials, before I saw your recommendation for Studiopress. I don’t know how to tell if I should scrap Divi and pay up again for Studiopress. Would you?

    I like Studiopress a great deal. It’s secure, it’s stable, it’s updated responsibly and reasonable, and Andrea Rennick is one of my BFFs. Divi I dislike because of how they handle sessions. But whichever you use is up to you. If you want a free theme to start with, I’d pick up Theme Hybrid. Justin’s code is second to none.

    2. I want to be able to make each page in my Wordpress site show up under its own subdomain. I’ve tried a few plugs like “page links to” which doesn’t work. I saw that there are some plugins that do this for categories. Do you know a plugin that enable each page resolve to a subdomain otherwise do you recommend one of the category plugins over another?

    This stems from his URL design which is page.example.com and … I just wouldn’t. It’s a waste of time and effort and locks you into a categorization that will be insane to unroll later.

    Now as a category that’s less weird and you can try one of these plugins:

    • https://wordpress.org/plugins/subdomains/
    • https://wordpress.org/plugins/main-category-as-subdomain/
    • https://wordpress.org/plugins/wp-subdomains-revisited/

    I still wouldn’t use Multisite unless you really enjoy logging into a separate site for each post and not having an easy way to cross reference.

    3. Is there a plugin out there that allows different people to receive ad revenue for their posts? We have two different writers for one website, each should get ad revenue related to each’s own posts on the same website.

    This is actually why I bothered to answer. This is a cool question and I had no idea at all when I first read it.

    Turns out, yes you totally can have separate ads per author. If you’re using Google AdSense (you didn’t say), then try Multi Author Adense, which looks like you could set the code per author. There’s also Revenue Share which may be a little simpler.

    Good luck!

  • HTTPS and WordPress

    HTTPS and WordPress

    Really there’s a right way and a not-quite-as-right way to handle HTTPS on WordPress. It’s not that hard to do, and if your whole site is going to be HTTPS, then the easiest way is to change your home and site URLs to be https://example.com/ and put define( 'FORCE_SSL_ADMIN', true ); in your wp-config.php file. Then you should (if this is an existing site) search your database for the old HTTP url and change that to HTTPS.

    Seriously, that’s it. That tells WordPress to be HTTPS all the way and you’re done. Of course, that doesn’t actually work 100% for everyone, because there are some silly plugins and themes that do things like this:

    add_action('wp_enqueue_scripts', 'enqueue_google_maps');
    function enqueue_google_maps() {
      wp_enqueue_script('google-maps', 'http://maps.googleapis.com/maps/api/js?&sensor=false', array(), '3', true);
    }
    

    The problem there is they’ve defined the script as HTTP and if your site is HTTPS then you’re going to get mixed content messages. And the real issue here is that means your connection is only partially encrypted! That non-encrypted content is accessible to sniffers and can be modified by man-in-the-middle attackers. This, clearly, is not safe anymore. The right way to do your enqueues is with protocol relative URLs:

      wp_enqueue_script('google-maps', '//maps.googleapis.com/maps/api/js?&sensor=false', array(), '3', true);
    

    Alternately you can just use the HTTPS url, because that won’t break HTTP visits and it won’t make anything less secure.

    But. Since you really can’t go in and edit all your themes and plugins, the plugin WordPress HTTPS is the way to go. That can force everything around. I know it’s not updated in a long time, but it still works. I keep thinking I’ll fork and clean it up… Well in my free time. The point of that plugin is that it lets you force everything to HTTPS, and will rewrite things on the fly. It’s a good idea.

    Instead of using the plugin, I’ve seen a lot of people do this in their .htaccess:

    RewriteEngine On 
    RewriteCond %{SERVER_PORT} 80 
    RewriteRule ^(.*)$ https://example.com/$1 [R,L]
    

    In and of itself, this isn’t wrong. This forces everything HTTP to redirect to HTTPS. The problem is you’re still actually sending data from WordPress over HTTP first, and you’re right back to opening up to man-in-the-middle attacks because the data from WordPress goes from HTTP first and that’s, say it with me kids, insecure!

    Now that said. This should be okay for most things. The POST calls should be sent securely, and all you should see on the return end is everything after that 301 redirect, but we can’t be absolutely sure about this. My buddy Jan used mod_substitute to force HTTPS (back before he moved to nginx). His code looks like this:

    <Location />
     AddOutputFilterByType SUBSTITUTE text/html
     Substitute "s|href="http://example.com/|href="https://example.com/|"
     Substitute "s|href='http://example.com/|href='https://example.com/|"
     Substitute "s|src=\'http:|src=\'|"
     Substitute "s|src=\"http:|src=\"|"
    </Location>
    

    In doing this, he doesn’t need to worry about the HTTPS plugin I mentioned, because it forces everything with a src attribute to be protocol relative. He also doesn’t have to search/replace his content if he doesn’t want to, which makes switching back easier. If you wanted to do that. But as Jan pointed out to me, he switched to nginx because it’s easier and supports variable substitutions.

    Should you use .htaccess or nginx to force https instead of a plugin? That’s totally up to you. I use the plugin since I trust it to only mess with WordPress and not anything else I may have lying around. Also since my domains are often more than just WordPress, it’s a little easier for me to segregate their control. The flip side to this is that WordPress doesn’t redirect http traffic.

    By this I mean if you turn your whole site to HTTPS properly, you can still go to http://example.com/this-is-a-page/ and WordPress will load it as HTTP. This is and is not a bug. WordPress is (properly) trusting your server to tell it what it should be. Your server is saying “Be HTTP or HTTPS! Whatever!” Now there is a trac ticket to have FORCE_SSL really force SSL but that’ll be a while because there are a lot of complications in that change.

    So yes, for now, I would use .htaccess to add an extra later of SSL forcing, but with a bit of caution. If you’re proxying HTTPS (like you’re on a Varnish cache behind something like Pound or nginx) then you may need to use this code for your .htaccess redirect.

    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
    

    The reason for this is Apache can’t always see SSL if it’s not in charge of it (because it’s proxied or handled by a load balancer), and to teach it where it really lives. The trick there is the code I just showed you may not be right because every server’s a little different. There’s a great StackOverflow post on the problems of redirect loops while forcing https that you should read.

    Good luck, and safe HTTPSing!

  • On Site Advertising: Affiliates

    On Site Advertising: Affiliates

    This is related to a series of reviewing on-site advertising I have used: Project Wonderful, Google Adsense, WordAds.

    So what about those affiliates?

    Affiliates are simply links to other sites that earn you money because, after clicking on your link, they buy something. And in my experience, they are never going to be the big money earners.

    I’ve used the following, in no particular order:

    All those links are affiliate links, by the way.

    Unless I’m making a post that has a direct link to them, like I’m discussing them specifically, they don’t get a lot of traffic. The problem is, like ads, where do you put affiliate links for the best traction?

    In a weird way, links like those are why spammers spam links. They trust people will click on the random links and buy a product. If you turn your affiliate links into banner ads, then you can be more successful, but now you just have more and more cluttering up your site.

    This is pretty much why I suck at them, though. I don’t enjoy marketing. I hate the push of sales. The way I buy things is I look around, I ask around, and I test. I know what features I want and, if I don’t, I actually do ask people for help understanding them.

    I’ve read multiple essays on how to effectively be an affiliate, and the advice boils down to what CopyBlogger says about being honest and authentic.

    But I do reviews rarely, which means affiliate links are just these links that sit around and look link ‘powered by’ links, which they really are. I will say that I don’t have an affiliate link for anything I don’t use.

  • Mailbag: Finding A Rogue WordPress Setting

    Mailbag: Finding A Rogue WordPress Setting

    After helping someone track down a weird WordPress setting, he asked the logical question:

    How did you even find that!?

    The issue was that a person was missing the menu option to edit their themes. I asked if they were also missing the menu option for editing plugins. As soon as he said yes, I knew it had to be the define to disable the plugin and theme editor:

    define( 'DISALLOW_FILE_EDIT', true );

    That literally says “No editing files!” So we looked first in the wp-config.php file for it and came up empty. Now as much as we yell at people for editing functions.php or at themes for creating a mess of settings that aren’t needed, I knew the fastest way to find it was this:

    $ grep -R 'DISALLOW_FILE_EDIT' ./wp-content/
    

    And as expected, that gave me a file: ./wp-content/plugins/ninjafirewall/lib/firewall.php

    Since we had wp-cli, I opened that file and looked for the term:

    // Disable the plugin and theme editor ?
    if (! empty($nfw_['nfw_options']['disallow_edit']) ) {
           define('DISALLOW_FILE_EDIT', true);
    }
    

    Then I ran this: wp option get nfw_options

    If you don’t have wp-cli, just pop into the database and look at the option value for nfw_options — either way you’ll see this:

    array (
      'logo' => 'https://www.example.com/wp-content/plugins/ninjafirewall/images/ninjafirewall_75.png',
      'enabled' => 1,
      [...]
      'disallow_edit' => 1,
      [...]
    )
    

    I’ve snipped out a lot of the data, but you can see that disallow_edit is set to 1.

    We had the user change that setting. Imagine that. It worked!

    The moral of the story? Don’t make settings changes without reading what they do!