LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Networking (https://www.linuxquestions.org/questions/linux-networking-3/)
-   -   iptables script is blocking voip asterisk (https://www.linuxquestions.org/questions/linux-networking-3/iptables-script-is-blocking-voip-asterisk-812339/)

juan10dan 06-05-2010 12:42 PM

iptables script is blocking voip asterisk
 
Hi everybody, this is my first post so please forgive any unappropiate stuff.

I have two asterisk servers each one behind a linux firewall/gw. Linux is Centos 5.4, kernel 2.6.18-164.el5, iptables v1.3.5.

Routes on the fws are ok and when iptables is stoped the servers are see each other, all good.

But when I run iptables script in any fw, one server (not always the same) goes unreachable. I verify this with asterisk -r, then show sip trunk, and status becomes UNREACHABLE.

Iptables scripts is generated by fwbuilder. The weird part is I put only one rule to de script and it looks like Source=any, Destination=any, Service=any, Interface=any, Direction (Inbound,Outbound)=any, Time=Any, Action=ACCEPT. So as you can see I tried something like "Do not do anything at all". But anyway I run the script in any fw and one server becomes UNREACHABLE.

I think the script does something wrong after all or maybe I have some missconfiguration in my asterisk conf files. The point is I am not so expert in iptables or shell scripting so I can't see anything in the iptables script.

I have look for some issues like iptables blocking because of ip_conntrack table full, or "dont fragment" bit set in kernel problem, but nothing seems to be the right problem at all.

You guys please help me!, next post I will paste the iptables script.

Thanks a lot in advance!!

Juan M. Jaramillo

juan10dan 06-05-2010 12:55 PM

iptables script
 
Script iptables:
Code:

#!/bin/sh
#
#  This is automatically generated file. DO NOT MODIFY !
#
#  Firewall Builder  fwb_ipt v4.0.1-2936
#
#  Generated Sat Jun  5 12:39:35 2010 COT by root
#
# files: * fwnuevos.fw
#
# Compiled for iptables 1.3.0
#
# Similar to fw 1, but the firewall is used as DHCP and DNS server for internal network.
# This firewall has two interfaces. Eth0 faces outside and has a dynamic address; eth1 faces inside.
# Policy includes basic rules to permit unrestricted outbound access and anti-spoofing rules. Access to the firewall is permitted only from internal network and only using SSH. The firewall can send DNS queries to servers out on the Internet. Another rule permits DNS queries from internal network to the firewall. Special rules permit DHCP requests from internal network and replies sent by the firewall.




FWBDEBUG=""

PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}"
export PATH



LSMOD="/sbin/lsmod"
MODPROBE="/sbin/modprobe"
IPTABLES="/sbin/iptables"
IP6TABLES="/sbin/ip6tables"
IPTABLES_RESTORE="/sbin/iptables-restore"
IP6TABLES_RESTORE="/sbin/ip6tables-restore"
IP="/sbin/ip"
IFCONFIG="/sbin/ifconfig"
VCONFIG="/sbin/vconfig"
BRCTL="/usr/sbin/brctl"
IFENSLAVE="/sbin/ifenslave"
LOGGER="/bin/logger"

log() {
    echo "$1"
    test -x "$LOGGER" && $LOGGER -p info "$1"
}

check_file() {
    test -r "$2" || {
        echo "Can not find file $2 referenced by AddressTable object $1"
        exit 1
    }
}

getInterfaceVarName() {
    echo $1 | sed 's/\./_/'
}

getaddr_internal() {
    dev=$1
    name=$2
    af=$3
    L=$($IP $af addr show dev $dev |  sed -n '/inet/{s!.*inet6* !!;s!/.*!!p}' | sed 's/peer.*//')
    test -z "$L" && {
        eval "$name=''"
        return
    }
    eval "${name}_list=\"$L\""
}

getaddr() {
    getaddr_internal $1 $2 "-4"
}

getaddr6() {
    getaddr_internal $1 $2 "-6"
}

# function getinterfaces is used to process wildcard interfaces
getinterfaces() {
    NAME=$1
    $IP link show | grep ": $NAME" | while read L; do
        OIFS=$IFS
        IFS=" :"
        set $L
        IFS=$OIFS
        echo $2
    done
}

diff_intf() {
    func=$1
    list1=$2
    list2=$3
    cmd=$4
    for intf in $list1
    do
        echo $list2 | grep -q $intf || {
        # $vlan is absent in list 2
            $func $intf $cmd
        }
    done
}

find_program() {
  PGM=$1
  $PGM </dev/null >/dev/null 2>&1; test $? = 127 && {
    echo "$PGM not found"
    exit 1
  }
}
check_tools() {
  find_program $IPTABLES
  find_program $MODPROBE
  find_program $IP
}
reset_iptables_v4() {
  $IPTABLES -P OUTPUT  DROP
  $IPTABLES -P INPUT  DROP
  $IPTABLES -P FORWARD DROP

cat /proc/net/ip_tables_names | while read table; do
  $IPTABLES -t $table -L -n | while read c chain rest; do
      if test "X$c" = "XChain" ; then
        $IPTABLES -t $table -F $chain
      fi
  done
  $IPTABLES -t $table -X
done
}

reset_iptables_v6() {
  $IP6TABLES -P OUTPUT  DROP
  $IP6TABLES -P INPUT  DROP
  $IP6TABLES -P FORWARD DROP

cat /proc/net/ip6_tables_names | while read table; do
  $IP6TABLES -t $table -L -n | while read c chain rest; do
      if test "X$c" = "XChain" ; then
        $IP6TABLES -t $table -F $chain
      fi
  done
  $IP6TABLES -t $table -X
done
}


P2P_INTERFACE_WARNING=""

missing_address() {
    address=$1
    cmd=$2

    oldIFS=$IFS
    IFS="@"
    set $address
    addr=$1
    interface=$2
    IFS=$oldIFS



    $IP addr show dev $interface | grep -q POINTOPOINT && {
        test -z "$P2P_INTERFACE_WARNING" && echo "Warning: Can not update address of interface $interface. fwbuilder can not manage addresses of point-to-point interfaces yet"
        P2P_INTERFACE_WARNING="yes"
        return
    }

    test "$cmd" = "add" && {
      echo "# Adding ip address: $interface $addr"
    }

    test "$cmd" = "del" && {
      echo "# Removing ip address: $interface $addr"
    }

    $FWBDEBUG $IP addr $cmd $addr dev $interface
    $FWBDEBUG $IP link set $interface up
}

list_addresses_by_scope() {
    interface=$1
    scope=$2
    ignore_list=$3
    $IP addr ls dev $interface | \
      awk -v IGNORED="$ignore_list" -v SCOPE="$scope" \
        'BEGIN {
          split(IGNORED,ignored_arr);
          for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;}
        }
        (/inet |inet6 / && $0 ~ SCOPE && !($2 in ignored_dict)) {print $2;}' | \
        while read addr; do
          echo "${addr}@$interface"
        done | sort
}


update_addresses_of_interface() {
    ignore_list=$2
    set $1
    interface=$1
    shift

    FWB_ADDRS=$(
      for addr in $*; do
        echo "${addr}@$interface"
      done | sort
    )

    CURRENT_ADDRS_ALL_SCOPES=""
    CURRENT_ADDRS_GLOBAL_SCOPE=""

    $IP link show dev $interface >/dev/null 2>&1 && {
      CURRENT_ADDRS_ALL_SCOPES=$(list_addresses_by_scope $interface 'scope .*' "$ignore_list")
      CURRENT_ADDRS_GLOBAL_SCOPE=$(list_addresses_by_scope $interface 'scope global' "$ignore_list")
    } || {
      echo "# Interface $interface does not exist"
      # Stop the script if we are not in test mode
      test -z "$FWBDEBUG" && exit 1
    }

    diff_intf missing_address "$FWB_ADDRS" "$CURRENT_ADDRS_ALL_SCOPES" add
    diff_intf missing_address "$CURRENT_ADDRS_GLOBAL_SCOPE" "$FWB_ADDRS" del
}

clear_addresses_except_known_interfaces() {
    $IP link show | sed 's/://g' | awk -v IGNORED="$*" \
        'BEGIN {
          split(IGNORED,ignored_arr);
          for (a in ignored_arr) {ignored_dict[ignored_arr[a]]=1;}
        }
        (/state/ && !($2 in ignored_dict)) {print $2;}' | \
        while read intf; do
            echo "# Removing addresses not configured in fwbuilder from interface $intf"
            $FWBDEBUG $IP addr flush dev $intf scope global
            $FWBDEBUG $IP link set $intf down
        done
}

load_modules() {
    :
    HAVE_NAT=$1
    MODULES_DIR="/lib/modules/`uname -r`/kernel/net/"
    MODULES=`find $MODULES_DIR -name '*conntrack*'|sed  -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/'`
    test -n "$HAVE_NAT" && {
        MODULES="$MODULES `find $MODULES_DIR -name '*nat*'|sed  -e 's/^.*\///' -e 's/\([^\.]\)\..*/\1/'`"
    }
    for module in $MODULES; do
        if $LSMOD | grep ${module} >/dev/null; then continue; fi
        $MODPROBE ${module} ||  exit 1
    done
}

verify_interfaces() {
    :
    echo "Verifying interfaces: eth1 eth0 lo eth2"
    for i in eth1 eth0 lo eth2 ; do
        $IP link show "$i" > /dev/null 2>&1 || {
            log "Interface $i does not exist"
            exit 1
        }
    done
}

prolog_commands() {
    echo "Running prolog script"
   
}

epilog_commands() {
    echo "Running epilog script"
   
}

run_epilog_and_exit() {
    epilog_commands
    exit $1
}

configure_interfaces() {
    :
    # Configure interfaces
    update_addresses_of_interface "eth1 X.X.X.X/30" ""
    update_addresses_of_interface "eth0 Y.Y.Y.Y/24" ""
    update_addresses_of_interface "lo 127.0.0.1/8" ""
    update_addresses_of_interface "eth2 172.16.1.1/24" ""
}

script_body() {
    # Using 0 address table files
    echo 1 > /proc/sys/net/ipv4/ip_dynaddr
    echo 1 > /proc/sys/net/ipv4/conf/all/accept_source_route
    echo 1 > /proc/sys/net/ipv4/conf/all/accept_redirects


    # ================ IPv4


    # ================ Table 'filter', automatic rules
    # accept established sessions
    $IPTABLES -A INPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
    $IPTABLES -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
    $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT






    # ================ Table 'filter', rule set Policy
    #
    # Rule 0 (global)
    #
    echo "Rule 0 (global)"
    #
    $IPTABLES -A OUTPUT  -m state --state NEW  -j ACCEPT
    $IPTABLES -A INPUT  -m state --state NEW  -j ACCEPT
    $IPTABLES -A FORWARD  -m state --state NEW  -j ACCEPT
}

ip_forward() {
    :
    echo 1 > /proc/sys/net/ipv4/ip_forward
}

reset_all() {
    :
    reset_iptables_v4
}

stop_action() {
    reset_all
}

check_iptables() {
    IP_TABLES="$1"
    [ ! -e $IP_TABLES ] && return 151
    NF_TABLES=$(cat $IP_TABLES 2>/dev/null)
    [ -z "$NF_TABLES" ] && return 152
    return 0
}
status_action() {
    check_iptables "/proc/net/ip_tables_names"
    ret_ipv4=$?
    check_iptables "/proc/net/ip6_tables_names"
    ret_ipv6=$?
    [ $ret_ipv4 -eq 0 -o $ret_ipv6 -eq 0 ] && return 0
    [ $ret_ipv4 -eq 151 -o $ret_ipv6 -eq 151 ] && {
        echo "iptables modules are not loaded"
    }
    [ $ret_ipv4 -eq 152 -o $ret_ipv6 -eq 152 ] && {
        echo "Firewall is not configured"
    }
    exit 3
}

# See how we were called.
# For backwards compatibility missing argument is equivalent to 'start'

test -z "$1" && {
    $0 start
    exit $?
}

case "$1" in
    start)
        log "Activating firewall script generated Sat Jun  5 12:39:35 2010 by root"
        check_tools
        prolog_commands
        load_modules
        configure_interfaces
        verify_interfaces
       
        reset_all
       
        script_body
        ip_forward
        epilog_commands
        RETVAL=$?
        ;;

    stop)
        stop_action
        RETVAL=$?
        ;;

    status)
        status_action
        RETVAL=$?
        ;;

    reload)
        $0 stop
        $0 start
        RETVAL=$?
        ;;

    interfaces)
        configure_interfaces
        RETVAL=$?
        ;;

    test_interfaces)
        FWBDEBUG="echo"
        configure_interfaces
        RETVAL=$?
        ;;

    *)
        echo "Usage $0 {start|stop|status|reload|interfaces|test_interfaces}"
        ;;

esac

exit $RETVAL


juan10dan 06-05-2010 12:56 PM

Plese forgive the long post, I hadn't notice the scrpt was that big. Specially when it has not rules at all.

Robhogg 06-05-2010 01:26 PM

What is the output of iptables -L before and after running the script?

By the way, it makes a long chunk of code / output much easier to read if you wrap [code]...[/code] tags around it.

juan10dan 06-07-2010 12:20 AM

iptables -L
 
Before script:
Code:

[root@fwnuevos ~]# iptables -L
Chain INPUT (policy ACCEPT)
target    prot opt source              destination

Chain FORWARD (policy ACCEPT)
target    prot opt source              destination

Chain OUTPUT (policy ACCEPT)
target    prot opt source              destination

After script:
Code:

[root@fwnuevos ~]# iptables -L
Chain INPUT (policy DROP)
target    prot opt source              destination
ACCEPT    all  --  anywhere            anywhere            state RELATED,ESTABLISHED
ACCEPT    all  --  anywhere            anywhere            state NEW

Chain FORWARD (policy DROP)
target    prot opt source              destination
ACCEPT    all  --  anywhere            anywhere            state RELATED,ESTABLISHED
ACCEPT    all  --  anywhere            anywhere            state NEW

Chain OUTPUT (policy DROP)
target    prot opt source              destination
ACCEPT    all  --  anywhere            anywhere            state RELATED,ESTABLISHED
ACCEPT    all  --  anywhere            anywhere            state NEW


nimnull22 06-07-2010 12:35 AM

With what conditions does your Asterisk work? Iptables remove/tured off?

Have you simply tried to change all default rules to "ACCEPT", when you will do it, please check default rules states with command "iptables-save".

juan10dan 06-07-2010 12:31 PM

Asterisk servers work with iptables stoped. So output of iptables -L is:

Code:

[root@fwnuevos ~]# iptables -L
Chain INPUT (policy ACCEPT)
target    prot opt source              destination

Chain FORWARD (policy ACCEPT)
target    prot opt source              destination

Chain OUTPUT (policy ACCEPT)
target    prot opt source              destination

If all servers work this way, asterisk servers work ok.

Changing all default rules to ACCEPT is what I supposedly tried to do with the script, and the output of iptables -L shows that for me, I think. But I think the script I'm showing you have to be doing something else in the server that is affecting communication.

If you mean changing the rules manually, well, maybe that could work, but the thing is I have to use fwbuilder because that is the software the company use. Or at least I have to know exactly why is it failing to think about another option. Besides, I configure the firewalls with all ACCEPTing for testing purposes, but these firwalls have a bunch set of rules and nat and routing, and all that works properly, so maybe changing the script generator can not be an option for me.

nimnull22 06-08-2010 01:54 PM

If your problem still exist, please, can you apply your script and then type "iptables-save". If possible, please post here output.

Second what you can do - is to add a LOG rule at the end of (it should be LAST rule): Chain INPUT, Chain FORWARD, Chain OUTPUT.
Then you can start to do some thing with asterisk. All that you will find in the log, according to firewall rules, will be dropped.

juan10dan 06-08-2010 05:19 PM

iptables-save
 
Hi, tnnks for keeping on answering.

The output of iptables-save in one of the firewalls with only one rule in fwbuilder is:

Code:

# Generated by iptables-save v1.3.5 on Tue Jun  8 17:06:31 2010
*mangle
:PREROUTING ACCEPT [12133700:5890029074]
:INPUT ACCEPT [1249720:748345578]
:FORWARD ACCEPT [10883100:5141611296]
:OUTPUT ACCEPT [1086404:759715357]
:POSTROUTING ACCEPT [11895205:5896205368]
COMMIT
# Completed on Tue Jun  8 17:06:31 2010
# Generated by iptables-save v1.3.5 on Tue Jun  8 17:06:31 2010
*filter
:INPUT DROP [2:152]
:FORWARD DROP [5:5059]
:OUTPUT DROP [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m state --state NEW -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -m state --state NEW -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state NEW -j ACCEPT
COMMIT
# Completed on Tue Jun  8 17:06:31 2010
# Generated by iptables-save v1.3.5 on Tue Jun  8 17:06:31 2010
*nat
:PREROUTING ACCEPT [351972:20012909]
:POSTROUTING ACCEPT [271654:13563320]
:OUTPUT ACCEPT [23093:1426014]
COMMIT
# Completed on Tue Jun  8 17:06:31 2010

I just see this now and wonder, what's the meaning of those three DROP rules and why they put them???. Is that the problem?

Another thing I could find was: The udp packet is getting stuck always on the second firewall. for example look at this figure:

In these case sending the packet from Asterisk 1 to Asterisk 2, the packet get lost on outbound interface in FW B, just where the X marks.
Asteris 1 ------- FWA ---------- FWB -x--------- Asterisk 2

In these other case sending the packet from Asterisk 2 to Asterisk 1, the packet get lost on outbound interface in FWA, just where the X marks.
Asteris 1 ------x- FWA ---------- FWB ----------- Asterisk 2.

Well, thnks again guys.

Hope I'm near to get this solved! With your help of course.

nimnull22 06-09-2010 01:51 AM

First of all, check if you have "1" in /proc/sys/net/ipv4/ip_forward.
If not you can use: echo 1 > /proc/sys/net/ipv4/ip_forward. Remember that it is NOT permanent, next reboot will wipe it.

Second. Take a look and try to understand, please.
:FORWARD DROP [5:5059]
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -m state --state NEW -j ACCEPT

Those mean, that anything doesn't match ACCEPT rules will be dropped.
So you NEED to add LOG rule after those two:
iptables -I FORWARD 3 -j LOG
It will add logging everything that was not assume like ACCEPT, and you can analyze it. It easily can be SNMP.

Apply it to both firewalls.

None of as is genius, but there are alway a ways how to find a problem, logging is first of them.

juan10dan 06-09-2010 04:26 PM

Hello,

iptables -I FORWARD 3 -j LOG, worked wery well. Effectively the firewall started to log some packets denied which I don't understand why if the rules say allow everything.

But saddly nothing from any of the two asterisk.

I am really stuck. I have tried to log that traffic in all possible ways (Accepting and denied using fwbuilder) but I canīt see it.

How can I configure iptables to log absolutely everything???

Please if you can continiu helping me I'll appreciate it a lot!

juan10dan 06-09-2010 06:41 PM

Ok I have now seen something really weird.

It seems to fail when in the two firewalls nat is activated, maybe "activated" is not the right word, but anyway I mean when these 5 rules appears in iptables-save's output:

Code:

*nat
:PREROUTING ACCEPT [351972:20012909]
:POSTROUTING ACCEPT [271654:13563320]
:OUTPUT ACCEPT [23093:1426014]
COMMIT

One firewall can has them but not the two at the same time. It is weird to me because no nat rules are actually activated, am I wrong??

Is it possible that the problem could be solved in asterisk configuration??

nimnull22 06-10-2010 01:12 AM

Let's clarify some question.

From your first post: "I have two asterisk servers each one behind a linux firewall/gw. Linux is Centos 5.4, kernel 2.6.18-164.el5, iptables v1.3.5.".

Can you tell please - is "linux firewall/gw" a different box, connected to "asterisk server" by ethernet?
Or is it ONE linux box? = Software (hardware) asterisk and embedded linux iptables firewall?

I will give you another questions after you answer that one, because I need to understand your network topology.

Thanks.

kirukan 06-10-2010 03:14 AM

Have you allowed udp port from 5000 to 20000 and tcp 554

juan10dan 06-10-2010 09:55 AM

Ok,

In total they are 4 linux boxes, 2 asterisk and 2 fw/gw. Firewall on asterisk boxes is completely inactivated. The two linux fw/gw boxes are PCs.

And responding to kirukan, the fw/gw are supposedly configured allowing all, but not explicitly those ports.

Another info that could be of interest: the two fw/gw are connected by a wireless network based on Motorola Canopy Appliances. Before the linux boxes, there were a couple of cisco routers making the connection to the Canopys for the two subnets. Using the cisco routers everything worked fine.

nimnull22 06-11-2010 12:42 PM

Thanks.
As long as 4 boxes are Linux it makes life easier.
I hope you know IP addresses of your asterisk.
I will use your picture:
Asteris 1 ------- FWA ---------- FWB -x--------- Asterisk 2
Please, on FWA execute command:
tcpdump -nnt src <IP of the Asterisk 1> -i <FWA INPUT interface>
You will see what asterisk #1 sends to FWA. Then you can execute it on FWB and compare those outputs.
It gives you an idea of what comes to FWA (without any changes by firewall) and what FWB receives.

Then execute that command on Asterisk 2 you will see what comes through FWB.

Try, it may give you many interesting details.

P.S. I added input interface, because FW has 2 interfaces, where tcpdump can catch source IP, so you need to specify one you need.

juan10dan 06-11-2010 03:44 PM

Thanks nimnull22,

I did what you told me about tcpdump and the packet was disappearing on the last interfase of the last fw. No packet droped at all according to the logs.

But more important is... the problem was extrangely gone now. I don't know why. I did not do anything and I tend to think people in charge of asterisk servers changed something on these boxes, although they say no.

It is maybe too soon to claim victory, but thanks a lot for your help, and I will post again if the problem returns.


All times are GMT -5. The time now is 05:08 PM.