SSL detection by PHP scripts run through FastCGI on nginx

How’s that title for acronym soup?

I ran across this issue when playing around with nginx. I was trying to set up phpMyAdmin for SQL administration, but ran into a rather peculiar issue. To explain the problem, let me give you some context.

I’m running nginx only on port 443, using SSL for everything. As I’m going through the setup for phpMyAdmin, imagine my surprise when it alerts me that I’m not using an SSL connection. In fact, it’s impossible for me not to use SSL, because there’s no regular HTTP server running on port 80. I continued with the setup anyway, checking the ForceSSL option which requires all phpMyAdmin requests to be done over SSL. When I finished installing it and tried to log in, I got a Firefox error that it was stuck in a redirect loop.

Much Google searching later, I still couldn’t find the problem. This was when I remembered that PHP is configured differently on nginx that is typically done with Apache. With Apache, many people use the mod_php module that compiles PHP support directly into the server. With nginx, you generally process PHP requests using FastCGI.

I wondered if perhaps the fact that the connection was taking place over SSL wasn’t being passed through to the FastCGI process. If that was the case, the phpMyAdmin setup script wouldn’t know it was being invoked over HTTPS, and when you tried to log in it would try to forward you to the HTTPS url, which is the same page you had just requested. That would push you into an infite redirect loop.

In fact, that’s exactly what was happening. You can fix this with a simple addition to your nginx.conf file:

server {
    listen 443;
    ... more config here, include SSL ...
    location ~ \.php$ {
        ... FastCGI config here ...
        fastcgi_param HTTPS on;
    }
}

That fastcgi_param HTTPS on; line does the trick. Now the PHP script knows it’s being invoked over SSL and doesn’t try to infinitely redirect you. Awesome.

Fedora, you need some slimfast

Let me get this out of the way up front. I absolutely love Fedora to death.

It’s my favorite distribution of linux by far, and I’ve played with a lot of different distros. I love the way way it works, I love how it’s on the bleeding edge, I love how things are laid out and they just make sense. I love the massive repository of almost every piece of software I want to run right at my fingertips. I love being able to type

# yum install package

and it just works. Absolutely fantastic. I’ve been a user since Fedora Core 3, and the team just pushed out version 11. Good job, guys.

But there’s one thing nagging me about the distro. I almost never notice it, but I’ve been running a lot fresh installs of Fedora lately, so it’s become pretty obvious to me. If she asks me if she looks fat in her Leonidas dress, I’m going to be honest and say yes.

Now let’s give it a fair shake here, it is, after all, a distro designed for desktop use. It’s aimed to be usable to folks who might be trying linux for the first time, and it’s stellar for that. But that comes at an expense to us power users on occasion.

About half the time or more I use it as a GUI-less server, so I’ll be the first to admit I’m probably using the wrong tool for the job, but I just can’t give it up. She makes a great server distro too…

Except for the fat.

I just did a fresh install of Fedora 11, and I challenged myself to configure it with the absolutely minimal set of packages I needed. No desktops, no windowing system, no crazy text-based packages either. I unchecked all the unnecessary WiFi drivers (all of them, I don’t have wireless on this machine) and really slimmed it down to the bare, bare essentials.

Or so I thought… it still installed a whopping 600 packages and takes up almost 2 gigs worth of space. I realize 2 gigs might seem like a small number, but I’m provisioning an old box that uses a 20 GB hard drive. I’d like to see a ~500 MB install rather than have it take up 10% of the disk for the OS alone.

As the package installs were flying by, I tried to get a glimpse of what on earth was taking up so much space. One package that caught my attention was the Leonidas wallpaper pack. Really Fedora? I didn’t even install a desktop or windowing system and you’re installing wallpapers? What am I going to use those for?

My guess is that they’re just standard packages included with every installation, but that doesn’t make much since if it offers me the ability to install without a desktop or X Windows. Perhaps some more intelligent package sorting is in order.

Thankfully I’m not the only one that’s noticed.

One of the planned features for Fedora 11 was a new Minimal Platform, which would install the bare minimum package set to get up and running, allowing you to bring up exactly what you needed with yum. When I originally read about it, I was ecstatic.

But alas, after realizing how much package culling it would require, dispute over where the option should appear in Anaconda (the graphical installer), and a general feeling that it wasn’t critical, it was pushed to Fedora 12.

Crap.

I guess I’ll stick with her… for now. Maybe I’ll hit the gym and see if she gets the hint. It’s just not good for your health Fedora, you’ve gotta drop some of that heft.

Using a file as input for iptables-restore

I deal with headless linux boxes a lot, and one of the first things you always want to do is configure your firewall. The general rule of thumb says to deny all traffic and only poke holes where you need them. It’s an awful pain to configure iptables one rule at a time from the command line. It’s also a pain if you need to open one more port before that deny-all at the end of a chain, because that involves running through the whole chain again.

Now there’s probably some clever “iptables ninja” way to do it, but I prefer simplicity, so I use the iptables-save and iptables-restore commands. The first will dump your current firewall rules to standard out. The second will read rules from standard in into the firewall table.

For reference, my distro of choice is Fedora, so these commands are Red-Hat-centric.

Using iptables-save to dump your rules to a file is simple enough. Just redirect standard out to a file. Don’t forget to run it as root.

# sudo iptables-save > ./firewall.rules

Open up that file in vim (or a less worthy text editor… take that emacs!) and you’ll see it’s just a list of iptables commands. Perfect. Just drop in the new rule where you wanted it.

Reloading the firewall table from this file is a little more tricky, though. Specifically, iptables-restore takes input from standard input, but mysteriously doesn’t work when you redirect standard in from a file with the < redirector.

The solution? Call the plumber! Using the piped output from cat works just fine. Don’t forget to flush the firewall rules before you read them in again, and run both the iptables commands as root.

# sudo iptables -F
# cat ./firewall.rules | sudo iptables-restore

Now double check to make sure that the firewall configuration is really what you think it is.

# sudo iptables -L

Lastly, save the firewall configuration so that it persists after a reboot. If you skip this step, your old configuration will come back when the iptables service starts next time.

# sudo service iptables save

For good measure, I always like to restart the iptables service to verify that it will come back up using the config that I expect.

# sudo service iptables restart
# sudo iptables -L

All done! Not to painful, right? This is also a great way to backup your firewall config. If anything bad happens, you need to reinstall iptables, or you’re provisioning a duplicate server, just run the back half of this process with iptables-restore and your backed up firewall.rules file.