load balancing for my dual adsl

Yeah I was working on fixing that right now.

I’m making it so that instead of setting a connection mark it will add the dst address to an address list for like 10 minutes and that will cause every dst address to go out through the same line.. It breaks load balancing to a single host however it still allows both lines to be used when many users are connecting to many diff hosts..
-Gerard

Well, MY banking and MY instant messaging works, and that is my only point of concern :slight_smile: Indeed, as Christian has pointed out, it does round-robin on all connections, but as I have said, this does not cause any problems … for me.

To “fix” it to NAT all connections from a particular user to the same IP address, you have to do the following:

/ ip firewall mangle


add chain=prerouting src-address-list=odd in-interface=Local action=mark-connection new-connection-mark=odd passthrough=yes

add chain=prerouting src-address-list=odd in-interface=Local action=mark-routing new-routing-mark=odd 

add chain=prerouting src-address-list=even in-interface=Local action=mark-connection new-connection-mark=even passthrough=yes

add chain=prerouting src-address-list=even in-interface=Local action=mark-routing new-routing-mark=even 

add chain=prerouting in-interface=Local connection-state=new nth=1,1,0 \
    action=mark-connection new-connection-mark=odd passthrough=yes comment="" \
    disabled=no 

add chain=prerouting in-interface=Local action=add-src-to-address-list address-list=odd address-list-timeout=1d connection-mark=odd passthrough=yes

add chain=prerouting in-interface=Local connection-mark=odd action=mark-routing \
    new-routing-mark=odd passthrough=no comment="" disabled=no 
add chain=prerouting in-interface=Local connection-state=new nth=1,1,1 \
    action=mark-connection new-connection-mark=even passthrough=yes comment="" \
    disabled=no 

add chain=prerouting in-interface=Local action=add-src-to-address-list address-list=even address-list-timeout=1d connection-mark=even passthrough=yes


add chain=prerouting in-interface=Local connection-mark=even action=mark-routing \
    new-routing-mark=even passthrough=no comment="" disabled=no

Eugene

If one of the link goes down does it mean that some traffic won`t be routed at all.

yes. you are welcome to enhance the wiki example.

thanks, but please make the links shorter :slight_smile: I will do this for you ..

Guee i will have to test this, just a curious question does this work if i wanted to use a pppo3 client on the MT? or must I set my modem as pppoe and DHCP the MT?
The online banking issue it can be solved simply with some kind of binding to a wan port? like bind port 445 to wan1

just the same as the netcomm nb750 ?

I surely hope to find the time to dig out and polish up my example.

But in the mean time: It was working practically the same way (by adding new src-addresses to address-lists, but with a lower address-list-timeout).

Then I added a script to check the uplinks every few seconds and have it redistribute the users/connections on the “dead” link to the (or one of the) alive uplinks.

Best regards,
Christian Meis

So whats next to fix the link down issue?

and which script needed polishing?

so far so good i added the script a dozen times now it works as far as using 2 ip’s download managers threading works 2 links are being used.


Eugene looking really go so far mate what can we do about this other part about links going down

OK, let me try to get this done from some short notes - don’t have access to the system my tests are on :frowning:

My script worked by assigning every user to a dedicated uplink (that was required by the customer). This way you will absolutely be sure that the user will go out with the same source ip address every time (masquerading was involved here…). Of course this creates other “load-balancing-fairness” problems, as the users are not distributed among the uplinks using the acutal bandwidth-usage…

Effectively it works similar to the script posted above/in the Wiki: By assigning ip addresses to address lists and routing everyone in one address-list out one uplink.

As I was required to distribute the users so that each user was bound to a dedicated uplink, I was only taking into account the src-addresses. There are two uplinks involved in the example, named uplinkA and uplinkB (genious strikes…).

I put in the following mangle rules:

/ ip firewall mangle 
add chain=prerouting src-address-list=use_uplink_a action=mark-routing new-routing-mark=uplink_a passthrough=no comment="set routing mark for uplink A" disabled=no 
add chain=prerouting src-address-list=use_uplink_b action=mark-routing new-routing-mark=uplink_b passthrough=no comment="set routing mark for uplink B" disabled=no 
add chain=prerouting action=mark-packet new-packet-mark=new_srcadr  passthrough=yes comment="" disabled=no

Thus putting a routing-mark for uplinkA on everyone who already is on the address-list “user_uplink_a” and the same for uplinkB. Those routing-marks are later used to force traffic out a specific uplink (not shown in this post). Note that the first two mangle rules do NOT have passthrough activated. So only packets from source addresses NOT already on address-list “use_uplink_a” or “use_uplink_b” reach the third rule which marks packets from “unknown” source addresses with a packet-mark of “new_srcadr”.

Then a firewall filter takes care of putting those unkown (until now) source addresses onto a third address list called “new_user”:

/ ip firewall filter 
add chain=forward in-interface=ether1 packet-mark=new_srcadr action=add-src-to-address-list address-list=new_user address-list-timeout=0s comment="" disabled=no

The following script is run via scheduler every few seconds. Its’ purpose is putting newly discovered users (= source addresses) onto one of the address-lists that map users to uplinks:

:local uplinkacount
:local uplinkbcount
:local newipadr
:log debug "script checking for new source addresses"
:foreach i in=[/ip firewall address-list find list=new_user] do={
	:set newipaddr [/ip firewall address-list get $i address]
	:set uplinkacount [:len [/ip firewall address-list find list=use_uplink_a]]
	:set uplinkbcount [:len [/ip firewall address-list find list=use_uplink_b]]
	:log debug ("   found new source address " . $newipaddr)
	:log debug ("   " . $uplinkacount . " User auf Uplink A")
	:log debug ("   " . $uplinkbcount . " User auf Uplink B")
	:if ($uplinkacount < $uplinkbcount) do={
		:log debug ("about to add " . $newipaddr . " to list a")
		/ip firewall address-list remove $i
		/ip firewall address-list add address=$newipaddr list=use_uplink_a disabled=no
		:log info ("added new source address " . $newipaddr . " to address-list use_uplink_a")
	} else={
		:log debug ("about to add " . $newipaddr . " to list b")
		/ip firewall address-list remove $i
		/ip firewall address-list add address=$newipaddr list=use_uplink_b disabled=no
		:log info ("added new source address " . $newipaddr . " to address-list use_uplink_b")
	}
}

So to sum up, the following way is used to distribute (“load-balance”) users (internal source addresses) to the two uplinks:
If the router detects a source address not already on one of the address-lists that manage the user-to-uplink mapping, it marks packets from that address. A firewall rule then put this source address onto a temporary address-list. The script running every few seconaddds the distributes the users among the two uplinks so that the number of users on each uplink is (more or less) equal.

You could modify the script above to monitor some global variable for each uplink that signals if the uplink is available. If it’s not available, users are not put on the corresponding address-list for that uplink.

Now you can have netwatch (or a own script) check if the uplinks and set the global variable to “not available” when a uplink is down. Then the script would just have to remove all addresses from the address-list for that uplink, and the users would get re-added to the other list.

Some shortcomings, here, too:

  • You cannot specify a timeout for an entry on an address-list if you add it via script (opposed to having it automatically added by a firewall rule :frowning: ), so a user mapped to one uplink will stay there “forever”. This could be easily changed by having a script remove users from address-lists from time to time (to force re-addition to an address-list).
  • As the first packets arrive from a “new” user, they will probably not be getting out on the internet, as the source address is not on any “mapping” address-list. So this could mean a few seconds “hick-up” when a new user is coming online. But this depends on how you policy-route your traffic: This is only the case if you don’t let out any traffic from source addresses NOT on the address-lists use_uplink_a/use_uplink_b.

After all, these might be just some confusing bits and pieces, but until I get access to the test system again I thought I put them here for you guys to read over and perhaps already someone using the idea for something…

Comments welcome…

Best regards,
Christian Meis

cmit So whould it be right to say that your individual script spreads users evenly over the (2) links eg.

10 users on wan1
10 users on wan2

im taking this is the way your individual script works im taking it that interigating yours with the one pasted above is different?

there for users cant utilize both links for faster speeds?
all in all your script would definatly solve the online bamking problem i am very sure.

how does this script work does it keep the specific wan port set for each ip the client connects to?
or how does this solve the banking issue ?

Just for kicks i got a feeling of how it works it logs the ip address and clients ip and saves that client to use a wan port for each ip they connect to..

eg. of problem if this is correct
i have a multithreaded newsgroup client that conencts to 1 news server and downloads a sigle file multithreaded it would be kinda a problem if only 1 wan port will be downloading the file. it will tri multi attemps via 1 route :frowning:

Netcomm NB750 solves all these problems by binding any destination port via 443 to always use eg. WAN1 or WAN2 optional also some other options of wan1 first or wan2 first

port 443 bind to a wan port tottal fixed everything

if that can be fixed that simple like netcomm do that would be great for us all.

a little eye opener there are other options

Session : new route new connection like the one above
Weight round robin : works on a ratio like 1:1 or 1:2 etc.. etc..
Dymamic Traffic : works by a live monitor of how much usage is being used per wan, it has an option to set link speed so it can create a value as a percentage % there for balances according to that.

It’s not very difficult to bind outgoing HTTPS traffic to a specific WAN port: mangle it, policy-route it…

Best regards,
Christian Meis

inncom,
You can either add a new mangle rule to mark all tcp traffic to port 443 as either odd/even OR make a NAT rule that src-nat’s all tcp traffic to port 443 to a specific ip so that it always goes out of a single line..

add chain=prerouting protocol=tcp dst-port=443 action=mark-connection
new-connection-mark=even passthrough=yes comment=“” disabled=no
OR
add chain=srcnat protocol=tcp dst-port=443 action=src-nat
to-addresses=10.1.1.202 to-ports=0-65535 comment=“” disabled=no

You will have to move either one of these rules before the other mangle or nat rules for them to work..

I switched my office and a few tester clients to using the load balancer yesterday afternoon and I had everyone try their online banking and any other secure sites they use and no-one has had any problems..
I know that some sites do bind your session to your IP.. BUT I do know that web requests from AOL customers will come from several different proxy ips within a session so I don’t think it should mess up too badly if they are doing it..

-Gerard

yes, we also tested eugene’s example and there were no problems with any sites.

THANKS! Gerard this one works.

add chain=prerouting protocol=tcp dst-port=443 action=mark-connection
new-connection-mark=even passthrough=yes comment=“” disabled=no

added it in order right after the odd mangle rule and wam it works

Chek this: http://wiki.mikrotik.com/wiki/Load_Balancing_Persistent

You could play with address-list-timeout settings or place dst-address instead of src-address to address list. In any case, leave feedback what works best for you.

Eugene

Eugene,

My setup is very similar to your example(see my code above) but in order for me to get it to work I have to add these two routing rules.

/ ip route rule
add routing-mark=odd action=lookup table=odd comment=“” disabled=no
add routing-mark=even action=lookup table=even comment=“” disabled=no

Am I doing something wrong?
Thanks
-Gerard