Portál AbcLinuxu, 10. května 2025 02:10
"`echo $IP | cut -d. -f1`"ten je ale relativně pomalý a tak bych se chtěl zeptat jestli neexistuje něco rychlejšího než tento postup? Zkoušel jsem samozřejmě awk, který je o cca 20% pomalejší než cat.
user@stroj:~$ ip=($(echo "127.0.0.1" | tr '.' ' ')) user@stroj:~$ echo "${ip[0]} : ${ip[1]} : ${ip[2]} : ${ip[3]}" 127 : 0 : 0 : 1
ip=($(tr '.' ' ' <<< "127.0.0.1")) echo "${ip[0]} : ${ip[1]} : ${ip[2]} : ${ip[3]}"
Šlo by to zproduktivnit tak, že si ty IP adresy uložíš do souboru a pak je jedním spuštěním cut "rozsekáš". Nástin řešení by mohl např. být:
#!/bin/sh
# vytvoreni souboru s IP adresama
for ip in 192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4
do
echo $ip >> ip.txt
done
# vybrani pozadovane casti IP
cut -d . -f 1 ip.txt
for ip in 192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 do echo $ip done | cut -d . -f 1
oldIFS=$IFS; IFS="."
#! /bin/bash DEV="eth0" FILE="/test_2" CHAIN_TYPE="post" # pre/post/fwd M1="" M2="" M3="" M4="" IP1="" IP2="" IP3="" IP4="" BC="" BCN="" rm -rf "$FILE" convert_net_to_mask() { if let $(( (32-$1) > 0)); then M4=$(( (255 << (32-$1)) & 255)) else M4=255 fi if let $(( (24-$1) > 0)); then M3=$(( (255 << (24-$1)) & 255)) else M3=255 fi if let $(( (16-$1) > 0)); then M2=$(( (255 << (16-$1)) & 255)) else M2=255 fi if let $(( (8-$1) > 0)); then M1=$(( (255 << (8-$1)) & 255)) else M1=255 fi } convert_ip_to_network() { IP=($(tr '/' ' ' <<< "$1")) BC=${IP[1]} IP=($(tr '.' ' ' <<< "${IP[0]}")) BCN="$(($BC - 1))" convert_net_to_mask "$BCN" IP="$((${IP[0]} & $M1)).$((${IP[1]} & $M2)).$((${IP[2]} & $M3)).$((${IP[3]} & $M4))/$BCN" } A="0" while [ $A -lt 40 ]; do IP="10.93.49.194/32" IPR="10.93.0.0/16" chain="chain_${CHAIN_TYPE}_`echo $IPR | cut -d. -f1``echo $IPR | cut -d. -f2``echo $IPR | cut -d. -f3``echo $IPR | cut -d. -f4 | cut -d/ -f1`_`echo $IPR | cut -d/ -f2`" echo IPTABLES=\"iptables\" > "$FILE" if [ "`iptables -t nat -L -n | grep \"$chain\" | grep \"$IPR\"`" == "" ]; then echo \$IPTABLES -t nat -N "$chain" >> "$FILE" if [ "$CHAIN_TYPE" == "post" ]; then echo \$IPTABLES -t nat -A POSTROUTING -o $DEV -s $IPR -j "$chain" >> "$FILE" elif [ "$CHAIN_TYPE" == "pre" ]; then echo \$IPTABLES -t nat -A PREROUTING -i $DEV -d $IPR -j "$chain" >> "$FILE" elif [ "$CHAIN_TYPE" == "fwd" ]; then echo \$IPTABLES -A FORWARD -i $DEV -d $IPR -j "$chain" >> "$FILE" fi fi I="0" J="$((`echo $IP | cut -d/ -f2` - `echo $IPR | cut -d/ -f2` ))" while [ $I -lt $J ]; do convert_ip_to_network "$IP" CHAIN="chain_${CHAIN_TYPE}_${IP[0]}${IP[1]}${IP[2]}${IP[3]}_$BC" if [ "`iptables -t nat -L -n | grep \"$CHAIN\"`" == "" ]; then echo \$IPTABLES -t nat -N "$CHAIN" >> "$FILE" fi IPS="${IP[0]}.${IP[1]}.${IP[2]}.${IP[2]}/$BC1 $IPS" CHAINS="$CHAIN $CHAINS" I="$(($I + 1))" done CHAINS="$chain $CHAINS" I="1" for IP in $IPS; do CHAIND="`echo $CHAINS | cut -d \" \" -f $(($I + 1))`" if [ "`iptables -t nat -L -n | grep \"$CHAIND\"`" == "" ]; then echo \$IPTABLES -t nat -A "`echo $CHAINS | cut -d \" \" -f $I`" -s $IP -j "$CHAIND" >> "$FILE" fi I="$(($I + 1))" done A="$(($A + 1))" done
[
a ]
raději [[
a ]]
(první je builtin, druhé keyword).
A="$(($A + 1))"
je kupříkladu ((A++))
.
[
') a keyword je klíčové slovo (to je zase '[[
'). Keyword je rychlejší:
$ time for((i=0;i<99999;i++)); do [ "" ]; done real 0m1.493s user 0m1.402s sys 0m0.061s $ time for((i=0;i<99999;i++)); do [[ "" ]]; done real 0m1.096s user 0m1.054s sys 0m0.025s
$ [ ] $ [[ ]] bash: syntax error near `]]'
$(tohle je lepší)
než zastaralé `toto`
[[ -z "něco" ]]
je (trochu) rychlejší, než [[ "něco" == "" ]]
while read A B C; do /tree.sh $A $B $C done < config.cfgdruhý soubor je hlavní:
#! /bin/sh # Vytvoreno 31.10.2006 # definujeme cesty v systemu PATH="/usr/sbin:/usr/bin:/sbin:/bin" # zadame cesty k potrebnym programum IPTABLES="/sbin/iptables" IP="/sbin/ip" #NAT_CONFIG="/etc/nat_1-1.conf" NAT_CONFIG="/nat-1-1.conf" # rozsah czela.netu, nebo vnitrni site NAT_DEV="eth0" INTERNAL_IP="10.93.0.0/16" EXTERNAL_IP="88.146.200.0/22" # dummy rozhrani DUMMY_IFACE="dummy0" DUMMY_IP="10.93.0.32" convert_net_to_mask() { if let $(( (32-$1) > 0)); then M4=$(( (255 << (32-$1)) & 255)) else M4=255 fi if let $(( (24-$1) > 0)); then M3=$(( (255 << (24-$1)) & 255)) else M3=255 fi if let $(( (16-$1) > 0)); then M2=$(( (255 << (16-$1)) & 255)) else M2=255 fi if let $(( (8-$1) > 0)); then M1=$(( (255 << (8-$1)) & 255)) else M1=255 fi } convert_ip_to_network() { IP_POM=($(tr '/' ' ' <<< "$1")) BC=${IP_POM[1]} IP_POM=($(tr '.' ' ' <<< "${IP_POM[0]}")) BCN="$(($BC - 1))" convert_net_to_mask "$BCN" } # Tady zacina nat 1:1 if [ ! -e $NAT_CONFIG ]; then echo "error, $NAT_CONFIG does not exist!" else # Zakladni cast celkem peti stromu IP_POM="" M1="" M2="" M3="" M4="" BC="" BCN="" # vytvorime zakladni chainy if [ -z "`$IPTABLES -t nat -L -n | grep \"chain_pre\"`" ]; then $IPTABLES -t nat -N "chain_pre" $IPTABLES -t nat -A PREROUTING -i $NAT_DEV -d $EXTERNAL_IP -j "chain_pre" $IPTABLES -t nat -N "chain_post" $IPTABLES -t nat -A POSTROUTING -o $NAT_DEV -s $INTERNAL_IP -j "chain_post" $IPTABLES -N "chain_fwd" $IPTABLES -A FORWARD -i $NAT_DEV -s $INTERNAL_IP -j "chain_fwd" $IPTABLES -t nat -N "chain_pre_2" $IPTABLES -t nat -A PREROUTING -i ! $NAT_DEV -s $INTERNAL_IP -d $EXTERNAL_IP -j "chain_pre_2" $IPTABLES -t nat -N "chain_post_2" $IPTABLES -t nat -A POSTROUTING -o ! $NAT_DEV -s $INTERNAL_IP -d $INTERNAL_IP -j "chain_post_2" fi #while read UserName PublicIP PrivateIP; do PublicIP=$1 PrivateIP=$2 UserName=$3 if [ "`echo $UserName | cut -c1`" == "#" ] || [ "`echo $PublicIP | cut -c1`" == "#" ]; then if [ "`echo $UserName | cut -c2`" != " " ] && [ "`echo $UserName | cut -c2`" != "" ] && [ "`echo $UserName | cut -c2`" echo " $UserName commented" fi if [ "`echo $PublicIP | cut -c2`" != " " ]; then echo " $UserName commented" fi else echo " $UserName ($PrivateIP -> $PublicIP)" for LOCAL_IP in $PrivateIP; do # rozdeleni na porty if [ "`echo $LOCAL_IP | grep :`" ]; then PORT_TYPE="`echo $LOCAL_IP | cut -d: -f2`" PUBLIC_PORT="`echo $LOCAL_IP | cut -d: -f3`" PRIVATE_PORT="`echo $LOCAL_IP | cut -d: -f4`" fi # local ip musi byt jako posledni! LOCAL_IP="`echo $LOCAL_IP | cut -d: -f1`" if [ "`echo $PUBLIC_PORT | grep -`" != "" ]; then PUBLIC_PORT="`echo $PUBLIC_PORT | cut -d- -f1`:`echo $PUBLIC_PORT | cut -d- -f2`" fi echo 0 # Tato cast je opet pro generovani stromu # tam kde je rozdeleni podle INTERNAL_IP # chain_post if [ -z "`echo $LOCAL_IP | grep /`" ]; then LOCAL_IP=$LOCAL_IP/32 fi if [ -z "`echo $PublicIP | grep /`" ]; then PublicIP=$PublicIP/32 fi I="0" J="$((`echo $LOCAL_IP | cut -d/ -f2` - `echo $INTERNAL_IP | cut -d/ -f2`))" IP_POM="$LOCAL_IP" CHAINS="" while [[ $I -lt $J ]]; do convert_ip_to_network "$IP_POM" CHAIN="chain_post_${IP_POM[0]}${IP_POM[1]}${IP_POM[2]}${IP_POM[3]}_$BC" if [[ -z "`$IPTABLES -t nat -L -n | grep \"$CHAIN\"`" ]]; then $IPTABLES -t nat -N "$CHAIN" fi IP_POMS="${IP_POM[0]}.${IP_POM[1]}.${IP_POM[2]}.${IP_POM[3]}/$BC $IP_POMS" CHAINS="$CHAIN $CHAINS" IP_POM="$((${IP_POM[0]} & $M1)).$((${IP_POM[1]} & $M2)).$((${IP_POM[2]} & $M3)).$((${IP_POM[3]} & $M4))/$BCN" ((I++)) done CHAINS="chain_post $CHAINS" I="1" for IP_POM in $IP_POMS; do CHAIND="`echo $CHAINS | cut -d \" \" -f $(($I + 1))`" if [[ -z "`$IPTABLES -t nat -L -n | grep \"$CHAIND\"`" ]]; then $IPTABLES -t nat -A "`echo $CHAINS | cut -d \" \" -f $I`" -s $IP_POM -j "$CHAIND" fi ((I++)) done echo 1 if false; then # chain_post_2 I="0" J="$((`echo $LOCAL_IP | cut -d/ -f2` - `echo $INTERNAL_IP | cut -d/ -f2`))" IP_POM="$LOCAL_IP" CHAINS="" while [[ $I -lt $J ]]; do convert_ip_to_network "$IP_POM" CHAIN="chain_post_2_${IP_POM[0]}${IP_POM[1]}${IP_POM[2]}${IP_POM[3]}_$BC" if [[ -z "`$IPTABLES -t nat -L -n | grep \"$CHAIN\"`" ]]; then $IPTABLES -t nat -N "$CHAIN" fi IP_POMS="${IP_POM[0]}.${IP_POM[1]}.${IP_POM[2]}.${IP_POM[3]}/$BC $IP_POMS" CHAINS="$CHAIN $CHAINS" IP_POM="$((${IP_POM[0]} & $M1)).$((${IP_POM[1]} & $M2)).$((${IP_POM[2]} & $M3)).$((${IP_POM[3]} & $M4))/$BCN" ((I++)) done CHAINS="chain_post_2 $CHAINS" I="1" for IP_POM in $IP_POMS; do CHAIND="`echo $CHAINS | cut -d \" \" -f $(($I + 1))`" if [[ -z "`$IPTABLES -t nat -L -n | grep \"$CHAIND\"`" ]]; then $IPTABLES -t nat -A "`echo $CHAINS | cut -d \" \" -f $I`" -d $IP_POM -j "$CHAIND" fi ((I++)) done fi echo 2 # chain_fwd I="0" J="$((`echo $LOCAL_IP | cut -d/ -f2` - `echo $INTERNAL_IP | cut -d/ -f2`))" IP_POM="$LOCAL_IP" CHAINS="" while [[ $I -lt $J ]]; do convert_ip_to_network "$IP_POM" CHAIN="chain_fwd_${IP_POM[0]}${IP_POM[1]}${IP_POM[2]}${IP_POM[3]}_$BC" if [[ -z "`$IPTABLES -L -n | grep \"$CHAIN\"`" ]]; then $IPTABLES -N "$CHAIN" fi IP_POMS="${IP_POM[0]}.${IP_POM[1]}.${IP_POM[2]}.${IP_POM[3]}/$BC $IP_POMS" CHAINS="$CHAIN $CHAINS" IP_POM="$((${IP_POM[0]} & $M1)).$((${IP_POM[1]} & $M2)).$((${IP_POM[2]} & $M3)).$((${IP_POM[3]} & $M4))/$BCN" ((I++)) done CHAINS="chain_fwd $CHAINS" I="1" for IP_POM in $IP_POMS; do CHAIND="`echo $CHAINS | cut -d \" \" -f $(($I + 1))`" if [[ -z "`$IPTABLES -L -n | grep \"$CHAIND\"`" ]]; then $IPTABLES -A "`echo $CHAINS | cut -d \" \" -f $I`" -d $IP_POM -j "$CHAIND" fi ((I++)) done echo 3 # pro ty kde je rozdeleni podle EXTERNAL_IP # chain_pre I="0" J="$((`echo $PublicIP | cut -d/ -f2` - `echo $EXTERNAL_IP | cut -d/ -f2`))" IP_POM="$PublicIP" CHAINS="" while [[ $I -lt $J ]]; do convert_ip_to_network "$IP_POM" CHAIN="chain_pre_${IP_POM[0]}${IP_POM[1]}${IP_POM[2]}${IP_POM[3]}_$BC" if [[ -z "`$IPTABLES -t nat -L -n | grep \"$CHAIN\"`" ]]; then $IPTABLES -t nat -N "$CHAIN" fi IP_POMS="${IP_POM[0]}.${IP_POM[1]}.${IP_POM[2]}.${IP_POM[3]}/$BC $IP_POMS" CHAINS="$CHAIN $CHAINS" IP_POM="$((${IP_POM[0]} & $M1)).$((${IP_POM[1]} & $M2)).$((${IP_POM[2]} & $M3)).$((${IP_POM[3]} & $M4))/$BCN" ((I++)) done CHAINS="chain_pre $CHAINS" I="1" for IP_POM in $IP_POMS; do CHAIND="`echo $CHAINS | cut -d \" \" -f $(($I + 1))`" if [[ -z "`$IPTABLES -t nat -L -n | grep \"$CHAIND\"`" ]]; then $IPTABLES -t nat -A "`echo $CHAINS | cut -d \" \" -f $I`" -d $IP_POM -j "$CHAIND" fi ((I++)) done echo 4 # chain_pre_2 if false; then I="0" J="$((`echo $PublicIP | cut -d/ -f2` - `echo $EXTERNAL_IP | cut -d/ -f2`))" IP_POM="$PublicIP" CHAINS="" while [[ $I -lt $J ]]; do convert_ip_to_network "$IP_POM" CHAIN="chain_pre_2_${IP_POM[0]}${IP_POM[1]}${IP_POM[2]}${IP_POM[3]}_$BC" if [[ -z "`$IPTABLES -t nat -L -n | grep \"$CHAIN\"`" ]]; then $IPTABLES -t nat -N "$CHAIN" fi IP_POMS="${IP_POM[0]}.${IP_POM[1]}.${IP_POM[2]}.${IP_POM[3]}/$BC $IP_POMS" CHAINS="$CHAIN $CHAINS" IP_POM="$((${IP_POM[0]} & $M1)).$((${IP_POM[1]} & $M2)).$((${IP_POM[2]} & $M3)).$((${IP_POM[3]} & $M4))/$BCN" ((I++)) done CHAINS="chain_pre_2 $CHAINS" I="1" for IP_POM in $IP_POMS; do CHAIND="`echo $CHAINS | cut -d \" \" -f $(($I + 1))`" if [[ -z "`$IPTABLES -t nat -L -n | grep \"$CHAIND\"`" ]]; then $IPTABLES -t nat -A "`echo $CHAINS | cut -d \" \" -f $I`" -d $IP_POM -j "$CHAIND" fi ((I++)) done fi echo 5 # no a strom je za nami # zakladni nat 1:1 PUBLIC_POM="`echo $PublicIP | cut -d. -f1``echo $PublicIP | cut -d. -f2``echo $PublicIP | cut -d. -f3``echo $Publi LOCAL_POM="`echo $LOCAL_IP | cut -d. -f1``echo $LOCAL_IP | cut -d. -f2``echo $LOCAL_IP | cut -d. -f3``echo $LOCAL_ PublicIP2="`echo $PublicIP | cut -d/ -f1`" LOCAL_IP2="`echo $LOCAL_IP | cut -d/ -f1`" if [ "$PUBLIC_PORT" == "" ]; then $IPTABLES -t nat -A chain_pre_"$PUBLIC_POM" -d $PublicIP2 -j DNAT --to $LOCAL_IP2 $IPTABLES -t nat -A chain_post_"$LOCAL_POM" -s $LOCAL_IP2 -j SNAT --to $PublicIP2 $IPTABLES -A chain_fwd_"$LOCAL_POM" -d $LOCAL_IP2 -j ACCEPT elif [ "$PRIVATE_PORT" == "" ]; then $IPTABLES -t nat -A chain_pre_"$PUBLIC_POM" -d $PublicIP2 -p $PORT_TYPE --dport $PUBLIC_PORT -j DNAT --to $LOC $IPTABLES -t nat -A chain_post_"$LOCAL_POM" -s $LOCAL_IP2 -j SNAT --to $PublicIP2 $IPTABLES -A chain_fwd_"$LOCAL_POM" -d $LOCAL_IP2 -p $PORT_TYPE --dport $PUBLIC_PORT -j ACCEPT else $IPTABLES -t nat -A chain_pre_"$PUBLIC_POM" -d $PublicIP2 -p $PORT_TYPE --dport $PUBLIC_PORT -j DNAT --to $LOC $IPTABLES -t nat -A chain_post_"$LOCAL_POM" -s $LOCAL_IP2 -j SNAT --to $PublicIP2 $IPTABLES -A chain_fwd_"$LOCAL_POM" -d $LOCAL_IP2 -p $PORT_TYPE --dport $PRIVATE_PORT -j ACCEPT fi # Zaroven by bylo pekne zevnitr site na svou verejnou ip pingnout, # pro tohle je idealne nutne mit dummy, dalsi moznost je nastavit # DUMMY_IFACE na jedno z rozhrani LAN, kde se neprovadi nat. if false; then [ "$DUMMY_IFACE" == "" ] && DUMMY_IFACE="dummy0" [ "$DUMMY_IP" == "" ] && DUMMY_IP="`$IP addr show $DUMMY_IFACE | grep inet | grep -v inet6 | awk '{print \$2}' | c if [ "$PUBLIC_PORT" == "" ]; then $IPTABLES -t nat -A chain_pre_2_"$PUBLIC_POM" -d $PublicIP2 -j DNAT --to $LOCAL_IP2 $IPTABLES -t nat -A chain_post_2_"$LOCAL_POM" -d $LOCAL_IP2 -j SNAT --to $DUMMY_IP elif [ "$PRIVATE_PORT" == "" ]; then $IPTABLES -t nat -A chain_pre_2_"$PUBLIC_POM" -d $PublicIP2 -p $PORT_TYPE --dport $PUBLIC_PORT -j DNAT --to $L $IPTABLES -t nat -A chain_post_2_"$LOCAL_POM" -d $LOCAL_IP2 -p $PORT_TYPE --dport $PUBLIC_PORT -j SNAT --to $D else $IPTABLES -t nat -A chain_pre_2_"$PUBLIC_POM" -d $PublicIP2 -p $PORT_TYPE --dport $PUBLIC_PORT -j DNAT --to $L $IPTABLES -t nat -A chain_post_2_"$LOCAL_POM" -d $LOCAL_IP2 -p $PORT_TYPE --dport $PRIVATE_PORT -j SNAT --to $ fi fi done fi fiTřetí soubor je konfigurační:
62.240.181.2 10.93.0.1 ns.czela.net 62.240.181.3 10.93.1.211 vochomurka 62.240.181.4 10.93.0.18 mikael.czela.net 62.240.181.9 10.93.0.103 zapy.czela.net 62.240.181.10 10.93.16.9 nns.neverhood.cz 62.240.181.13 10.93.34.139 cermaksip.czela.net 62.240.181.15 10.93.0.30 karany.czela.net 62.240.181.18 10.93.11.7 wg.czela.net
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.