Hey there,
recently I got an abuse complaint from my provider for sending packets to private network ranges into their network and I should do necessary precautions to avoid that in future.
Those packages came from an application inside a LXC container.
Blocking the affected IP ranges sounds easy but I realized that this is quite difficult without causing collateral damage.
Anyway my first attempt was to create an additional output chain with netfilter like
chain OUTPUT3 {
type filter hook output priority filter - 1; policy accept;
oifname "eno1" ip daddr 10.0.0.0/8 counter packets 0 bytes 0 reject
oifname "eno1" ip daddr 192.168.0.0/16 counter packets 0 bytes 0 reject
oifname "eno1" ip daddr 172.16.0.0/12 counter packets 0 bytes 0 reject
However that did not catch anything whatsoever.
I am not that familiar with nft (yet) but I assume due to the routing LXD with lxdbr0 does it skips the output entirely and goes directly to postrouting.
There though I cannot filter packets.
Next though was using ACLs:
lxc network acl show test1
name: test1
description: ""
egress:
- action: reject
destination: 172.16.0.0/12
state: enabled
- action: reject
destination: 10.0.0.0/8
state: enabled
- action: reject
destination: 192.168.0.0/16
state: enabled
- action: reject
destination: 100.64.0.0/10
state: enabled
ingress: []
config: {}
used_by: []
Checking the nft ruleset afterwards it seems like that did something kind a similar to my first attempt.
However this made my containers inaccessible even though I set the default egress action
to allow
as well.
The last option I had in mind was to add individual iptables/nft rules inside each and every container blocking those ranges. However this then will prevent containers to communicate with each other if I do not whitelist individual addresses of those.
So on the bottom line I am kind a stuck how to prevent packets addressed to private ranges from the public network interface.
Looking forward to some advice.
Cheers
Running Ubuntu 22.04 with LXD 5.5
My current full ruleset of the host machine:
table inet lxd {
chain pstrt.lxdbr0 {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.10.10.0/24 ip daddr != 10.10.10.0/24 masquerade
ip6 saddr fd42:10::/120 ip6 daddr != fd42:10::/120 masquerade
}
chain fwd.lxdbr0 {
type filter hook forward priority filter; policy accept;
ip version 4 oifname "lxdbr0" accept
ip version 4 iifname "lxdbr0" accept
ip6 version 6 oifname "lxdbr0" accept
ip6 version 6 iifname "lxdbr0" accept
}
chain in.lxdbr0 {
type filter hook input priority filter; policy accept;
iifname "lxdbr0" tcp dport 53 accept
iifname "lxdbr0" udp dport 53 accept
iifname "lxdbr0" icmp type { destination-unreachable, time-exceeded, parameter-problem } accept
iifname "lxdbr0" udp dport 67 accept
iifname "lxdbr0" icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-solicit, nd-neighbor-solicit, nd-neighbor-advert, mld2-listener-report } accept
iifname "lxdbr0" udp dport 547 accept
}
chain out.lxdbr0 {
type filter hook output priority filter; policy accept;
oifname "lxdbr0" tcp sport 53 accept
oifname "lxdbr0" udp sport 53 accept
oifname "lxdbr0" icmp type { destination-unreachable, time-exceeded, parameter-problem } accept
oifname "lxdbr0" udp sport 67 accept
oifname "lxdbr0" icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, mld2-listener-report } accept
oifname "lxdbr0" udp sport 547 accept
}
}