mirroring traffic with iptables doesn't work - iptables

I want to mirror specific traffic to ip 192.168.200.1
I use the following solution:
Mirror Port via iptables
However, when I enter following command, this error occurs:
iptables –I PREROUTING -t mangle -j ROUTE --gw 192.168.200.1 --tee
iptables v1.4.12: unknown option "--gw"
When I replace "--gw" with "-gateway", like this:
iptables –I PREROUTING -t mangle -j ROUTE -gateway 192.168.200.1 --tee
this error occur:
iptables v1.4.12:multiple -j flag not allowed
Why is this?

Try:
iptables -t mangle -A PREROUTING -j TEE --gateway 192.168.200.1
For that version of iptables -j ROUTE doesn't work.

Related

What's the right way to allow systemd-timesyncd through iptables firewall?

First, I set up my firewall like this to allow everything:
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables --flush
Then, I check if NTP is working:
sudo systemctl daemon-reload
sudo systemctl restart systemd-timesyncd
timedatectl
and I can see that it says System clock synchronized: yes.
But then if I reboot and set up my firewall like this (reject everything except for NTP):
sudo iptables -P INPUT REJECT
sudo iptables -P OUTPUT REJECT
sudo iptables -P FORWARD REJECT
sudo iptables -A INPUT -p udp --dport 123 -j ACCEPT
sudo iptables -A OUTPUT -p udp --sport 123 -j ACCEPT
then I get System clock synchronized: no and the clock won't sync.
Based on the above steps, I'm convinced it's the firewall that's blocking timesyncd. I have read (for example, here) that perhaps it has to do with extra ports being opened by the service or the fact that is uses SNTP instead of NTP. I have tried different combinations of rules, but with no success yet as I am not an expert with iptables.
But there must be a way to set it up such that it works without altogether disabling the firewall.
Summary
--dport and --sport are switched.
Explanation
For the other services that I am allowing through the firewall, my machine is the server. For NTP, my machine is the client. Because the rest of my original configuration actually looked more like this:
...
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 5353 -j ACCEPT
...
sudo iptables -A OUTPUT -p tcp --sport 443 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
sudo iptables -A OUTPUT -p udp --sport 5353 -j ACCEPT
...
I assumed that --dport was meant to be used with INPUT and --sport was used with OUTPUT. However, you have to think about what it means. To use NTP as a client, I need to allow INPUT packets that are coming from a source port of 123, not input packets that are coming to a destination port of 123. Likewise, I need to allow OUTPUT packets with destination port 123, not output with source 123.
So the answer to my question is to use this:
sudo iptables -P INPUT REJECT
sudo iptables -P OUTPUT REJECT
sudo iptables -P FORWARD REJECT
sudo iptables -A INPUT -p udp --sport 123 -j ACCEPT
sudo iptables -A OUTPUT -p udp --dport 123 -j ACCEPT

libvirt iptables rules disrupt port forwarding to my KVM VM's

When I clear IPtables and then add the following rules, incoming connections can connect to my KVM VM on port 1234 without any problems.
-A PREROUTING -i br0 -p tcp -m tcp --dport 1234 -j DNAT --to-destination 192.168.122.194:1234
-A FORWARD -d 192.168.122.194/32 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 1234 -j ACCEPT
-A FORWARD -s 192.168.122.194/32 -p tcp -m tcp --sport 1234 -j ACCEPT
-A FORWARD -d 192.168.122.194/32 -p tcp -m tcp --dport 1234 -j ACCEPT
But I also want NAT to work inside my KVM VM's. By default libvirt sets up some rules that provide my VM's with NAT. However when I try sending SIGHUP to libvirt (that's how you ask it to add it's rules to iptables), it adds the following rules to iptables that breaks my port forwarding that I have specified above.
-A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A FORWARD -i virbr0 -o virbr0 -j ACCEPT
-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT
-A POSTROUTING -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
I've tried running these commands manually. I can run all of the FORWARD and OUTPUT commands and they do not break my port forwarding. However I can't run any of the POSTROUTING commands manually. I get an error saying: "No chain/target/match by that name."
*These libvirt iptables rules in the last grey section above were obtained by running iptables-save and confirming port forwarding was working, then sending SIGHUP to libvirt, confirming port forwarding was broken, then running iptables-save again and running a diff on the two outputs to find which new iptables rules were added by libvirt.
I just enabled NAT with my own rules. I didn't bother with any of the default libvirt rules.
Adding NAT is as simple as 3 iptables commands.
(where br0 is your internet facing adapter (it could be ppp0 or whatever))
iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE
iptables -A FORWARD -i br0 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i virbr0 -o br0 -j ACCEPT

Captive Portal for a bridged interface

I like to create a simple captive portal that works for an interface that is part of a bridge.
The bridge interface br0 (10.19.1.1/16) consists of two interfaces eth0 and eth1.
Behind eth1 are the client computers. Behind eth0 is a switch that has the internet gateway connected to.
For the captive portal, all tcp requests to port 80 coming from the clients behind eth1 need to be directed the local web server.
The following lines seem to work as the website request are redirected to the local web server. The problem is that once the authentication line below is used, the client cannot load any regular websites anymore.
I have already searched the internet but haven't found a solution.
PORTAL_INT="eth1"
PORTAL_IP="10.19.1.1"
#'drop' packets from being bridged
ebtables -t broute -A BROUTING -i $PORTAL_INT -p IPv4 --ip-proto tcp --ip-dport 80 -j redirect --redirect-target DROP
iptables -N internet -t mangle
iptables -t mangle -A PREROUTING -j internet
#authenticated
#iptables -t mangle -I internet 1 -m mac --mac-source $CLIENT_MAC -j RETURN
#mark all traffic
iptables -t mangle -A internet -j MARK --set-mark 99
#redirect website access
iptables -t nat -A PREROUTING -m mark --mark 99 -p tcp --dport 80 -j DNAT --to-destination $PORTAL_IP
iptables -t filter -A FORWARD -m mark --mark 99 -j DROP
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -m mark --mark 99 -j DROP

iptables - remove packet mark on certain packets

I am using the following iptables script to redirect packets on port 443 to a proxy server:
iptables -t mangle -A PREROUTING -p tcp --dport 443 -j MARK --set-mark 2
I am redirecting it to my proxy server later on, which is working. For one host, however, I need to remove the iptables mark (i.e. the packets will not be redirected.) I tried the following:
iptables -t mangle -A PREROUTING -p tcp -s 192.168.0.47 --dport 443 -j ACCEPT
I have also tried (attempting to rewrite the mark to a different number):
iptables -t mangle -A PREROUTING -p tcp -s 192.168.0.47 --dport 443 -j MARK --set-mark 1
However none of them are working. Is there a --remove-mark? I couldn't find anything on Google.
Any help would be appreciated.
When using the MARK target, the mark is a added as a bitmask. If you check in the documentation, there's an optional [/mask] for the mark.
So use "--set-mark 0/2" to remove 2.
I figured it out. I used the following:
iptables -t mangle -A PREROUTING -p tcp ! -s 192.168.0.47 --dport 443 -j MARK --set-mark 2
To mark it so it doesn't mark the host in the first place.

iptables src-range and dst-range

How do we use these flags with iptables? I keep getting invalid option/bad argument errors:
sudo iptables -A FORWARD --src-range 192.168.25.149-192.168.25.151 -j ACCEPT
You forgot "iprange" match.
This works:
sudo iptables -A INPUT -m iprange --src-range 192.168.25.149-192.168.25.151 -j ACCEPT
http://www.frozentux.net/iptables-tutorial/chunkyhtml/x2702.html#TABLE.IPRANGEMATCH