diff options
-rw-r--r-- | ctdb/config/ctdb.sysconfig | 37 | ||||
-rw-r--r-- | ctdb/config/events.d/11.natgw | 79 |
2 files changed, 116 insertions, 0 deletions
diff --git a/ctdb/config/ctdb.sysconfig b/ctdb/config/ctdb.sysconfig index db5d16c3fe..bcc1184225 100644 --- a/ctdb/config/ctdb.sysconfig +++ b/ctdb/config/ctdb.sysconfig @@ -128,6 +128,43 @@ # CTDB_CAPABILITY_RECMASTER=yes # CTDB_CAPABILITY_LMASTER=yes +# NAT-GW configuration +# Some services running on nthe CTDB node may need to originate traffic to +# remote servers before the node is assigned any IP addresses, +# This is problematic since before the node has public addresses the node might +# not be able to route traffic to the public networks. +# One solution is to have static public addresses assigned with routing +# in addition to the public address interfaces, thus guaranteeing that +# a node always can route traffic to the external network. +# This is the most simple solution but it uses up a large number of +# additional ip addresses. +# +# A more complex solution is NAT-GW. +# In this mode we only need one additional ip address for the cluster from +# the exsternal public network. +# One of the nodes in the cluster is elected to be hosting this ip address +# so it can reach the external services. This node is also configured +# to use NAT MASQUERADING for all traffic from the internal private network +# to the external network. This node is the NAT-GW node. +# +# All other nodes are set up with policy routing so that all traffic with +# a source address of the private network and a destination outside of +# the private network are instead routed through the NAT-GW node. +# +# The effect of this is that only when a node does not have a public address +# or a route to the external network will the node use the private address +# as the source address and only then will it use the policy routing +# through the NAT-GW. +# As long as a node has a public address and can route to the external network +# the node will always pick the public address as the source address and NAT-GW +# routing will not be used. +#NATGW_PUBLIC_IP=10.0.0.227/24 +#NATGW_PUBLIC_IFACE=eth0 +#NATGW_DEFAULT_GATEWAY=10.0.0.1 +#NATGW_PRIVATE_IFACE=eth0 +#NATGW_PRIVATE_NETWORK=10.0.0.0/24 + + # where to log messages # the default is /var/log/log.ctdb # CTDB_LOGFILE=/var/log/log.ctdb diff --git a/ctdb/config/events.d/11.natgw b/ctdb/config/events.d/11.natgw new file mode 100644 index 0000000000..23fe4ae32c --- /dev/null +++ b/ctdb/config/events.d/11.natgw @@ -0,0 +1,79 @@ +#!/bin/sh +# Script to set up one of the nodes as a NAT gateway for all other nodes. +# This is used to ensure that all nodes in the cluster can still originate +# traffic to the external network even if there are no public addresses +# available. +# + +. $CTDB_BASE/functions +loadconfig ctdb + +[ -z "$NATGW_PUBLIC_INTERFACE" ] && exit 0 + +cmd="$1" +shift +PATH=/usr/bin:/bin:/usr/sbin:/sbin:$PATH + +case $cmd in + recovered) + MYPNN=`ctdb pnn | cut -d: -f2` + + # Find the first connected node + FIRST=`ctdb status -Y | grep ":0:$" | head -1` + FIRSTNODE=`echo $FIRST | cut -d: -f2` + FIRSTIP=`echo $FIRST | cut -d: -f3` + + # Delete everything that might have been set in a previous iteration + # when we were not the NAT-GW + ip rule del fwmark 11 table 11 >/dev/null 2>/dev/null + iptables -D OUTPUT -t mangle -s $NATGW_PRIVATE_NETWORK -d ! $NATGW_PRIVATE_NETWORK -j MARK --set-mark 11 >/dev/null 2>/dev/null + iptables -D OUTPUT -t mangle -s $NATGW_PRIVATE_NETWORK -d ! $NATGW_PRIVATE_NETWORK -p tcp --sport 22 -j ACCEPT >/dev/null 2>/dev/null + ip route del $NATGW_PRIVATE_NETWORK dev $NATGW_PRIVATE_IFACE table 11 >/dev/null 2>/dev/null + ip route del 0.0.0.0/0 dev $NATGW_PRIVATE_IFACE table 11 >/dev/null 2>/dev/null + + # Delete the masquerading setup from a previous iteration where we + # was the NAT-GW + iptables -D POSTROUTING -t nat -s $NATGW_PRIVATE_NETWORK -d ! $NATGW_PRIVATE_NETWORK -j MASQUERADE >/dev/null 2>/dev/null + ip addr del $NATGW_PUBLIC_IP dev $NATGW_PUBLIC_IFACE >/dev/null 2>/dev/null + + if [ "$FIRSTNODE" == "$MYPNN" ]; then + # This is the first node, set it up as the NAT GW + echo 1 >/proc/sys/net/ipv4/ip_forward + iptables -A POSTROUTING -t nat -s $NATGW_PRIVATE_NETWORK -d ! $NATGW_PRIVATE_NETWORK -j MASQUERADE + ip addr add $NATGW_PUBLIC_IP dev $NATGW_PUBLIC_IFACE + ip route add 0.0.0.0/0 via $NATGW_DEFAULT_GATEWAY >/dev/null 2>/dev/null + else + # This is not the NAT-GW + # We now need to set up a separate routing table for + # all traffic we originate and with a destination that is + # outside of the local private network and route these + # packets via the NAT-GW + + + # Mark all outgoing packets that have the private address + # as source address with fwmarker 11 + # We expect that the only time the the source address will be + # selected as the private address would be when there are + # no static or public addresses assigned at all to the node. + # Othervise the routing would have picked a different address. + # + # Except for traffic to the ssh daemon, so that it is easier + # to test in the lab without disrupting the ssh sessions + iptables -A OUTPUT -t mangle -s $NATGW_PRIVATE_NETWORK -d ! $NATGW_PRIVATE_NETWORK -p tcp --sport 22 -j ACCEPT + iptables -A OUTPUT -t mangle -s $NATGW_PRIVATE_NETWORK -d ! $NATGW_PRIVATE_NETWORK -j MARK --set-mark 11 + + + # create a routing table for the natgw traffic and set it + # up with both an interface toute for the private network + # as well as a default route that goes via the NAT-GW + ip route add $NATGW_PRIVATE_NETWORK dev $NATGW_PRIVATE_IFACE table 11 + ip route add 0.0.0.0/0 via $FIRSTIP dev $NATGW_PRIVATE_IFACE table 11 >/dev/null 2>/dev/null + + # Create a rule to use routing table 11 for these packets + ip rule add fwmark 11 table 11 + fi + ;; + +esac + +exit 0 |