📜 ⬆️ ⬇️

We use 2+ providers (second part)

Let's continue setting up our gateway, which I mentioned in the previous article . I remind you that we configured the routing rules there, now we need to do iptables. Now we will configure the network consisting of a gateway and a server. SSH and DNS will work on the gateway, and we will have a Windows server on it with RDP and SMTP. The network will be configured in such a way that through any of the external IPs we will be able to connect to any of the servers, and the SMTP server will go outside through the main provider.

And of course, let's start with the variables, and put the following settings into a separate file, it will be very useful to us in the future:
#! / bin / bash

export GLOBAL_ETH_PRIM = eth1
export GLOBAL_ETH_SEC = eth2
export GLOBAL_IP_PRIM = 10.10.10.10
export GLOBAL_IP_SEC = 20.20.20.20
export MARK_PRIM = 10
export MARK_SEC = 20

Name this file ipt_p1.conf . It contains data on which of the interfaces is the main one, and which is the spare one (PRIM and SEC, respectively) and the values ​​for marking the packets.
Let's go to the main configuration file iptables, let's call it ipt.conf . We write the variables ;-)
#! / bin / bash
IPTABLES = / sbin / iptables
MODPROBE = / sbin / modprobe

This is in order to be less dependent on the distribution kit - the path to the executable files.
LOCAL_ETH = eth0
GLOBAL_ETH_P1 = eth1
GLOBAL_ETH_P2 = eth2
LOCAL_IP = 192.168.0.1
LOCAL_NET = 192.168.0.0 / 24
GLOBAL_IP_P1 = 10.10.10.10
GLOBAL_IP_P2 = 20.20.20.20

Here we described the configuration of our network, in order: the local interface, the interfaces that look to the providers, the local IP and the subnet, the IPs that are issued by the providers.
SRV11 = 192.168.0.11
SRV12 = 192.168.0.12

And this is our server for which we configured policy-based routing using labels. As I have already said, this server has two IPs on its network interface, just below I will tell why this is useful to us.
. $ 1

Hooked external settings, in this case it will be our file ipt_p1.conf .
Enough about boring, let's get down to setting it up, and try to do everything beautifully:
echo "[+] Flushing existing iptables rules ..."
$ IPTABLES -F
$ IPTABLES -F -t nat
$ IPTABLES -F -t raw
$ IPTABLES -F -t mangle
$ IPTABLES -X
$ IPTABLES -P INPUT DROP
$ IPTABLES -P OUTPUT DROP
$ IPTABLES -P FORWARD DROP

We clear all iptables rules, in the first line we say what we are doing, why in English, and so that there are no problems with the encodings. The last three lines set the default rules - all packages not matching the list of rules will be simply dropped.
$ MODPROBE ip_conntrack
$ MODPROBE iptable_nat

Loaded kernel modules that we will use.
Now go through the iptables chains and fill them with the necessary rules:
echo "[+] Setting up INPUT chain ..."

$ IPTABLES -A INPUT -m state --state INVALID -j DROP
$ IPTABLES -A INPUT -m state --state ESTABLISHED, RELATED -j ACCEPT

Using the capabilities of the state module, we discard incorrect packets and accept packets related to already established connections or to secondary connections (such as data transfer in ftp).
$ IPTABLES -A INPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT

We accept SSH connections from everywhere.
$ IPTABLES -A INPUT -i $ LOCAL_ETH -s $ LOCAL_NET -j ACCEPT

Local traffic will go without restrictions, although this is not always correct.
$ IPTABLES -A INPUT -i lo -j ACCEPT

Also on localhost.
We continue with the OUTPUT chain:
echo "[+] Setting up OUTPUT chain ..."
')
$ IPTABLES -A OUTPUT -m state --state INVALID -j DROP
$ IPTABLES -A OUTPUT -m state --state ESTABLISHED, RELATED -j ACCEPT

These rules are similar to the rules in the INPUT chain.
$ IPTABLES -A OUTPUT -o $ GLOBAL_ETH_PRIM -p udp --dport 53 -j ACCEPT

We allowed our DNS server to work through the main provider
$ IPTABLES -A OUTPUT -o $ GLOBAL_ETH_PRIM -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT

And also allowed to go outside on SSH.
$ IPTABLES -A OUTPUT -o $ LOCAL_ETH -d $ LOCAL_NET -m state --state NEW -j ACCEPT

Again, there are no restrictions on outgoing local traffic.
We proceed to the processing of traffic from the local network:
echo "[+] Setting up FORWARD chain ..."

$ IPTABLES -A FORWARD -m state --state INVALID -j DROP
$ IPTABLES -A FORWARD -m state --state ESTABLISHED, RELATED -j ACCEPT

All the same two convenient rules.
$ IPTABLES -A FORWARD -i $ GLOBAL_ETH_P1 -d $ SRV11 -p tcp --dport 25 --syn -m state --state NEW -j ACCEPT
$ IPTABLES -A FORWARD -i $ GLOBAL_ETH_P2 -d $ SRV12 -p tcp --dport 25 --syn -m state --state NEW -j ACCEPT
$ IPTABLES -A FORWARD -i $ GLOBAL_ETH_P1 -d $ SRV11 -p tcp --dport 3389 --syn -m state --state NEW -j ACCEPT
$ IPTABLES -A FORWARD -i $ GLOBAL_ETH_P2 -d $ SRV12 -p tcp --dport 3389 --syn -m state --state NEW -j ACCEPT

So we get that packets coming to the first provider are only passed to the first server IP address, the second to the second one.
$ IPTABLES -A FORWARD -i $ LOCAL_ETH -s $ SRV11 -j ACCEPT
$ IPTABLES -A FORWARD -i $ LOCAL_ETH -s $ SRV12 -j ACCEPT

We scan all outgoing traffic from our server, again, this is not entirely correct.
Next come the NAT rules:
$ IPTABLES -t nat -A POSTROUTING -s $ SRV11 -p tcp --dport 25 -j SNAT --to-source $ GLOBAL_IP_PRIM
$ IPTABLES -t nat -A POSTROUTING -s $ SRV12 -p tcp --dport 25 -j SNAT --to-source $ GLOBAL_IP_PRIM

All that our server will try to send via SMTP will go through the main provider.
And again the most interesting thing left for us. We turn to PREROUTING, here we will use the opportunity to mark the packets that we need for routing in these two lines:
ip rule add from $ srv11 fwmark 10 table T1
ip rule add from $ srv12 fwmark 20 table T2

So our rules are:
$ IPTABLES -t mangle -A PREROUTING -i $ LOCAL_ETH -s $ SRV11 -p tcp --dport 25 -j MARK --set-mark $ MARK_PRIM
$ IPTABLES -t mangle -A PREROUTING -i $ LOCAL_ETH -s $ SRV12 -p tcp --dport 25 -j MARK --set-mark $ MARK_PRIM

We mark all packets leaving our internal server on port 25 with the value of $ MARK_PRIM. Let's see what this gives us: the outgoing packet is marked with a value of 10, it means it will be routed according to table T1, and corresponding to this table the packet must go through the first provider, there is a resolving rule in the FORWARD chain, so the packet passes without hindrance - all is correct for us and was required.
Now we need to deal with the connections coming to us. First, of course, DNAT should work:
$ IPTABLES -t nat -A PREROUTING -i $ GLOBAL_ETH_P1 -d $ GLOBAL_IP_P1 -p tcp --dport 25 -j DNAT --to-destination $ SRV11
$ IPTABLES -t nat -A PREROUTING -i $ GLOBAL_ETH_P1 -d $ GLOBAL_IP_P1 -p tcp --dport 3389 -j DNAT --to-destination $ SRV11
$ IPTABLES -t nat -A PREROUTING -i $ GLOBAL_ETH_P2 -d $ GLOBAL_IP_P2 -p tcp --dport 25 -j DNAT --to-destination $ SRV12
$ IPTABLES -t nat -A PREROUTING -i $ GLOBAL_ETH_P2 -d $ GLOBAL_IP_P2 -p tcp --dport 3389 -j DNAT --to-destination $ SRV12

It seems that everything is correct, we check: the packet comes to the external interface of the gateway, depending on the interface’s belonging to the provider, it is redirected to the first or second IP server of the internal server, the server responds from the same (!) IP address, the packet on the gateway is routed through the main table, passes through FORWARD and sent through the main provider, but this is no longer correct, because the package could come through a backup provider. Fix it by adding rules:
$ IPTABLES -t mangle -A PREROUTING -i $ LOCAL_ETH -s $ SRV11 -p tcp --sport 25 -j MARK --set-mark $ MARK_PRIM
$ IPTABLES -t mangle -A PREROUTING -i $ LOCAL_ETH -s $ SRV11 -p tcp --sport 3389 -j MARK --set-mark $ MARK_PRIM
$ IPTABLES -t mangle -A PREROUTING -i $ LOCAL_ETH -s $ SRV12 -p tcp --sport 25 -j MARK --set-mark $ MARK_SEC
$ IPTABLES -t mangle -A PREROUTING -i $ LOCAL_ETH -s $ SRV12 -p tcp --sport 3389 -j MARK --set-mark $ MARK_SEC

Now on the way back, we label the packets according to the address from which they are sent. Next, the routing tables T1 and T2 come into play, so the decision through which interface to send packets is taken correctly.
Everything! Is done. To apply the rules, execute the "./ipt.conf ipt_p1.conf" command . Now our servers are available, as long as at least one of the providers gives us access to the Internet.
I also wanted to tell you how to switch between providers and make a couple of comments, but the volume of the article is already too large, probably there will be a third part.

Download scripts from the first and second part.

original article in my blog Use 2+ provider (second part)
ps Written to understand yourself and tell others.

Source: https://habr.com/ru/post/55132/


All Articles