Sunday, November 23, 2008

Iptables and iproute2

  1. Declaration of variables in shell script:

    WAN=eth1
    VPN=tun0
    PROT=tcp
    WANPORT=3389
    RHOST=remote hostname
    RIP=`getent hosts $RHOST |cut -d' ' -f1`
    WANIP=`ip addr list $WAN |grep "inet " |cut -d' ' -f6|cut -d/ -f1`
    TBL=vpn
    PRIO=500
    
    #cat /etc/iproute2/rt_tables
    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    8       vpn
    
  2. Routing based on destination port and IP address (required route to the remote IP is via a VPN tunnel interface). I first modified the script /etc/vpnc/vpnc-script to limit its *_route functions only updating the routing table $TBL.

    Since the NAT clients need to connect to the remote desktop service of RIP via the tunnel, their packets should be mangled before routing/forwarding when they arrive at the PREROUTING chain:
    CHAIN=PREROUTING
    iptables -t mangle -A ${CHAIN} -p $PROT -d $RIP --dport $WANPORT -j MARK --set-mark 1
    #iptables -t mangle -A ${CHAIN} -m mark --mark 1 -j LOG --log-level DEBUG --log-prefix "fwmark 1: "


    The packets originated from the router will most likely arrive at the WAN interface and the OUTPUT chain of mangle table after the routing decision is made by kernel according to the table 3-2 of this article. Therefore their routing are not affected. In order to make it work, the packets need to arrive at the LAN interface and the OUTPUT chain of the mangle table.
    CHAIN=OUTPUT
    iptables -t mangle -A ${CHAIN} -p $PROT -d $RIP --dport $WANPORT -j MARK --set-mark 1
    #iptables -t mangle -A ${CHAIN} -m mark --mark 1 -j LOG --log-level DEBUG --log-prefix "fwmark 1: "

    This can be achieved by binding the socket to the LAN interface first then send the packets.
    #IP address of the LAN interface
    my $raddr = inet_aton("192.168.0.1");
    # create and bind the socket
    my $proto = getprotobyname('tcp');
    socket(SOCKET, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
    bind(SOCKET, pack_sockaddr_in(0, $raddr)) or die "bind: $!";


    All the marked packets will then be routed by the following rule:
    ip rule del prio $PRIO
    ip rule add prio $PRIO from fwmark 1 table $TBL


    #ip rule
    0: from all lookup local
    500: from all fwmark 0x1 lookup vpn
    32766: from all lookup main
    32767: from all lookup default

    #ip route show table vpn
  3. Block Ping requests from WAN:
    iptables -A INPUT -p icmp --icmp-type 8 -i $WAN -m state --state NEW,ESTABLISHED,RELATED -j DROP
  4. Check log target of iptables:
    iptables -n -L -v|grep -i log
    cat /etc/shorewall/policy
    #SOURCE         DEST            POLICY          LOG LEVEL       LIMIT:BURST      
    loc     net     ACCEPT
    loc     fw      ACCEPT
    fw      loc     ACCEPT
    fw      net     ACCEPT
    #net    all     DROP    info
    #Disable logging of dropped packets
    net     all     DROP
    all     all     REJECT  info
    

1 comment:

alex smith said...

I've been reading about SSH for while and heard that it is a good way to secure my information, but on the other hand I've heard proxy is good