Help with IPTables or..? (coming from ipfw FreeBSD)

I’m looking to recreate what I had going in a FreeBSD 11.2 (FreeNAS really) iocage jail, in a Linux environment. In the FreeBSD jail I basically took this guide to setup OpenVPN with PrivateInternetAccess, and then not permit any traffic outside the LAN if the tunnel were to go down. In addition to Transmission as outlined in the guide, I also configured ipfw to block other services such as Jackett, Radarr, and Sonarr.

So in the end, here is what the output of “ipfw list” looks like:

root@PirateVPN:~ # ipfw list
00001 allow ip from any to any via lo0
00010 allow ip from any to any via tun0
00101 allow ip from me to 192.168.1.0/24 uid transmission
00102 allow ip from 192.168.1.0/24 to me uid transmission
00110 allow ip from me to 192.168.1.0/24 uid jackett
00111 allow ip from 192.168.1.0/24 to me uid jackett
00112 allow ip from me to 192.168.1.0/24 uid sonarr
00113 allow ip from 192.168.1.0/24 to me uid sonarr
00114 allow ip from me to 192.168.1.0/24 uid radarr
00115 allow ip from 192.168.1.0/24 to me uid radarr
00116 allow ip from me to 192.168.1.0/24 uid _sabnzbd
00117 allow ip from 192.168.1.0/24 to me uid _sabnzbd
00120 deny ip from any to any uid transmission
00121 deny ip from any to any uid jackett
00122 deny ip from any to any uid sonarr
00123 deny ip from any to any uid radarr
00124 deny ip from any to any uid _sabnzbd
65535 allow ip from any to any

Now I’m a longtime Windows user, somewhat comfortable with FreeNAS (no expert by any means), but I’m a Linux newbie. I haven’t decided the distro yet, but it’s probably going to be Debian 9 or Ubuntu 18 LTS. I’ve played around in a VM just setting up the different programs, and they work without issue. The eventual goal is to migrate most of my stuff from FreeNAS into a ProxMox server, and I found a great guide on here that’s going to be a huge help (How To Create A NAS Using ZFS and Proxmox (with pictures))

So I’m assuming the way to go here is iptables. Is something like this easily re-creatable? I don’t need it done for me, just pointed in the right direction. Love watching the YouTube channel so figured I’d hop in here :smile:

I’d say play around with firewalld if you want a gui. Reckon it can do what you want.

1 Like

Nope, I don’t really care about a GUI. I will be running a server based Linux distro with no window manager and only access it via SSH.

But would it still be possible to use firewalld GUI under those circumstances?

X11 over ssh

Yes you can do all that with policy routing and firewall rules in linux. Netfilter is the kernel framework that, among other things, handles packet filtering. Iptables is a common userland frontend to add/modify netfilter rules. It’s been mostly the same since kernel 2.6 and is well documented in many places including The Linux Documentation Project in the howto: Linux Advanced Routing & Traffic Control

For your firewall rules they all belong in the filter table in the OUTPUT/FORWARD/INPUT chains.

And rules in the OUTPUT chain can use the owner extension to match against the originating uid. You can read the specifics about the owner extension in the iptables-extensions man page, but your rule would look something similar to:

iptables -t filter -A OUTPUT -d 192.168.1.0/24 -m owner --uid-owner transmission -j ACCEPT 

For your input rules you will have to use other extensions like protocol/port/source address. And through the conntrack extension, the entire state machine is available, so it shouldn’t be hard to come up with rules.

For simple source based policy routing, iproute2 is the preferred package. If you need something more granular than just source address, you can route based on a packet mark:

ip rule add fwmark (mark-value) [table table_name] [priority priority_value]

And you can use iptables and the mangle table which has PREROUTING/INPUT/OUTPUT/FORWARD/POSTROUTING chains with the MARK --set-mark (mark-value) to mark packets based on anything.

If you want a related openvpn/iptables/polixy routing example to start you off, I posted this:

about two years ago when I was trying to figure out why responses to marked packets were being dropped. I eventually found the answer in a circa kernel 2.6 mailing list referencing and edge case with SNAT/MASQUERADE and the reverse path filter, so if rp_filter is enabled (which is by default on debian based distros), the return packets get dropped.

Thanks for the detailed reply! Rather than define the rules based on the services (transmission, radarr, etc…) - would something like this work just as well?

https://zorrovpn.com/articles/linux-iptables-vpn-only?lang=en

Instead of individually defining the IPs for LAN traffic I would just use my subnet.

firewalld also has a CLI.

I’m not sure if it is on every linux these days, or just Fedora/RHEL specific (i’m sure someone will correct me) but it abstracts a lot of the low level crap (e.g. which config file to edit, making mistakes in it, etc.) and enables you to add either temp or permanent firewall rules (or commit the current set to permanence) by specifying either service names or TCP/UDP ports, supports multiple zones, etc.

Check out man firewall-cmd for more info.

Essentially, firewall-cmd is sort of a user-friendly interface to the low level stuff that is actually done by iptables, etc.

I’d also suggest that using firewall-cmd with firewalld is likely more prevalent in an enterprise environment where say Centos or RHEL is deployed.

Couple things to add:

Ubuntu uses ufw by default (still iptables backend afaik)

https://help.ubuntu.com/lts/serverguide/firewall.html.en

Debian is deprecating iptables for nftables in Buster.

https://wiki.debian.org/nftables

I have a very basic iptables example script here. Which shows how to structure a filter table.

On a Debian / Ubuntu headless box create /etc/network/if-pre-up.d/iptables & make it executable with chmod +x:

 #!/bin/sh
 
 /sbin/iptables-restore -c < /etc/iptables/iptables-save

& in your root ~/.bashrc or wherever you keep your shell aliases add something like:

alias fwedit='nano /etc/iptables.rules'
alias fwload='iptables-restore < /etc/iptables.rules && iptables-restore < /etc/iptables.nat.rules'
alias fwsave='iptables-save > /etc/iptables/iptables-save'

In Linux your main firewall table is filter & you also have nat / raw / mangle. If you use functionality from ipset to protect your system these rules should go in the raw table.

In your shell you can then just type fwedit / fwload / fwsave to manage your firewall without a gui.

It’s probable that I am not sure exactly what you are trying to do, but my initial understanding was that you have a host on your local network that you only want to be able to communicate with the internet through an vpn connection to PIA, but traffic destined for other local hosts does not need to go (and can’t go) through PIA.

If that is correct, you can do that with the iptables rules you linked, but there is a much simpler way: set the default route through the PIA tun device and specific routes through your ethernet interface for local subnets.

 ip route add 192.168.1.0/24 dev eth0
 ip route add default dev tun0

Prior to adding those routes, you will probably need to delete the current default route and add a route to PIA’s server’s address via your former default gateway address. That is stuff that openvpn would do for you if you had a redirect-gateway option in your local config or pushed to you from PIA

Just a side note here, but you might also be interested in checking out tc and/or nftables. Doing what you ask with nftables would be something like (code not tested, double check with tutorials!):

nft add rule ip output tcp daddr 192.168.1.0/24 dport {transmission, jackett, sonarr, radarr, _sabnzbd} allow
nft add rule ip input tcp saddr 192.168.1.0/24 dport {transmission, jackett, sonarr, radarr, _sabnzbd} allow
nft add rule ip output { tcp, udp } deny