linux_router:nftables_control

I primarily set this feature up to act as a form of parental control on my home internet access.

The DHCP assigned addresses in the range 100 - 254 were to be disabled (dropped) in the evening. The addresses below 100 were assigned a specific IP address in the DHCP based upon MAC.

I added a NFtables named set with ipV4 address and timeout function:

     set controllist {
         type ipv4_addr
         flags interval
         flags timeout
     }

In the forward chain the controllist IP set was dropped for all the source and destination packets.

       ip daddr @controllist counter drop
       ip saddr @controllist counter drop

Router NFtable Setup - with named set IP filtering

Some important NFtables Commands with named sets:

  • sudo nft list table inet firewall : will list all the active firewall table
  • sudo nft add element inet firewall controllist { 192.168.1.130 timeout 5m} : will add the IPv4 address 192.168.1.130 to the named set controllist for 5 minutes
    • where timeout values are: h m s and can be used in tandem as such: 5h30m for 5 hours 30 minutes.
  • sudo nft list set inet firewall controllist : will list the current elements in named set controllist
  • sudo nft flush set inet firewall controllist : will flush the current named set controllist
  • sudo vim /etc/nftables.conf : to edit the current NFTables configuration
  • sudo systemctl restart nftables to restart with the current nftables configuration
    • status to list current running status of nftables
    • start to start nftables with the current configuration
    • stop to stop nftables
    • journalctl -b0 -xe -u nftables to list the end of all the nftables journal entries since the last boot

I made a couple of bash scripts to assist with the use of these controllist name sets.

  • sudo vim controllist.sh : This script automates the entry of a a range of IP address with timeout limits in the the named set. (The timeout option does not seem to function with the interval option.)

controllist.sh

  • A key change to this script to improve functionality would be to allow an input of the timer duration.
  • sudo vim deletecontrol.sh : This is a simple script to flush the control list.

deletecontrol.sh

  • Do not forget to run sudo chmod 774 controllist.sh on the script files to make them executable

I then created a cron job to run the script as required every evening

  • sudo crontab -l : to list current cron jobs (use sudo for root)
  • sudo crontab -e : to edit the cornjobs
  • journalctl -b0 -u cron | grep control : to list all the related cron jobs since last boot

crontab is finicky! crontab does not necessary use BASH and the full path to the command must be given for reliable performance. Further to this cron error messages are sent to the system mail server, so if this is not setup or otherwise not working the error message go nowhere. Systemd has a service to redirect output of cron jobs to systemd's journal: /usr/bin/systemd-cat -t controllist, again the full path is given. The command path can be found using which, e.g. which nft. In any case the final crontab command entry would look like: /usr/bin/systemd-cat -t controllist /home/baumkp/controllist.sh, remembering everything after the 5th space is passed to the system shell command interpreter.

example: ''sudo crontab -e''

The crontab files are stored at /var/spool/cron/crontabs/$USER. You should not edit these files directly, use crontab -e for current user or sudo crontab -e for root.

The rate limit command needs to be placed before the other commands that could accept packets before reaching the rate limit command, e.g. ct state established, related counter accept. The following command will add the command at handle 29:

  • sudo nft add rule inet firewall forward handle 29 iifname ppp1 ip daddr { 192.168.1.100-192.168.1.253 } limit rate 1200kbytes/second burst 4000kbytes counter accept

The existing rules with handles displayed can be displayed with:

  • sudo nft list table inet firewall -a

The above command will accept packets according to filter that do not exceed 1200kbytes/second with a burst of 9000kbytes. Another form of syntax would be to drop packets that exceed the limit, this allows the amount of drop packets to be seen with the counter enabled:

  • sudo nft add rule inet firewall forward handle 29 iifname ppp1 ip daddr { 192.168.1.100-192.168.1.253 } limit rate over 1200kbytes/second burst 4000kbytes counter drop

My internet bandwidth is currently limited to about 25Mbit/s, dividing by 8 give approximate MByte/s, i.e. about 3MB/s or 3000mbytes/s or 3000kbytes/s, hence I limit the kids bandwidth to 1200kbytes/s with an allowed burst of 4000kbytes.

  • sudo nmap -sn 192.168.1.0/24
    • -sP lists all IP addresses with any open port (with sudo will also list mac addresses)
    • -sL lists all IP addresses even not active
    • -sT lists all IP addresses with all open ports (with sudo will also list mac addresses) Note this can take a long time so better to limit IP address range.
    • -sn Ping scan, does not scan for port and is hence much faster (with sudo will also list mac addresses)

  • /mnt/shared/www/dokuwiki/data/pages/linux_router/nftables_control.txt
  • Last modified: 2022-01-16 Sun wk02 11:37
  • by baumkp