The Problem with the Internet
Each of my children at some point has asked me to block them from YouTube (Instagram, Pinterest, etc.) as a plea to eliminate the distraction from homework. I am careful to talk to them about taking responsibility for their own internet use, and offer to help them with the various issues. My approach is to come along side them to help them fight whatever demon they need to fight. However, at midnight, when mom and dad are asleep, and homework still must get done, well, it's a different battle, but one in which I will concede that they need dad to put a stop to the distraction.Solving the Problem with Mikrotik
If you have a Mikrotik Router, I have a solution that has taken me countless hours to run-down and perfect (well, it will never be perfected). This solution can work as a potential throttle, to avoid excessive bandwidth use; or as an effective block, to prevent use of certain sites.
The Basic Outline:
- Make a list of the internal IP Addresses (LAN) that need to be protected (Address List)
- Make a list of the offending external IP Addresses (Address List)
- Mark the traffic (mangle) between any of these sources (Mangle)
- Block or throttle the traffic (Queue Tree)
Step by Step
Assumption: Your router is setup to provide DNS for your network. This is not covered here. If you aren't sure, or it is not, stop here and set it up.
1. Make a list of internal IP Addresses
You need to know the IP Addresses of your children's devices. To find this, in your Mikrotik interface (I use the webfig interface) go to:
IP->DHCP Server->Leases
- Click on a device in the list
- Click Make Static
- Note the IP Address for each as you go
- Click Close
- Repeat for each device
(If you know your way around, you can create a new Pool and assign these devices to this pool, thereby grouping them neatly. Devices will have to refresh their IP to get the new one. For this exercise this is not needed.)
Next go: IP->Firewall->Address Lists
- Click Add New
- Enter a Name ("Throttle" is what I used)
- Enter an IP Address from your list from above
- Click Ok
- Repeat for each IP Address
2. Make a list of the offending external IP Addresses
Ok, now we get to some fun automation, where the Mikrotik will create and maintain this list for you.
Go to System->Scheduler
- Click Add New
- Give the item a name (I used "List of Sites")
- Set the Start Date to yesterday's date (so it will start running right away)
- Set the Start Time to 01:00:00 (or PRIOR to now, but ending in 00)
- Set the Interval to 00:00:10 (ten seconds)
- Under Policy check "read" and "write"
- Copy-and-paste the following code into On Event (it will expand):
:local hosts {"googlevideo";}
:local listname "streaming"
:foreach k,v in=$hosts do={
:foreach i in=[/ip dns cache all find where name~$v and type="A"] do={
:local ipaddr [/ip dns cache all get $i data]
:do {
/ip firewall address-list add list=$listname address=$ipaddr comment=$v
:log info "IP address: $ipaddr"
} on-error {}
:delay delay-time=10ms
}
:foreach i in=[/ip dns cache all find where name~$v and type="AAAA"] do={
:local ipaddr [/ip dns cache all get $i data]
:do {
/ipv6 firewall address-list add list=$listname address=$ipaddr comment=$v
:log info "IPv6 address: $ipaddr"
} on-error {}
:delay delay-time=10ms
}
}
Note: If you DO NOT have IPv6 in the left menu of your Mikrotik webfig, you MUST nuke lines 12-19 above, otherwise the script will fail.
- Now click OK to accept the changes and return to the Scheduler list. Stay and watch this list for a minute, to be sure you see the "Run Count" increment -- it should do so every 10 seconds.
- Now go to IP->Firewall->Address Lists
- On the right site choose "all" from the pull-down menu
- You should see IP Addresses begin appearing in this list (actually they should already be there) with the Name "streaming" and a comment indicating the "host" from the first line of the code above. If you do NOT see these entries, go visit YouTube and start a video. They should then start appearing. If you still aren't seeing them, did you check to be sure your router is doing DNS (red warning above)?
Step-by-Step Explanation of the Code
- The first line is a list of the domains you need to affect. You can put more than one in here so long as you put it in quotes, with a semi-colon between each item, and at the end. Note that I used a partial name in the case of YouTube. You will also notice that I used "googlevideo" and NOT YouTube. Almost all assets and video for YouTube are served from domains that look like "r6.sn-hp57kn6e.googlevideo.com" -- this script will catch all variations.
- The second line is the name of the list (used later).
- Sets up the loop for each domain
- Sets up the loop to look through all IPv4 name entries matching domain
- Grabs the IPv4 address for a matching entry
- :do to catch errors in the next line without causing a failure
- add the IPv4 address to the list
- write an entry to the log
- catch errors
- pause (to prevent consuming all CPU time)
- From 12 -19 are identical to 2 - 9 except it grabs IPv6 addresses
3. Mark the traffic between these sources
Now we need to identify any traffic going between our devices and these sites.
Go to IP->Firewall->Mangle
Marking the Connections
- Click Add New
- Set Chain to "prerouting"
- Set Src. Address List to "Throttle" (or whatever you used for your devices list above)
- Set Dst. Address List to "streaming" (or whatever you used in the code above)
- Set Action to "mark connection"
- Set New Connection Mark to "throttle"
- UNCHECK Passthrough
- Click Ok
Repeat with 1 change
- Click Add New
- Set Chain to "prerouting"
- Set Src. Address List to "streaming" (or whatever you used for your devices list above)
- Set Dst. Address List to "Throttle" (or whatever you used in the code above)
- Set Action to "mark connection"
- Set New Connection Mark to "throttle"
- UNCHECK Passthrough
- Click Ok
Notice that we flipped the Src. and Dst. Address Lists in the second version. One of these two rules will be obsolete in your router -- but it won't hurt either.
Marking the Packets
- Click Add New
- Set Chain to "forward"
- Set Connection Mark to "throttle"
- Set Action to "mark packet"
- Set New Packet Mark to "streaming"
- UNCHECK Passthrough
- Click Ok
What is going on here is we are marking any traffic that matches an IP Address in BOTH of our lists. We mark the connection, and then each packet, now we can "find" these packets and start to block or limit them.
4. Block or throttle the traffic
Go to Queue->Queue Tree
- Click Add New
- Name "Parent Queue"
- Parent "global"
- Click Ok
This creates an overall parent queue which can be used to limit the TOTAL amount of traffic for ALL users in our address list. We won't apply any limit here at this time. You might find a use for this YMMV.
- Click Add New
- Name "My Devices"
- Parent "Parent Queue"
- Packet Marks "streaming"
- Queue Type: pcq-download-default
- Priority: 8
- Bucket Size: 0.100
- Limit at: 200
- Max Limit: 200
- Click Ok
Test
Go ahead, grab one of your kids devices and see if YouTube (or your sites) are functioning. Now grab device NOT in your list and see if it CAN view YouTube.
You can play with Limit at and Max Limit. 200 is pretty ridiculously slow, effectively blocking sites. 20 will block them so effectively that your browser will typically give up with an error.
Why not 0? And Why not block "youtube" as well. Well, in the particular case of YouTube, if you block "youtube" you inadvertently block ALL of Google for authentication purposes. By using 200, you make authentication go slowly, but you don't kill all of it. This is because when you login to a Google service, google ALWAYS checks-in with YouTube -- don't ask me why, ask Google.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.