Score:0

firewalld: outgoing NTP connection will be logged as blocked, but isn't blocked

in flag

I have configure firewalld on CentOS7 so it blockes all outgoing connections. Only the needed connections are white listed by adding some rules. Also I have add rules to enable logging of blocked connections (outgoing direction).

The current firewalld rules are (some IPs I have masquarade wit "xxx"):

/> firewall-cmd --permanent --direct --get-all-rules
ipv4 filter OUTPUT 1 -p udp -m udp --dport=53 -d 185.12.64.1 -j ACCEPT
ipv4 filter OUTPUT 1 -p udp -m udp --dport=53 -d 185.12.64.2 -j ACCEPT
ipv4 filter OUTPUT 1 -p udp -m owner --uid-owner root --dport 67:68 -j ACCEPT
ipv4 filter OUTPUT 1 -p icmp --icmp-type 8 -m state --state NEW,ESTABLIS -m owner -- uid-owner root -j ACCEPT
ipv4 filter OUTPUT 1 -p tcp -m tcp --dport=25 -d 193.111.XXX.XXX -j ACCEPT
ipv4 filter OUTPUT 1 -p tcp --dport=58443 -d 10.254.XXX.XXX -j ACCEPT
ipv4 filter OUTPUT 1 -p tcp --dport=58443 -d 193.111.XXX.XXX -j ACCEPT
ipv4 filter OUTPUT 1 -p tcp --dport=5667 -d 10.254.XXX.XXX -j ACCEPT
ipv4 filter OUTPUT 1 -p udp -m udp --dport=1194 -d 193.111.XXX.XXX -j ACCEPT
ipv4 filter OUTPUT 1 -m owner --uid-owner root -p tcp -m tcp --dport=443 -j ACCEPT
ipv4 filter OUTPUT 1 -m owner --uid-owner root -p tcp -m tcp --dport=80 -j ACCEPT
ipv4 filter OUTPUT 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
ipv4 filter OUTPUT 1 -m owner --uid-owner clamupdate -p tcp -m tcp --dport=443 -j ACCEPT
ipv4 filter OUTPUT 2 -j DROP
ipv4 filter OUTPUT 1 -j LOG_OUTPUT
ipv4 filter OUTPUT 1 -m owner --uid-owner chrony -p udp -m udp --dport=123 -j ACCEPT
ipv6 filter OUTPUT 1 -p udp -m owner --uid-owner root --dport 67:68 -j ACCEPT
ipv6 filter OUTPUT 1 -p icmpv6 --icmpv6-type 8 -m state --state NEW,ESTABLIS -m owner --uid-owner root -j ACCEPT
ipv6 filter OUTPUT 1 -p tcp -m tcp --dport=25 -d 2001:4ba0:XXXX:XX::X -j ACCEPT
ipv6 filter OUTPUT 1 -p tcp -m tcp --dport=58443 -d 2001:4ba0:XXXX:XX::X -j ACCEPT
ipv6 filter OUTPUT 1 -p tcp --dport=5667 -d fe80::bf18:c142:XXXX:XXXX -j ACCEPT
ipv6 filter OUTPUT 1 -p udp -m udp --dport=1194 -d 2001:4ba0:XXXX:XX::X -j ACCEPT
ipv6 filter OUTPUT 1 -m owner --uid-owner root -p tcp -m tcp --dport=443 -j ACCEPT
ipv6 filter OUTPUT 1 -m owner --uid-owner root -p tcp -m tcp --dport=80 -j ACCEPT
ipv6 filter OUTPUT 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
ipv6 filter OUTPUT 1 -m owner --uid-owner clamupdate -p tcp -m tcp --dport=443 -j ACCEPT
ipv6 filter OUTPUT 2 -j DROP
ipv6 filter OUTPUT 1 -m owner --uid-owner chrony -p udp -m udp --dport=123 -j ACCEPT
ipv4 filter LOG_OUTPUT 1 -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix 'FINAL_REJECT: '

The corrosponding iptable rules are (someone likes iptable's more as firewalld ...):

/> iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N FORWARD_IN_ZONES
-N FORWARD_IN_ZONES_SOURCE
-N FORWARD_OUT_ZONES
-N FORWARD_OUT_ZONES_SOURCE
-N FORWARD_direct
-N FWDI_public
-N FWDI_public_allow
-N FWDI_public_deny
-N FWDI_public_log
-N FWDI_XXXX
-N FWDI_XXXX_allow
-N FWDI_XXXX_deny
-N FWDI_XXXX_log
-N FWDO_public
-N FWDO_public_allow
-N FWDO_public_deny
-N FWDO_public_log
-N FWDO_XXXX
-N FWDO_XXXX_allow
-N FWDO_XXXX_deny
-N FWDO_XXXX_log
-N INPUT_ZONES
-N INPUT_ZONES_SOURCE
-N INPUT_direct
-N IN_public
-N IN_public_allow
-N IN_public_deny
-N IN_public_log
-N IN_XXXX
-N IN_XXXX_allow
-N IN_XXXX_deny
-N IN_XXXX_log
-N LOG_OUTPUT
-N OUTPUT_direct
-A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j INPUT_direct
-A INPUT -j INPUT_ZONES_SOURCE
-A INPUT -j INPUT_ZONES
-A INPUT -m conntrack --ctstate INVALID -j LOG --log-prefix "STATE_INVALID_DROP: "
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -j LOG --log-prefix "FINAL_REJECT: "
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A FORWARD -i virbr0 -o virbr0 -j ACCEPT
-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i lo -j ACCEPT
-A FORWARD -j FORWARD_direct
-A FORWARD -j FORWARD_IN_ZONES_SOURCE
-A FORWARD -j FORWARD_IN_ZONES
-A FORWARD -j FORWARD_OUT_ZONES_SOURCE
-A FORWARD -j FORWARD_OUT_ZONES
-A FORWARD -m conntrack --ctstate INVALID -j LOG --log-prefix "STATE_INVALID_DROP: "
-A FORWARD -m conntrack --ctstate INVALID -j DROP
-A FORWARD -j LOG --log-prefix "FINAL_REJECT: "
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
-A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -j OUTPUT_direct
-A FORWARD_IN_ZONES -i enp0s31f6 -g FWDI_public
-A FORWARD_IN_ZONES -i tun0 -g FWDI_XXXX
-A FORWARD_IN_ZONES -g FWDI_public
-A FORWARD_OUT_ZONES -o enp0s31f6 -g FWDO_public
-A FORWARD_OUT_ZONES -o tun0 -g FWDO_XXXX
-A FORWARD_OUT_ZONES -g FWDO_public
-A FWDI_public -j FWDI_public_log
-A FWDI_public -j FWDI_public_deny
-A FWDI_public -j FWDI_public_allow
-A FWDI_public -p icmp -j ACCEPT
-A FWDI_XXXX -j FWDI_XXXX_log
-A FWDI_XXXX -j FWDI_XXXX_deny
-A FWDI_XXXX -j FWDI_XXXX_allow
-A FWDI_XXXX -p icmp -j ACCEPT
-A FWDO_public -j FWDO_public_log
-A FWDO_public -j FWDO_public_deny
-A FWDO_public -j FWDO_public_allow
-A FWDO_XXXX -j FWDO_XXXX_log
-A FWDO_XXXX -j FWDO_XXXX_deny
-A FWDO_XXXX -j FWDO_XXXX_allow
-A INPUT_ZONES -i enp0s31f6 -g IN_public
-A INPUT_ZONES -i tun0 -g IN_XXXX
-A INPUT_ZONES -g IN_public
-A INPUT_direct -p tcp -m set --match-set f2b-sshd src -j REJECT --reject-with icmp-port-unreachable
-A INPUT_direct -p tcp -m set --match-set f2b-f2bLongList src -j REJECT --reject-with icmp-port-unreachable
-A INPUT_direct -p tcp -m set --match-set f2b-blocklist_de src -j REJECT --reject-with icmp-port-unreachable
-A IN_public -j IN_public_log
-A IN_public -j IN_public_deny
-A IN_public -j IN_public_allow
-A IN_public -p icmp -j ACCEPT
-A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_public_allow -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_public_allow -p tcp -m tcp --dport 58443 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_public_allow -p tcp -m tcp --dport 444 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_public_deny -m set --match-set badIPsSet src -j DROP
-A IN_XXXX -j IN_XXXX_log
-A IN_XXXX -j IN_XXXX_deny
-A IN_XXXX -j IN_XXXX_allow
-A IN_XXXX -p icmp -j ACCEPT
-A IN_XXXX_allow -p tcp -m tcp --dport 59943 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_XXXX_allow -p tcp -m tcp --dport 9945 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_XXXX_allow -p tcp -m tcp --dport 9944 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_XXXX_allow -p tcp -m tcp --dport 9943 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A IN_XXXX_allow -p tcp -m tcp --dport 9947 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
-A LOG_OUTPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "FINAL_REJECT: "
-A OUTPUT_direct -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT_direct -d 185.12.64.1/32 -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT_direct -d 185.12.64.2/32 -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT_direct -p udp -m owner --uid-owner 0 -m udp --dport 67:68 -j ACCEPT
-A OUTPUT_direct -p icmp -m icmp --icmp-type 8 -m state --state NEW,ESTABLISHED -m owner --uid-owner 0 -j ACCEPT
-A OUTPUT_direct -d 193.111.XXX.XXX/32 -p tcp -m tcp --dport 25 -j ACCEPT
-A OUTPUT_direct -d 10.254.XXX.XXX/32 -p tcp -m tcp --dport 58443 -j ACCEPT
-A OUTPUT_direct -d 193.111.XXX.XXX/32 -p tcp -m tcp --dport 58443 -j ACCEPT
-A OUTPUT_direct -d 10.254.XXX.XXX/32 -p tcp -m tcp --dport 5667 -j ACCEPT
-A OUTPUT_direct -d 193.111.XXX.XXX/32 -p udp -m udp --dport 1194 -j ACCEPT
-A OUTPUT_direct -p tcp -m owner --uid-owner 0 -m tcp --dport 443 -j ACCEPT
-A OUTPUT_direct -p tcp -m owner --uid-owner 0 -m tcp --dport 80 -j ACCEPT
-A OUTPUT_direct -p tcp -m owner --uid-owner 986 -m tcp --dport 443 -j ACCEPT
-A OUTPUT_direct -j LOG_OUTPUT
-A OUTPUT_direct -p udp -m owner --uid-owner 993 -m udp --dport 123 -j ACCEPT
-A OUTPUT_direct -j DROP

The UDP port 123 (NTP protocol) is open for outgoing connections for user "''chrony''". If I call chrony manually from command line I get:

/> chronyd -q 'server 178.63.52.31 iburst'
2022-03-07T09:09:45Z chronyd version 3.4 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 +DEBUG)
2022-03-07T09:09:45Z Initial frequency -13.925 ppm
2022-03-07T09:09:49Z System clock wrong by 0.000131 seconds (step)
2022-03-07T09:09:49Z chronyd exiting

Ok, seems that works (like expected). But the firewall logs following:

Mar  7 10:09:45 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=24554 DF PROTO=UDP SPT=55470 DPT=123 LEN=56 
Mar  7 10:09:47 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=25563 DF PROTO=UDP SPT=48110 DPT=123 LEN=56 
Mar  7 10:09:49 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=25796 DF PROTO=UDP SPT=46482 DPT=123 LEN=56 

If remove the rules for Port "123":

/> firewall-cmd --permanent --direct --remove-rule ipv4 filter OUTPUT 1 -m owner --uid-owner chrony -p udp -m udp --dport=123 -j ACCEPT
success
/> firewall-cmd --permanent --direct --remove-rule ipv6 filter OUTPUT 1 -m owner --uid-owner chrony -p udp -m udp --dport=123 -j ACCEPT
success
/> firewall-cmd --reload
success

and call chrony again:

chronyd -q 'server 178.63.52.31 iburst'
2022-03-07T09:12:46Z chronyd version 3.4 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 +DEBUG)
2022-03-07T09:12:46Z Initial frequency -13.925 ppm
2022-03-07T09:12:56Z No suitable source for synchronisation
2022-03-07T09:12:56Z chronyd exiting

(which fails like expected) I get 6 lines in the firewall log file (instead of 3 lines above):

Mar  7 10:12:46 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=30341 DF PROTO=UDP SPT=45581 DPT=123 LEN=56 
Mar  7 10:12:48 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=32318 DF PROTO=UDP SPT=36395 DPT=123 LEN=56 
Mar  7 10:12:50 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=33178 DF PROTO=UDP SPT=56503 DPT=123 LEN=56 
Mar  7 10:12:52 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=34311 DF PROTO=UDP SPT=55691 DPT=123 LEN=56 
Mar  7 10:12:54 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=35963 DF PROTO=UDP SPT=57795 DPT=123 LEN=56 
Mar  7 10:12:56 static kernel: FINAL_REJECT: IN= OUT=enp0s31f6 SRC=136.243.139.67 DST=178.63.52.31 LEN=76 TOS=0x00 PREC=0x00 TTL=64 ID=37075 DF PROTO=UDP SPT=51338 DPT=123 LEN=56 

This behavior I have only with NTP connections. At example if I open a SMTP connection on port 25 to 193.111.xxx.xxx (which is explicitly allowed by the firewall rule) I get (like expected) no firewall log message.

Why I get firewall log messages of blocked UDP Port 123 connections when the port is explicitly allowed and chrony works like expected?

mlichvar avatar
cn flag
I think you might need to reorder the firewall rules to have the LOG_OUTPUT before the chrony-specific rule.
in flag
@mlichvar: You are right! The correct priority is 2 for the LOG rule and 3 for the DROP role! If you post your comment as answer, I will accept it. Thx
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.