|
This is part two of "Inbound and outbound routing over multiple internet connections " Any self respecting router not only routes traffic outwards, but of course allows certain services to be hosted and accessed by the "outside" In the case of routers with a single connection, this is fairly simple, but with two internet connections, it gets a bit more complex.
If the service you are hosting is running on the router itself, its quite simple to solve with some additional routing table rules. If however, the service is hosted on another server, then there needs to be some ip rules set in place to handle the request.
So lets tackle these in turn. Im assuming you read the first part of this guide ( Inbound and outbound routing over multiple internet connections ) because its going to build on what we've covered already.
We should already have a single script that does the following:
- Uses IPTABLES to setup the pc as a router and firewall
- Copies the main (and default) routing table to another table called tbr (which uses a secondary internet connection as its default)
- Uses IPTABLES to tag traffic of a certain type
- Defines IP rules to route packets that have been marked over the tbr table
We need to define some tables that cope with what happens when an incoming request it received. Requests coming in on the default connection (internet connection a) should be serviced no problem. Incomming requests coming in on internet connection b however will not be serviced. This is because the request will be recieved, a response sent, but it will send the response by the default connection (interent connection A) the ISP router will probably get it, and discard it because its unknown traffic. So what we need is two tables, one with interent connection a is the default, and another where internet connection b is the default, and some rules to decide when to use them. In theory, we could use the existing Main and tbr tables, but for good orders sake (and that of my sanity) I decided to create two new routing tables. So lets call them inboundA and inboundB.
- InboundA has internet connection A as its default
- InboundB has internet connection B as its default
Before we add these tables, we going to need to assemble some information, namely:
- The name of the interface for each internet connection
- The ip address of the router (the pc we're working on) as the adsl modem sees
- The ip address range between the router (the pc we're working on) and the adsl modem
- The public ip address of the connection
In the case of internet connection A, as we can see from part 1 of this guide, the interface card for this connection is eth2 (should have been eth1 for understandability i guess, but hey ho). The address of the adsl modem for this connection is 192.168.4.1 . The ip address for the router on this range is 192.168.4.2 , so we know that the range we need (for internet connection A) is 192.168.4.0/24. Finally the public IP address of this connection is (lets say) 1.1.1.1. So lets see how this will look in terms of creating a routing table:
ip route add <ip address range> dev <ethx> scope link src <public ip address> table inboundA
ip route add default via <ip address of router> dev <ethx> table inboundA
For internet connection A
ip route add 192.168.4.0/24 dev eth2 scope link src 1.1.1.1 table inboundA
ip route add default via 192.168.4.1 dev eth2 table inboundA
So this creates a new routing table that deals specifically with inbound requests comming in on internet connection A, now the same for B
ip route add 192.168.5.0/24 dev eth1 scope link src 2.2.2.2 table inboundB
ip route add default via 192.168.5.1 dev eth1 table inboundB
We now have both of our inbound routing tables, and we need to define rules as to when they should be used. They are fairly simple. They basically say, if the request comes in on internet connection A, route via inboundA. If it comes in on internet connection B, route via inboundB:
ip rule add from 1.1.1.1 lookup inboundA
ip rule add from 2.2.2.2 lookup inboundB
Finally, dont forget to allow whatever service your publishing through your firewall:
$IPTABLES -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
That gets things working for hosting a service on the router itself. Try it and see, start apache If its not started already, and (preferably using a third interent connection) try accessing a page on your web server, it should return the same page which ever public ip address you request (1.1.1.1 or 2.2.2.2) .Put these additional command into your .sh file so they can be executed when the router is rebooted. I prefer to group my routing table creation commands together based on function (e.g. command for outbound routing in one block, and inbound routing in another), and the firewall commands together. Ive written a script which (with the correct hardware) will turn your router into a dual internet connection inbound / outbound router with conditional traffic type routing on. Its available in Part 3
Lets tackle what happens when we want to port forward to another pc that is hosting our service (lets say a mail server). Now there probaby a couple of other ways of achieving this, this solution isnt particularly elegant, but it works.
The basis for this working is that each server you have hosting a service, has two ip address (its multihomed), so for exmaple our mail server has two ip addresses on the network, that being 192.168.1.10 and 192.168.1.11. Essentailly we work it by saying, if a mail request comes in on internet connection A, route it to 192.168.1.10. If a request comes in on internet connection B route it to 192.168.1.11. both end up at the same mail server, just via different routes. We achieve this using IPTABLES, and we make sure the response is sent to the correct internet connection using ip rules, So lets set up the rules first:
ip rule add from <serverip> lookup inboundx
or for mail coming in on internet connection A:
ip rule add from 192.168.1.10 lookup inboundA
and for mail coming in on internet connection B:
ip rule add from 192.168.1.11
And now use IPTABLES to forward the request to the correct IP address
# FOR INCOMING ON INTERNET CONNECTION A
$IPTABLES -A INPUT -i eth2 -p tcp --dport 25 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES - t nat -A PREROUTING -i eth2 -p tcp --dport 25 -j DNAT --to 192.168.1.10:25
$IPTABLES -A FORWARD -i eth2 -p 25 -d 192.168.1.10 --dport 25 -j ACCEPT
# FOR INCOMING ON INTERNET CONNECTION B
$IPTABLES -A INPUT -i eth1 -p tcp --dport 25 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES - t nat -A PREROUTING -i eth1 -p tcp --dport 25 -j DNAT --to 192.168.1.11:25
$IPTABLES -A FORWARD -i eth1 -p 25 -d 192.168.1.11 --dport 25 -j ACCEPT
IPTABLES will now forward to one ip address or the other depending on which interface it comes in on (or in other words, which internet connection) and forwards it to either the primary ip address of the server, or the aliased, either way, they both end up with the same server. The ip rules then ensure that the repsonse gets sent out on the correct internet connection. Finally, we just need to alias our server. Theres plenty of sites that will tell you how to do this (for linux... heres one : http://www.xenocafe.com/tutorials/linux/redhat/bind_multiple_ip_addresses_to_single_nic/index.php )
Windows is fairly easy to multi home, simply bring up your network connection properties:
- control panel->network connections
- right click on "local area connection 1" and click properties
- Click on internet protocol (TCP/IP) and click properties
- Click on advanced
- Click on Add - It appears that doing this while having the ip address determined by DHCP is not permitted, so you'd have to give it a static ip in order for it to work.
- In the above example, we have a mail server, its address is already 192.168.1.10, we add 192.168.1.11.Click on OK
- Click on OK to the TCP/IP Properties dialogue
- Click on OK to the local area connection properties dialogue
Try pinging your new address, and check a reply is sent back
Now we test our configuration. Again, Ideally with another (third) internet connection. we can do this by typing (at linux # prompt or Windows cmd prompt)
telnet 1.1.1.1 25
You should get a response like
220 mail.yourdomain.com ESTMP Postfix
(if your using a postfix mail server)
Conclusion
So there it is. Theres quite a bit of information on the internet about this sort of thing (if you look hard enough) Configurations like this are great for mission critical applications, especially email. Consider the situation: the primary internet connection goes down, and thats how email was getting in on the STMP feed. No problem, change your domain MX record to point at the seconday internet connection, and hey presto, your back up and running. Again using the DNS records, theres even a level of load balancing you can do. Brilliant! Like I said, I've merged everything needed to route over two internet connection into a .sh script which you can download in part 3. As ever, any questions or comments use the comment form below. |