通过iptables实现负载均衡的shell脚本
#!/bin/bash
# implement load balance by iptables (rr)
# should be setup by root.

# be safe
set -u

# env
export PATH="/sbin:/usr/sbin:/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin"

# usage
[ "$#" -ne 1 ] && { echo "Usage:./$0 <iplist_file>";exit 1;}


# var
port=1080
iplist=$1
protocal=tcp
basedir=/usr/local/iptables-lb
logdir=$basedir/log
logsavedays=30

# enable supports forward
sed -i 's/^net.ipv4.ip_forward.*$/net.ipv4.ip_forward  = 1/' /etc/sysctl.conf
sysctl -q -p

# set iptables policy
iptables -t nat -F
iptables -F

[ -f /etc/sysconfig/iptables.lbbak ] || cp /etc/sysconfig/iptables{,.lbbak}

linenu=1
while read ip;do
    echo "iptables -t nat -A PREROUTING -p $protocal --dport $port
        -m statistic --mode nth --every $linenu --packet 0 -j DNAT
        --to-destination $ip"

    ((linenu++))
done < "$iplist"|sort -k15 -nr|bash

iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -A FORWARD -p $protocal --dport $port -j LOG \
    --log-prefix 'IPTABLES_FORWARD_LOG:' --log-level debug
iptables-save >/etc/sysconfig/iptables

/etc/init.d/iptables restart

# set iptables log
mkdir -p $logdir
grep -q '^kern\.\*' /etc/rsyslog.conf &&
    sed -i "s#^kern\.\*.*#kern.* $logdir/access.log#" /etc/rsyslog.conf ||
        echo "kern.* $logdir/access.log" >>/etc/rsyslog.conf
/etc/init.d/rsyslog restart

cat >$logdir/logrotate.sh<<EOF
#!/bin/bash
# log rotate

/bin/mv $logdir/access.log{,.\$(/bin/date +%Y%m%d_%H%M%S)}
/etc/init.d/rsyslog reload
/bin/find $logdir -type f -mtime $logsavedays -exec rm -f {} \;

exit 0
EOF

chmod u+x $logdir/logrotate.sh
grep -q "$logdir/logrotate.sh" /var/spool/cron/root ||
    echo "0 * * * * $logdir/logrotate.sh" >>/var/spool/cron/root

# ip pool servers live detect
cat >$basedir/ip_pool_probe.sh <<EOF
#!/bin/bash
# ip pool live detect

rootdir=\$(cd \$(dirname \$0) && pwd)
cd \$rootdir
>fail_ip.txt >probe.log

while sleep 3;do
while read ip;do
    if nc -4vzw 2 \$ip $port &>/dev/null;then
        grep -q \$ip fail_ip.txt && {
            eval \$(grep "PREROUTING.*--to-destination" \
                /etc/sysconfig/iptables|head -1|
                    sed -r "s/[ /t]*$//;s/^/iptables -t nat /;s/ [0-9.]+$/ \$ip/")
            sed -i "/\$ip/d" fail_ip.txt
            echo "[\$(date +%F" "%T)]: \$ip:$port recover" >>probe.log
        }
    else
        grep -q \$ip fail_ip.txt && continue
        eval \$(grep "\--to-destination \$ip" /etc/sysconfig/iptables|
            sed 's/^-A/iptables -t nat -D/')
        echo \$ip >>fail_ip.txt
        echo "[\$(date +%F" "%T)]: \$ip:$port not connect" >>probe.log
    fi
done < <(grep "PREROUTING.*--to-destination" /etc/sysconfig/iptables|awk '{print \$NF}')
done

exit 0
EOF

chmod u+x $basedir/ip_pool_probe.sh
killall ip_pool_probe.sh &>/dev/null
($basedir/ip_pool_probe.sh &)

[[ -f "$basedir"/$(basename "$0") ]] || cp ./"$0" "$iplist" "$basedir"

echo "SUCCESS: IPTABLES-LB SETUP COMPLETE!"


exit 0