Struggling to implement PCI compliance
Posted by lloyd on Fri 14 Mar 2008 at 11:00
I'm striving to comply with PCI standards, but I'm running into a wall - due mostly to confusing, out-of-date, contradictory, and-or incomplete documentation. Or maybe just my own dense mentality. Does anybody have any guidance help me walk through the security thickets of setting up my Debian-based web store?
BACKGROUND
I'm setting up a small web store on a remote VPS to supplement my Social Security. The software stack is:
- Debian etch kernel 2.6.18
- Apache2.0.54
- MySQL 4.1.11
- PHP 4.4.6-0a
- Viart Enterprise (latest version) web store
Credit cards are run through SSL; orders are confirmed via e-mail. I use SSH for remote administration. I've disabled (I hope) all unnecessary services and moved the SSH port to a high address. I've scanned the system with a commercial vulnerability scan service (ScanAlert) -- turns up old version of PHP as only vulnerability (which, presumably Debian security patches address.)
PCI Compliance
PCI compliance requires, among other things:
- server firewall
- rigorous password policy
- intrusion detection
I've spent several weeks now studying netfilter/iptables, PAM, Snort, and Tripwire documentation. In each case I run into "gotchas" that bring me up short.
For instances, one authoritative doc says:
"CONFIG_NETFILTER - This option is required if you're going to use your computer as a firewall or gateway to the Internet. In other words, this is most definitely required for anything in this tutorial to work at all."QUESTION: But how do I determine if the CONFIG_NETFILTER option is set? If not, how do I set it? Do I really have to recompile the kernel to set it? If necessary, how do I recompile the kernel on a remote VPS without risking everything configured so far?
Further on I'm told that I need to install a script to make sure that my firewall rules survive a reboot. I can find examples of firewall scripts, more of less understand what they're doing, but with less confidence that I can morph them to my needs.
QUESTION: But where do I install my firewall script? How do I test it?
I think I almost grasp the PAM docs. Just not sure which modules I need to satisfy PCI.
QUESTION: So many choice, so little guidance on which to choose when. Which PAM modules do I need?
Snort seems fairly straight forward until I need to interpret the output. Haven't delved too far into this yet. But looks scary.
QUESTION: What do I need to know to decode the arcana?
And Tripwire-- Looks terrific except... Should have installed it very first thing upon bringing my VPS on-line. It's been on-line for awhile now.
QUESTION: Is it too late now to install Tripwire? If so, what can I do short of tearing everything down and reinstalling?
In short, I've read the docs and will continue to do so. But I'm stuck.
Where can I turn; who can help me cut through the documentation cruft to an understanding of what I need to know to implement these basic security provisions?
Many thanks,
Lloyd
grep CONFIG_NETFILTER=y /boot/config-$(uname -r)
If the above command returns 'CONFIG_NETFILTER=y', you're all set.
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
Simpler than that; if you can add a new firewall rule you know it is enabled!
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
You ask lots of good questions, and I'm sure you'll receive some useful comments here.
With regards to CONFIG_NETFILTER I'm certain that will be enabled, so I'll ignore that. For getting a firewall to survive reboot we did have some previous discussion on the topic.
Personally I create a shell script in the directory /etc/network/if-up.d/ - every executable file in that directory will be executed after the network interface(s) have been brought up.
So I have a simple firewall there:
#!/bin/sh # clear existing rules iptables --flush iptables --delete-chain # Set default policies for all three default chains iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # Enable free use of loopback interfaces iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # now allowing incoming http, ssh, and stmp iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m state --state NEW -s 0.0.0.0/0 -j ACCEPT iptables -A INPUT -p tcp --dport 25 -m state --state NEW -s 0.0.0.0/0 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -m state --state NEW -s 0.0.0.0/0 -j ACCEPT # and now outgoing: dns + smtp iptables -I OUTPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p udp --dport 53 -m state --state NEW -j ACCEPT iptables -A OUTPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT iptables -A OUTPUT -p tcp --dport 25 -m state --state NEW -j ACCEPT
Running this will setup rules, testing it is a matter of trying to connect remotely when you should/shouldn't be able to and seeing if it succeeds. (A tip: When working with a firewall for the first time add a cron-job to clear all your rules every 30 minutes - that way if you get locked out you're not lost!
Regarding tripwire it is later than ideal, but if you're certain you're not already compromised you may add it.
Pam configuration? We've talked about it before - honestly? I don't see what you need to mess with it for here.
[ Parent | Reply to this comment ]
Suppose you have your Debian init.d-style firewall script named /etc/init.d/pf. You are sure (== tested another way) that calling it with the argument 'stop' works in any circumstances.
Then create a file containing the following lines:
remote-pf.sh:
#! /bin/bash /etc/init.d/pf "$1" ANSWER='' echo 'If you are _able_ to answer y, it will be safe to do that.' echo -n 'Keep the current firewall rules (press 'y' or wait for timeout)? ' read -t5 ANSWER if [ -z "$ANSWER" ] then /etc/init.d/pf stop fiYou can call this script:
bash remote-pf.sh start, or
bash remote-pf.sh restart
It will apply the new firewall rules, then asks you whether to keep it. If you answer 'y', then we're done with the new config, but if you answer 'n', or you cannot answer in five seconds, then it will revert the settings to a known, clean state.
[ Parent | Reply to this comment ]
Anon :-)
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
If you're like me then you might have an exception which says something like:
- Allow all connections from foo.bar.com.
If you run that rule before networking is brought up then DNS resolution will fail .. So I accept the small risk to avoid having to use IPs not DNS.
(Again relying on DNS to be correct is also a hole, but I think it is a small risk.)
[ Parent | Reply to this comment ]
But: is DNS resolution needed before a packet arrives? Presumably no packets can arrive until the interfaces have been brought up. I don't know whether iptables resolves the name at rule intialisation or whenever a packet arrives. If it only resolves the domain name when the rule is initialised, then presumably it will fail if the IP number later changes, cancelling one of the reasons to use a name instead of an IP number in the first place.
I remember being discouraged from using names instead of IP numbers by the following section of man iptables:
-s, --source [!] address[/mask]
Source specification. Address can be either a network name, a host-
name (please note that specifying any name to be resolved with a
remote query such as DNS is a really bad idea), a network IP address
(with /mask), or a plain IP address. [more...]
[ Parent | Reply to this comment ]
Cheers,
Jonesy
[ Parent | Reply to this comment ]
For persistent firewall rules, I really like shorewall. I've also found it much easier to read configs than raw iptables scripts (even well written ones), and maintaining your firewall is at least as important as the initial configuration.
For password policy, we wound up using kerberos, because the company we were dealing with had some quite convoluted rules regarding password re-use and expiry, which we couldn't easily do with pam. If you just want to expire passwords regularly, you can do this with shadow. Make sure root's password doesn't expire, or your cron jobs will stop working.
IDS is a tricky one. Tripwire is a bit of a pain to install, and update, and tweak. It encrypts its database too, which is nice. Does get frustrating typing your passphrase in every time you want to update it, though. It's recommended that you keep your databases off-server, or in hardcopy, but that's not something I've ever done. Also don't get too enthusiastic when telling it what to monitor - this quickly becomes a pain and you'll just wind up ignoring your "file has changed" emails, which makes the whole system useless. I'd stick to something minimal, like binary directories. The default install, last time I did it on Debian, tried to monitor /dev, so you'd get alerts about /dev/pty/'s having changed.
It's not impossible to install tripwire on an existing system. You'll just have a bit more work to do ensuring that all of the files it is including in its database are real, and they should be there. debsums can help a little, here.
Aide is also worth considering. It doesn't (or at least didn't last time I checked) do the database encryption that tripwire does, making it easier for an intruder to hide his steps if you don't have offsite copies of your database), but I found it much easier to work with.
For network intrusion detection, snort is the best choice. The main problems with it are that you need to get decent baselines so that you can tell it what to ignore. It will then proceed to send you so many emails that you'll ignore them anyway. Using snort with a MySQL backend, and something like ACID can help make it a bit more manageable.
If you're doing this for someone else, it's worth trying to find out of they have a security person, or can appoint someone, to check snort/tripwire emails. This way it becomes someone else's problem.
mod-security for apache can be useful too, especially if you're only running a single application, which you control, and don't need to worry about angry messages from users complaining that someone couldn't post "wget%20" to their php forum. I usually tell it not to block anything, and just rely on its audit log to help track down the buggy bit of code that's let some malicious user on to a server.
Because of the vagueness of the PCI definition, a lot of the work is simply documentation and trying to prove that you've met the requirements. If this is an important project then it's worth getting an external auditing company in to take a look, as they'll be able to tell you exactly what to do. Beware of companies that will just give you a Nessus-generated PDF and charge you a few thousand for the privilege.
[ Parent | Reply to this comment ]
Shorewall - Really great and the latest version are always better.
Nmap - Pound on your system make sure everything is set right.
Snort - Good if you can get it going
Aide - I am much happier with aide than I was with tripwire. Tripwire and AIDE both take continued support. Each update your system runs you have to update the database. But it's imperative not to put the database on the server or somebody could just mess up your system and then update the DB. The easiest way to do this (you need physical access) is use a floppy disk on read only tab or a CDRW (as long as the server does not have a burner). The floppy disk is great because you just do an update on your computer, umount the floppy, flip the tab, mount the floppy and copy the db over, umount, flip the tab back to RO, remount and your back in business. Doing this method, only with physical access can they compromise the DB.
Also, if I remember correctly a lot of it has to do with written policy, as in a company policy to change passwords every 3 months etc.
[ Parent | Reply to this comment ]
And I have to agree with a few of the others: Install a proper firewall, like Shorewall for example. SOOOOO much simpler to understand and maintain than Netfilter low level stuff.
Good luck!
/MBL
[ Parent | Reply to this comment ]
I am currently developing a PCI compliant, middleware and back-end tiers (including repository) for a major currency exchange company. In order to comply with PCI rulings, here in the UK, the following business (and PCI) rules have been applied:
. No Credit Card Numbers or CV2 Numbers are stored, ever!
. The BINS, length and last 4 characters of the CC Number are stored.
. Single transactions including CC Number and CV2 are encrypted and transmitted, to the clearers, using https 443
. CC Numbers and CV2 numbers are not to be stored on site in any form, either on paper or elecronically. i.e. email or database
Follow these rules and you can't go wrong and even if you have a security breach as you can't 'leak' what you don't have.
Regards
Nick Adie
Consultant Developer
[ Parent | Reply to this comment ]
So I would first ask do you *really* need to store the card number? Once you have authorization and settlement for the transaction from your card aquirer do you really need to keep the data?
[ Parent | Reply to this comment ]
My few limited attempts at e-commerce have always used a third-party payment processor, so the card numbers and other sensitive data doesn't pass through my server at all (e.g. worldpay, paypal). You might consider this if making your own server sufficiently secure is too much work.
I normally take the word "firewall" to mean "hardware firewall", unless they explicitly say that a software firewall is acceptable. Would other people agree with me? If a software firewall is acceptable, here's what I've done on my web server:
My first attempt used the "guarddog" program. This is a nice GUI that lets you set up the rules. Eventually I got around to learning how to do it manually; this was mainly based on reading the iptables man page. I wrote a script, which is only about 50 lines, and put it in /etc/rc.firewall; this is called from /etc/init.d/firewall. I think this setup is based on how guarddog did it.
> QUESTION: But how do I determine if the CONFIG_NETFILTER option is set?
It probably is set; if it's not you'll get an error later.
> QUESTION: But where do I install my firewall script?
I've described how mine is done above. It doesn't really matter.
> How do I test it?
By trying to connect to ports that you have blocked, and seeing if you get in.
I hesitate to say this, but those questions are rather basic. Securing credit-card numbers is important. Maybe you should get some more experience of practical security on a less-critical system first?
[ Parent | Reply to this comment ]
By hardware I am assuming you mean appliance firewall. No I do not take it to mean that. There really is no difference and I would say an appliance firewall can even be more of a risk than software in a Debian box. Everybody updates their Debian box, that can't be said about your Cisco and Linksys firmware you have not touched in years. Also, a good number of the appliance firewalls are nothing more than low end Linux boxes running netfilter/iptables.
Firewalls are a good way to make people feel better but really are not that magical. If you have a hole in apache, your firewall is worthless. If you have a bunch of stuff running that you only want to allow certain access to then they suddenly become very useful.
[ Parent | Reply to this comment ]
I just mean a box, of any sort, with two network interfaces that filters traffic between them, and is probably dedicated to just this task.
I think I agree with your comments about updates and magic; but I still guess that when something like PCI says "firewall", they may well not include software running on the same machine as the services being protected.
[ Parent | Reply to this comment ]
Lloyd
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]