Filtering direct IP addresses

I have since a week my hEX router and I want to use it without a Fritz.box (AVM) in between my local network. I like one feature very much on my Fritz.box. That is filtering of IP addresses that are going directly to the internet without requesting a resolve of the DNS. So all a program, page or script is directly going to 159.148.147.196 and not first ask the DNS what the IP address is.

My impression how it can function. Two lists, the first is the list of allowed IP addresses to be called directly and the second the list of gathered IP addresses that are being blocked.

Triggering the capture of an IP address (159.148.147.196) to the blocked list is when a new connection is made. The request is checked if there is a host (http://www.mikrotik.com) is present and if that is the case the IP address will not put on the blocked list. If I type in my browser http://159.148.147.196 then it will trigger the collection of the IP to the blocked list.

Now 159.148.147.196 is on the list it will be blocked forever until I move it to the allowed list. This allowed list will be now also will be checked each time by the trigger capture filter is finding a new connect with only a IP address present. If the used IP address is on the allowed list it can proceed and if not it will be added to the blocked list if it not already present.

In short for each new connection on HTTP (not https) requests:

IF no host present AND ip address NOT on the allowed list
THEN add to blocked list (if not already present) and terminate request
ELSE allowed through

On the fritz.box a web page is show that the IP address was not allowed through to the internet and that the address is on the blocked list.

I hope this is also interesting for others that can assist me in putting the rules in the firewall together if possible.

Update, I tried web-proxy and that worked but not to my satisfaction. So I implemented firewall rules and Layer 7 filtering and I could filter one specific ip-address that I also put in the Layer 7 filter.

So I made a regex to catch all direct calls however it did not work. The regex is:

([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})

It is a mystery why a know IP address is filtered by 159.148.147.196 but then not by the filter above?

Many hours later I finally found the correct regex and I just wanted to do it to fancy which the Mikrotik just not translate despite accepting the string.

The regex to recognize a IPv4 address is:

[0-2]?[0-9]?[0-9]?.[0-2]?[0-9]?[0-9]?.[0-2]?[0-9]?[0-9]?.[0-2]?[0-9]?[0-9]?

So [0-9] means any number between 0 and 9 and the “?” behind makes it possible to omit the number.

[0-2]?[0-9]?[0-9]? allows xxx or xx or x

Then the “.” symbols. This is just the dot in between the two numbers (123.123) and the backslash in front makes it a literal dot.

This filtering takes 48 steps in the regex and that is not fast but doable.

So now I can test it further and first just to log because tonight I mixed up the bit and was locked out of the Mikrotik and luckily I had a SSH still open and I could remove the Layer 7 regex by hand. :sunglasses:

Update: “[0-2][0-9][0-9]?.” also works and brings down the 48 steps to 24 (in real 16 if omiting of the string in front) steps which a real improvement.

Update two: the following string works even better and now also browsers are filtered when using “Host”

.ost:.[0-2]?[0-9]?[0-9]?.[0-2]?[0-9]?[0-9]?.[0-2]?[0-9]?[0-9]?.[0-2]?[0-9]?[0-9]?

“.ost” → Host or host

I got it working in the direction that had in mind. It is not perfect because still one request is going before being blocked.

The regex string I am now using is: “[HOST|.ost]:.[0-2]?[0-9]?[0-9]?.[0-2]?” which matching enough to have almost no false positives.

I add in /ip filter address the following ranges: VOIP provider if using no domain name and as example Cloudfront.net and you can also find with nslookup your local Google Cache address that you also allow.
I am using a “allowedlist” and a “blokcklist”. Filtered ip-addresses go to the “blocklist” and you can change them manually to allowed by changing the name.

/ip firewall address-list
add address=123.123.123.123/29 comment="stun.betamax.voip sip.betamax.voip" disabled=\
    no dynamic=no list=allowedlist
add address=456.456.0.0/16 disabled=no dynamic=no list=allowedlist
add address=144.76.143.182 disabled=no dynamic=no list=allowedlist
add address=789.789.789.10-789.789.789.187 comment="Google.com block" disabled=no \
    dynamic=no list=blocklist
add address=147.147.147.0/24 comment=Cloudfront disabled=no dynamic=no list=\
    allowedlist

123=VOIP - 456=Internet provider - 789=Google cache - 147=Cloudfront.net

Add the filtered ip-address to the blocklist"

/ip firewall mangle
add action=add-dst-to-address-list chain=prerouting \
connection-nat-state=srcnat protocol=tcp src-address=192.168.1.0/24 \
dst-address=!192.168.1.0/24 dst-address-list=!allowedlist \
address-list=blocklist address-list-timeout=23h59m \
layer7-protocol=add2blocklist dst-port=80



/ip firewall filter
add chain=forward action=reject reject-with=tcp-reset protocol=tcp \
dst-address-list=!allowedlist layer7-protocol=add2blocklist dst-port=80

You have to CHECK the lines for yourself and adapt the lines to your own situation and the /ip firewall filter goes closest to the top of the rules.

I still have to find the bit to stop the address in the first place and I have put now an 24 hour block on it so a problem will resolve in 24hours if not attended earlier to is…however it will be still triggered again after those 24 hours.

Source for the L7 filtering: http://mum.mikrotik.com/presentations/PL10/l7_interprojekt.pdf