firewalld / firewalld

Stateful zone based firewall daemon with D-Bus interface
GNU General Public License v2.0
878 stars 275 forks source link

RFE: socket UID and GID matching #725

Open Bogdan107 opened 3 years ago

Bogdan107 commented 3 years ago

I am using a firewall on my laptop and I have no relationship to networking.

Production routers:

Personal laptop:

Long time I using self-writted script for control nftables daemon. Now I am learning firewald and have some troubles due to the fact that firewalld does not have some feature, because focused to serving forwarded network packets as many others firewall's...

I usу DENY policy by default, and allow network usage only for controlled list of system users. Users with uid>=1000 can connect to internet only over local proxy (like squid or privoxy), and each user program (web-browser, torrent, media-player) for network activity outside the laptop must have their own login/password for proxy authentification.

Some lines from my script:

# Prepare sets: nft add rule inet filter output tcp dport @tcp_port_out_allow ct state new counter accept; nft add rule inet filter input tcp dport @tcp_port_in_allow ct state new counter accept; nft add rule inet filter output udp dport @udp_port_out_allow ct state new counter accept; nft add rule inet filter input udp dport @udp_port_in_allow ct state new counter accept; nft add rule inet filter output meta skuid @user_out_allow ct state new counter accept; nft add rule inet filter input meta skuid @user_in_allow ct state new counter accept;

nft add rule inet filter output tcp dport @tcp_port_out_deny ct state new counter drop; nft add rule inet filter input tcp dport @tcp_port_in_deny ct state new counter drop; nft add rule inet filter output udp dport @udp_port_out_deny ct state new counter drop; nft add rule inet filter input udp dport @udp_port_in_deny ct state new counter drop; nft add rule inet filter output meta skuid @user_out_deny ct state new counter drop; nft add rule inet filter input meta skuid @user_in_deny ct state new counter drop;

# Allow basic network activity for all users: nft add element inet filter udp_port_out_allow { 53, 123, 1900 }; nft add element inet filter tcpp_port_out_allow { 53, 123, 1900, 6667 };

# Allow full network activity for list of users: nft add element inet filter user_out_allow { root, portage, sync, ddclient, ntp, dnscrypt-proxy, miredo, i2pd, tor, privoxy };

# Allow limited network activity for 'squid' user: nft add rule inet filter output meta skuid { squid } tcp dport { 21, 80-88, 443 } ct state new counter accept;

I need command line options for:

erig0 commented 3 years ago

What's missing is skuid and skgid matching. Then you could use rich rules. e.g.

# firewalld -cmd --add-rich-rule='port port=1234 protocol=tcp socket uid=1000 accept'

Firewalld currently lacks the socked uid=1000 support. We should also be able to support actual user names, e.g. socket uid=root.

ragnvaldf commented 3 years ago

I also need skuid and skgid matching on puppet-managed RHEL with firewalld+nftables. Is there any known workarounds for this use case?

erig0 commented 3 years ago

I also need skuid and skgid matching on puppet-managed RHEL with firewalld+nftables. Is there any known workarounds for this use case?

No. If you want to DROP traffic based on skuid/skgid, then you can use a direct rule. But ACCEPT won't work as the packet still needs to pass through nftables.

ragnvaldf commented 3 years ago

Thank you for advice @erig0 . This solved my current problem: firewall-cmd --direct --add-rule ipv4 filter OUTPUT 0 -d xxx.xxx.xxx.xxx/32 -p tcp -m tcp --dport 443 -m owner ! --uid only_allowed_user -j REJECT --reject-with icmp-port-unreachable

Talkless commented 2 years ago

+1 for skuid/skgid matching support!

erig0 commented 2 years ago

PSA: upstream nftables has proposed patches for INPUT and OUTPUT socket matching. Currently skuid/skgid matching is limited to OUTPUT only.

INPUT support means we could say things like "only apache can accept https connections".

Bogdan107 commented 2 years ago

PSA: upstream nftables has proposed patches for INPUT and OUTPUT socket matching. Currently skuid/skgid matching is limited to OUTPUT only.

INPUT support means we could say things like "only apache can accept https connections".

Yes! I want a quick and easy mechanism to limit just OUTPUT traffic! This is an extremely high priority function for me!

With this function, I can allow only WHITELISTED programs. So, any user installed programs, which needs to use internet, must be configured to use system proxy server (in my case - this is Privoxy) or configured personally by firewalld administrator. So, any unconfigured program can-not access internet or can use internel only in very limited mode.

For example:

Rule 1: Allow OUTPUT connections for whitelisted users:

Rule 2: Allow OUTPUT to the internal proxy servers:

Rule 3: Allow OUTPUT to the external proxy servers:

Rule 4: Disallow OUTPUT connections for non-whitelisted users or non-configured programs:

With this rules:

My proposal:

Add new tab "Limit OUTPUT" into Settings/Zones/\/Limit OUTPUT. This tab has:

If user select checkbox "Deny OUTPUT connections from all unselected users/groups", then spinbox with "Limit rate" must be disabled. If user select checkbox "Use global configuration", then config for limit output conenctions per zone must be as in global config for "Limit OUTPUT" (e.g. config for zone must use "jump" to global chain, which configured for control output connections).

Changes by my proposal - is trivial or usual, but not "feat".

erig0 commented 2 years ago

The more I think about socket matching, the more I like the idea of implementing them as a zone source, e.g. --zone apache --add-source gid:apache. Then you can use the zone and policy filtering features.

# firewall-cmd --zone apache --add-service https

This also means different processes groups (e.g. users, cgroups) can be represented by zones.

Talkless commented 2 years ago

I might be really mistaken (as I am not yet firewalld user), but that example firewall-cmd --zone apache --add-service https would not work because skuid/skgid only works for OUTPUT, meanwhile zones in firewalld is about INPUT?

For policies though I do get it, as policies implement OUTPUT / FORWARD filtering, right?

erig0 commented 2 years ago

I might be really mistaken (as I am not yet firewalld user), but that example firewall-cmd --zone apache --add-service https would not work because skuid/skgid only works for OUTPUT, meanwhile zones in firewalld is about INPUT?

IIRC, there were recent nftables patches to allow INPUT socket matching. i.e. meta skuid, meta skgid, and meta cgroup should work on both INPUT/OUTPUT on modern kernel/nftables.

I have not verified this though.

erig0 commented 2 years ago

Adding "blocked" because this requires support in nftables.