Y'herd thisun? 

“! could either watch it happen, or be part of it.”
-Elon Musk

MONO/Ubuntu part 6 - Firewalling Ubuntu 8.10 Server


"Hardware Firewalls" (including router service rules and port forwards) are the first line of defense for shielding internals from abuse from the wild. But "security is an onion" so adding layers to make external forces have to work their way in is a smart & easy measure.

Most linux software "firewalls" are technically interfaces on top of the OS's NetFilter/Mangler/iptables network packet system; that group of components commonly referred to enmasse as "iptables" IS the actual firewall. You can talk directly to the lower systems and code the iptables processing chains from the commandline, but doing so can get complicated real fast. So, as in Windows, using a higher level tool is the faster way to market.

A few of the non-gui biggie tools are ufw (Uncomplicated FireWall), firehol and shorewall. We'll use ufw because, well, because when you start up your Ubuntu server you see it listed in the scroll and that sounds to me like an endorsement :).

ufw is already installed (and running, awaiting commands), all you have to do is tell it to start managing the network traffic. Once it is enabled it will automatically start every time you boot the machine. Before we enable it though, let's point a port scanner at the server to get a baseline.

Aside from port 21 (which shows up as open in most scanners, on most boxes regardless of the OS, regardless of the networking, regardless of anything) the only thing running on our server so far is OpenSSH. By default the port scanner doesn't see it because in ourĀ SSH tutorial we changed the service's port from the default ssh 22 to an abnormal 6666 (Most scanners don't hit all 65 thousand possible ports out of the box, they hit just the typical ones so general purpose scans won't take forever). Telling the tool to include port 6666 changes the tune.

Good, so if a kiddie was bored enough to hit all ports, they'd see 6666 as open.

For the first couple of examples you'll have to have physical access to the server box. We're going to use ufw to close the ports to outsiders and if you're using ssh... you'll be an outsider. So physically log onto the box.

Let's state that again. Unlike most services, changes made to ufw take place right away without the need to manually restart the service and, unlike changes to the SSH server options, existing connections on a newly closed port won't be kept alive. If you're remoting into a server and accidentally shut off the remoting port then you'll have to go physically to the box to fix that mistake.

Just for paranoia purposes, before enabling ufw the very first time and setting any rules, you might want to goose it to make sure that it is set to default all ports to closed unless they have been specifically set to be open.

sudo ufw default deny

Check the current ufw status and it it's not enabled, flip it on. Easy commandline stuff.

sudo ufw status verbose

Returns a status of not enabled? Enable it:

sudo ufw enable

Now go back to a client and try ssh/PuTTY/WinSCP to connect to the server. You shouldn't be able to because the default "enable" has shut down all ports to all external connections.

A scan now should also confirm the firewall being completely up

Of course, closing all ports is kinda silly for a server. You may as well not install SSH server or apache or wowzamediaserver, etc. because nobody's going to be able to use them. The power of a firewall comes from selectively allowing access to specific external entities.

Opening a specific port

Let's keep the ufw enabled, but open up the SSH port. There are three main syntaxes to do that, here are the two most common ones.

Service ("profile") Name style:

sudo ufw allow ssh

Or, [port]/[protocol] shorthand:

sudo ufw allow 6666/tcp

The first option, using the service name "ssh", takes advantage of the service's authors putting details about the connection requirements into their installation scripts. OpenSSH, Apache2 and other major players code their installers to put configuration files into the /etc/ufw/applications.d/ folder. ufw reads these config files when it starts and can use them to enforce typical firewall rules for common needs. You can get a list of all of the named services (called "profiles") installed on your server by using the command:

sudo ufw app list

The second style, specifying the port number, slash and protocol, is the broad-stroked quickie for adding custom port rules.

In our case of using the alternate port 6666 for OpenSSH, if we'd just used the named style then port 22 would be open for business but no actual SSH business would be possible because SSH is not listening for knocks at that door. So instead we create a rule that allows tcp protocol packets to pass through to the 6666 port.

Do a remote ssh/Putty/WinSCP connection to confirm that you can now get into the server from any remote client. yay, yawn.

Obviously this simple example isn't all that useful yet. Our server is behind a router firewall that isn't forwarding packets from the outside world (riiiight?) and so far we only have OpenSSH running and so far we do want all SSH connections to be allowed. Remember though that the big goal is to be using the server for Mono ASP.Net deployments so in the end we'll want Apache2 (port 80 at the minimum) to be externally accessible but probably not want OpenSSH allowing every Tom, Dick and Kali to be typing in.

Restricting access to specific remote addresses

Let's change the ufw rule for OpenSSH so that even if we do put the box in a DMZ, it will should allow in remote connections only from a specific IP. We can do that by adding a FROM clause to the allow command.

To use FROM you can't just tack onto the previous port/protocol syntax, though, instead you have to start being more formal with the format: "ufw proto [protocol type] from [IP address] to [machine IP address or "any"] port [port number]" ...

With that, unless the cracker knows that specific allowed address and is able to spoof the connection with it, ufw shouldn't - we hope - let them in. Give it a test by running that rule command with a remote client's specific IP Address. Then change the same client machine's IP Address andor use another client machine and test again.

BTW: You can use the [IP Address] to specify address ranges but only CIDR format is supported ([IP Address base]/[netmask bits]). Netrange format allowances and restrictions (xxxx.xxxx.xxxx.xxxx-yyyy.yyyy.yyyy.yyyy) apparently are not supported so if you have a specific set of ranges you'll have to add multiple rule commands.

Important point: If you run a rule allow command, then decide that *instead* you want to only allow some other IP Address, you have to drop the first rule. If you just run a second command, like "sudo ufw allow 6666/tcp FROM" then BOTH of the rules are in the ufw set and BOTH the IP addresses will be allowed to attempt an SSH connection. When in doubt of the current rules, run the status checker command:

sudo ufw status verbose

Dropping firewall rules

To completely drop an existing rule, use "delete allow" command, as in:

sudo ufw delete allow 6666/tcp

It's important to remember that "delete allow" requires you to use the same full information that you used when you created the rule. If ufw doesn't find an exact criteria match then you may not get the rule removed (A good reason to remember to use the "ufw status" command after every rule change attempt).

For example, the above command would fail if we'd added the rule with a FROM clause. Instead we'd have to match the original add, like this:

DENYing by rules

Same as when we secured OpenSSH server using its config file and the machine hosts.allow/deny files, there are times when ALLOW rules won't easily describe what we need. In those cases we can augment with inside-out logic using specific DENY rules.

Adding denies is the exact same syntax as adding allows, just substitute "deny" for "allow" in the command.

In the examples so far we've taken advantage of ufw setting a DENY ALL rule when you first turned it on. So really you can think of the previous commands as being parts of a chain of checks (or an If...Then or CASE...Default code block). At a very high level, when a packet comes into the box it hits the iptables system which checks each manually-entered rule. If the packet matches an ALLOW rule then it is passed along to the rule's specified port listener, if all the ALLOW rules are checked and there is no match then the final rule of DENY ALL rule is applied and the packet is denied access.

When you start mixing allows and denies, remember that the processing is a chain of events and as a criteria match is found, the rule is applied. There is no "priority" switch in the rule syntax, as far as I know, so the order in which rules are tested are based on the order that you added them. Be careful about the order in which you add your allow and deny rules for a port and test them well. If you find a mistake in the logic of a set, you'll have to remove all of them and start over. "sudo ufw status" shows you the order in which rules were added.

Creating your own Profile rules

Remember back when we mentioned that big-name netapp servers such as Apache and SSH put their common firewall settings into config files so that ufw's app LIST command would show them by name ("profile")? That feature for the big guys lets you easily add/delete their rules by the profile name instead of specifying the protocols and ports manually.

I'll bet you were wondering if you could name your own custom rules to make management easier.

I wondered the same thing when I started kicking the Ubuntires, but because all of the ufw tipsites showed only the manual commands it seemed that more that just adding a file would be needed. Plus, I remember seeing on a tipsite and in the Ubuntu docs the gist that only a full package setup could make profiles. So in the rush of installing I forgot about it and got used to the manual commands.

Then came the day I was using "delete allow" commands and hitting the annoyance of not getting the criteria right. That got me rethinking the custom profile idea... and I found that it does work. To a point anyway.

You can't do denies, or IP Address restrictions. But when you just want to just allow protocols and ports it's got ticket.

If you've been following the steps, use a matching "delete allow" command to remove a rule that you manually created and test to make sure that it is no longer in the rules list. Then navigate to the /etc/ufw/applications.d/ folder and create a new file called whatever, I called my example file "customrule".

Inside nano, follow this four line format to add you own rule to the ufw app list. Yes, the first line has to be in brackets, even if it has no spaces.

[My Nifty Rule]
title= here is my nifty title
description=wow, a long description

Close nano, saving the file.

Ask ufw to list you the profiles on the machine with "sudo ufw app list" and you can get your profile details using "ufw app info [profile name]:

Looks good (if a little blurry ;-0 )? Now add it to the ufw rules using the standard syntax "sudo ufw allow [profile name]". Note that because I named mine with spaces I had to wrap the profile name with single quotes... spaces in a profile name aren't very smart but even the big guys do it, so I did it to show how to get around the usage issue ;-).

Removing the rule is also just like removing a "big guy" profile

sudo ufw delete allow 'My Nifty Rule'

I don't know why this ability isn't mentioned, maybe it's new to 8.10 or maybe there's something I'm missing? Maybe it's simply retarded? Perhaps. But I've restarted my servers a bunch of times and the named rules appear to be sticking around and being enforced.

So with this trick you lessen the need to furrow your brow a month after setting up a box, when you're looking at the ufw list and wondering what the heck it was you pointed to port 63423 ;-).

Hope it helps.

Coming next: Installing Apache2 and Mono and Lynx

jump to:

  • 1: Why?
  • 2: Installation
  • 3: Update the OS with APT
  • 4: Remoting to the box with SSH
  • 5: NANO quickies for 95% of the jobs
  • 6: Firewalling Ubuntu 8.10 Server
  • 7: Installing Apache2 and MONO
  • 8: Test client host files
  • 9: Configure MONO on Apache2
  • 10: Apache default pages
  • 11: Handling Apache and Mono Errors
  • 12: Subdomains and Christian porn
  • 13: Virtual Host Tweak: unmanaged cAse sensitiviTy
  • 14: Managed cAse sensitiviTy
  • 15: Managing files and folders
  • 16: Logging Apache Accesses and Errors
  • 17: Ubuntu Task Managers
  • 18: Ubuntu Services and Service Managers
  • 19: Installing Oracle 10g XE Server
  • 20: Connecting Mono to Oracle

  • home     who is smith    contact smith     rss feed π
    Since 1997 a place for my stuff, and it if helps you too then all the better