Intro

This focuses on Ubuntu's command-line firewall ufw, Uncomplicated Firewall.

There is a GUI available as well; gufw. The GUI version is however not our topic this time.

 

Important

Worth noting is that ufw is disabled by default on most, if not all, Ubuntu-based desktop distros. It may, or may not be, likewise on the server distros.

This is quite contrary to eg CentOS that has a firewall installed and active, although in a permissive mode.

 

Installing ufw

Check if it's installed:
# dpkg -s ufw | grep Status
Status: install ok installed

The full list:
# dpkg -s ufw
Package: ufw
Status: install ok installed
Priority: optional
Section: admin
Installed-Size: 818
Maintainer: Jamie Strandboge <This email address is being protected from spambots. You need JavaScript enabled to view it.>
Architecture: all
Version: 0.35-0ubuntu2
Depends: iptables, ucf, python3:any (>= 3.3.2-2~), debconf (>= 0.5) | debconf-2.0, init-system-helpers (>= 1.18~), lsb-base (>= 4.1+Debian11ubuntu7)
Suggests: rsyslog
Conffiles:
/etc/default/ufw ef91ecde4a64da5c98da8968849804d5
/etc/init.d/ufw ee21ed926eb989f8afbb0e10d2f56d24
/etc/init/ufw.conf b85f80257c81675ef38e9db139fb0921
/etc/logrotate.d/ufw 12b1fb7cee76fc46f161e1ead1a22ce6
/etc/rsyslog.d/20-ufw.conf 98e2f72c9c65ca8d6299886b524e80d1
/etc/ufw/sysctl.conf 3539cf073de407e030340351fe3f5fb7
Description: program for managing a Netfilter firewall
The Uncomplicated FireWall is a front-end for iptables, to make managing a
Netfilter firewall easier. It provides a command line interface with syntax
similar to OpenBSD's Packet Filter. It is particularly well-suited as a
host-based firewall.
Homepage: https://launchpad.net/ufw

If not installed:
# apt install ufw

Need the ufw-GUI?
# apt install gufw

 

 

All commands need to be run as root or sudo

# su -

Or use sudo to perform the action.
$ sudo ufw {action/s}
Password:

 

Daemon control

# ufw status
Status: inactive

# ufw enable
Firewall is active and enabled on system startup

# ufw status
Status: active

# ufw disable
Firewall stopped and disabled on system startup

# ufw status
Status: inactive

 

All went pearshaped!

This assumes you have physical access to the computer, or that ssh is still allowed in to the pearshaped computer.

Using the reset command will delete all rules and reset ufw to its initial state.

This is useful for example when you want to start over from scratch with your firewall setup.

# ufw status verbose
Status: active

Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To Action From
-- ------ ----
80 ALLOW IN Anywhere
22 ALLOW IN Anywhere

# ufw reset
setting all rules to installed defaults. Proceed with operation (y|n)? y
Backing up 'user.rules' to '/etc/ufw/user.rules.20181215_162800'
Backing up 'after6.rules' to '/etc/ufw/after6.rules.20181215_162800'
Backing up 'before.rules' to '/etc/ufw/before.rules.20181215_162800'
Backing up 'user6.rules' to '/etc/ufw/user6.rules.20181215_162800'
Backing up 'after.rules' to '/etc/ufw/after.rules.20181215_162800'
Backing up 'before6.rules' to '/etc/ufw/before6.rules.20181215_162800'

# ufw status verbose
Status: inactive

 

 

Set up default policies

Normally you want to block everything, unless specifically allowed. Likewise you probably want to allow all outgoing traffic.

# ufw default deny incoming
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)

# ufw default allow outgoing
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)

 

Setting rules

Since we blocked everything incoming, we need to allow some incoming traffic, or we have a pretty plastic computer case just sitting there.

Ssh is one of those must-allow traffic types.

Note that allowing ssh in, creates a rule for both IPv4 and IPv6. If IPv6 is not really needed, it's suggested that you leave it in anyway or just disable the IPv6-stack.

See https://serverfault.com/questions/294699/can-i-block-all-ipv6-traffic-if-im-not-using-it-planning-to-use-it for a discussion on this topic.

# ufw allow ssh
Rule added
Rule added (v6)

# ufw status numbered
Status: active

To Action From
-- ------ ----
[ 1] 22 ALLOW IN Anywhere
[ 2] 22 (v6) ALLOW IN Anywhere (v6)


Alternative:

# ufw allow 22
Rule added

# ufw status
Status: active

To Action From
-- ------ ----
22 ALLOW Anywhere

 

 

Info on disabling the IPv6-stack can be found here; https://support.purevpn.com/how-to-disable-ipv6-linuxubuntu.

For the remainder of this guide, I've disabled the IPv6-stack as well as removed rule number two as seen above.

 

Allowing other services

# ufw allow http
Rule added

# ufw allow https
Rule added

# ufw status numbered
Status: active

To Action From
-- ------ ----
[ 1] 22 ALLOW IN Anywhere
[ 2] 80 ALLOW IN Anywhere
[ 3] 443 ALLOW IN Anywhere

 

 

Adding specific ports or port ranges

# ufw allow 6701:6710/tcp
Rule added

# ufw allow 6701:6710/udp
Rule added

# ufw allow 25
Rule added

# ufw status numbered
Status: active

To Action From
-- ------ ----
[ 1] 22 ALLOW IN Anywhere
[ 2] 80 ALLOW IN Anywhere
[ 3] 443 ALLOW IN Anywhere
[ 4] 6000:6007/tcp ALLOW IN Anywhere
[ 5] 6000:6007/udp ALLOW IN Anywhere
[ 6] 25 ALLOW IN Anywhere

 

 

Allow specific IP-addresses or IP-ranges

Allow any connections from 192.168.0.9:
# ufw allow from 192.168.0.9

# ufw status
To Action From
-- ------ ----
[ 7] Anywhere ALLOW IN 192.168.0.9


Allow connections from 192.168.0.9 to port 22:
# ufw allow from 192.168.0.9 to any port 22

# ufw status
To Action From
-- ------ ----
[ 7] 22 ALLOW IN 192.168.0.9

Allow an entire IP-range:
# ufw allow from 192.168.0.0/24

# ufw status
To Action From
-- ------ ----
[ 7] Anywhere ALLOW IN 192.168.0.0/24

Allow an entire IP-range to specific port:
# ufw allow from 192.168.0.0/24 to any port 22

# ufw status
To Action From
-- ------ ----
[ 7] 22 ALLOW IN 192.168.0.0/24

 

Denying (block) specific IPs or ranges

Block access to all ports:

# ufw deny from x.y.z.n to any

Block access to specific port:

# ufw deny from x.y.z.n to any port 80

Block access for a whole subnet:

# ufw deny from x.y.z.0/24 to any

Block access for a whole subnet to a specific port:

# ufw deny from x.y.z.0/24 to any port 80

 

Inserting rules

Deny-rules must be placed before any allowed ones.

First check what rules are active.

# ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] Anywhere ALLOW IN 192.168.0.0/24

 

Now, say that we want to deny any incoming traffic to port 22 from 10.0.0.0/24.

# ufw insert 1 deny from 10.0.0.0/24 to any port 22
Rule inserted

# ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22 DENY IN 10.0.0/24
[ 2] Anywhere ALLOW IN 192.168.0.0/24

 

See how the inserted rule is now at the top as number 1?

 

 

Deleting rules

The simplest way to delete rules is this way.

# ufw status numbered
Status: active

To Action From
-- ------ ----
[ 1] 80 ALLOW IN Anywhere
[ 2] 80 (v6) ALLOW IN Anywhere (v6)

# ufw delete 2
Deleting:
allow 80
Proceed with operation (y|n)? y
Rule deleted (v6)

# ufw status numbered
Status: active

To Action From
-- ------ ----
[ 1] 80 ALLOW IN Anywhere


Alternative:
By actual rule.

# ufw delete allow http

 

 

Getting more info from ufw

# ufw status verbose
Status: active

Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To Action From
-- ------ ----
80 ALLOW IN Anywhere
22 ALLOW IN Anywhere  

 

 

Bonus tips'n'tricks: ufw with CentOS

Want to use ufw with CentOS? I've successfully installed it on a CentOS 6-server after which I dumped iptables (turned off the daemon indefinitely). This is how to do it.

 

Why ufw with CentOS??

Why would I want to do this at all? Iptables rocks as we all know, right? Wrong (YMMV of course)!

These are my reasons:

  1. My work is in an Ubuntu-shop. I use Ubuntu eight hours a day, five days a week. With Ubuntu, ufw is the default firewall system. For that reason I rarely, if ever, touch iptables anymore. It's a known fact that stuff you selldom work with quickly disappears from memory and into the mists of obscurity; ie remembering stuff requires you to repeat it, and doing it often.

  2. I've also come to appreciate the simplicity of setting up ufw and seeing in no uncertain way what exact rules are applied, which way and to what. Iptables is powerful, no question about it, but it can be a bit of a mess when appending or modifying rules to an already complicated list of rules.

  3. Also, I was seeing a lot of traffic from iptables on my server from (mostly) torrent connection attempts while file-sharing linux-distros and such. In fact a lot more than usual. In fact so much that /var/log/messages filled up my root partition, all the 50 GB free I had just the other day...
    This in turn lead me to believe I had some kind of iptables-mismatch-problem-or-setup-thingy going on. No amount of iptables tweaking seemed to make any difference. So, since ufw was pretty much a well-known territory to me, I did a quick Google search on how ufw works with CentOS. And, badoom-tisch, here we are!
    Starting from scratch with ufw and adding one rule at a time, I cut down on the log chatter most significantly, and the server got a lot more responsive while still giving me a good idea what's going on, on the network.

So there, that's why. On with the tips'n'tricks already!

 

Guide

  1. You need the epel repo for this. Most probably you already have it installed, but in case you don't, here's how.
    # yum install epel-release
    # yum install ufw
  2. You should now set some default rules, eg default deny incoming and allow ssh in. See above for a guide!

  3. To enable autostarting the ufw daemon at boot.
    # ufw enable
    # chkconfig ufw on
    # service ufw restart
    Stopping Uncomplicated firewall: [ OK ]
    Starting Uncomplicated firewall: [ OK ]
  4. Run this to confirm what runlevels ufw is active on.
    # chkconfig --list | grep ufw
    ufw 0:off 1:off 2:on 3:on 4:on 5:on 6:off
  5. If all looks fine and you have your uwf rules set properly, you might want to disable iptables altogether.
    # service iptables stop
    # service ip6tables stop
    # chkconfig iptables off
    # chkconfig ip6tables off
    # chkconfig --list | grep ip
    iptables 0:off 1:off 2:off 3:off 4:off 5:off 6:off
    # chkconfig --list | grep ip6
    ip6tables 0:off 1:off 2:off 3:off 4:off 5:off 6:off
  6. Done!

 

Logging ufw

  1. When using ufw with CentOS, all the logging is written to /var/log/messages, not /var/log/ufw*, as is the normal with Ubuntu and it's clones.

  2. Enable logging, default is on and low.
    # ufw logging on
    # ufw status verbose
    Status: active
    Logging: on (low)
    Default: deny (incoming), allow (outgoing), disabled (routed)
    New profiles: skip
    To Action From
    -- ------ ----
    22 ALLOW IN Anywhere
    ...
  3. Disable logging.
    # ufw logging off
  4. With the default low logging level, you'll basically just see blocked connection attempts in /var/log/messages; [UFW BLOCK].

  5. Choose the logging level like so.
    # ufw logging LEVEL

    LEVEL may be one of the following; on, off, low, medium, high, full.

    For example:
    # ufw logging medium 
    or
    # ufw logging full
    or
    # ufw logging off

 

 

 

Sources

https://wiki.ubuntu.com/UncomplicatedFirewall

https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-16-04

https://serverfault.com/questions/294699/can-i-block-all-ipv6-traffic-if-im-not-using-it-planning-to-use-it

https://support.purevpn.com/how-to-disable-ipv6-linuxubuntu

https://ubuntuforums.org/showthread.php?t=823741

https://serverfault.com/questions/662460/check-ufw-default-action

https://linuxize.com/post/how-to-setup-a-firewall-with-ufw-on-ubuntu-18-04/

https://help.ubuntu.com/community/UFW#Logging

https://serverfault.com/questions/516838/where-are-the-logs-for-ufw-located-on-ubuntu-server

https://superuser.com/questions/730208/is-it-possible-to-put-ufw-on-centos

http://manpages.ubuntu.com/manpages/bionic/man8/ufw.8.html#logging

 

 

 

 

 

 

 

 

 

Hits: 1267