id: Гость   вход   регистрация
текущее время 16:01 10/05/2024
создать
просмотр
редакции
ссылки

PF-to-iptables-конвертер


#!/bin/sh
# Simple pf to iptables converter
 
pass_out=" iptables -A OUTPUT -j ACCEPT"
block_out="iptables -A OUTPUT -j DROP"
pass_in=" iptables -A INPUT -j ACCEPT"
block_in="iptables -A INPUT -j DROP"
 
block_out_logged="iptables -A LOGGING -j DROP"
match_out_log="iptables    -A LOGGING -j LOG --log-level 4 --log-uid"
match_out_label="iptables  -A OUTPUT -j CONNMARK --set-mark"
label="-m connmark --mark"
 
on_o="-o"
on_i="-i"
 
log_label="--log-prefix"
 
proto="-p"
 
from="-s"
from_not="! -s"
 
to="-d"
to_not="! -d"
 
st_port="-m tcp --sport"
dt_port="-m tcp --dport"
 
su_port="-m udp --sport"
du_port="-m udp --dport"
 
to_ipset="dst,dst"
from_ipset="src,src"
for_ipset="-m set --match-set"
ipt_module="-m"
 
user="-m owner --uid-owner"
user_not="-m owner ! --uid-owner"
 
keep_state="-m state --state ESTABLISHED"
#keep_state="-m state --state RELATED,ESTABLISHED"
state_invalid="-m state --state INVALID"
 
socket_exists="-m owner --socket-exists"
 
clear_all(){
    iptables -F 
    iptables -X LOGGING
}
 
block_all(){
    # Default policy is to block everything except of tcp and udp.
    iptables -P INPUT DROP
    iptables -P OUTPUT DROP
    iptables -P FORWARD DROP
    for block_proto in udplite esp ah sctp; do
    #for block_proto in udplite icmp esp ah sctp; do
        $block_out $proto $block_proto
    done
}
 
block_tor_bug(){
    # Эта функция блокирует все Tor-пакеты на lo, которые, в любом случае,
    # не были бы пропущены правилами (kernel-Tor-iptables баг?). Функция
    # принимает в качестве аргумента список портов Tor'а на lo-интерфейсе.
    for i in $(seq 1 $#) ; do
        local dstPORT=$(eval echo "\$$i")
        # Client:
        $block_out $on_o lo $proto tcp $from $lh $to $lh $dt_port $dstPORT
        # Server:
        $block_out $on_o lo $proto tcp $from $lh $st_port $dstPORT $to $lh
    done
}
 
allow_out(){
    # This function allows outgoing traffic and the corresponding replies.
    # The network myIP/24 is blocked.
    local intf=$1
    local our_proto=$2
    local srcIP=$3    # local IP
    local dstIP=$4    # remote IP
    local dstPORT=$5    # remote port
    local our_user=$6
    if [ $dstIP = all ]; then
        if [ $our_proto = tcp ]; then
            $pass_out $on_o $intf $proto tcp $from $srcIP \
                $to_not $srcIP/24 $dt_port $dstPORT $user $our_user
            $pass_in  $on_i $intf $proto tcp $from_not $srcIP/24 $st_port $dstPORT \
                $to $srcIP $keep_state
        elif [ $our_proto = udp ]; then
            $pass_out $on_o $intf $proto udp $from $srcIP \
                $to_not $srcIP/24 $du_port $dstPORT $user $our_user
            $pass_in  $on_i $intf $proto udp $from_not $srcIP/24 $su_port $dstPORT \
                $to $srcIP $keep_state
        fi
    else
        if [ $our_proto = tcp ]; then
            $pass_out $on_o $intf $proto tcp $from $srcIP \
                $to $dstIP $dt_port $dstPORT $user $our_user
            $pass_in  $on_i $intf $proto tcp $from $dstIP $st_port $dstPORT \
                $to $srcIP $keep_state
        elif [ $our_proto = udp ]; then
            $pass_out $on_o $intf $proto udp $from $srcIP \
                $to $dstIP $du_port $dstPORT $user $our_user
            $pass_in  $on_i $intf $proto udp $from $dstIP $su_port $dstPORT \
                $to $srcIP $keep_state
        fi
    fi
}
 
allow_out_ipset(){
    # This function allows outgoing traffic to particular ipset list
    # (hash:ip,proto:port) and the corresponding replies. It is supposed 
    # that all protocols in ipset list are the same (either tcp or udp).
    local intf=$1
    local our_proto=$2
    local srcIP=$3    # local IP
    local ipset_list=$4
    local our_user=$5
    $pass_out $on_o $intf $proto $our_proto $from $srcIP \
        $for_ipset $ipset_list $to_ipset $ipt_module $our_proto $user $our_user
    $pass_in  $on_i $intf $proto $our_proto $to   $srcIP \
        $for_ipset $ipset_list $from_ipset $ipt_module $our_proto $keep_state
}
 
multi_allow_out(){
    # This function allows outgoing traffic and the corresponding replies to the
    # list of hosts. The network myIP/24 is blocked.
    local intf=$1
    local our_proto=$2
    local srcIP=$3    # local IP
    local dstIPandPORT_list=$4  # Format: HOST:PORT
    local our_user=$5
    old_IFS=$IFS
    cat $dstIPandPORT_list | sed 's/#.*//;/^[[:space:]]*$/d' \
        | while IFS=: read dstIP dstPORT; do
        allow_out $intf $our_proto $srcIP $dstIP $dstPORT $our_user
    done
    IFS=$old_IFS
}
 
allow_out_tor(){
    # This function allows outgoing traffic of tor users and the corresponding
    # replies. The function accepts list of Tor ports as argument.
    local intf=$1
    local srcIP=$2
    local dstIP=$3
    local our_user=$(eval echo "\$$#")
    for i in `seq 4 $(($#-1))` ; do
        local dstPORT=$(eval echo "\$$i")
        allow_out $intf tcp $srcIP $dstIP $dstPORT $our_user
    done
}
 
allow_in(){
    # This function allows incoming traffic and the corresponding replies.
    local intf=$1
    local our_proto=$2
    local srcIP=$3    # remote side
    local dstIP=$4    # local side
    local dstPORT=$5    # local port
    local our_user=$6
    if [ $our_proto = tcp ]; then
        $pass_in  $on_i $intf $proto tcp $from $srcIP \
            $to $dstIP $dt_port $dstPORT
        $pass_out $on_o $intf $proto tcp $from $dstIP $st_port $dstPORT \
            $to $srcIP $user $our_user $keep_state
    elif [ $our_proto = udp ]; then
        $pass_in  $on_i $intf $proto udp $from $srcIP \
            $to $dstIP $du_port $dstPORT
        $pass_out $on_o $intf $proto udp $from $dstIP $su_port $dstPORT \
            $to $srcIP $user $our_user $keep_state
    fi
}
 
allow_in_tor(){
    # This function allows incoming tor traffic for tor user and the corresponding
    # replies. It also includes bug workaround to allow replies from user root.
    # The function accepts list of ports as argument.
    local intf=$1
    local srcIP=$2
    local dstIP=$3
    local our_user=$(eval echo "\$$#")
    for i in `seq 4 $(($#-1))` ; do
        local dstPORT=$(eval echo "\$$i")
        $pass_in  $on_i $intf $proto tcp $from $srcIP \
            $to $dstIP $dt_port $dstPORT
        $pass_out $on_o $intf $proto tcp $from $dstIP $st_port $dstPORT \
            $to $srcIP $user $our_user $keep_state
        $pass_out $on_o $intf $proto tcp $from $dstIP $st_port $dstPORT \
            $to $srcIP $user root $keep_state
    done
}
 
lh_filter(){
    # This function allows both outgoing and incoming traffic on loopback interface.
    # It is also assumed that the same user runs both the client and the server.
    local dstPORT=$1
    local our_user=$2
    # Client side:
    allow_out lo tcp $lh $lh $dstPORT $our_user
    # Server (daemon) side:                  
    allow_in  lo tcp $lh $lh $dstPORT $our_user
}
 
tor_lh_filter(){
    # Experimental function, it consists of lh_filter + hacks to catch all Tor
    # traffic. It catches more than usual lh_filter, but not all.
    local dstPORT=$1
    local our_user=$2
    # Client side:
    $match_out_label 1 $on_o lo $proto tcp $from $lh \
        $to $lh $dt_port $dstPORT $user $our_user
    $pass_out $on_o lo $proto tcp $from $lh \
        $to $lh $dt_port $dstPORT $user $our_user
    $pass_in $on_i lo $proto tcp $from $lh $st_port $dstPORT \
        $to $lh $keep_state
    $pass_in $on_i lo $proto tcp $from $lh $st_port $dstPORT \
        $to $lh $label 1
    # Server (daemon) side:                  
    $pass_in $on_i lo $proto tcp $from $lh \
        $to $lh $dt_port $dstPORT
    $pass_out $on_o lo $proto tcp $from $lh $st_port $dstPORT \
        $to $lh $user $our_user $keep_state
    $pass_out $on_o lo $proto tcp $from $lh $st_port $dstPORT \
        $to $lh $keep_state $label 1
    $pass_out $on_o lo $proto tcp $from $lh $st_port $dstPORT \
        $to $lh $label 1
}
 
allow_dns(){
    # This function allows DNS requests for particular user.
    local our_user=$1
    #for DNS_server in $DNS_local_1 $DNS_local_2; do
    #    allow_out $eIF udp $eIP $DNS_server 53 $our_user
    #done
    for DNS_server in $DNS_inet_1 $DNS_inet_2; do
        allow_out $oIF udp $oIP $DNS_server 53 $our_user
    done
}
 
allow_dhcp(){
    local dhcp_server=$1
    $pass_out $on_o $oIF $proto udp $from $az          $su_port 68 \
        $to $a255 $du_port 67 $user root 
    $pass_in  $on_i $oIF $proto udp $from $dhcp_server $su_port 67 \
        $to $az   $du_port 68 $keep_state
}
 
bug_workaround(){
    # Experimental function.
    # An attempt to find workaround for iptables-tor-firefox bug.
    $pass_out $on_o lo $proto tcp $from $lh $st_port 9150:9151 \
        $to $lh $socket_exists $user_not 0-2000 $keep_state 
    $pass_out $on_o lo $proto tcp $from $lh $st_port 9150:9151 \
        $to $lh                $user_not 0-2000 $keep_state 
    #$pass_out $on_o lo $proto tcp $from $lh $st_port 9150:9151 \
    #    $to $lh $socket_exists $user_not 0-2000 $state_invalid
    #$pass_out $on_o lo $proto tcp $from $lh $st_port 9150:9151 \
    #    $to $lh                $user_not 0-2000 $state_invalid
}
 
start_out_logging(){
    # Start of logging all dropped packets.
    # This function should be called at the end of the set of iptables rules.
    iptables -N LOGGING
    iptables -A OUTPUT -j LOGGING
}
 
log_out_connections(){
    # Logging out connections that will be blocked later. 
    local intf=$1
    local our_proto=$2
    local our_log_label=$3
    $match_out_log $on_o $intf $log_label $our_log_label $proto $our_proto
}