Use the Uncomplicated FireWall to create basic host-based firewall.
I prefer to use firewalld, but ufw is more than enough in most cases.
Preliminary information
Display application version.
$ sudo ufw version
ufw 0.36.1 Copyright 2008-2021 Canonical Ltd.
Display help information.
$ sudo ufw help
Usage: ufw COMMAND Commands: enable enables the firewall disable disables the firewall default ARG set default policy logging LEVEL set logging to LEVEL allow ARGS add allow rule deny ARGS add deny rule reject ARGS add reject rule limit ARGS add limit rule delete RULE|NUM delete RULE insert NUM RULE insert RULE at NUM prepend RULE prepend RULE route RULE add route RULE route delete RULE|NUM delete route RULE route insert NUM RULE insert route RULE at NUM reload reload firewall reset reset firewall status show firewall status status numbered show firewall status as numbered list of RULES status verbose show verbose firewall status show ARG show firewall report version display version information Application profile commands: app list list application profiles app info PROFILE show information on PROFILE app update PROFILE update PROFILE app default ARG set default application policy
Display application defaults.
$ cat /etc/default/ufw
# /etc/default/ufw # # Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback # accepted). You will need to 'disable' and then 'enable' the firewall for # the changes to take affect. IPV6=yes # Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if # you change this you will most likely want to adjust your rules. DEFAULT_INPUT_POLICY="DROP" # Set the default output policy to ACCEPT, DROP, or REJECT. Please note that if # you change this you will most likely want to adjust your rules. DEFAULT_OUTPUT_POLICY="ACCEPT" # Set the default forward policy to ACCEPT, DROP or REJECT. Please note that # if you change this you will most likely want to adjust your rules DEFAULT_FORWARD_POLICY="DROP" # Set the default application policy to ACCEPT, DROP, REJECT or SKIP. Please # note that setting this to ACCEPT may be a security risk. See 'man ufw' for # details DEFAULT_APPLICATION_POLICY="SKIP" # By default, ufw only touches its own chains. Set this to 'yes' to have ufw # manage the built-in chains too. Warning: setting this to 'yes' will break # non-ufw managed firewall rules MANAGE_BUILTINS=no # # IPT backend # # only enable if using iptables backend IPT_SYSCTL=/etc/ufw/sysctl.conf # Extra connection tracking modules to load. IPT_MODULES should typically be # empty for new installations and modules added only as needed. See # 'CONNECTION HELPERS' from 'man ufw-framework' for details. Complete list can # be found in net/netfilter/Kconfig of your kernel source. Some common modules: # nf_conntrack_irc, nf_nat_irc: DCC (Direct Client to Client) support # nf_conntrack_netbios_ns: NetBIOS (samba) client support # nf_conntrack_pptp, nf_nat_pptp: PPTP over stateful firewall/NAT # nf_conntrack_ftp, nf_nat_ftp: active FTP support # nf_conntrack_tftp, nf_nat_tftp: TFTP support (server side) # nf_conntrack_sane: sane support IPT_MODULES=""
Display application configuration file.
$ cat /etc/ufw/ufw.conf
# /etc/ufw/ufw.conf # # Set to yes to start on boot. If setting this remotely, be sure to add a rule # to allow your remote connection before starting ufw. Eg: 'ufw allow 22/tcp' ENABLED=no # Please use the 'ufw' command to set the loglevel. Eg: 'ufw logging medium'. # See 'man ufw' for details. LOGLEVEL=medium
Display sysctl settings applied by the uncomplicated firewall.
$ cat /etc/ufw/sysctl.conf
# # Configuration file for setting network variables. Please note these settings # override /etc/sysctl.conf and /etc/sysctl.d. If you prefer to use # /etc/sysctl.conf, please adjust IPT_SYSCTL in /etc/default/ufw. See # Documentation/networking/ip-sysctl.txt in the kernel source code for more # information. # # Uncomment this to allow this host to route packets between interfaces #net/ipv4/ip_forward=1 #net/ipv6/conf/default/forwarding=1 #net/ipv6/conf/all/forwarding=1 # Disable ICMP redirects. ICMP redirects are rarely used but can be used in # MITM (man-in-the-middle) attacks. Disabling ICMP may disrupt legitimate # traffic to those sites. net/ipv4/conf/all/accept_redirects=0 net/ipv4/conf/default/accept_redirects=0 net/ipv6/conf/all/accept_redirects=0 net/ipv6/conf/default/accept_redirects=0 # Ignore bogus ICMP errors net/ipv4/icmp_echo_ignore_broadcasts=1 net/ipv4/icmp_ignore_bogus_error_responses=1 net/ipv4/icmp_echo_ignore_all=0 # Don't log Martian Packets (impossible addresses) # packets net/ipv4/conf/all/log_martians=0 net/ipv4/conf/default/log_martians=0 #net/ipv4/tcp_fin_timeout=30 #net/ipv4/tcp_keepalive_intvl=1800 # Uncomment this to turn off ipv6 autoconfiguration #net/ipv6/conf/default/autoconf=1 #net/ipv6/conf/all/autoconf=1 # Uncomment this to enable ipv6 privacy addressing #net/ipv6/conf/default/use_tempaddr=2 #net/ipv6/conf/all/use_tempaddr=2
Basic usage
Display initial status.
$ sudo ufw status
Status: inactive
Enable logging (on uses default value, low, medium, high, full, off to disable).
$ sudo ufw logging on
Logging enabled
Sample log will look like this.
Nov 3 22:04:30 jammy kernel: [955028.363387] [UFW BLOCK] IN=ens18 OUT= MAC=72:0b:18:14:8a:0a:64:d9:8a:4a:cd:a3:06:00 SRC=192.168.6.200 DST=192.168.8.156 LEN=71 TOS=0x00 PREC=0x00 TTL=63 ID=61224 PROTO=UDP SPT=51258 DPT=53 LEN=51
Define default incoming and outgoing policy.
$ sudo ufw default deny incoming
Default incoming policy changed to 'deny' (be sure to update your rules accordingly)
$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow' (be sure to update your rules accordingly)
Allow access to SSH server, but enforce connection attempts limit (up to 6 connections within 30 seconds).
$ sudo ufw limit 22/tcp
Rules updated Rules updated (v6)
Allow access to DNS server, but use rich rule and log each connection.
$ sudo ufw allow in on ens18 log proto tcp from 192.168.8.0/24 to 192.168.8.156 port 53
Rules updated
$ sudo ufw allow in on ens18 log proto udp from 192.168.8.0/24 to 192.168.8.156 port 53
Rules updated
Allow access to HTTP server.
$ sudo ufw allow 80/tcp
Rules updated Rules updated (v6)
Enable firewall.
$ sudo ufw --force enable
Firewall is active and enabled on system startup
Display firewall status.
$ sudo ufw status
Status: active To Action From -- ------ ---- 22/tcp LIMIT Anywhere 192.168.8.156 53/tcp on ens18 ALLOW 192.168.8.0/24 (log) 192.168.8.156 53/udp on ens18 ALLOW 192.168.8.0/24 (log) 80/tcp ALLOW Anywhere 22/tcp (v6) LIMIT Anywhere (v6) 80/tcp (v6) ALLOW Anywhere (v6)
Display verbose firewall status.
$ sudo ufw status verbose
Status: active Logging: on (medium) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp LIMIT IN Anywhere 192.168.8.156 53/tcp on ens18 ALLOW IN 192.168.8.0/24 (log) 192.168.8.156 53/udp on ens18 ALLOW IN 192.168.8.0/24 (log) 80/tcp ALLOW IN Anywhere 22/tcp (v6) LIMIT IN Anywhere (v6) 80/tcp (v6) ALLOW IN Anywhere (v6)
Deny incoming traffic from specific IP address.
$ sudo ufw deny in on ens18 from 192.168.8.199
Rule added
Deny outgoing traffic to specific port.
$ sudo ufw deny out 25/tcp
Rule added Rule added (v6)
Display firewall rules using numbered list.
$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp LIMIT IN Anywhere
[ 2] 192.168.8.156 53/tcp on ens18 ALLOW IN 192.168.8.0/24 (log)
[ 3] 192.168.8.156 53/udp on ens18 ALLOW IN 192.168.8.0/24 (log)
[ 4] 80/tcp ALLOW IN Anywhere
[ 5] Anywhere on ens18 DENY IN 192.168.8.199
[ 6] 25/tcp DENY OUT Anywhere (out)
[ 7] 22/tcp (v6) LIMIT IN Anywhere (v6)
[ 8] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 9] 25/tcp (v6) DENY OUT Anywhere (v6) (out)
Delete specific rule.
$ sudo ufw --force delete 5
Rule deleted
Insert rule at specific position.
$ sudo ufw insert 5 reject out 21/tcp
Rule inserted Rule inserted (v6)
Prepend specific rule.
$ sudo ufw prepend reject in on ens18 from 192.168.8.199
Rule inserted
Display firewall rules using numbered list.
$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] Anywhere on ens18 REJECT IN 192.168.8.199
[ 2] 22/tcp LIMIT IN Anywhere
[ 3] 192.168.8.156 53/tcp on ens18 ALLOW IN 192.168.8.0/24 (log)
[ 4] 192.168.8.156 53/udp on ens18 ALLOW IN 192.168.8.0/24 (log)
[ 5] 80/tcp ALLOW IN Anywhere
[ 6] 21/tcp REJECT OUT Anywhere (out)
[ 7] 25/tcp DENY OUT Anywhere (out)
[ 8] 22/tcp (v6) LIMIT IN Anywhere (v6)
[ 9] 80/tcp (v6) ALLOW IN Anywhere (v6)
[10] 21/tcp (v6) REJECT OUT Anywhere (v6) (out)
[11] 25/tcp (v6) DENY OUT Anywhere (v6) (out)
List added rules. Other reports include more information (raw, builtins, before-rules, user-rules, after-rules, logging-rules, , ,)
$ sudo ufw show added
Added user rules (see 'ufw status' for running firewall): ufw reject in on ens18 from 192.168.8.199 ufw limit 22/tcp ufw allow in on ens18 log from 192.168.8.0/24 to 192.168.8.156 port 53 proto tcp ufw allow in on ens18 log from 192.168.8.0/24 to 192.168.8.156 port 53 proto udp ufw allow 80/tcp ufw reject out 21/tcp ufw deny out 25/tcp
Inspect firewall rules
iptables
$ sudo iptables -L -v -n
Chain INPUT (policy DROP 3 packets, 96 bytes)
pkts bytes target prot opt in out source destination
26396 3770K ufw-before-logging-input all -- * * 0.0.0.0/0 0.0.0.0/0
26396 3770K ufw-before-input all -- * * 0.0.0.0/0 0.0.0.0/0
6699 518K ufw-after-input all -- * * 0.0.0.0/0 0.0.0.0/0
6512 490K ufw-after-logging-input all -- * * 0.0.0.0/0 0.0.0.0/0
6512 490K ufw-reject-input all -- * * 0.0.0.0/0 0.0.0.0/0
6512 490K ufw-track-input all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ufw-before-logging-forward all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ufw-before-forward all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ufw-after-forward all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ufw-after-logging-forward all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ufw-reject-forward all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ufw-track-forward all -- * * 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
18397 4058K ufw-before-logging-output all -- * * 0.0.0.0/0 0.0.0.0/0
18397 4058K ufw-before-output all -- * * 0.0.0.0/0 0.0.0.0/0
4105 1016K ufw-after-output all -- * * 0.0.0.0/0 0.0.0.0/0
4105 1016K ufw-after-logging-output all -- * * 0.0.0.0/0 0.0.0.0/0
4105 1016K ufw-reject-output all -- * * 0.0.0.0/0 0.0.0.0/0
4105 1016K ufw-track-output all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-after-forward (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-after-input (1 references)
pkts bytes target prot opt in out source destination
2 156 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:137
2 458 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:138
0 0 ufw-skip-to-policy-input tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:139
0 0 ufw-skip-to-policy-input tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:445
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:68
1 118 ufw-skip-to-policy-input all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type BROADCAST
Chain ufw-after-logging-forward (1 references)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "
Chain ufw-after-logging-input (1 references)
pkts bytes target prot opt in out source destination
2 64 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "
Chain ufw-after-logging-output (1 references)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW ALLOW] "
Chain ufw-after-output (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-before-forward (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 3
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 11
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 12
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
0 0 ufw-user-forward all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-before-input (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
265 18724 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ufw-logging-deny all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 3
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 11
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 12
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:67 dpt:68
9 899 ufw-not-local all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT udp -- * * 0.0.0.0/0 224.0.0.251 udp dpt:5353
0 0 ACCEPT udp -- * * 0.0.0.0/0 239.255.255.250 udp dpt:1900
9 899 ufw-user-input all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-before-logging-forward (1 references)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW AUDIT] "
Chain ufw-before-logging-input (1 references)
pkts bytes target prot opt in out source destination
8 867 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW AUDIT] "
Chain ufw-before-logging-output (1 references)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW AUDIT] "
Chain ufw-before-output (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0
165 35102 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ufw-user-output all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-logging-allow (0 references)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW ALLOW] "
Chain ufw-logging-deny (2 references)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW AUDIT INVALID] "
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "
Chain ufw-not-local (1 references)
pkts bytes target prot opt in out source destination
1 71 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
3 96 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type MULTICAST
5 732 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type BROADCAST
0 0 ufw-logging-deny all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 3/min burst 10
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-reject-forward (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-reject-input (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-reject-output (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-skip-to-policy-forward (0 references)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-skip-to-policy-input (7 references)
pkts bytes target prot opt in out source destination
5 732 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-skip-to-policy-output (0 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-track-forward (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-track-input (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-track-output (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW
Chain ufw-user-forward (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-user-input (1 references)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- ens18 * 192.168.8.199 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
0 0 ufw-user-limit tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW recent: UPDATE seconds: 30 hit_count: 6 name: DEFAULT side: source mask: 255.255.255.255
0 0 ufw-user-limit-accept tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
0 0 ufw-user-logging-input tcp -- ens18 * 192.168.8.0/24 192.168.8.156 tcp dpt:53
0 0 ACCEPT tcp -- ens18 * 192.168.8.0/24 192.168.8.156 tcp dpt:53
1 71 ufw-user-logging-input udp -- ens18 * 192.168.8.0/24 192.168.8.156 udp dpt:53
1 71 ACCEPT udp -- ens18 * 192.168.8.0/24 192.168.8.156 udp dpt:53
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
Chain ufw-user-limit (1 references)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 3/min burst 5 LOG flags 0 level 4 prefix "[UFW LIMIT BLOCK] "
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain ufw-user-limit-accept (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-user-logging-forward (0 references)
pkts bytes target prot opt in out source destination
Chain ufw-user-logging-input (2 references)
pkts bytes target prot opt in out source destination
0 0 LOG tcp -- ens18 * 192.168.8.0/24 192.168.8.156 tcp dpt:53 ctstate NEW limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW ALLOW] "
0 0 RETURN tcp -- ens18 * 192.168.8.0/24 192.168.8.156 tcp dpt:53
1 71 LOG udp -- ens18 * 192.168.8.0/24 192.168.8.156 udp dpt:53 ctstate NEW limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW ALLOW] "
1 71 RETURN udp -- ens18 * 192.168.8.0/24 192.168.8.156 udp dpt:53
Chain ufw-user-logging-output (0 references)
pkts bytes target prot opt in out source destination
Chain ufw-user-output (1 references)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:21 reject-with tcp-reset
0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25
nft
$ sudo nft list table filter
table ip filter {
chain ufw-before-logging-input {
ct state new limit rate 3/minute burst 10 packets counter packets 9 bytes 899 log prefix "[UFW AUDIT] "
}
chain ufw-before-logging-output {
ct state new limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW AUDIT] "
}
chain ufw-before-logging-forward {
ct state new limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW AUDIT] "
}
chain ufw-before-input {
iifname "lo" counter packets 0 bytes 0 accept
ct state related,established counter packets 341 bytes 23424 accept
ct state invalid counter packets 0 bytes 0 jump ufw-logging-deny
ct state invalid counter packets 0 bytes 0 drop
meta l4proto icmp icmp type destination-unreachable counter packets 0 bytes 0 accept
meta l4proto icmp icmp type time-exceeded counter packets 0 bytes 0 accept
meta l4proto icmp icmp type parameter-problem counter packets 0 bytes 0 accept
meta l4proto icmp icmp type echo-request counter packets 0 bytes 0 accept
meta l4proto udp udp sport 67 udp dport 68 counter packets 0 bytes 0 accept
counter packets 10 bytes 931 jump ufw-not-local
meta l4proto udp ip daddr 224.0.0.251 udp dport 5353 counter packets 0 bytes 0 accept
meta l4proto udp ip daddr 239.255.255.250 udp dport 1900 counter packets 0 bytes 0 accept
counter packets 10 bytes 931 jump ufw-user-input
}
chain ufw-before-output {
oifname "lo" counter packets 0 bytes 0 accept
ct state related,established counter packets 237 bytes 68654 accept
counter packets 0 bytes 0 jump ufw-user-output
}
chain ufw-before-forward {
ct state related,established counter packets 0 bytes 0 accept
meta l4proto icmp icmp type destination-unreachable counter packets 0 bytes 0 accept
meta l4proto icmp icmp type time-exceeded counter packets 0 bytes 0 accept
meta l4proto icmp icmp type parameter-problem counter packets 0 bytes 0 accept
meta l4proto icmp icmp type echo-request counter packets 0 bytes 0 accept
counter packets 0 bytes 0 jump ufw-user-forward
}
chain ufw-after-input {
meta l4proto udp udp dport 137 counter packets 2 bytes 156 jump ufw-skip-to-policy-input
meta l4proto udp udp dport 138 counter packets 2 bytes 458 jump ufw-skip-to-policy-input
meta l4proto tcp tcp dport 139 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
meta l4proto tcp tcp dport 445 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
meta l4proto udp udp dport 67 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
meta l4proto udp udp dport 68 counter packets 0 bytes 0 jump ufw-skip-to-policy-input
fib daddr type broadcast counter packets 1 bytes 118 jump ufw-skip-to-policy-input
}
chain ufw-after-output {
}
chain ufw-after-forward {
}
chain ufw-after-logging-input {
limit rate 3/minute burst 10 packets counter packets 3 bytes 96 log prefix "[UFW BLOCK] "
}
chain ufw-after-logging-output {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW ALLOW] "
}
chain ufw-after-logging-forward {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW BLOCK] "
}
chain ufw-reject-input {
}
chain ufw-reject-output {
}
chain ufw-reject-forward {
}
chain ufw-track-input {
}
chain ufw-track-output {
meta l4proto tcp ct state new counter packets 0 bytes 0 accept
meta l4proto udp ct state new counter packets 0 bytes 0 accept
}
chain ufw-track-forward {
}
chain INPUT {
type filter hook input priority filter; policy drop;
counter packets 26473 bytes 3774990 jump ufw-before-logging-input
counter packets 26473 bytes 3774990 jump ufw-before-input
counter packets 6700 bytes 517553 jump ufw-after-input
counter packets 6513 bytes 490325 jump ufw-after-logging-input
counter packets 6513 bytes 490325 jump ufw-reject-input
counter packets 6513 bytes 490325 jump ufw-track-input
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
counter packets 18469 bytes 4091957 jump ufw-before-logging-output
counter packets 18469 bytes 4091957 jump ufw-before-output
counter packets 4105 bytes 1016476 jump ufw-after-output
counter packets 4105 bytes 1016476 jump ufw-after-logging-output
counter packets 4105 bytes 1016476 jump ufw-reject-output
counter packets 4105 bytes 1016476 jump ufw-track-output
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
counter packets 0 bytes 0 jump ufw-before-logging-forward
counter packets 0 bytes 0 jump ufw-before-forward
counter packets 0 bytes 0 jump ufw-after-forward
counter packets 0 bytes 0 jump ufw-after-logging-forward
counter packets 0 bytes 0 jump ufw-reject-forward
counter packets 0 bytes 0 jump ufw-track-forward
}
chain ufw-logging-deny {
ct state invalid limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW AUDIT INVALID] "
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW BLOCK] "
}
chain ufw-logging-allow {
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW ALLOW] "
}
chain ufw-skip-to-policy-input {
counter packets 5 bytes 732 drop
}
chain ufw-skip-to-policy-output {
counter packets 0 bytes 0 accept
}
chain ufw-skip-to-policy-forward {
counter packets 0 bytes 0 drop
}
chain ufw-not-local {
fib daddr type local counter packets 1 bytes 71 return
fib daddr type multicast counter packets 4 bytes 128 return
fib daddr type broadcast counter packets 5 bytes 732 return
limit rate 3/minute burst 10 packets counter packets 0 bytes 0 jump ufw-logging-deny
counter packets 0 bytes 0 drop
}
chain ufw-user-input {
iifname "ens18" ip saddr 192.168.8.199 counter packets 0 bytes 0 reject
meta l4proto tcp tcp dport 22 ct state new # recent: SET name: DEFAULT side: source mask: 255.255.255.255 counter packets 0 bytes 0
meta l4proto tcp tcp dport 22 ct state new # recent: UPDATE seconds: 30 hit_count: 6 name: DEFAULT side: source mask: 255.255.255.255 counter packets 0 bytes 0 jump ufw-user-limit
meta l4proto tcp tcp dport 22 counter packets 0 bytes 0 jump ufw-user-limit-accept
iifname "ens18" meta l4proto tcp ip saddr 192.168.8.0/24 ip daddr 192.168.8.156 tcp dport 53 counter packets 0 bytes 0 jump ufw-user-logging-input
iifname "ens18" meta l4proto tcp ip saddr 192.168.8.0/24 ip daddr 192.168.8.156 tcp dport 53 counter packets 0 bytes 0 accept
iifname "ens18" meta l4proto udp ip saddr 192.168.8.0/24 ip daddr 192.168.8.156 udp dport 53 counter packets 1 bytes 71 jump ufw-user-logging-input
iifname "ens18" meta l4proto udp ip saddr 192.168.8.0/24 ip daddr 192.168.8.156 udp dport 53 counter packets 1 bytes 71 accept
meta l4proto tcp tcp dport 80 counter packets 0 bytes 0 accept
}
chain ufw-user-output {
meta l4proto tcp tcp dport 21 counter packets 0 bytes 0 reject with tcp reset
meta l4proto tcp tcp dport 25 counter packets 0 bytes 0 drop
}
chain ufw-user-forward {
}
chain ufw-user-logging-input {
iifname "ens18" meta l4proto tcp ip saddr 192.168.8.0/24 ip daddr 192.168.8.156 tcp dport 53 ct state new limit rate 3/minute burst 10 packets counter packets 0 bytes 0 log prefix "[UFW ALLOW] "
iifname "ens18" meta l4proto tcp ip saddr 192.168.8.0/24 ip daddr 192.168.8.156 tcp dport 53 counter packets 0 bytes 0 return
iifname "ens18" meta l4proto udp ip saddr 192.168.8.0/24 ip daddr 192.168.8.156 udp dport 53 ct state new limit rate 3/minute burst 10 packets counter packets 1 bytes 71 log prefix "[UFW ALLOW] "
iifname "ens18" meta l4proto udp ip saddr 192.168.8.0/24 ip daddr 192.168.8.156 udp dport 53 counter packets 1 bytes 71 return
}
chain ufw-user-logging-output {
}
chain ufw-user-logging-forward {
}
chain ufw-user-limit {
limit rate 3/minute counter packets 0 bytes 0 log prefix "[UFW LIMIT BLOCK] "
counter packets 0 bytes 0 reject
}
chain ufw-user-limit-accept {
counter packets 0 bytes 0 accept
}
}
Disable and reset configuration
Disable firewall.
$ sudo ufw disable
Firewall stopped and disabled on system startup
Reset firewall configuration.
$ sudo ufw --force reset
Backing up 'user.rules' to '/etc/ufw/user.rules.20231103_192008' Backing up 'before.rules' to '/etc/ufw/before.rules.20231103_192008' Backing up 'after.rules' to '/etc/ufw/after.rules.20231103_192008' Backing up 'user6.rules' to '/etc/ufw/user6.rules.20231103_192008' Backing up 'before6.rules' to '/etc/ufw/before6.rules.20231103_192008' Backing up 'after6.rules' to '/etc/ufw/after6.rules.20231103_192008'
Define and use application profiles
List application profiles.
$ sudo ufw app list
Available applications: Bind9 Nginx Full Nginx HTTP Nginx HTTPS OpenSSH
Display details for specific profile.
$ sudo ufw app info Nginx\ Full
Profile: Nginx Full Title: Web Server (Nginx, HTTP + HTTPS) Description: Small, but very powerful and efficient web server Ports: 80,443/tcp
List and display these these definitions.
$ ls /etc/ufw/applications.d/
bind9 nginx openssh-server
$ cat /etc/ufw/applications.d/bind9
[Bind9] title=Internet Domain Name Server description=The Berkeley Internet Name Domain (BIND) implements an Internet domain name server. ports=53
$ cat /etc/ufw/applications.d/nginx
[Nginx HTTP] title=Web Server (Nginx, HTTP) description=Small, but very powerful and efficient web server ports=80/tcp [Nginx HTTPS] title=Web Server (Nginx, HTTPS) description=Small, but very powerful and efficient web server ports=443/tcp [Nginx Full] title=Web Server (Nginx, HTTP + HTTPS) description=Small, but very powerful and efficient web server ports=80,443/tcp
$ cat /etc/ufw/applications.d/openssh-server
[OpenSSH] title=Secure shell server, an rshd replacement description=OpenSSH is a free implementation of the Secure Shell protocol. ports=22/tcp
Allow specific application.
$ sudo ufw allow OpenSSH
Rules updated Rules updated (v6)
Allow specific application using rich rule.
$ sudo ufw allow in on ens18 from any app Nginx\ Full
Rules updated Rules updated (v6)
Display firewall status.
$ sudo ufw status verbose
Status: active Logging: on (medium) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp (OpenSSH) ALLOW IN Anywhere Anywhere on ens18 ALLOW IN 80,443/tcp (Nginx Full) 22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6) Anywhere (v6) on ens18 ALLOW IN 80,443/tcp (Nginx Full (v6))
Update application profile.
$ cat <<EOF | sudo tee /etc/ufw/applications.d/nginx [Nginx HTTP] title=Web Server (Nginx, HTTP) description=Small, but very powerful and efficient web server ports=80/tcp [Nginx HTTPS] title=Web Server (Nginx, HTTPS) description=Small, but very powerful and efficient web server ports=443/tcp [Nginx Full] title=Web Server (Nginx, HTTP + HTTPS) description=Small, but very powerful and efficient web server ports=80,443|8080/udp EOF
Verify application profile.
$ sudo ufw app info Nginx\ Full
Profile: Nginx Full Title: Web Server (Nginx, HTTP + HTTPS) Description: Small, but very powerful and efficient web server Ports: 80,443/tcp 8080/udp
Inspect current rules related to this application.
$ sudo ufw show user-rules| grep Nginx%20Full
0 0 ACCEPT tcp -- ens18 * 0.0.0.0/0 0.0.0.0/0 multiport sports 80,443 /* 'sapp_Nginx%20Full' */
0 0 ACCEPT tcp ens18 * ::/0 ::/0 multiport sports 80,443 /* 'sapp_Nginx%20Full' */
Update application profile.
$ sudo ufw app update Nginx\ Full
Rules updated for profile 'Nginx Full' Skipped reloading firewall
Reload firewall configuration.
$ sudo ufw reload
Firewall reloaded
Inspect current rules related to this application.
$ sudo ufw show user-rules| grep Nginx%20Full
0 0 ACCEPT tcp -- ens18 * 0.0.0.0/0 0.0.0.0/0 multiport sports 80,443 /* 'sapp_Nginx%20Full' */
0 0 ACCEPT udp -- ens18 * 0.0.0.0/0 0.0.0.0/0 multiport sports 8080 /* 'sapp_Nginx%20Full' */
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443 /* 'dapp_Nginx%20Full' */
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 8080 /* 'dapp_Nginx%20Full' */
0 0 ACCEPT tcp ens18 * ::/0 ::/0 multiport sports 80,443 /* 'sapp_Nginx%20Full' */
0 0 ACCEPT udp ens18 * ::/0 ::/0 multiport sports 8080 /* 'sapp_Nginx%20Full' */
0 0 ACCEPT tcp * * ::/0 ::/0 multiport dports 80,443 /* 'dapp_Nginx%20Full' */
0 0 ACCEPT udp * * ::/0 ::/0 multiport dports 8080 /* 'dapp_Nginx%20Full' */
Alternatively, you can change default application policy to allow automatic update of the firewall, but from my point of view it causes only more problems, so I am against of using it and simply removed this part.
Create custom rules
Use /etc/ufw/before[6].rules and /etc/ufw/after[6].rules to store custom rules, but remember that these files are overwritten during reset operation.
Inspect rules added before these defined by user.
$ sudo ufw show before-rules
IPV4 (before):
Chain ufw-before-input (1 references)
pkts bytes target prot opt in out source destination
8 1228 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
1144 1057484 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ufw-logging-deny all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 3
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 11
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 12
1 84 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:67 dpt:68
12 1122 ufw-not-local all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT udp -- * * 0.0.0.0/0 224.0.0.251 udp dpt:5353
0 0 ACCEPT udp -- * * 0.0.0.0/0 239.255.255.250 udp dpt:1900
12 1122 ufw-user-input all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-before-forward (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 3
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 11
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 12
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
0 0 ufw-user-forward all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-before-output (1 references)
pkts bytes target prot opt in out source destination
8 1228 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0
957 123916 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
4 260 ufw-user-output all -- * * 0.0.0.0/0 0.0.0.0/0
IPV6:
Chain ufw6-before-input (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all lo * ::/0 ::/0
0 0 DROP all * * ::/0 ::/0 rt type:0
0 0 ACCEPT all * * ::/0 ::/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 129
0 0 ufw6-logging-deny all * * ::/0 ::/0 ctstate INVALID
0 0 DROP all * * ::/0 ::/0 ctstate INVALID
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 1
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 2
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 3
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 4
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 128
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 133 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 134 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 135 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 136 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 141 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 142 HL match HL == 255
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 130
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 131
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 132
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 143
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 148 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 149 HL match HL == 255
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 151 HL match HL == 1
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 152 HL match HL == 1
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 153 HL match HL == 1
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 144
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 145
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 146
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 147
0 0 ACCEPT udp * * fe80::/10 fe80::/10 udp spt:547 dpt:546
0 0 ACCEPT udp * * ::/0 ff02::fb udp dpt:5353
0 0 ACCEPT udp * * ::/0 ff02::f udp dpt:1900
0 0 ufw6-user-input all * * ::/0 ::/0
Chain ufw6-before-forward (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP all * * ::/0 ::/0 rt type:0
0 0 ACCEPT all * * ::/0 ::/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 1
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 2
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 3
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 4
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 128
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 129
0 0 ufw6-user-forward all * * ::/0 ::/0
Chain ufw6-before-output (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all * lo ::/0 ::/0
0 0 DROP all * * ::/0 ::/0 rt type:0
0 0 ACCEPT all * * ::/0 ::/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 1
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 2
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 3
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 4
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 128
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 129
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 133 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 136 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 135 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 134 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 141 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 142 HL match HL == 255
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 130
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 131
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 132
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 143
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 148 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 149 HL match HL == 255
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 151 HL match HL == 1
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 152 HL match HL == 1
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 153 HL match HL == 1
0 0 ufw6-user-output all * * ::/0 ::/0
Modify /etc/ufw/before.rules file.
$ cat <<EOF | sudo tee /etc/ufw/before.rules # # rules.before # # Rules that should be run before the ufw command line added rules. Custom # rules should be added to one of these chains: # ufw-before-input # ufw-before-output # ufw-before-forward # # Don't delete these required lines, otherwise there will be errors *filter :ufw-before-input - [0:0] :ufw-before-output - [0:0] :ufw-before-forward - [0:0] :ufw-not-local - [0:0] # End required lines # allow all on loopback -A ufw-before-input -i lo -j ACCEPT -A ufw-before-output -o lo -j ACCEPT # quickly process packets for which we already have a connection -A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # drop INVALID packets (logs these in loglevel medium and higher) -A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny -A ufw-before-input -m conntrack --ctstate INVALID -j DROP # ok icmp codes for INPUT -A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT -A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT -A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT -A ufw-before-input -p icmp --icmp-type echo-request -j DROP # ok icmp code for FORWARD -A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT -A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT -A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT -A ufw-before-forward -p icmp --icmp-type echo-request -j DROP # allow dhcp client to work -A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT # # ufw-not-local # -A ufw-before-input -j ufw-not-local # if LOCAL, RETURN -A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN # if MULTICAST, RETURN -A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN # if BROADCAST, RETURN -A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN # all other non-local packets are dropped -A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny -A ufw-not-local -j DROP # allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above # is uncommented) -A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT # allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above # is uncommented) -A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT # don't delete the 'COMMIT' line or these rules won't be processed COMMIT EOF
Reload firewall configuration.
$ sudo ufw reload
Firewall reloaded
Inspect changes.
$ sudo ufw show before-rules
IPV4 (before):
Chain ufw-before-input (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
73 5268 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ufw-logging-deny all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 3
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 11
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 12
0 0 DROP icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:67 dpt:68
0 0 ufw-not-local all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT udp -- * * 0.0.0.0/0 224.0.0.251 udp dpt:5353
0 0 ACCEPT udp -- * * 0.0.0.0/0 239.255.255.250 udp dpt:1900
0 0 ufw-user-input all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-before-forward (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 3
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 11
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 12
0 0 DROP icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
0 0 ufw-user-forward all -- * * 0.0.0.0/0 0.0.0.0/0
Chain ufw-before-output (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0
65 8144 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ufw-user-output all -- * * 0.0.0.0/0 0.0.0.0/0
IPV6:
Chain ufw6-before-input (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all lo * ::/0 ::/0
0 0 DROP all * * ::/0 ::/0 rt type:0
0 0 ACCEPT all * * ::/0 ::/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 129
0 0 ufw6-logging-deny all * * ::/0 ::/0 ctstate INVALID
0 0 DROP all * * ::/0 ::/0 ctstate INVALID
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 1
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 2
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 3
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 4
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 128
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 133 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 134 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 135 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 136 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 141 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 142 HL match HL == 255
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 130
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 131
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 132
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 143
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 148 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 149 HL match HL == 255
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 151 HL match HL == 1
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 152 HL match HL == 1
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 153 HL match HL == 1
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 144
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 145
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 146
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 147
0 0 ACCEPT udp * * fe80::/10 fe80::/10 udp spt:547 dpt:546
0 0 ACCEPT udp * * ::/0 ff02::fb udp dpt:5353
0 0 ACCEPT udp * * ::/0 ff02::f udp dpt:1900
0 0 ufw6-user-input all * * ::/0 ::/0
Chain ufw6-before-forward (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP all * * ::/0 ::/0 rt type:0
0 0 ACCEPT all * * ::/0 ::/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 1
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 2
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 3
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 4
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 128
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 129
0 0 ufw6-user-forward all * * ::/0 ::/0
Chain ufw6-before-output (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all * lo ::/0 ::/0
0 0 DROP all * * ::/0 ::/0 rt type:0
0 0 ACCEPT all * * ::/0 ::/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 1
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 2
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 3
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 4
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 128
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 129
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 133 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 136 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 135 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 134 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 141 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 142 HL match HL == 255
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 130
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 131
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 132
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 143
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 148 HL match HL == 255
0 0 ACCEPT icmpv6 * * ::/0 ::/0 ipv6-icmptype 149 HL match HL == 255
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 151 HL match HL == 1
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 152 HL match HL == 1
0 0 ACCEPT icmpv6 * * fe80::/10 ::/0 ipv6-icmptype 153 HL match HL == 1
0 0 ufw6-user-output all * * ::/0 ::/0
Inspect rules added after these defined by user.
$ sudo ufw show after-rules
IPV4 (after):
Chain ufw-after-input (1 references)
pkts bytes target prot opt in out source destination
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:137
2 484 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:138
0 0 ufw-skip-to-policy-input tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:139
0 0 ufw-skip-to-policy-input tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:445
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:68
0 0 ufw-skip-to-policy-input all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type BROADCAST
Chain ufw-after-forward (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-after-output (1 references)
pkts bytes target prot opt in out source destination
IPV6:
Chain ufw6-after-input (1 references)
pkts bytes target prot opt in out source destination
0 0 ufw6-skip-to-policy-input udp * * ::/0 ::/0 udp dpt:137
0 0 ufw6-skip-to-policy-input udp * * ::/0 ::/0 udp dpt:138
0 0 ufw6-skip-to-policy-input tcp * * ::/0 ::/0 tcp dpt:139
0 0 ufw6-skip-to-policy-input tcp * * ::/0 ::/0 tcp dpt:445
0 0 ufw6-skip-to-policy-input udp * * ::/0 ::/0 udp dpt:546
0 0 ufw6-skip-to-policy-input udp * * ::/0 ::/0 udp dpt:547
Chain ufw6-after-forward (1 references)
pkts bytes target prot opt in out source destination
Chain ufw6-after-output (1 references)
pkts bytes target prot opt in out source destination
Append custom rules.
$ cat <<EOF | sudo tee /etc/ufw/after.rules # # rules.input-after # # Rules that should be run after the ufw command line added rules. Custom # rules should be added to one of these chains: # ufw-after-input # ufw-after-output # ufw-after-forward # # Don't delete these required lines, otherwise there will be errors *filter :ufw-after-input - [0:0] :ufw-after-output - [0:0] :ufw-after-forward - [0:0] # End required lines # don't log noisy services by default -A ufw-after-input -p udp --dport 137 -j ufw-skip-to-policy-input -A ufw-after-input -p udp --dport 138 -j ufw-skip-to-policy-input -A ufw-after-input -p tcp --dport 139 -j ufw-skip-to-policy-input -A ufw-after-input -p tcp --dport 445 -j ufw-skip-to-policy-input -A ufw-after-input -p udp --dport 67 -j ufw-skip-to-policy-input -A ufw-after-input -p udp --dport 68 -j ufw-skip-to-policy-input # don't log noisy broadcast -A ufw-after-input -m addrtype --dst-type BROADCAST -j ufw-skip-to-policy-input # custom rules -A ufw-after-input -i ens18 -p tcp --dport 80 -j ACCEPT -m comment --comment 'CustomNginx' -A ufw-after-input -i ens18 -p tcp --dport 22 -j ACCEPT -m comment --comment 'CustomOpenSSH' # don't delete the 'COMMIT' line or these rules won't be processed COMMIT EOF
Reload firewall configuration.
$ sudo ufw reload
Firewall reloaded
Verify changes.
$ sudo ufw show after-rules
IPV4 (after):
Chain ufw-after-input (1 references)
pkts bytes target prot opt in out source destination
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:137
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:138
0 0 ufw-skip-to-policy-input tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:139
0 0 ufw-skip-to-policy-input tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:445
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ufw-skip-to-policy-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:68
0 0 ufw-skip-to-policy-input all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type BROADCAST
0 0 ACCEPT tcp -- ens18 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 /* 'CustomNginx' */
0 0 ACCEPT tcp -- ens18 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 /* 'CustomOpenSSH' */
Chain ufw-after-forward (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-after-output (1 references)
pkts bytes target prot opt in out source destination
IPV6:
Chain ufw6-after-input (1 references)
pkts bytes target prot opt in out source destination
0 0 ufw6-skip-to-policy-input udp * * ::/0 ::/0 udp dpt:137
0 0 ufw6-skip-to-policy-input udp * * ::/0 ::/0 udp dpt:138
0 0 ufw6-skip-to-policy-input tcp * * ::/0 ::/0 tcp dpt:139
0 0 ufw6-skip-to-policy-input tcp * * ::/0 ::/0 tcp dpt:445
0 0 ufw6-skip-to-policy-input udp * * ::/0 ::/0 udp dpt:546
0 0 ufw6-skip-to-policy-input udp * * ::/0 ::/0 udp dpt:547
Chain ufw6-after-forward (1 references)
pkts bytes target prot opt in out source destination
Chain ufw6-after-output (1 references)
pkts bytes target prot opt in out source destination
Missing log file
The ufw.log file is missing, so everything ends up in the syslog log file.
Simply create this file and restart rsyslogd daemon to fix this issue.
$ sudo install --owner syslog --group syslog --mode 640 /dev/null /var/log/ufw.log
$ sudo systemctl restart rsyslog
Inspect log file.
$ sudo tail /var/log/ufw.log
Nov 3 22:31:00 jammy kernel: [956617.666640] [UFW AUDIT] IN=ens18 OUT= MAC=72:0b:29:24:9a:0a:74:36:9a:ca:1d:ae:08:00 SRC=192.168.8.200 DST=192.168.8.156 LEN=73 TOS=0x00 PREC=0x00 TTL=63 ID=22719 PROTO=UDP SPT=51254 DPT=53 LEN=53 Nov 3 22:31:00 jammy kernel: [956617.666691] [UFW ALLOW] IN=ens18 OUT= MAC=72:0b:29:24:9a:0a:74:36:9a:ca:1d:ae:08:00 SRC=192.168.8.200 DST=192.168.8.156 LEN=73 TOS=0x00 PREC=0x00 TTL=63 ID=22719 PROTO=UDP SPT=51254 DPT=53 LEN=53 Nov 3 22:31:10 jammy kernel: [956628.403157] [UFW AUDIT] IN=ens18 OUT= MAC=01:00:5e:00:00:01:00:38:a4:0b:0e:68:08:00 SRC=192.168.8.1 DST=224.0.0.1 LEN=32 TOS=0x00 PREC=0xC0 TTL=1 ID=21693 PROTO=2 Nov 3 22:31:10 jammy kernel: [956628.403208] [UFW BLOCK] IN=ens18 OUT= MAC=01:00:5e:00:00:01:00:38:a4:0b:0e:68:08:00 SRC=192.168.8.1 DST=224.0.0.1 LEN=32 TOS=0x00 PREC=0xC0 TTL=1 ID=21693 PROTO=2
Additional information
Please read ufw-framework and ufw manual pages and use Ansible to manage firewall with UFW.