iptables and firewalld tricks

Cause

Some libev port version of something does not support the --forbidden-ip option. To avoid SMTP abuse, originally I moved back to the python version of it.

Later I found python version has some bugs and crashes for unknown reasons, so I try to implement the ip blocking feature in other ways.

Iptables Owner Module

The owner module provides functionality that we can filter out packets from a specific command name(deprecated), process id(deprecated), user and group id. So the only way may be to spawn the process under a specific user or group.

Privileged Ports

However, connection to non-privileged ports are under severe interference, but non-root users’ process cannot bind those ports, and of course, it’s ridiculous to forbid root from access localhosts.

Fortunately, I find that there exists a command to allow a specific executable to bind these ports:

1
setcap 'cap_net_bind_service=+ep' /path/to/exec

While this method still seems to have some security issues, it’s the best solution I knew.

Conclusion

  1. Create a user.
  2. Add the following rules into the iptables where $UID is the created user.
    1
    2
    iptables -A OUTPUT -m owner --uid-owner $UID -d 127.0.0.1 -j DROP
    iptables -A OUTPUT -m owner --uid-owner $UID -d ::1 -j DROP

If you use RHEL 7 or something that already adopts firewalld, just use

1
2
3
4
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 \
-m owner --uid-owner $UID -d 127.0.0.1 -j DROP
firewall-cmd --permanent --direct --add-rule ipv6 filter OUTPUT 0 \
-m owner --uid-owner $UID -d ::1 -j DROP

  1. Start the service as the user you created.
Share