UFW: Allow app/profile only from specific IP

I want to restrict external access to e. g. Dovecot to specific source IPs. Allowing an app profile works great at all, but the connection's source is never limited ("From: Anywhere"):

$ sudo ufw status

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Nginx Full                 ALLOW       Anywhere                  
Postfix                    ALLOW       Anywhere                  
Dovecot IMAP               ALLOW       Anywhere      

But how can I restrict Dovecot IMAP to a specific source IP?

I tried:

$ sudo ufw allow "Dovecot IMAP" from 1.1.1.1
ERROR: Wrong number of arguments

So this seems not working...

Asking for Ubuntu 20.04 LTS, ufw 0.36


The short answer:

sudo ufw allow from <IP adress>/<subnet mask> to any app <profile name>

Remember to quote 'Dovecot IMAP', in your case.

The long answer:

I tried: $ sudo ufw allow "Dovecot IMAP" from 1.1.1.1

Tho that would be the most intuitive command, the syntax is a little trickier.

I don't know what Dovecot IMAP is, so I'll take OpenVPN as an example.


We want to allow an app profile trough ufw only if it comes from a certain IP/subnet.

Consider we have the following ufw app profile in /etc/ufw/applications.d/ named openvpn (the profile filename is important here):

[OpenVPN]
title=OpenVPN server
description=This rule allows connections to VPN server at <servername>.
ports=8880/udp

NOTE: We're using a customized port here for OpenVPN.

Now add the rule to ufw with:

 sudo ufw allow from 10.0.0.0/24 to any app openvpn

This will open the port specified in /etc/ufw/applications.d/openvpn for incoming connections from 10.0.0.0/24.

And check:

sudo ufw status verbose

If it worked you should have an output like:

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

To                         Action      From
--                         ------      ----
8880/udp (OpenVPN)         ALLOW IN    10.0.0.0/24

Be careful with the profile filename and the service name.

sudo ufw allow from 10.0.0.0/24 proto udp to any port openvpn

This is a very similar syntax, also correct. But it applies to the service's port configuration in /etc/services , wich may not be the one you want to allow (like we changed OpenVPN port to 8880). In this case, we still have the following in /etc/services :

openvpn         1194/tcp
openvpn         1194/udp

Ufw recognizes openvpn as the service, unless we say something else.

any port openvpn (<- service)

any app openvpn (<- app profile)

So issuing sudo ufw allow from 10.0.0.0/24 proto udp to any port openvpn results in:

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

To                         Action      From
--                         ------      ----
1194/udp                   ALLOW IN    10.0.0.0/24

This way we effectively opened a port for OpenVPN, but not the port we specified in our /etc/ufw/applications.d/openvpn app profile.

Never tried but should work if you change the port in /etc/services (risking to break something else).

You can check this Ubuntu manpage for detailed info on the ufw command.

Hope it helps.