How to Mark routing to some ports and websites?

Hi, to simplify I have two gateways to internet.

One is a DSL line and the other is a Metro Ethernet Access.

What I want to do is mark all the traffic to ports 53 and 443 and make it go trough the Metro Ethernet access. This is easy to do.

What I don´t know to do is how to mark all the traffic that goes to some websites such facebook.com, fbcdn.net, cloudfront.net, google.com and youtube.com.

I want this websites go to the MetroEthernet, and everything else goes trough the DSL lines.

I have tried creating some address-lists but is too hard because the have a very large amount of ip and in very different subnets.

Unfortunately address lists are exactly what you need to do if you have to solve the problem on just the router and have to source NAT to provider IPs on router egress to the WAN, which I’m assuming you have to.

The real problem and limitation is this: NAT happens on the first packet of a connection. There’s no way to change your mind on what to NAT to after the first packet. The first packet of an HTTP connection is the TCP SYN of a three-way handshake. You don’t get to see the hostname someone requests before the fourth packet of a connection (TCP three-way handshake is over, client sends HTTP GET or whatever other command).

Once the handshake starts, though, you have to already set source NAT on your router to one of the two circuits, and now you’re locked into that IP address and circuit because the other circuit would throw out traffic from the IP of the other circuit - and you can’t change that, there’s no mechanism for it. Additionally if you were to change NAT IPs in the middle of a connection the server on the other side wouldn’t know what to do with the packets after the change as it was expecting to talk to IP 1.1.1.1 and now is suddenly getting stuff from 2.2.2.2 when it never set up a connection with 2.2.2.2.

There are two-and-a-half workarounds:

  • the half a one is to use your own public IP space for everything and peer with the providers so you can send your publics through either circuits, and can shift routing without shifting NAT. Of couse that still leaves the return path, which you can’t influence, so you can only shift your upload.
  • make decisions based on properties that are available with the first packet, which you’ve done for HTTPS and DNS already, and tried for these HTTP requests by using the destination IP address. This works well, but can be hard to track as you found
  • use some sort of proxy that can apply other properties to connections that are available with the first packet. More on that below.

Proxies work by splitting up connections: the client connects to the proxy, and makes a request. The proxy goes and talks to the actual destination in a completely unrelated connection, and fetches the content. It then relays the content back to the client. The cool thing about that is that potentially the proxy can be on your own network (so there’s no WAN usage from client to proxy), and that it has to listen to what the client wants BEFORE it goes and fetches the content. Therefore the proxy finishes his three-way handshake with the client and gets to see the HTTP request before it starts building its own connection to the content.

Some proxies such as Squid can then apply DSCP marks to the packets of their connections based on what they’re fetching and who they’re fetching it from. DSCP, if you’re unfamiliar with it, is a QoS tool that allows for permanent marks in a packet header to let other devices make forwarding decisions. The RouterOS router could then take the connection from Squid to the actual content server and route it out one way or the other based on DSCP marks. The RouterOS wouldn’t know why some packets have different marks from others - it would just react to remote signaling by the Squid server present in all packets of a connection including the first one. You’re using the proxy to make policy decisions, and the router to act on that policy.

The built in proxy in RouterOS cannot do that for you. I’m pretty sure Squid can. But I don’t use proxies much.

Hope that helps.

Fewi, of course it helps.

Actually I am using a Proxy Cache (ThunderCache), and I am able to change TOS of cached packets, so I can apply some limits in the router.

What it doesn´t allow is to change TOS to outgoing packets based on the hostname or anything else.

So, my options are this:

a) Work with address-list and destinations ip (this is extremely hard to maintain).
b) Work with Squid and change DSCP of outgoing connections to certain hostname without resolving its ip address (I have no idea how to do this, I supose there is a lot of reading waiting for me)

The bad thing about the “b” option is that I need another machine to install squid. More power consumption and more space in my cabinet, without to mention the extra cost.

Thanks a lot for your help.