Press "Enter" to skip to content

Category: Sysadmin

Understanding IN, OUT, and LOCAL in Ubiquiti EdgeRouter and Unifi Firewall ACLs

EdgeRouter and Unifi routers are built on top of Linux with Netfilter/iptables. This gives them quite a bit of flexibility compared to other routing platforms systems based on proprietary operating systems.

Understanding how rules are applied in the netfilter stack are important in building an effective firewall.

IN and OUT Target Direction

IN and OUT rules are specifically for routing and only apply to packets that are going through the router, not originating from the router.

IN is processed first, and is the direction you should be using when trying to control what packets coming in on an interface should be doing.

For example, if you want to prevent your GUEST (eth2) network on 172.16.1.0/24 from communicating with your LAN (eth1) on 192.168.1.0/24…

set firewall name GUEST-IN rule 10 action drop
set firewall name GUEST-IN rule 10 description 'Drop traffic from GUEST to LAN'
set firewall name GUEST-IN rule 10 log disable
set firewall name GUEST-IN rule 10 protocol all
set firewall name GUEST-IN rule 10 source address 172.16.1.0/24
set firewall name GUEST-IN rule 10 destination address 192.168.1.0/24
set interfaces ethernet eth2 firewall in name GUEST-IN

Basically, you want to act on packets as early on in the stack as possible.

OUT rules are handled in the same way as IN rules and handled after IN rules. Because they are both handled in the netfilter FORWARD chain, they are technically handled in the same way and mostly are separated just for the benefit of the user.

LOCAL Target Direction

LOCAL rules are specifically for controlling traffic directed at the router and have no impact on routed traffic.

For example, if you wanted to restrict access to SSH from the WAN (eth0)…

set firewall name WAN-IN rule 10 action drop
set firewall name WAN-IN rule 10 description 'Drop SSH connections from WAN'
set firewall name WAN-IN rule 10 log disable
set firewall name WAN-IN rule 10 protocol tcp
set firewall name WAN-IN rule 10 destination port 22
set interfaces ethernet eth0 firewall in name WAN-IN

LOCAL rules are applied to the netfilter INPUT chain. There is no way to add rules to the netfilter OUTPUT chain unless you directly insert them in via iptables.

ImageNet Consulting Decides To Pocket Employee’s Stimulus Checks

The Lost Ogle has a great post about the actions of one Oklahoma City company, ImageNet Consulting, that has decided that their employees don’t need paychecks due to the govt surplus checks.

It was also covered by KXAN – but they wouldn’t name and shame like The Lost Ogle did. There is also a Reddit post here with comments and other links.

Oh, they even want half of the $500 per kid stipend too!

If your company is trying to do something similar to you – contact a lawyer that specializes in employment law ASAP.

Update: The company appears to be trying to purge articles, blog posts, etc about their actions from the web and various search engines.

Configuring DNSDist – A Basic Config

DNSDist is a great load balancing DNS forwarder/resolver designed by the same people behind PowerDNS.

It works on Linux and other UNIX OSs, and is fairly easy to set up once you understand how its configuration file works.

An example config with some comments…

controlSocket('127.0.0.1:5199')
setConsoleACL('127.0.0.1/32')
setKey("PUT-KEY-HERE")
addLocal('127.0.0.1')
addLocal('10.0.0.1')
addLocal('::1')
webserver('10.0.0.1:8083', 'dnsdist', 'dnsdist')

This is the initial section defining what IPs DNSDist uses to listen for its control and general purpose sockets:

  • controlSocket() – sets local IP and port that the control listens on
  • setControlACL() – sets what can connect to the control socket
  • setKey() – sets your unique key to prevent unauthorized access
  • addLocal() – sets the local IP and port that the resolver listens on
  • webserver() – sets the local IP and port that the stats webserver listens on, with the username and password it expects
addDOHLocal("172.16.5.1:5053",
                "/etc/letsencrypt/live/domain.com/fullchain.pem",
                "/etc/letsencrypt/live/domain.com/privkey.pem",
                "/dns-query",
                { doTCP=true, reusePort=true }
                )
doh_ips=newNMG()
doh_ips:addMask('0.0.0.0/0')
doh_ips:addMask('::/0')
addAction(AndRule({NetmaskGroupRule(doh_ips, true), DSTPortRule(5053)}), PoolAction('recursive'))

This section we set up DNS over HTTPS for use with Firefox, Chrome, etc that can take advantage of a secure channel to query DNS separate from their provider’s servers.

In this case, we’re allowing anyone to query over DOH, but you can change that by removing the addMask() covering ‘everything’.

  • addDOHLocal() – this sets the local IP and port that the DOH HTTPS server listens on. The paths are to the local letsencrypt generated certificates. The “/dns-query” path is the web server path to use as the base for the queries.
  • doh_ips=newNMG() – sets up the Network Mask Group variable
  • doh_ips:addMask() – configures the source IP ranges to allow
  • addAction() – this one in particular allows anyone from the doh_ips variable who queries DOH on port 5053 to recursive query DNS.
recursive_ips=newNMG()
recursive_ips:addMask('127.0.0.0/8')
recursive_ips:addMask('::1/128')
recursive_ips:addMask('fe80::/10')
recursive_ips:addMask('10.0.0.0/24')
addAction(NetmaskGroupRule(recursive_ips), PoolAction('recursive'))

This section we set up the standard port 53 UDP/TCP resolver to accept queries. It works the same way as the previous block does, with the exception of the addAction().

  • addAction() – this allows anyone from recursive_ips variable to query your resolver on port 53 UDP or TCP.
newServer({address="8.8.8.8:53", pool="recursive"})
newServer({address="1.1.1.1:53", pool="recursive"})

recursivepc = newPacketCache(10000, {maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false})
getPool("recursive"):setCache(recursivepc)

setACL({'::/0','0.0.0.0/0'})

This section sets up the recursive pool of servers to use for querying.

  • newServer() – sets the parent recursive DNS servers to balance between. In the above examples, we use two public ones – Google and Cloudflare. Can be your provider’s recursive or other public ones.
  • recursivepc=newPacketCache() – sets up the details on the packet cache to improve performance and expire old entries.
  • getPool():setCache() – links the recursive pool to the recursivepc packet cache defined before
  • setACL() – needed to allow any incoming queries to hit the Netmask Group ACLs previously defined.