Link to home
Start Free TrialLog in
Avatar of afrazee
afrazee

asked on

[IPTABLES] Only allowing certain mac addresses to masquerade, DROP all others

I'm working on a somewhat strict firewall, what i want to do is basically add mac addresses to a txt file which are the only ones allowed to get thru the gateway (linux iptables), let me paste /etc/firewall (main firewall)

::/etc/firewall (start)
#STARTING FIREWALL
echo "Firewall initiated"

#SETTING VARIABLES
IPT="/sbin/iptables"
AM="/etc/firewall-macs"
AI="/etc/firewall-ips"
AP="/etc/firewall-ports"
OUTSIDE=eth0
INSIDE=eth1

#IP Variables
OUTSIDE_IP=1.1.1.1 (not real of course ;])
INSIDE_IP=192.168.100.1
LOCALHOST=127.0.0.1
INSIDE_BCAST=192.168.100.255
VPN_SERVER_INSIDE=192.168.100.254

echo "Variables initiated"

#FLUSHING
$IPT -F
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t filter -F
$IPT -t filter -X
$IPT -t mangle -F
$IPT -t mangle -X

echo "Flushing complete"

#DEFAULT POLICY
$IPT -P INPUT DROP
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT

echo "Default input policy set to drop."

#SECURITY
$IPT -N silent
$IPT -A silent -j DROP
$IPT -N tcpflags
$IPT -A tcpflags -m limit --limit 15/minute -j LOG --log-prefix TCPflags:
$IPT -A tcpflags -j DROP
$IPT -N firewalled
$IPT -A firewalled -m limit --limit 15/minute -j LOG --log-prefix Firewalled:
$IPT -A firewalled -j DROP
$IPT -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j tcpflags
$IPT -A INPUT -p tcp --tcp-flags ALL ALL -j tcpflags
$IPT -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j tcpflags
$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j tcpflags
$IPT -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j tcpflags
$IPT -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j tcpflags
$IPT -A INPUT -p icmp --icmp-type 0 -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type 3 -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type 11 -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT
$IPT -A INPUT -p icmp -j firewalled

echo "Security settings complete"

#LOOPBACK INTERFACE
$IPT -A INPUT -i lo -j ACCEPT

echo "Loopback interface initiated"
$IPT -A INPUT -i $INSIDE -d $INSIDE_IP -s 192.168.100.20 -j ACCEPT
$IPT -A INPUT -i $INSIDE -d $INSIDE_IP -s 192.168.100.21 -j ACCEPT
$IPT -A INPUT -i $INSIDE -d $INSIDE_IP -s 192.168.100.22 -j ACCEPT
$IPT -A INPUT -i $INSIDE -d $INSIDE_IP -s 192.168.100.23 -j ACCEPT
$IPT -A INPUT -i $INSIDE -d $INSIDE_IP -s 192.168.100.24 -j ACCEPT
$IPT -A INPUT -i $INSIDE -d $INSIDE_IP -s 192.168.100.25 -j ACCEPT
$AM

#ALLOW DHCP BROADCASTS
$IPT -A INPUT -i $INSIDE -d $INSIDE_BCAST -j ACCEPT
$IPT -A INPUT -i $INSIDE -d 255.255.255.255 -j ACCEPT

echo "DHCP broadcasts now allowed"

#MASQUERADING
$IPT -t nat -A POSTROUTING -o $OUTSIDE -s 192.168.100.0/255.255.255.0 -j SNAT --to $OUTSIDE_IP
$IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

echo "Masquerading complete"

#INCOMING PORTS
$AP
$IPT -A INPUT -p tcp --dport 113 -j ACCEPT

echo "Loaded possible incoming ports"

#Allowing VPN
$IPT -A FORWARD -p gre -d $VPN_SERVER_INSIDE -j ACCEPT
$IPT -A FORWARD -p tcp --dport 1723 -d $VPN_SERVER_INSIDE -j ACCEPT
$IPT -A PREROUTING -t nat -p gre -d $OUTSIDE_IP -j DNAT --to-destination $VPN_SERVER_INSIDE
$IPT -A PREROUTING -t nat -p tcp --dport 1723 -d $OUTSIDE_IP -j DNAT --to-destination $VPN_SERVER_INSIDE:1723
echo "VPN now initialized."

#RDP Forwarding
$AI

echo "RDP forwarding initialized"


#LOG EVERYTHING ELSE
#$IPT -A INPUT -j firewalled

echo "Logging started"

echo "Firewall completed"
::/etc/firewall(stop)

Just to show you what is in the variable firewall names i will paste each of those as well

::/etc/firewall-macs(start)
#!/bin/bash
IPT="/sbin/iptables"
AM="/etc/firewall-macs"
OUTSIDE=eth0
INSIDE=eth1
OUTSIDE_IP=1.1.1.1
INSIDE_IP=192.168.100.1
LOCALHOST=127.0.0.1
INSIDE_BCAST=192.168.100.255

if [ -f /etc/allowed_macs ]
then
        for ALLOWED_MACS in `cat /etc/allowed_macs`
        do
                iptables -A INPUT -i $INSIDE -d $INSIDE_IP -m mac --mac-source $ALLOWED_MACS -j ACCEPT
        done
else
        echo "Can't read allowed_macs"
fi
::/etc/firewall-macs(stop)

This file is so i can allow certain macs to be accepted, in /etc/allowed_macs there is just 1 mac address per line.  This part seems to work well.

::/etc/firewall-ips(start)
#!/bin/bash
IPT="/sbin/iptables"
AI="/etc/firewall-ips"
OUTSIDE_IP=1.1.1.1
ANTHONY_IP=192.168.100.70
DEREK_IP=192.168.100.73
MIKE_IP=1.1.1.1
GEORGE_IP=1.1.1.1
SWORK_IP=1.1.1.1
GIRLS_IP=1.1.1.1
TAMMY_IP=1.1.1.1
SIMPSON_SERVER1=192.168.100.254
STUDIO_IP=192.168.100.210
DAN_IP=192.168.100.59

if [ -f /etc/allowed_ips ]
then
        for ALLOWED_IPS in `cat /etc/allowed_ips`
        do
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10000 -d $OUTSIDE_IP -j DNAT --to-destination $ANTHONY_IP:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10001 -d $OUTSIDE_IP -j DNAT --to-destination $DEREK_IP:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10002 -d $OUTSIDE_IP -j DNAT --to-destination $MIKE_IP:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10003 -d $OUTSIDE_IP -j DNAT --to-destination $GEORGE_IP:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10004 -d $OUTSIDE_IP -j DNAT --to-destination $SWORK_IP:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10005 -d $OUTSIDE_IP -j DNAT --to-destination $GIRLS_IP:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10006 -d $OUTSIDE_IP -j DNAT --to-destination $TAMMY:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10007 -d $OUTSIDE_IP -j DNAT --to-destination $SIMPSON_SERVER1:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10008 -d $OUTSIDE_IP -j DNAT --to-destination $STUDIO_IP:3389
                $IPT -A PREROUTING -t nat -s $ALLOWED_IPS -p tcp --dport 10009 -d $OUTSIDE_IP -j DNAT --to-destination $DAN_IP:3389
        done
else
        echo "Can't read allowed_ips"
fi
::/etc/firewall-ips(stop)

This file is to make RDP forwarders to each of our LAN machines from wherever we may be, inside /etc/allowed_ips is a list of internal and external ips that will only have access, this comes in handy if i want to restrict which external ips i want to be able to SSH into the server.

::/etc/firewall-ports(start)
#!/bin/bash
IPT="/sbin/iptables"
AP="/etc/firewall-ports"
OUTSIDE=eth0
INSIDE=eth1
OUTSIDE_IP=1.1.1.1
INSIDE_IP=192.168.100.1
LOCALHOST=127.0.0.1
INSIDE_BCAST=192.168.100.255

if [ -f /etc/allowed_ips ]
then
        for ALLOWED_IPS in `cat /etc/allowed_ips`
        do
                $IPT -A INPUT -s $ALLOWED_IPS -p TCP --dport 22 -j ACCEPT
        done
else
        echo "Can't read allowed_ips"
fi
::/etc/firewall-ports(stop)

This file is for when i want to open certain ports on the firewall i want it so only certain accepted IPs can do it, in this example is SSH which uses the same file as the previous one (/etc/allowed_ips)

I think my problem lies in here (/etc/firewall):
#MASQUERADING
$IPT -t nat -A POSTROUTING -o $OUTSIDE -s 192.168.100.0/255.255.255.0 -j SNAT --to $OUTSIDE_IP
$IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Because i brought up another computer which used 192.168.100.63, and it can get out to the internet without me adding the mac address into /etc/allowed_macs  which makes me think that line is doing it, i tried to create a file that uses something like:

#!/bin/bash
IPT="/sbin/iptables"
AM="/etc/firewall-macs"
OUTSIDE=eth0
INSIDE=eth1
OUTSIDE_IP=1.1.1.1
INSIDE_IP=192.168.100.1
LOCALHOST=127.0.0.1
INSIDE_BCAST=192.168.100.255

if [ -f /etc/allowed_macs ]
then
        for ALLOWED_MACS in `cat /etc/allowed_macs`
        do
                $IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                $IPT -t nat -A PREROUTING -m mac --mac-source $ALLOWED_MACS -j MASQUERADE
        done
else
        echo "Can't read allowed_macs"
fi

But i have no luck whatsoever, invalid syntax.. and im not sure if i can do something like this or not, please someone help ;]

Anthony
ASKER CERTIFIED SOLUTION
Avatar of jlevie
jlevie

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of afrazee
afrazee

ASKER

I just restarted this Windows 2003 Server, and now it seems my current firewall is working properly... but before it was restarted it was on .63 and it could get on to the internet even after i reloaded the firewall.  and now it cannot get out to the internet unless i give it an ip address of 20-25 or add its mac address, so technically it was working to begin with, i wonder why it could access the internet before though, very strange.  I'm not sure what happened but i guess i never needed to post this.  Thanks anyway.  Might be a good thing for people to see my firewall in case they need something similar, eh? ;]  Can you tell the way i did it, if i did it properly though?

Do you think i should change:
iptables -A INPUT -i $INSIDE -d $INSIDE_IP -m mac --mac-source $ALLOWED_MACS -j ACCEPT

to forward instead of INPUT, if so, why does this work?
Avatar of afrazee

ASKER

I have a question but its more like a linux bash scripting question, i hope you can help.  I want to even further script this firewall.  I want to make it so that IPs and well as mac addresses have to match.  so you couldnt switch IPs...  In my one script i have:
if [ -f /etc/allowed_macs ]
then
        for ALLOWED_MACS in `cat /etc/allowed_macs`
        do
                iptables -A INPUT -i $INSIDE -d $INSIDE_IP -m mac --mac-source $ALLOWED_MACS -j ACCEPT
        done
else
        echo "Can't read allowed_macs"
fi

what i want to do is make it so /etc/allowed_macs could have 2 variables..   first word in line would be IP address, second word would be mac address looking like:
192.168.100.70 00:90:F5:24:CA:72
for example

is there a way to make 2 variables per line.. so i could do iptables -A INPUT -i $INSIDE -d $INSIDE_IP -s $IP -m mac --mac-source $ALLOWED_MACS -j ACCEPT
that is adding a -s $IP to it, im not even sure if you can do that, but i would like to.  If you know of anyway i can implement iptables command that i have 1 txt file with IPs with their corresponding mac address, I would greatly appreciate it, thank you.  If you don't understand what i mean tell me and ill try to be more specific.. it's hard for me to explain myself, im no programmer.. Thanks.

Avatar of afrazee

ASKER

Nevermind, i have found the solution for me, what i did was in /etc/firewall-macs i put:

#!/bin/bash
IPT="/sbin/iptables"
INSIDE=eth1
INSIDE_IP=192.168.100.1
column=0
allowed_ip=""
allowed_mac=""

if [ -f /etc/allowed_macs ]
then
        for DATA_WORD_IN in `cat /etc/allowed_macs`
        do
                if [ $column = 0 ]
                then
                        allowed_ip=$DATA_WORD_IN
                        column=1
                else
                        allowed_mac=$DATA_WORD_IN
                        $IPT -A INPUT -i $INSIDE -d $INSIDE_IP -s $allowed_ip -m mac --mac-source $allowed_mac -j ACCEPT
                        column=0
                fi
        done
else
        echo "Can't read allowed_macs"
fi

In case anyone else would like a simple way of doing it.

Thanks anyway
Avatar of afrazee

ASKER

I forgot to mention that also in /etc/allow_macs i have:

Line 1:192.168.100.1
Line 2:00:00:00:00:00:00
Line 3:192.168.100.2
Line 4:11:11:11:11:11:11
etc..

Ignore the Line #:  

Again, this is for those people who would like to do this, i find it very easy this way, thanks
According to the Netfiler documentation connection from an inside machine destined for the Internet don't traverse the INPUT chain (see http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO-6.html). So to limit Internet access you need to be using a default DENY stance for the FORWARD chain and explict FORWARD rules rather than INPUT rules.