1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
Dismiss Notice

Welcome To SNBForums

SNBForums is a community for anyone who wants to learn about or discuss the latest in wireless routers, network storage and the ins and outs of building and maintaining a small network.

If you'd like to post a question, simply register and have at it!

While you're at it, please check out SmallNetBuilder for product reviews and our famous Router Charts, Ranker and plenty more!

Proper/best way to block traffic from external range, including port forwards

Discussion in 'Asuswrt-Merlin' started by bengalih, Dec 3, 2019.

  1. bengalih

    bengalih Regular Contributor

    Joined:
    Dec 13, 2016
    Messages:
    110
    So I have several port forwards setup on my device (using the GUI).

    I know the default firewall blocks all incoming traffic, but obviously port forwards are still acessible.
    I want to be able to block all traffic from a particular IP or range of IPs. Preferably block just to a particular forwarded port, but if required all ports will work.

    I assume I will want to use some type of iptables drop rule?
    Can someone help me with the proper way to add this, and the best place/script to put it?

    thanks.
     
  2. skeal

    skeal Part of the Furniture

    Joined:
    Apr 30, 2016
    Messages:
    3,923
    Location:
    Riderville, SK
    I recommend Skynet.
     
    martinr likes this.
  3. Martineau

    Martineau Part of the Furniture

    Joined:
    Jul 8, 2012
    Messages:
    3,392
    Location:
    UK
    For specific Ports you will probably need to write your own rules.

    Old-skool method is to add individual/multiple rules for the source IPs and the target local Ports.
    Code:
    iptables -I FORWARD -i $(nvram get wan0_ifname) -s xxx.xxx.xxx.xxx[,123.xxx.xxx.xxx...] [-d 192.168.1.xxx] -p tcp -m tcp -m multiport --dport nnn[,nnn...] -j DROP
    or
    iptables -I FORWARD -i $(nvram get wan0_ifname) -m iprange --src-range xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx [-d 192.168.1.xxx] -p tcp -m tcp -m multiport --dport nnn,nnn -j DROP
    e.g. The following rule syntax generates two rules, one for each CIDR range
    Code:
    iptables -I FORWARD -i $(nvram get wan0_ifname) -s 1.2.3.0/24,3.2.1.0/24  -p tcp -m tcp -m multiport --dports 22,3389 -j DROP
    whereas the following rule syntax creates just one
    Code:
    iptables -I FORWARD -i $(nvram get wan0_ifname) -m iprange --src-range 4.5.6.0-10.9.8.0  -p tcp -m tcp -m multiport --dports 22,3389 -j DROP
    i.e.
    Code:
    iptables --line -t filter -nvL FORWARD
    
    Chain FORWARD (policy DROP 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination     
    1        0     0 DROP       tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0            source IP range 4.5.6.0-10.9.8.0 tcp multiport dports 22,3389
    2        0     0 DROP       tcp  --  eth0   *       3.2.1.0/24           0.0.0.0/0            tcp multiport dports 22,3389
    3        0     0 DROP       tcp  --  eth0   *       1.2.3.0/24           0.0.0.0/0            tcp multiport dports 22,3389
    However, depending on the number of IPs/CIDRs it is usually considered easier to use IPSETs, which means the number of rules can be greatly reduced - sometimes even down to a single rule.

    e.g. Create three IPSETs containing separate entities - and of course the Ports defined in the two Port IPSETs must be mutually exclusive!
    Code:
              BAD_Guys         PROTECTED_Ports     ALLOWED_Ports
         xxx.xxx.xxx.xxx            3389                 80
         123.xxx.xxx.0/24             22                443
             etc.                                      8080
                                                       4321
    So a single rule that would BLOCK hundreds of source IP-to-Port combinations
    Code:
    iptables -I FORWARD -i $(wan0_ifname) -m set --match-set BAD_GUYS src -p tcp -m tcp -m set --match-set PROTECTED_PORTS dst -m set ! --match-set ALLOWED_PORTS dst -j DROP
    but simply adding a second rule would allow the BAD_GUYS to access your public Ports
    Code:
    iptables -I FORWARD -i $(wan0_ifname) -m set --match-set BAD_GUYS src -p tcp -m tcp -m set --match-set ALLOWED_PORTS dst -j ACCEPT
    firewall-start would probably be the best place for your custom rules.
     
    Last edited: Dec 15, 2019
    martinr likes this.
  4. bengalih

    bengalih Regular Contributor

    Joined:
    Dec 13, 2016
    Messages:
    110
    2 questions here:
    1) Old-skool as compared to what other method might I use?
    2) If I just wanted to block entire IP/ranges instead of specific ports, would there be another method, or is manual IP tables still the way to go?

    Apart from creating one vs. two rules, what are the real differences/advantages/disadvantages to one over the other?

    Also, I tested these out and they aren't working for me. I tried one entry of each to block my cell phone's public WAN IP from being able to access port 443 (which is nginx running on my box) and they didn't work. I thought perhaps there might be an issue since this is a local service (on-router), so I then setup a port forward for RDP to a particular box and then blocked it and that seemed to work.

    How should/might I adjust these rules to block access to 443/nginx on the box itself?
    Would that just be an INPUT rule instead of a FORWARD? That seems to work, but wanted to confirm.

    thanks.
     
  5. Martineau

    Martineau Part of the Furniture

    Joined:
    Jul 8, 2012
    Messages:
    3,392
    Location:
    UK
    A1. You still need iptables rules, but maintaining an IPSET containing all the IP/ranges means you only ever need one iptables rule per IPSET rather than (possibly) one rule per IP.
    A2. Yes.

    Services that are hosted on the Router use the '-t filter' INPUT/OUTPUT chains rather than the '-t filter' FORWARD chain which is used for services hosted on LAN devices.
     
    Last edited: Dec 15, 2019
    Wisiwyg and martinr like this.
  6. bengalih

    bengalih Regular Contributor

    Joined:
    Dec 13, 2016
    Messages:
    110
    Thanks, still curious as to the advantages/disadvantages of the two different types of syntax you showed.
    If looks like the -m option is the one I need to use if I go with a set (-m set vs -m iprange)?
    If that's the case than it is clear that the advantage to the -m one is that I can use sets.
    Exclusive of sets however (if I'm just writing a one off rule), why choose one syntax over the other?
     
  7. Martineau

    Martineau Part of the Furniture

    Joined:
    Jul 8, 2012
    Messages:
    3,392
    Location:
    UK
    IPSETs are extremely efficient (even with thousands of member entries), furthermore they can contain of IPs/CIDR ranges etc.

    Ultimately it is your choice to choose how you want to manage the iptables rules.

    The difference in syntax means that you can save on typing and reduce the number of iptables rules, but depending on the method chosen, the downside is that you lose the ability to extract detailed statistics

    i.e. if the single rule that matches the IPSET has fired 1000 times, if the IPSET contains 1000 entities (IPs/CIDR ranges) how do you know if one IP matched 1000 times or each entity matched only once?

    Similarly for the following one-rule multi-IP syntax
    Code:
    -m iprange --src-range xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx
     
    Last edited: Dec 15, 2019
    martinr likes this.
  8. bengalih

    bengalih Regular Contributor

    Joined:
    Dec 13, 2016
    Messages:
    110
    Ok, I get that - but maybe I wasn't specific enough. I'm asking more simply if I presented each of these rules to you as an option:

    Code:
    iptables -I FORWARD -i $(wan0_ifname) -s 20.149.12.12/32 -d 10.10.10.102 -p tcp -m tcp -m multiport --dport 443 -j DROP
    or
    iptables -I FORWARD -i $(wan0_ifname) -m iprange --src-range 20.149.12.12 -d 10.10.10.102 -p tcp -m tcp -m multiport --dport 443 -j DROP
    What is the difference between the two? Is there any advantage to one of the other for a simple rule like above (no IPSETs involved).
     
  9. ColinTaylor

    ColinTaylor Part of the Furniture

    Joined:
    Mar 31, 2014
    Messages:
    12,027
    Location:
    UK
    No significant difference... other than you have a syntax error in the second command. --src-range should be a range, e.g. 20.149.12.12-20.149.12.250. Therefore it is more flexible than using -s where you are restricted to using specific IP's or IP's that are CIDR ranges.
     
  10. Martineau

    Martineau Part of the Furniture

    Joined:
    Jul 8, 2012
    Messages:
    3,392
    Location:
    UK
    Wrong.
     
  11. Martineau

    Martineau Part of the Furniture

    Joined:
    Jul 8, 2012
    Messages:
    3,392
    Location:
    UK
    For a single source IP address, technically no difference, but they are visually different which, in a large table, one version might be more human-friendly over the other?
    e.g.
    Code:
    iptables  --line -t filter -nvL FORWARD
     
    Chain FORWARD (policy DROP 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination      
    1        0     0 DROP       tcp  --  eth0   *       20.149.12.12         10.10.10.102         tcp multiport dports 443
    2        0     0 DROP       tcp  --  eth0   *       0.0.0.0/0            10.10.10.102         source IP range 20.149.12.12-20.149.12.12 tcp multiport dports 443
     
    Last edited: Dec 15, 2019
  12. bengalih

    bengalih Regular Contributor

    Joined:
    Dec 13, 2016
    Messages:
    110
    Heh...looks like I started a debate.

    So it is ok to use a single IP address in the --src-range? I realize it may be not ideal, but which is valid

    Code:
    --src-range 20.149.12.12
    or
    --src-range 20.149.12.12-20.149.12.12
    
    or either?

    Also, you seem to be an expert on IPtables. Is there a particular book/guide/tutorial you would recommend.
    I do have some experience with it, but never used it on a regular basis. I would say I have a pretty good grasp on firewall fundamentals, but not necessarily how the stack is implemented in linux. I don't want to jump in with just the man pages, so if you have recommended anything in the past I'll bookmark it for some downtime.

    thanks
     
  13. ColinTaylor

    ColinTaylor Part of the Furniture

    Joined:
    Mar 31, 2014
    Messages:
    12,027
    Location:
    UK
    :D Not really. Martineau replied faster than I could correct my own mistake.
     
  14. Martineau

    Martineau Part of the Furniture

    Joined:
    Jul 8, 2012
    Messages:
    3,392
    Location:
    UK
    Yes.

    iptables is smart enough to complete the range...

    e.g. the following created the rule shown in post #11
    Code:
    iptables -I FORWARD -i $(nvram get wan0_ifname) -m iprange --src-range 20.149.12.12 -d 10.10.10.102  -p tcp -m tcp -m multiport --dports 443 -j DROP
    
     
  15. Martineau

    Martineau Part of the Furniture

    Joined:
    Jul 8, 2012
    Messages:
    3,392
    Location:
    UK
    L&LD, bengalih and dave14305 like this.