From mboxrd@z Thu Jan 1 00:00:00 1970 From: Brian Burch Date: Sat, 21 Dec 2013 12:53:35 +0000 Subject: Re: How to override the default source ipv4 address on packets originating from a router Message-Id: <52B58F4F.3000201@pingtoo.com> List-Id: References: <52B43271.7040807@PingToo.com> In-Reply-To: <52B43271.7040807@PingToo.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: lartc@vger.kernel.org On 20/12/13 18:46, Brian Burch wrote: > On 20/12/13 13:05, Joel Gerber wrote: >> Your problem is one I've come up against a number of times in the >> past. You are definitely on the right route using "policy routing" >> (otherwise known as utilizing IP Rules), but the snag you're hitting >> is that the source address of a locally generated packet isn't chosen >> until a destination route has already been selected. Using the from >> statement in an ip rules table is only useful when you're routing >> packets from other subnets. > > What a quick and helpful reply! Not only did my problem motivate you to > respond, but I am very relieved to find the answer isn't just RTFM. > > Your explanation about the timing for kernel selection of the source > address is crucial and now my failed experiments all make sense. Your > suggested solution also makes sense, although it is counter-intuitive... > at least to me! > >> Now, just so you know, the local table should normally be left alone. >> It's used for locally connected subnets only. It is given the highest >> priority on purpose... don't mess with it! :) > > I read somewhere (possibly the howto guide or the ip-cref) a statement > that the kernel treats this table as read-only. My system is running > ubuntu 13.04 with a custom non-pae 3.8.0 kernel, so it is reasonably > modern. When I thought more about the purpose of this table, I decided > there would be no point in trying to modify it, even if that was possible. > >> There are a few methods you could try here, but I'm only going to >> recommend one of them. Have your main routing table hold the routes >> that your local machine will use, and then have a separate table for >> all routed hosts. Then, use ip rule statements to force any traffic >> coming in from a routed host into that routing table. >> >> IE: on firewall-router (assuming eth1 is facing your static subnet >> hosts): >> >> # ip rule list >> 0: from all lookup local >> 32765: iif eth1 lookup static-hosts >> 32766: from all lookup main >> 32767: from all lookup default >> >> Have table main include all of the routes your local firewall-router >> should use, and have static-hosts contain all of the routes that your >> static-subnet-hosts should use. > > Great! I understand the principle you propose and will try to implement > it over the weekend. I will update this thread when I have something to > report. Excellent news!! My router/firewall is currently collecting 200+ updated packages from the repository server! The solution was achieved using ONLY policy routing, based on Joel's suggested approach. However, I hit some fairly nasty snags along the way and had to do a lot of trial and error fiddling to make it work. I am certain my working solution can be made more elegant, but that will take a couple of hours pen-and-pencil time to map out the current routing table entries in selection order and then perform some experiments. I don't have time to do it at the moment, but will get started over the next couple of days. If I get stuck, I will post the "current best" configuration and ask for help to improve it. Regards, Brian > Once again, thanks for helping, > > Brian > >> Joel Gerber >> Network Specialist >> Network Operations >> Eastlink >> E: Joel.Gerber@corp.eastlink.ca T: 519.786.1241 >> -----Original Message----- >> From: lartc-owner@vger.kernel.org [mailto:lartc-owner@vger.kernel.org] >> On Behalf Of Brian Burch >> Sent: December-20-13 7:05 AM >> To: Linux Advanced Routing >> Subject: How to override the default source ipv4 address on packets >> originating from a router >> >> The mailing list has been dormant for 2 years, so I wonder whether >> anyone is still listening for new questions? >> >> My broadband router runs PPPoA and is dynamically assigned a single >> ipv4 internet address by my ISP. I have a static subnet which I host >> on a linux router/firewall (called chenin). The linux firewall and the >> adsl router communicate via a non-internet-addressable private subnet. >> Here is the topology: >> >> Internet -- adsl-router-ppp0-ipv4-dynamic >> -- adsl-router-eth0-172.16.101.1 >> -- >> -- firewall-router-eth0-172.16.101.2 >> -- firewall-router-217.154.193.209 >> -- >> -- static-subnet-hosts-217.154.193.154.208/28 >> >> Each of the hosts on the static subnet use 217.154.193.209 as their >> own default route. The adsl router forwards all incoming packets to >> the firewall/router's eth0. The firewall/router forwards all incoming >> packets to the static subnet via its own eth1. The firewall/router >> does not need to perform NAT, but it implements a simple set of >> iptables rules for blacklisting, etc. /All this works perfectly./ >> >> My problem is that I need to download software updates (debian apt-get >> http) for the firewall/router from a repository out on the internet. >> >> The firewall/router can successfully ping the repo-server when I force >> the source address like this: >> >> ping -I 217.154.193.209 163.1.221.67 >> >> ... but a simple "ping 163.1.221.67" (i.e. using the default source >> address selection algorithm) fails. Wireshark confirms these >> unanswered packets go out on eth0 with a source address of 172.16.101.2. >> >> I believe I should be able to resolve this problem with iproute2 >> policy routing, but so far I have not been successful. I've tried >> several variations, but they all give me the same "wrong" source address. >> >> >> Here is my simplest effort: >> >> brian@chenin:~$ ip rule list >> 0: from all lookup local >> 32765: from 172.16.101.2 lookup CHENIN_ONLY >> 32766: from all lookup main >> 32767: from all lookup default >> >> brian@chenin:~$ ip route list table CHENIN_ONLY >> 163.1.221.67 via 172.16.101.1 dev eth0 src 217.154.193.209 >> >> brian@chenin:~$ sudo ip route flush cache brian@chenin:~$ ip route get >> 163.1.221.67 >> 163.1.221.67 via 172.16.101.1 dev eth0 src 172.16.101.2 >> cache >> >> This shows me the source address in my policy rule has NOT been used, >> or the routing table entry does not work the way I think. >> >> >> The only rule table with higher priority than CHENIN_ONLY is local, >> which contains routes for addresses local to the firewall/router - >> nothing about remote addresses, i.e. >> >> brian@chenin:~$ ip route list table local >> broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1 >> local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 >> local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 >> broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1 >> broadcast 172.16.101.0 dev eth0 proto kernel scope link src >> 172.16.101.2 >> local 172.16.101.2 dev eth0 proto kernel scope host src 172.16.101.2 >> broadcast 172.16.101.255 dev eth0 proto kernel scope link src >> 172.16.101.2 >> broadcast 217.154.193.208 dev eth1 proto kernel scope link src >> 217.154.193.209 >> local 217.154.193.209 dev eth1 proto kernel scope host src >> 217.154.193.209 >> broadcast 217.154.193.223 dev eth1 proto kernel scope link src >> 217.154.193.209 >> >> and the main table looks like this: >> >> brian@chenin:~$ ip route list table main >> default via 172.16.101.1 dev eth0 >> 169.254.0.0/16 dev eth0 scope link metric 1000 >> 172.16.101.0/24 dev eth0 proto kernel scope link src 172.16.101.2 >> 217.154.193.208/28 dev eth1 proto kernel scope link src >> 217.154.193.209 >> >> >> I wonder whether my unsuccessful "naked" pings to 163.1.221.67 are >> passing through the tables three times: >> >> 1. My explicit policy should be applied to select a source address >> of 217.154.193.209. >> 2. The main table is used to select the default route via 172.16.101.1: >> 3. The main table then provides the explicit route to the default >> router, which seems to rewrite the source address to 172.16.101.2. >> >> I have read the latest lartc HOWTO sections relevant to policy routing, >> but didn't see anything similar to my situation. I also didn't see how >> to get a verbose (i.e. blow by blow) output from the "ip route get" >> command to show how it is selecting its route. >> >> Am I trying to do the impossible here, or am I just making a mistake in >> the way I am doing it? >> >> I hope this strikes someone as an interesting question. If I can achieve >> a solution, I would be happy to add the scenario to the HOWTO. >> >> Brian >> -- >> To unsubscribe from this list: send the line "unsubscribe lartc" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > > -- > To unsubscribe from this list: send the line "unsubscribe lartc" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html