iptables block client ip internet access and keep LAN access
With the increase of appliances having network access and the potential for hacking, I want to block specific ip address from accessing the internet, but allow LAN access. For instance, I use a Logitech Harmony remote to control my stereo, satellite, and TV with 1 button. I can also control it with my iPad over the local network. But I don't want a hacker to operate my TV, so I'd like to block the IP address assigned to the harmony remote with my IP Tables firewall.
Here is the current script I use to edit my IP Tables configuration. It is workning on my Fedora 20 box with 2 network cards. Section 6 is where I'm attempting to insert the rule. Everything else is working as intended. I'm including the entire script in hopes it helps someone else, even if unrelated to my question. After all, it's all built from knowledge gained from my own searches!
#!/bin/sh
#
# A script for creating an iptables firewall
#
#
# Start by clearing iptables
#
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -t nat -X
iptables -t mangle -X
#
# Define our interfaces, Squid IP, and Squid port
#
WAN="p4p1"
LAN="p4p2"
SQUIDIP="192.168.10.10"
SQUIDPORT="3129"
#
# Create log files to help troubleshooting. (We can comment out when not needed)
#
# iptables -A OUTPUT -j LOG
# iptables -A INPUT -j LOG
# iptables -A FORWARD -j LOG
#
# Now to create the Routing Firewall
#
#
# (1) Create the default policies (DROP)
#
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#
# (2) User-defined chain called "okay" for ACCEPTed TCP packets
#
iptables -N okay
iptables -A okay -p tcp --syn -j ACCEPT
iptables -A okay -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A okay -p tcp -j DROP
#
# (3) INPUT rules
#
###### (A) Rules for incoming packets from the LAN
iptables -A INPUT -p ALL -i $LAN -s 192.168.10.0/24 -j ACCEPT
iptables -A INPUT -p ALL -i lo -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p ALL -i lo -s 192.168.10.10 -j ACCEPT
iptables -A INPUT -p ALL -i lo -s 192.168.1.10 -j ACCEPT
iptables -A INPUT -p ALL -i $LAN -d 192.168.10.255 -j ACCEPT
##### (B) Rules for incoming packets from the Internet
###### (i) Packets for established connections
iptables -A INPUT -p ALL -d 192.168.1.10 -m state --state ESTABLISHED,RELATED -j ACCEPT
##### (ii) TCP rules ## Opens the server port to any TCP from the internet
iptables -A INPUT -p tcp -i $WAN -s 0/0 –dport 22 -j okay
##### (iii) UDP rules ## Opens the server port to any UDP from the internet
# iptables -A INPUT -p udp -i $WAN -s 0/0 –dport 53 -j okay
##### (iv) ICMP rules
iptables -A INPUT -p icmp -i $WAN -s 0/0 --icmp-tpe 8 -j ACCEPT
iptables -A INPUT -p icmp -i $WAN -s 0/0 --icmp-tpe 11 -j ACCEPT
#
# Creates the router between the 2 ethernet cards to accept the packets we want to forward
#
iptables -A FORWARD -i $LAN -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# (5) OUTPUT rules
# Only output packets with local addresses (no spoofing)
#
iptables -A OUTPUT -p ALL -s 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -p ALL -s 192.168.10.10 -j ACCEPT
iptables -A OUTPUT -p ALL -s 192.168.1.10 -j ACCEPT
#
# (6) OUTPUT rule to allow a client LAN access, but DROP internet access
# I use this to prevent various home appliances from accessing the internet
#
iptables -A OUTPUT -s 192.168.10.110 -j DROP
#
# (7) PREROUTING rules to allow a client to bypass our Squid proxy
# (NetFlix works better when it bypasses the proxy)
iptables -t nat -A PREROUTING -s 192.168.10.204 -j ACCEPT # BluRay player
iptables -t nat -A PREROUTING -s 192.168.10.205 -j ACCEPT # Sony TV
#
# (8) PREROUTING rules for transparent Squid proxy (also requires changes in the squid configuration file)
# (from: http://wiki.squidcache.org/ConfigExamples/Intercept/LinuxRedirect)
#
iptables -t nat -A PREROUTING -s $SQUIDIP -p tcp --dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port $SQUIDPORT
iptables -t mangle -A PREROUTING -p tcp --dport $SQUIDPORT -j DROP
#
# (9) POSTROUTING chain rules. SNAT is for static IP, MASQUERADE is for dynamic IP
#
iptables -t nat -A POSTROUTING -o $WAN -j SNAT --to-source 192.168.1.10
# iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE
#
# Last, but not least, save the new configuration in /etc/sysconfig/iptables
#
service iptables save
#
# EOF
#
Solution 1:
This won't work.
#
# (6) OUTPUT rule to allow a client LAN access, but DROP internet access
# I use this to prevent various home appliances from accessing the internet
# iptables -A OUTPUT -s 192.168.10.110 -j DROP
The reason it won't work is the OUTPUT table only filters traffic originating from your router, rather than passing through it. You want the rule applied to the FORWARD table like so:
iptables -A FORWARD -s 192.168.10.110 -j DROP
But it may not stick forever since IP addresses assigned to devices can change with DHCP. So I suggest you filter by mac address instead.
Something like:
/sbin/iptables -A PREROUTING -i $LAN -m mac --mac-source ff:ff:ff:ff:ff:ff -j DROP
Where ff:ff:ff:ff:ff:ff
is the mac address of your harmony remote or other device you want to filter.
Note: as pointed out in comments, MAC address only work at Layer2. examples I've seen suggest the above should work though as the filter is applied to the LAN interface. Test it out and let me know if it works as expected.
I'd like to also add:
#
# Creates the router between the 2 ethernet cards to accept the packets we want to forward
#
iptables -A FORWARD -i $LAN -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
No it doesn't create a router between 2 ethernet cards. Routing is done by the kernel automatically when ip forwarding is turned on.
The above iptables rules say ACCEPT or allow packets originating from $LAN passing through to any interface. And keep state on established/related sessions passing through the forward chain coming into the router not originating from $LAN. Because that'd hit the first rule and stop.
Solution 2:
Thanks Matt! I figured it would be something easy like this. So I need to use the FORWARD rule, not the OUTPUT! I don't have to worry about IP address changing, since this server also provides DHCP and I assign them to appliances based on MAC address. But I see how your suggestion would work in a different scenario.
As to the routing comments...I am a cut and paste programmer. I've been using that portion of the script since I copied if from "The RedHat 8 Bible" many years ago, before RedHat split off Fedora. While the comments were not in the original script, I attempted to comment for my own understanding. The actual comment from the book states:
"FOWARD chain rules - Because the firewall is also acting as a router, FORWARD rules are needed to limit what the firewall will and will not pass between the two networks (Internet and LAN)"
The comment is my mis-interpretation of what I read. My apologies. Here is the corrected script with Matt's change to a FORWARD rule. Additionally, its now moved to the top of the FORWARD section and I've updated the comments to reflect what was actually said in the book where I got the original script.
The desired IP now has local network access, but not internet access.
#!/bin/sh
#
# A script for creating an iptables firewall
#
#
# Start by clearing iptables
#
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -t nat -X
iptables -t mangle -X
#
# Define our interfaces, Squid IP, and Squid port
#
WAN="p4p1"
LAN="p4p2"
SQUIDIP="192.168.10.10"
SQUIDPORT="3129"
#
# Create log files to help troubleshooting. Comment out when not needed.
#
# iptables -A OUTPUT -j LOG
# iptables -A INPUT -j LOG
# iptables -A FORWARD -j LOG
# Turn on ip forwarding in the kernel with:
# echo 1 > /proc/sys/net/ipv4/ip_forward
# or edit /etc/sysctl.conf and add: "net.ipv4.ip_forward = 1"
#
##### Now to create the Routing Firewall
#
#
# (1) Create the default policies (DROP)
#
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
#
# (2) User-defined chain called "okay" for ACCEPTed TCP packets
#
iptables -N okay
iptables -A okay -p tcp --syn -j ACCEPT
iptables -A okay -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A okay -p tcp -j DROP
#
# (3) INPUT rules
#
###### (A) Rules for incoming packets from the LAN
iptables -A INPUT -p ALL -i $LAN -s 192.168.10.0/24 -j ACCEPT
iptables -A INPUT -p ALL -i lo -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p ALL -i lo -s 192.168.10.10 -j ACCEPT
iptables -A INPUT -p ALL -i lo -s 192.168.1.10 -j ACCEPT
iptables -A INPUT -p ALL -i $LAN -d 192.168.10.255 -j ACCEPT
##### (B) Rules for incoming packets from the Internet
###### (i) Packets for established connetions
iptables -A INPUT -p ALL -d 192.168.1.10 -m state --state ESTABLISHED,RELATED -j ACCEPT
##### (ii) TCP rules ## Opens the server port to any TCP from the internet
iptables -A INPUT -p tcp -i $WAN -s 0/0 --dport 22 -j okay
##### (iii) UDP rules ## Opens the server port to any UDP from the internet
# iptables -A INPUT -p udp -i $WAN -s 0/0 --dport 53 -j okay
##### (iv) ICMP rules
iptables -A INPUT -p icmp -i $WAN -s 0/0 --icmp-type 8 -j ACCEPT
iptables -A INPUT -p icmp -i $WAN -s 0/0 --icmp-type 11 -j ACCEPT
#
# (4) FORWARD rules
#
##### (A) FORWARD rule to allow a client LAN access, but DROP internet access
##### I use this to prevent various home appliances from accessing the internet
#
iptables -A FORWARD -s 192.168.10.110 -j DROP
##### (B) Since this firewall is also a router, limit what packets are forwarded
##### between the 2 ethernet cards
#
iptables -A FORWARD -i $LAN -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# (5) OUTPUT rules
# Only output packets with local addresses (no spoofing)
#
iptables -A OUTPUT -p ALL -s 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -p ALL -s 192.168.10.10 -j ACCEPT
iptables -A OUTPUT -p ALL -s 192.168.1.10 -j ACCEPT
#
# (6) PREROUTING rules to allow a client to bypass our Squid proxy
# (NetFlix works better when it bypasses the proxy)
iptables -t nat -A PREROUTING -s 192.168.10.204 -j ACCEPT # BluRay player
iptables -t nat -A PREROUTING -s 192.168.10.205 -j ACCEPT # Sony TV
#
# (7) PREROUTING rules for transparent Squid proxy
# Also requires changes in the squid configuration file
# (from: http://wiki.squid-cache.org/ConfigExamples/Intercept/LinuxRedirect)
#
iptables -t nat -A PREROUTING -s $SQUIDIP -p tcp --dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port $SQUIDPORT
iptables -t mangle -A PREROUTING -p tcp --dport $SQUIDPORT -j DROP
#
# (8) POSTROUTING chain rules. SNAT is for static IP, MASQUERADE is for dynamic IP
#
iptables -t nat -A POSTROUTING -o $WAN -j SNAT --to-source 192.168.1.10
# iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE
#
# Last, but not least, save the new configuration in /etc/sysconfig/iptables
#
service iptables save
#
# EOF
#