{"id":50,"date":"2007-03-12T01:05:26","date_gmt":"2007-03-11T23:05:26","guid":{"rendered":"http:\/\/lukav.com\/wordpress\/2007\/03\/12\/openwrt-multi-wan-how-to\/"},"modified":"2025-05-24T16:27:22","modified_gmt":"2025-05-24T14:27:22","slug":"openwrt-multi-wan-how-to","status":"publish","type":"post","link":"http:\/\/lukav.com\/wordpress\/2007\/03\/12\/openwrt-multi-wan-how-to","title":{"rendered":"OpenWRT Multi WAN How To"},"content":{"rendered":"<p>Draft<\/p>\n<p>This is a simple how to make your <a href=\"http:\/\/openwrt.org\/\" style=\"font-size: 16px; line-height: 20.8px\">openwrt<\/a> work with more than one WAN. I&#8217;ve used these steps to make my ASUS WL-500G Premium work with 2 WANs where in my case I route specific IP ranges through the second interface. However the instruction can be used to setup load balancing although not so perfect. I&#8217;ve actually installed <a href=\"http:\/\/x-wrt.org\/\">X-Wrt<\/a> to begin with so I use webif2 interface to setup some of the things. I&#8217;ll try to describe those steps without webif2 using ssh, but I must stress that those would be my assumptions and if something doesn&#8217;t work you should refer to openwrt and xwrt pages and forums.<\/p>\n<p>As a first step make sure you setup your primary WAN interface. Then we are going setup the second interface. Choose one of the LAN ports of your router and separate this port in a new vlan. In my case I&#8217;ve setup my 1-st port as vlan2.<\/p>\n<p>webif2: Network\/VLAN, click on &#8220;Add New VLAN&#8221; then deselect eNet1 from VLAN 0 row and select it on the VLAN 2 row, check Internal also on that row. Click Save and then Apply.<\/p>\n<p>ssh: Execute<\/p>\n<pre>nvram set vlan0ports=2 3 4 5*<\/pre>\n<p>to remove the port from vlan2 and<\/p>\n<pre>nvram set vlan2ports=1 5<\/pre>\n<p>to add it in the new vlan, I guess you should also execute:<\/p>\n<pre>nvram set vlan2hwname=et0<\/pre>\n<p>Now we need to setup IP address and bring up the second interface.<\/p>\n<p>webif2: you can use the System\/NVRAM page to setup the NVRAM variables described below: ssh:<\/p>\n<pre>nvram set wan2_ifname=vlan2\r\nnvram set wan2_proto=static\r\nnvram set wan2_ipaddr=xyz.xyz.xyz.xyz\r\nnvram set wan2_netmask=xyz.xyz.xyz.xyz\r\nnvram set wan2_gateway=xyz.xyz.xyz.xyz\r\nnvram set ifup_interfaces=\"lan wan wan2 wifi\"<\/pre>\n<p>The last line would make sure wan2 interface is broth up on restart.  Let&#8217;s try<\/p>\n<pre>ifup wan2<\/pre>\n<p>now.  If<\/p>\n<pre>ifconfig<\/pre>\n<p>show you vlan2 with the ip address you should be in business. Please note that you can use dhcp instead of static proto, but I haven&#8217;t tested this.<br \/>\nYou can do<\/p>\n<pre>nvram commit<\/pre>\n<p>so your changes are saved.<\/p>\n<p>Ok. Now we must make sure that requests on a certain interface are replied via the same interface. Detailed information can be found at  <a href=\"http:\/\/lartc.org\/howto\/lartc.rpdb.multiple-links.html\">http:\/\/lartc.org\/howto\/lartc.rpdb.multiple-links.html<\/a><br \/>\nCheck if the file \/etc\/iproute2\/rt_tables exists and if not create it. Then put\/add lines for the 2 interfaces in it:<\/p>\n<pre>mkdir \/etc\/iproute2\r\necho \"201 WAN1\" &gt;&gt; \/etc\/iproute2\/rt_tables\r\necho \"202 WAN2\" &gt;&gt; \/etc\/iproute2\/rt_tables<\/pre>\n<p>I&#8217;ve setup a little script that will add all the necessary rules in the ip tables as described in lartc howto. It would also remove the extra default route added for the second interface by the S40network script. So just save the following as S45routing and put it in \/etc\/init.d so it gets executed after on boot. Make sure it is executable:<\/p>\n<p>S45routing<\/p>\n<pre>cat &lt;&lt; EOF &gt; \/etc\/init.d\/S45routing\r\n#!\/bin\/sh\r\n\r\n. \/etc\/functions.sh\r\nWAN1=\"$(nvram get wan_ifname)\"\r\nWAN1_IP=\"$(nvram get wan_ipaddr)\"\r\nWAN1_NETMASK=\"$(nvram get wan_netmask)\"\r\nWAN1_GETEWAY=\"$(nvram get wan_gateway)\"\r\n\r\neval $(ipcalc.sh \"$WAN1_IP\" \"$WAN1_NETMASK\")\r\nWAN1_NETWORK=$NETWORK\r\nWAN1_PREFIX=$PREFIX\r\n\r\nWAN2=\"$(nvram get wan2_ifname)\"\r\nWAN2_IP=\"$(nvram get wan2_ipaddr)\"\r\nWAN2_NETMASK=\"$(nvram get wan2_netmask)\"\r\nWAN2_GETEWAY=\"$(nvram get wan2_gateway)\"\r\n\r\neval $(ipcalc.sh \"$WAN2_IP\" \"$WAN2_NETMASK\")\r\nWAN2_NETWORK=$NETWORK\r\nWAN2_PREFIX=$PREFIX\r\n\r\nLAN=\"$(nvram get lan_ifname)\"\r\nLAN_IP=\"$(nvram get lan_ipaddr)\"\r\nLAN_NETMASK=\"$(nvram get lan_netmask)\"\r\n\r\neval $(ipcalc.sh \"$LAN_IP\" \"$LAN_NETMASK\")\r\nLAN_NETWORK=$NETWORK\r\nLAN_PREFIX=$PREFIX\r\n\r\nroute del default gw $WAN2_GETEWAY\r\n\r\nip route flush table WAN1\r\nip route flush table WAN2\r\nip route del $WAN1_NETWORK\/$WAN1_PREFIX dev $WAN1 src $WAN1_IP\r\nip route del $WAN2_NETWORK\/$WAN2_PREFIX dev $WAN2 src $WAN2_IP\r\nip rule del from $WAN1_NETWORK\/$WAN1_PREFIX table WAN1\r\nip rule del from $WAN2_NETWORK\/$WAN2_PREFIX table WAN2\r\n\r\nip rule add from $WAN1_NETWORK\/$WAN1_PREFIX table WAN1 prio 201\r\nip rule add from $WAN2_NETWORK\/$WAN2_PREFIX table WAN2 prio 202\r\n\r\nip route add $WAN1_NETWORK\/$WAN1_PREFIX dev $WAN1 src $WAN1_IP\r\nip route add $WAN2_NETWORK\/$WAN2_PREFIX dev $WAN2 src $WAN2_IP\r\n\r\nip route add table WAN1 $WAN1_NETWORK\/$WAN1_PREFIX dev $WAN1 src $WAN1_IP\r\nip route add table WAN1 $LAN_NETWORK\/$LAN_PREFIX dev $LAN\r\nip route add table WAN1 127.0.0.0\/8 dev lo\r\nip route add table WAN1 $WAN2_NETWORK\/$WAN2_PREFIX dev $WAN2\r\nip route add table WAN1 default via $WAN1_GETEWAY dev $WAN1\r\n\r\nip route add table WAN2 $WAN2_NETWORK\/$WAN2_PREFIX dev $WAN2 src $WAN2_IP\r\nip route add table WAN2 $LAN_NETWORK\/$LAN_PREFIX dev $LAN\r\nip route add table WAN2 127.0.0.0\/8 dev lo\r\nip route add table WAN2 $WAN1_NETWORK\/$WAN1_PREFIX dev $WAN1\r\nip route add table WAN2 default via $WAN2_GETEWAY dev $WAN2\r\n\r\nip rule del table BG_ROUTES prio 220\r\nip rule add table BG_ROUTES prio 220\r\n\r\nEOF\r\nchmod +x \/etc\/init.d\/S45routing<\/pre>\n<p>Execute the file or restart your router. At this point you should have 2 working WANs where they both reply on ping from external network. Now there are 2 approaches from here:<\/p>\n<p><strong>1: Setup load balancing by specifying multiple default routes.  I&#8217;ll quote the LARTC on this:<\/strong><\/p>\n<p>quote: &#8221;<\/p>\n<p>The second question is how to balance traffic going out over the two providers. \t  This is actually not hard if you already have set up split access as above.<\/p>\n<p>Instead of choosing one of the two providers as your default route, \t  you now set up the default route to be a multipath route. In the default \t  kernel this will balance routes over the two providers. It is done \t  as follows (once more building on the example in the section on \t  split-access):<\/p>\n<pre>  ip route add default scope global nexthop via $P1 dev $IF1 weight 1\r\n     nexthop via $P2 dev $IF2 weight 1<\/pre>\n<p>This will balance the routes over both providers. The <strong class=\"COMMAND\">weight<\/strong> \t  parameters can be tweaked to favor one provider over the other.<\/p>\n<p>Note that balancing will not be perfect, as it is route based, and routes \t  are cached. This means that routes to often-used sites will always \t  be over the same provider.<\/p>\n<p>&#8221;<\/p>\n<p><strong>2: route specific range of ip via the second interface as me:<\/strong><\/p>\n<p>I&#8217;ll layout how I do it and you can tweak it as you like:<\/p>\n<p>First add one more line in \/etc\/iproute2\/rt_tables<\/p>\n<pre>echo \"220 BG_ROUTES\" &gt;&gt; \/etc\/iproute2\/rt_tables<\/pre>\n<p>Then I have 2 files in \/etc\/route directory:<\/p>\n<pre>mkdir \/etc\/route<\/pre>\n<pre>touch \/etc\/route\/bg_routes.txt<\/pre>\n<p>&#8211; those are the ip ranges that goes via the second interface<\/p>\n<pre>touch \/etc\/route\/exc_bg_routes.txt<\/pre>\n<p>&#8211; those are the ranges that I want to be sure would go via the first. I do this becuase I get bg_routes.txt from a third party periodically.<\/p>\n<p>Then I use those 2 scripts to populate the tables:<\/p>\n<p>clean_bg_routes.sh<\/p>\n<pre>cat &lt;&lt; EOF &gt; \/etc\/route\/clean_bg_routes.sh\r\n#!\/bin\/sh\r\nip route flush table BG_ROUTES\r\nEOF\r\nchmod +x \/etc\/route\/clean_bg_routes.sh<\/pre>\n<p>update_bg_routes.sh (2007.04.01 &#8211; this script has been updated with the contribution from robert at irrelevant dot com)<\/p>\n<pre>cat &lt;&lt; EOF &gt; \/etc\/route\/update_bg_routes.sh\r\n#!\/bin\/sh\r\n\r\nWAN1=\"$(nvram get wan_ifname)\"\r\nWAN1_IP=\"$(nvram get wan_ipaddr)\"\r\nWAN1_NETMASK=\"$(nvram get wan_netmask)\"\r\nWAN1_GETEWAY=\"$(nvram get wan_gateway)\"\r\n\r\nWAN2=\"$(nvram get wan2_ifname)\"\r\nWAN2_IP=\"$(nvram get wan2_ipaddr)\"\r\nWAN2_NETMASK=\"$(nvram get wan2_netmask)\"\r\nWAN2_GETEWAY=\"$(nvram get wan2_gateway)\"\r\n\r\nip route flush table BG_ROUTES\r\n\r\nawk '{\r\n       if (match($1,\/^[0-9]\/) &amp;&amp; $1 != \"192.168.0.0\/16\" &amp;&amp; $1 != \"172.16.0.0\/12\" &amp;&amp; $1 != \"10.0.0.0\/8\" )\r\n         print \"ip route add table BG_ROUTES \"$1\" via '$WAN2_GETEWAY' dev '$WAN2'\"\r\n     }' \/etc\/route\/bg_routes.txt | ash\r\n\r\nawk '{ if (match($1,\/^[0-9]\/))\r\n         print \"ip route add table BG_ROUTES \"$1\" via '$WAN1_GETEWAY' dev '$WAN1'\"\r\n     }' \/etc\/route\/exc_bg_routes.txt | ash\r\nEOF\r\nchmod +x \/etc\/route\/update_bg_routes.sh<\/pre>\n<p>I have added \/etc\/route\/update_bg_routes.sh as a last line to the file S45routing so it gets executed at boot.<\/p>\n<pre>echo \"\/etc\/route\/update_bg_routes.sh\" &gt;&gt; \/etc\/init.d\/S45routing<\/pre>\n<p>Ok the last thing we need to do is to modify \/etc\/init.d\/S35firewall so the firewall rules apply to both interfaces&#8230;.<\/p>\n<p>Here is my modified version: (<em><strong>It was been reported that this version is old so it would be better to make the changes by hand in your current version. In the beggining of the script add the lines that sets the variables WAN2 and WAN2DEV. Then follow the script line by line and whenever you see a rule for WAN, dublicate it for WAN2. Skip the rule MINIUPNPD<\/strong><\/em>)<\/p>\n<p><em>last update of this file was:12.04.2007<\/em><\/p>\n<pre>#!\/bin\/sh \r\n\r\n## Please make changes in \/etc\/firewall.user\r\n\r\n. \/etc\/functions.sh\r\nWAN=\"$(nvram get wan_ifname)\"\r\nWAN2=\"$(nvram get wan2_ifname)\"\r\nWANDEV=\"$(nvram get wan_device)\"\r\nWAN2DEV=\"$(nvram get wan2_device)\"\r\nLAN=\"$(nvram get lan_ifname)\"\r\n\r\n## CLEAR TABLES\r\nfor T in filter nat; do\r\n  iptables -t $T -F\r\n  iptables -t $T -X\r\ndone\r\n\r\niptables -N input_rule\r\niptables -N input_wan\r\niptables -N output_rule\r\niptables -N forwarding_rule\r\niptables -N forwarding_wan\r\n\r\niptables -t nat -N NEW\r\niptables -t nat -N prerouting_wan\r\niptables -t nat -N prerouting_rule\r\niptables -t nat -N postrouting_rule\r\n\r\niptables -N LAN_ACCEPT\r\n[ -z \"$WAN\" ] || iptables -A LAN_ACCEPT -i \"$WAN\" -j RETURN\r\n[ -z \"$WAN2\" ] || iptables -A LAN_ACCEPT -i \"$WAN2\" -j RETURN\r\n[ -z \"$WANDEV\" -o \"$WANDEV\" = \"$WAN\" ] || iptables -A LAN_ACCEPT -i \"$WANDEV\" -j RETURN\r\n[ -z \"$WAN2DEV\" -o \"$WAN2DEV\" = \"$WAN2\" ] || iptables -A LAN_ACCEPT -i \"$WAN2DEV\" -j RETURN\r\niptables -A LAN_ACCEPT -j ACCEPT\r\n\r\n### INPUT\r\n###  (connections with the router as destination)\r\n\r\n  # base case\r\n  iptables -P INPUT DROP\r\n  iptables -A INPUT -m state --state INVALID -j DROP\r\n  iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\r\n  iptables -A INPUT -p tcp --tcp-flags SYN SYN --tcp-option ! 2 -j  DROP\r\n\r\n  #\r\n  # insert accept rule or to jump to new accept-check table here\r\n  #\r\n  iptables -A INPUT -j input_rule\r\n  iptables -A INPUT -i $WAN -j input_wan\r\n  iptables -A INPUT -i $WAN2 -j input_wan\r\n\r\n  # allow\r\n  iptables -A INPUT -j LAN_ACCEPT       # allow from lan\/wifi interfaces\r\n  iptables -A INPUT -p icmp     -j ACCEPT       # allow ICMP\r\n  iptables -A INPUT -p gre      -j ACCEPT       # allow GRE\r\n\r\n  # reject (what to do with anything not allowed earlier)\r\n  iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset\r\n  iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable\r\n\r\n### OUTPUT\r\n### (connections with the router as source)\r\n\r\n  # base case\r\n  iptables -P OUTPUT DROP\r\n  iptables -A OUTPUT -m state --state INVALID -j DROP\r\n  iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\r\n\r\n  #\r\n  # insert accept rule or to jump to new accept-check table here\r\n  #\r\n  iptables -A OUTPUT -j output_rule\r\n\r\n  # allow\r\n  iptables -A OUTPUT -j ACCEPT          #allow everything out\r\n\r\n  # reject (what to do with anything not allowed earlier)\r\n  iptables -A OUTPUT -p tcp -j REJECT --reject-with tcp-reset\r\n  iptables -A OUTPUT -j REJECT --reject-with icmp-port-unreachable\r\n\r\n### FORWARDING\r\n### (connections routed through the router)\r\n\r\n  # base case\r\n  iptables -P FORWARD DROP\r\n  iptables -A FORWARD -m state --state INVALID -j DROP\r\n  iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\r\n  iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\r\n\r\n  #\r\n  # insert accept rule or to jump to new accept-check table here\r\n  #\r\n  iptables -A FORWARD -j forwarding_rule\r\n  iptables -A FORWARD -i $WAN -j forwarding_wan\r\n  iptables -A FORWARD -i $WAN2 -j forwarding_wan\r\n\r\n  # allow\r\n  iptables -A FORWARD -i br0 -o br0 -j ACCEPT\r\n  iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT\r\n  iptables -A FORWARD -i $LAN -o $WAN2 -j ACCEPT\r\n\r\n  # reject (what to do with anything not allowed earlier)\r\n  # uses the default -P DROP\r\n\r\n### MASQ\r\n  iptables -t nat -A PREROUTING -m state --state NEW -p tcp -j NEW\r\n  iptables -t nat -A PREROUTING -j prerouting_rule\r\n  iptables -t nat -A PREROUTING -i $WAN -j prerouting_wan\r\n  iptables -t nat -A PREROUTING -i $WAN2 -j prerouting_wan\r\n\r\n  iptables -t nat -A POSTROUTING -j postrouting_rule\r\n  iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE\r\n  iptables -t nat -A POSTROUTING -o $WAN2 -j MASQUERADE\r\n\r\n  iptables -t nat -A NEW -m limit --limit 50 --limit-burst 100 -j RETURN &amp;&amp; \r\n        iptables -t nat -A NEW -j DROP\r\n\r\n## USER RULES\r\n[ -f \/etc\/firewall.user ] &amp;&amp; . \/etc\/firewall.user\r\n[ -e \/etc\/config\/firewall ] &amp;&amp; {\r\n        awk -f \/usr\/lib\/common.awk -f \/usr\/lib\/firewall.awk \/etc\/config\/firewall | ash\r\n}<\/pre>\n<p>So, that&#8217;s about it. I may have missed something or some parts may be inaccurate or unclear, but I&#8217;ll update this as feedback from you dear readers comes in.<\/p>\n<div id=\"facebook_like\"><iframe src=\"\/\/www.facebook.com\/plugins\/like.php?href=http%3A%2F%2Flukav.com%2Fwordpress%2F2007%2F03%2F12%2Fopenwrt-multi-wan-how-to&amp;layout=standard&amp;show_faces=true&amp;width=500&amp;action=like&amp;font=segoe+ui&amp;colorscheme=light&amp;height=80\" scrolling=\"no\" frameborder=\"0\" style=\"border:none; overflow:hidden; width:500px; height:80px;\" allowTransparency=\"true\"><\/iframe><\/div>","protected":false},"excerpt":{"rendered":"<p>Draft This is a simple how to make your openwrt work with more than one WAN. I&#8217;ve used these steps to make my ASUS WL-500G Premium work with 2 WANs where in my case I route specific IP ranges through the second interface. However the instruction can be used to setup load balancing although not [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[70,40,30],"tags":[],"class_list":["post-50","post","type-post","status-publish","format-standard","hentry","category-en","category-tech","category-wl-500gp"],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/posts\/50","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/comments?post=50"}],"version-history":[{"count":1,"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/posts\/50\/revisions"}],"predecessor-version":[{"id":773,"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/posts\/50\/revisions\/773"}],"wp:attachment":[{"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/media?parent=50"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/categories?post=50"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/lukav.com\/wordpress\/wp-json\/wp\/v2\/tags?post=50"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}