I’m setting up a newly bought LHG-LTE6 within my environment. The LHG is in Passthrough mode connected to an RB951G. The latter one is doing NAT & all other useful things, including VPN link to a corporate network. It all works as expected, with a default route created automatically by DHCP client at RB951G.
Now, I’d like to set it up in a way so that most of traffic is flowing through the VPN, and only some (few) hosts are reachable directly through RB951 and the LHG.
I thought I would just add manual routes to that limited number of hosts to be accessed directly. But then I have an issue. When I set up the route using the name of the interface - like this:
The IP address (including Gateway address) on the LTE-Passthrough interface changes every now and then, so I can’t just leave a route with a fixed IP address.
> > /ip dhcp-client print detail where interface =LTE-Passthrough
Flags: X - disabled, I - invalid, D - dynamic
0 interface=LTE-Passthrough add-default-route=yes default-route-distance=10 use-peer-dns=yes dhcp-options=hostname,clientid
status=bound address=100.104.68.54/30 gateway=100.104.68.53 dhcp-server=100.104.68.53 primary-dns=213.87.142.84
secondary-dns=213.87.142.85 expires-after=53s
I can probably make a script to update the routing table whenever IP address changes.
But I thought adding a route using an interface NAME should do exactly that - make sure the routing is done through the gateway of respective interface.
Am I missing something?
Just as a side note. the RB951G has a GRE interface (with a static IP in a /30 subnet). The interface is used to route traffic through the VPN. And with that GRE, it’s sufficient to only put the name of the interface - not a remote GRE address - in the routing table. I’m not sure whether this is because of the static IP or because of the GRE nature itself. But it “works exactly as I expected” in this particular case, while in other cases it appears to be different.
There is a significant difference between point-to-point (tunnel) interfaces (like GRE, all flavors of PPP) where you don’t need to use any address to choose which of the remote devices should get the packet, simply because there is just a single remote device, and point-to-multipoint interfaces on shared media (such as Ethernet or WiFi) where you have to use some low-level address to indicate to one of the remote devices that the frame is intended for it. In the latter case, if you set the interface name as a route, it cannot actually start working until at least one of eventual routers accessible through that interface advertises the fact that it is a router via ICMP and your device stores its address (IP and MAC) to use it as a gateway. As far as I can tell, Mikrotik ignores these advertisements even if they come. But as said, I’ve never seen this to work, and I hazily remember the Mikrotik manual to say that on point-to-multipoint interfaces you have to specify the gateway as an IP address without explaining the background.
There is more to that algorithm, if there are more routers and they know about each other, one of them can determine that another one in the same subnet is a better route for a packet it has received from a client, so it informs the client using a backward ICMP message about the IP address of that other one, and the client caches that information for some time and sends the packets through that other one until it eventually gets another redirection. Mikrotik can send these redirects, but doesn’t advertise itself as a router.
If I may… Can you please advise on the script you posted in the topic you referred to?
I tried to modify it for my setup, but it doesn’t work… Does this look correct?
If you’ve put all that at a single line, there was a semicolon missing before the second :if
The export adds some escape \ signs, so below is the script without them. To edit it in this form, use a Winbox or WebFig editor or, if using the command line, /ip dhcp-client edit [find interface~“LTE”] script
Yeah, I fixed the missing semicolon after I posted the script…
Even with your version (thanks for the readable formatting!), it still doesn’t update the routing table… Hmmm…
This is the entry I want to be changed, the gateway = 1.1.1.1 is a dummy address that is expected to change to the real GW address:
Well, ok, the find takes the configuration literally. If you provide no dst-address value for a route, the effect on the routing is the same as if you provided dst-address=0.0.0.0/0, but the [find dst-address=0.0.0.0/0] doesn’t match on such a route. I’d recommend to add the dst-address=0.0.0.0/0 to the route rather than exclude it from the find in the script, to prevent the script from updating routes you actually didn’t want to update (the find can return a list and the set can operate on all items on the list).
OK, so I was completely wrong, to my defense I must say that I rarely export routes, I usually print them to see also the dynamically added ones. And also find dst-address=0.0.0.0/0 does find routes where the dst-address is not shown by export.
So type put followed by a space to the command line, copy-paste the [/ip route find …] part from the script after that, and press enter- If you get some *digits as a result, the find itself works. If you don’t, there may be a typo in the routing-mark value.
Now there is also a chance that the script is not being run at all - I never tried to attach a DHCP client to an LTE passthrough interface (mostly because I don’t have any).
So add to the very beginning of the script a separate line global test 1
and disable/re-enable the interface. If the script runs at all, /system script environment print should show a row n test 1 (n will likely be 0 if you don’t use any other global variables in scripts). If it doesn’t, it means the script is not triggered at all.
If the global variable appears but the gateway doesn’t change, there must be something else wrong in the script. But I have copy-pasted it from a running system where it works fine so I have no clue what it might be.
I’m not sure how to interpret this though.
EDIT: The “*d” seem to be the right response, as “put [/ip route get *d gateway]” returns the gateway IP of that specific route entry. So this part seems to work as expected.
Now there is also a chance that the script is not being run at all
I added a line in the beginning of the script to throw a message to the log each time the script is executed. So now I can see when it starts.
The script is executed every time I enable / disable the interface.
But the script is NOT executed when the lease is renewed. Unfortunately I can’t test the situation when the address is forcibly changed (I mean, the ‘renew’ request is not acknowledged and a new address is offered by the server). If the script will NOT be executed in this case either, then I’ll need to put this script elsewhere (netwatch?).
Yes, I forgot to wrote that the numbers are in hex. These are the real pointers to configuration objects, which RouterOS makes more user-friendly by translating them into row numbers when you do print; the row numbers (decimal, without * in the beginning) are temporary aliases to the actual pointers. The map is recreated with each print and is valid for that and for the CLI session that created the aliases. So if you do /ip route print and then /ip address print, you can use line numbers to refer to both routes and addresses. If you delete an object in the middle of the list, the line number → pointer translation doesn’t change, so you can go on using it until you run another print for the same object type.
To my knowledge the lease script is invoked at each change of address assignment, so it’s not really surprising if it is not invoked when the renew operation just extends the lease. I was nervous about LTE because it also can add a dhcp client dynamically, but that one cannot be disabled nor modified, so it’s a completely irrelevant opera as you’re adding the dhcp client manually. Hence you can set up a DHCP client with a lease script on another interface or another Mikrotik and test it against a DHCP server under your control (another Mikrotik?) where you’ll set the lease time to minutes, change the lease to static at the server once it assigns it first, and then change the IP address for the static lease. The next time the client asks for a renewal (at half the lease time), it will get a NAK and the new address. If you want to be really precise, don’t change the IP address in the static lease, but change the gateway under /ip dhcp-server network and see what happens at renewal.
A year or two ago, the ability of netwatch’s scripts to modify configuration has been seriously restricted “for security reasons”, apparently users who didn’t have privileges to change configuration but could set up netwatch could add scripts to netwatch doing what they actually wanted. I don’t know whether this has been solved in a less limiting manner, some users were really upset about the change back then. If not, you can only use netwatch to monitor the availability of the gateway, but to do an actual change, you need a periodically scheduled script - which can check the gateway availability on its own after all.
Yeah, I think I’ll get my hands on another Mikrotik device and try to experiment with DHCP Client a bit…
I ran into another issue. The RB951G has an IPsec tunnel to the head office. As soon as I set ‘default route’ to go via GRE, the router tries to re-establish the connection with sa-src-address set to my GRE address, not the LTE-Passthrough address! Of course, this attempt fails and I loose my VPN connection… As I read in some other thread, the modern RouterOS gets sa-src-address based on default route in the routing table. Unsurprisingly, the default route is NOT what I need it to use in this case. There is a routing entry specifically to the VPN server, but it looks like that line is ignored when deciding about the sa-src-address…
Ughh, it gets harder than I thought! I’m also thinking of a possible backup link - and that’s where it will become even more complicated…
How about another way? Is there an easy way to set a routing mark to all packets, with some little exception (the VPN server at the office and a few other hosts)? If that is possible, then I will be able to just add an entry to the routing table to push all marked traffic (which will mean almost everything) through the VPN tunnel. And keep default route via the LTE-Passthrough (or via an alternative link, if it will arrive). So there will (hopefully!) be no issues with sa-src-address.
Sure there is… to a certain extent of the word “easy”
Basically it’s a matter of the order of rules in the mangle table of the firewall - you first accept the traffic which should stay without a routing-mark, and assign the routing-mark to everything that is not matched by those first rules.
But in general, I always use connection-marks, it makes the firewall processing faster (you may have noticed that use of routing-mark is incompatible with fasttracking). You use the complex selection criteria only to assign the connection-mark to the very first packet of the connection, or in some applications to assign the routing-mark to the very first packet in upload direction and the connection-mark to the first one in download direction, and for all the subsequent packets, you just assign the routing-mark according to the connection-mark.
Can you link where you have read that the sa-src-address is derived from the default route? As far as I understand it, the sa-src-address is derived from the local address used by the peer to which the policy is linked to if it is explicitly configured on the peer (as local-address parameter), or just using the regular routing methods (the source IP associated to the route towards the remote destination of the peer). I cannot imagine why Mikrotik would only take into account the default route and ignore the more narrowly matching ones especially for SAs if it fully handles the routing when choosing source addresses for other protocols.
I’m still not fluent enough with these… I always mess something up!
Can you post an example, if possible?
Can you link where you have read that the sa-src-address is derived from the default route? As far as I understand it, the sa-src-address is derived from the local address used by the peer to which the policy is linked to if it is explicitly configured on the peer (as > local-address > parameter), or just using the regular routing methods (the source IP associated to the route towards the remote destination of the peer). I cannot imagine why Mikrotik would only take into account the default route and ignore the more narrowly matching ones especially for SAs if it fully handles the routing when choosing source addresses for other protocols.
Try to read this first; if it’s not clear enough, give me the particular scenario to handle. Since writing that, I’ve moved a bit and prefer to mark every connection, as it makes dealing with the non-initial packets even faster (only what has no connection-mark yet is let through to the classification rules, the rest goes straight to connection-mark => routing-mark translation).
This statement made by @Feklar is simply wrong, plus it is not related to a source address of an SA but of a mere ping (and is unrelated to a recent RouterOS either, the inheritance of sa-src-address from peer has appeared not more than a year ago and that post is 5 years old).
What I do is I mark all the connections to the hosts with direct access as “Conn-Direct” (I can probably change this to just ‘accept’). Then I mark whatever is NOT “Conn-Direct” as “Through-VPN”. And then I add a routing mark to all “Through-VPN” connections.
Mangle chain prerouting only handles input and forward traffic. To eventually assign a routing-mark to locally originated traffic, you have to use mangle chain output. Plus there is one more catch you can see on the packet flow diagram - the locally originated packets are first routed (so their source address is assigned), then possibly routing-marked in the mangle chain output, and if a routing-mark is actually assigned there, they pass through the routing one more time, but the source address remains the original one. So there must be a src-nat on the out-interface actually used even if only locally originated packets are sent through it.
But I had a feeling that you wanted to mark everything that should go to the GRE tunnel, so what exactly should have worked and doesn’t (leaving aside that only 172.16.0.0/12 is a private range, not the whole 172.0.0.0/8)?
I didn’t touch the output chain yet. I remember about it (sort of…), but I thought I will test this whole marking story on the forwarded traffic for a start.
Yes, I want to mark everything except for some hosts in the Direct_WAN_Connection address-list (these change every now and then) and the output chain going to the VPN server.
The private networks 192.168.0.0/16 and 172.16.0.0/12 (yep, thanks for the correction!!!) should definitely be routed over GRE. That’s clearly my mistake to mark them as ‘Conn-Direct’.