diff options
Diffstat (limited to 'doc/misc/clusterip.sh')
-rw-r--r-- | doc/misc/clusterip.sh | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/doc/misc/clusterip.sh b/doc/misc/clusterip.sh new file mode 100644 index 0000000..911f676 --- /dev/null +++ b/doc/misc/clusterip.sh @@ -0,0 +1,254 @@ +#!/bin/sh + +# +# (C) 2009-2011 by Pablo Neira Ayuso <pneira@us.es> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# + +# +# Here, you can find the variables that you have to change. +# + +# enable this for debugging +LOG_DEBUG=0 + +# number of cluster node (must be unique, from 1 to N cluster nodes) +NODE=1 + +# this is the real MAC address of eth1 +REAL_HWADDR1=00:18:71:68:f2:34 + +# this is the real MAC address of eth2 +REAL_HWADDR2=00:11:0a:60:e7:32 + +# +# These variables MUST have the same values in both cluster nodes +# + +# number of nodes that belong this cluster +TOTAL_NODES=2 + +# this is the cluster multicast MAC address of eth1 +MC_HWADDR1=01:00:5e:00:01:01 + +# this is the cluster multicast MAC address of eth2 +MC_HWADDR2=01:00:5e:00:01:02 + +# cluster IP address of eth1 +ADDR1=192.168.0.5/24 + +# cluster IP address of eth2 +ADDR2=192.168.1.5/24 + +# random seed for hashing +SEED=0xdeadbeef + +start_cluster_address() +{ + # set cluster IP addresses + ip a a $ADDR1 dev eth1 + ip a a $ADDR2 dev eth2 + # set cluster multicast MAC addresses + ip maddr add $MC_HWADDR1 dev eth1 + ip maddr add $MC_HWADDR2 dev eth2 + # mangle ARP replies to include the cluster multicast MAC addresses + arptables -I OUTPUT -o eth1 --h-length 6 \ + -j mangle --mangle-mac-s $MC_HWADDR1 + # mangle ARP request to use the original MAC address (otherwise the + # stack drops this packet). + arptables -I INPUT -i eth1 --h-length 6 --destination-mac \ + $MC_HWADDR1 -j mangle --mangle-mac-d $REAL_HWADDR1 + arptables -I OUTPUT -o eth2 --h-length 6 \ + -j mangle --mangle-mac-s $MC_HWADDR2 + arptables -I INPUT -i eth2 --h-length 6 --destination-mac \ + $MC_HWADDR2 -j mangle --mangle-mac-d $REAL_HWADDR2 +} + +stop_cluster_address() +{ + # delete cluster IP addresses + ip a d $ADDR1 dev eth1 + ip a d $ADDR2 dev eth2 + # delete cluster multicast MAC addresses + ip maddr del $MC_HWADDR1 dev eth1 + ip maddr del $MC_HWADDR2 dev eth2 + # delete ARP replies mangling + arptables -D OUTPUT -o eth1 --h-length 6 \ + -j mangle --mangle-mac-s $MC_HWADDR1 + # delete ARP requests mangling + arptables -D INPUT -i eth1 --h-length 6 --destination-mac \ + $MC_HWADDR1 -j mangle --mangle-mac-d $REAL_HWADDR1 + arptables -D OUTPUT -o eth2 --h-length 6 \ + -j mangle --mangle-mac-s $MC_HWADDR2 + arptables -D INPUT -i eth2 --h-length 6 --destination-mac \ + $MC_HWADDR2 -j mangle --mangle-mac-d $REAL_HWADDR2 +} + +start_nat() +{ + iptables -A POSTROUTING -t nat -s 192.168.0.11 \ + -j SNAT --to-source 192.168.1.5 + iptables -A POSTROUTING -t nat -s 192.168.0.2 \ + -j SNAT --to-source 192.168.1.5 +} + +stop_nat() +{ + iptables -D POSTROUTING -t nat -s 192.168.0.11 \ + -j SNAT --to-source 192.168.1.5 + iptables -D POSTROUTING -t nat -s 192.168.0.2 \ + -j SNAT --to-source 192.168.1.5 +} + +iptables_start_cluster_rules() +{ + # mark packets that belong to this node (go direction) + iptables -A CLUSTER-RULES -t mangle -i eth1 -m cluster \ + --cluster-total-nodes $TOTAL_NODES --cluster-local-node $1 \ + --cluster-hash-seed $SEED -j MARK --set-mark 0xffff + + # mark packet that belong to this node (reply direction) + # note: we *do* need this to change the packet type to PACKET_HOST, + # otherwise the stack silently drops the packet. + iptables -A CLUSTER-RULES -t mangle -i eth2 -m cluster \ + --cluster-total-nodes $TOTAL_NODES --cluster-local-node $1 \ + --cluster-hash-seed $SEED -j MARK --set-mark 0xffff +} + +iptables_stop_cluster_rules() +{ + iptables -D CLUSTER-RULES -t mangle -i eth1 -m cluster \ + --cluster-total-nodes $TOTAL_NODES --cluster-local-node $1 \ + --cluster-hash-seed $SEED -j MARK --set-mark 0xffff + + iptables -D CLUSTER-RULES -t mangle -i eth2 -m cluster \ + --cluster-total-nodes $TOTAL_NODES --cluster-local-node $1 \ + --cluster-hash-seed $SEED -j MARK --set-mark 0xffff +} + +start_cluster_ruleset() { + iptables -N CLUSTER-RULES -t mangle + + iptables_start_cluster_rules $NODE + + iptables -A PREROUTING -t mangle -j CLUSTER-RULES + + if [ $LOG_DEBUG -eq 1 ] + then + iptables -A PREROUTING -t mangle -i eth1 -m mark \ + --mark 0xffff -j LOG --log-prefix "cluster-accept: " + iptables -A PREROUTING -t mangle -i eth1 -m mark \ + ! --mark 0xffff -j LOG --log-prefix "cluster-drop: " + iptables -A PREROUTING -t mangle -i eth2 -m mark \ + --mark 0xffff \ + -j LOG --log-prefix "cluster-reply-accept: " + iptables -A PREROUTING -t mangle -i eth2 -m mark \ + ! --mark 0xffff \ + -j LOG --log-prefix "cluster-reply-drop: " + fi + + # drop packets that don't belong to us (go direction) + iptables -A PREROUTING -t mangle -i eth1 -m mark \ + ! --mark 0xffff -j DROP + + # drop packets that don't belong to us (reply direction) + iptables -A PREROUTING -t mangle -i eth2 -m mark \ + ! --mark 0xffff -j DROP +} + +stop_cluster_ruleset() { + iptables -D PREROUTING -t mangle -j CLUSTER-RULES + + if [ $LOG_DEBUG -eq 1 ] + then + iptables -D PREROUTING -t mangle -i eth1 -m mark \ + --mark 0xffff -j LOG --log-prefix "cluster-accept: " + iptables -D PREROUTING -t mangle -i eth1 -m mark \ + ! --mark 0xffff -j LOG --log-prefix "cluster-drop: " + iptables -D PREROUTING -t mangle -i eth2 -m mark \ + --mark 0xffff \ + -j LOG --log-prefix "cluster-reply-accept: " + iptables -D PREROUTING -t mangle -i eth2 -m mark \ + ! --mark 0xffff \ + -j LOG --log-prefix "cluster-reply-drop: " + fi + + iptables -D PREROUTING -t mangle -i eth1 -m mark \ + ! --mark 0xffff -j DROP + + iptables -D PREROUTING -t mangle -i eth2 -m mark \ + ! --mark 0xffff -j DROP + + iptables_stop_cluster_rules $NODE + + iptables -F CLUSTER-RULES -t mangle + iptables -X CLUSTER-RULES -t mangle +} + +case "$1" in +start) + echo "starting cluster configuration for node $NODE." + + # just in case that you forget it + echo 1 > /proc/sys/net/ipv4/ip_forward + + # disable TCP pickup + echo 0 > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_be_liberal + echo 0 > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_loose + + start_cluster_address + start_nat + + # drop invalid flows from eth2 (not allowed). This is mandatory + # because traffic which does not belong to this node is always + # labeled as INVALID by TCP and ICMP state tracking. For protocols like + # UDP, you will have to drop NEW traffic from eth2, otherwise reply + # traffic may be accepted by both nodes, thus duplicating the traffic. + iptables -A PREROUTING -t mangle -i eth2 \ + -m state --state INVALID -j DROP + + start_cluster_ruleset + ;; +stop) + echo "stopping cluster configuration for node $NODE." + + stop_cluster_address + stop_nat + + iptables -D PREROUTING -t mangle -i eth2 \ + -m state --state INVALID -j DROP + + stop_cluster_ruleset + ;; +primary) + logger "cluster-match-script: entering MASTER state for node $2" + if [ -x $CONNTRACKD_SCRIPT ] + then + sh $CONNTRACKD_SCRIPT primary $NODE $2 + fi + iptables_start_cluster_rules $2 + ;; +backup) + logger "cluster-match-script: entering BACKUP state for node $2" + if [ -x $CONNTRACKD_SCRIPT ] + then + sh $CONNTRACKD_SCRIPT backup $NODE $2 + fi + iptables_stop_cluster_rules $2 + ;; +fault) + logger "cluster-match-script: entering FAULT state for node $2" + if [ -x $CONNTRACKD_SCRIPT ] + then + sh $CONNTRACKD_SCRIPT fault $NODE $2 + fi + iptables_stop_cluster_rules $2 + ;; +*) + echo "$0 start|stop|add|del [nodeid]" + ;; +esac |