If you haven’t read part 1 of this series, now would be a good time to go back and read it. In the previous blog we came up with a basic firewall design. Now we’ll make that into a usable firewall and show how to apply it to live systems using the firewall support in CloudPassage’s Halo.
Firewall design recap
Here’s the firewall design we built in part 1:
- People coming from the Internet making HTTP requests (TCP port 80 and TCP port 443) to the web service on this machine: ALLOW
- The Apache web server making sql queries (TCP port 3306) to the sql service on this machine: ALLOW
- People coming from the Internet making sql queries (TCP port 3306) to the sql service on this machine: DROP
- People coming from just a few IP addresses connecting up via ssh (TCP port 22) for remote access to this machine: ALLOW
- All other connections from the Internet to this machine: DROP
- This machine going out to the Internet pulling down software updates (TCP ports 80 and 443): ALLOW
- This machine going out to the Internet making dns queries (UDP port 53 and TCP port 53): ALLOW
- All other connections from this machine to the Internet: DROP
Building a firewall policy in Halo
First, let’s build an empty policy. Go to the Halo Portal Firewall Policies page and click on “Add New Firewall Policy” to start:
To add our first HTTP rule we’ll use the blank template line under “Inbound rules”. “Source” stays at “any” since anyone can make web requests of this server. We need to change “Service” to HTTP, so press the drop-down triangle below Service to see the list of services. “HTTP (tcp/80)” shows up, so select that. “ACCEPT” is just what we want to do, so we leave the action as is. We’ll leave the remaining fields as is.
Your rule should end up looking like:
To add a second rule, click the round “+” icon at the far right of the first rule – the portal will add a new rule template line immediately below the first rule. Since we want to allow inbound HTTPS, press the drop-down triangle below “Service” on the second line. “HTTPS (tcp/443)” is exactly what we want, so select that. Like the HTTP on the previous line, “Source” stays at “any” and “Action” needs to be “ACCEPT”. Second rule done – save your work with “Apply” in the lower left, then select “LAMP Servers” to continue editing.
Press the “+” at the right of the second rule to get a third empty template. This rule will allow Apache to talk to MySQL. Change “Service” to “MySQL (tcp/3306)”, and change “Action” to “ACCEPT”.
With this rule, we need to only allow Apache running on this machine to talk to MySQL. The cleanest way to restrict this is to change the “Interface” to “lo”. “lo” is the loopback interface; it’s how one process on this computer talks to another process on this computer.
Now that Apache can talk to MySQL, let’s make sure nobody from the Internet can. Add another rule with the “+” at the right of the third line. In the fourth rule, change “Service” to “MySQL (tcp/3306)” and change the “Action” to “DROP”. The Inbound rules should look like this:
Since Apache talks to MySQL over the “lo” loopback interface, all web->database conversations are allowed. If anyone else from the Internet tried to talk directly to the database server, rule 4 would block them since they aren’t talking on the loopback interface (they’ll be using the normal ethernet interfaces like “eth0” or “eth1”).
There are a few convenience features that may be useful to you when working on policies. If you click and hold one of the “Up/Down” arrows to the left of a rule, you can drag the rule up or down in the firewall policy.
If you make a mistake, you can go back to the last saved policy by pressing Cancel in the lower left.
Once a policy is applied to one or more machines, you can still edit the policy. As soon as you press “Apply” after some changes the new firewall is scheduled to go out to all those machines automatically – you don’t have to do anything else. Because those machines check in with the Halo grid once a minute, it could be up to 60 seconds before the new firewall gets pushed out to them.
OK, a few more rules and we’re done with Inbound. Press the “plus” next to line 4 to get a line 5 to edit. We want to allow a few machines to manage this server over SSH, so change “Service” to “ssh (tcp/22)”. “Action” needs to change to “ACCEPT”. Since this type of connection is both rare and privileged, we’ll also check off “Log” for this rule. By doing this, each connection gets a log entry in the firewall log on the system so we have basic auditing.
At the moment, this rule would allow anyone to SSH in because the “Source” is “any”. To restrict that to just a few systems, click on the drop-down triangle next to “any” in this rule.
You get a few options here. We’ve already used “any” to represent “any IPv4 address”. The “Ghostports Users” category holds any user accounts that use the GhostPort One-time password token. “Server Groups”, down at the bottom, lets you pick a Halo Server group as the source. This would come in handy, for example, if we were writing a firewall for a group of dedicated MySQL servers and wanted to allow all the dedicated HTTP servers to place MySQL requests. By choosing “Apache Servers” as the source, the firewalls on the MySQL servers are automatically updated if we add or remove a web server or an IP address changes.
The remaining choice – “IP Zones” – is the one we want. With this choice we can manually create a list of IP addresses that can come in to the SSH service. Click on “Add New” under “IP Zones” and you’ll get a pop-up box. Let’s name this zone “Sysadmins” and put the IP addresses of the machines that can SSH in the “Address(es)” box, separated by commas. When you press Create, it both creates the zone and puts it in the Source for this rule.
Next we want a blanket rule that drops all other incoming traffic. If you look at the top of the Incoming box, you should have a reminder that “The last rule in a firewall rule set is almost always a default-deny. Add this rule.” Click on the “Add” and the portal will create this for you at the bottom. Remember to save your changes regularly with “Apply”.
Here’s the finished Inbound rule set:
First, we want rules to allow outbound http and https to anywhere on the Internet. Would you like to give that a try?
You should have ended up with something like:
Does it matter which comes first in the firewall? No, because we’re taking the exact same action for both (ACCEPT and not Log), so they can be in either order.
The next traffic type to handle is DNS. The good news? The Halo firewall actually takes care of outbound DNS already. While the rules aren’t shown on this screen, outbound DNS is so critical to the operation of a system and so easy to forget that the Halo firewall puts in DNS rules for you automatically. It also puts in rules to allow the Halo daemon to talk back to the Halo grid. To see these rules, press Apply in the lower left, but before you come back in to edit the firewall some more, look to the far right on the “LAMP Servers” line. Press the “Export” hyperlink there and you’ll see the exact rules that will be placed on a server using this firewall. The implicit rules are between the “# — start of Cloudpassage section” and “# — end of Cloudpassage section” lines; you’ll see the https rules used to communicate with the grid and the dns (port 53) rules. For those that like the gory details, you can always see the exact iptables firewall that be used by clicking on Export.
OK, so this machine has outbound HTTP and HTTPS rules for package updates, the implicit rules take care of DNS lookups, and that just leaves the rule blocking all other outbound traffic. As with the Inbound chain, the “The last rule in a firewall rule set is almost always a default-deny. Add this rule.” link takes care of this for you – press Add now.
There’s just one more step before this is a complete firewall. Remember when we gave Apache a special exception to talk to mysql over the loopback interface? It turns out there are a lot of programs that talk to each other over loopback, so firewalls almost always allow that communication on any port.
To add this loopback communication, press the “+” at the top right of the Inbound list and use the up-down arrow at the left of the new template line to move it to the top of the list. Change the Interface to “lo” and the Action to “ACCEPT”. Then do exactly the same set of steps to the Outbound rule list – you need this rule at the top of both.
Here’s the finished firewall:
Congratulations! You’ve just set up a firewall. Make sure you press “Apply” to save the changes.
So the firewall policy has been created, but no servers are actually using it. How do we push this firewall out to real systems?
To actually use this policy, go back to the “Servers” menu in the upper left and select “Firewall Management”. The left center column with “All Servers” at the top shows the server groups you’ve created:
I want to assign this policy to a group of test web servers, the “Test Apache” group. You can make this group by clicking on “Add a new group” at the bottom. Put “Test Apache” in the name field. You can actually put in a firewall policy in this box, but don’t – let’s see how to add one to an existing group. Press Save to use the defaults.
Now, click on the “Test Apache” name and the highlighting moves down to it away from “All Servers”:
Click on “Edit Details” and you get the same pop-up box you got when you created it. This allows you to Add and remove policies anytime. Press the drop-down triangle next to “Firewall Policy” and you can select your “LAMP Servers” firewall policy:
Because this newly-created group doesn’t actually have any servers in it, the firewall’s not being used yet. As soon as you move a server into this group, all the policies assigned to that group get automatically applied to that server.
Move on to part 3 –>