Hi list, I am further trying secmark labeling. Currently I am held up by a issue with ipsec. The host runs multiple services: - ipsec : strongswan - webserver : apache2 - imap-server : dovecot I use Debian sid: - kernel: Linux server 5.4.0-1-amd64 #1 SMP Debian 5.4.6-1 (2019-12-27) x86_64 GNU/Linux - nftables: nftables v0.9.3 (Topsy) My current nftables configuration is appended and one can find it at [1]. When connecting to the vpn, I am getting a lot of the following SELinux checks, which I allowed for now: type=AVC msg=audit(12/31/19 11:50:19.581:7033) : avc: granted { forward_in } for pid=0 comm=swapper/0 saddr=virtualvpn_ip src=33179 daddr=some_ip dest=5228 netif=eth0 scontext=system_u:object_r:unlabeled_t:s0 tcontext=system_u:object_r:ipsecnat_server_packet_t:s0 tclass=packet type=AVC msg=audit(12/31/19 11:50:19.581:7034) : avc: granted { forward_out } for pid=0 comm=swapper/0 saddr=host_ip src=7161 daddr=some_ip dest=5228 netif=eth0 scontext=system_u:object_r:unlabeled_t:s0 tcontext=system_u:object_r:ipsecnat_server_packet_t:s0 tclass=packet When I try to access a service (http or imaps) through the vpn and the service is on the same host, I am having troubles to set the correct packet label: # nft debug output rule: ct state established udp sport 4500 log flags all prefix "nft_est " Dec 31 11:54:50 server kernel: nft_est IN= OUT=eth0 SRC=host_ip DST=vpnclient_ip LEN=1476 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=4500 DPT=56602 LEN=1456 Dec 31 11:54:51 server kernel: nft_est IN= OUT=eth0 SRC=host_ip DST=vpnclient_ip LEN=1476 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=4500 DPT=56602 LEN=1456 Dec 31 11:54:52 server audit[0]: AVC avc: denied { send } for pid=0 comm="swapper/0" saddr=host_ip src=4500 daddr=vpnclient_ip dest=56602 netif=eth0 scontext=system_u:system_r:dovecot_t:s0 tcontext=system_u:object_r:ipsecnat_server_packet_t:s0 tclass=packet permissive=0 Dec 31 11:54:54 server audit[9]: AVC avc: denied { send } for pid=9 comm="ksoftirqd/0" saddr=host_ip src=4500 daddr=vpnclient_ip dest=56602 netif=eth0 scontext=system_u:system_r:dovecot_t:s0 tcontext=system_u:object_r:ipsecnat_server_packet_t:s0 tclass=packet permissive=0 Dovecot (reproducible with apache2) tries so send a ipsecnat-server (ipsecnat_server_packet_t) packet, while it should only send imaps-server (pop_server_packet_t). However the initial recv packet for dovecot seems to be labeled correctly. The source port of these packets is 4500, so I can't match on the source port. They are established packets, so the output rule `ct state established,related meta secmark set ct secmark` is setting the label. How do I setup an output rule to label these packet as pop_server_packet_t? (Or is this a kernel issue and the source process context should not be dovecot_t but rather ipsec_t?) King regards, Christian Göttsche [1]: https://salsa.debian.org/cgzones-guest/misc-config/blob/master/nftables/nftables.conf #!/usr/sbin/nft -f flush ruleset # commands # - list rules: nft list ruleset # - block ip: nft add element inet filter blacklist4 { IP } # nft add element inet filter blacklist4 { IP timeout 60s } # - list blacklist: nft list set inet filter blacklist4 define interface_inet = eth0 define port_ssh = 22 define port_ssh_alias = 5222 define port_quassel = 4242 define port_monit = 2812 define addrv4_vpngateway = 172.31.2.1 define addrv4_vpnnet = 172.31.2.0/24 #define addrv6_vpngateway = REPLACEME #define addrv6_vpnnet = REPLACEME table inet filter { set tcp_accepted { type inet_service; elements = { $port_ssh, $port_monit, $port_quassel, smtp, submission, imaps, sieve, http, https } } set udp_accepted { type inet_service; elements = { isakmp, ipsec-nat-t } } set blacklist4 { type ipv4_addr; flags timeout; } set blacklist6 { type ipv6_addr; flags timeout; } chain blacklist_sink { counter drop comment "blacklist" } chain base_checks { ip saddr @blacklist4 counter goto blacklist_sink ip6 saddr @blacklist6 counter goto blacklist_sink ct state invalid counter drop comment "invalid state" ct state { established, related } counter accept comment "established - related" iif lo counter accept comment "loopback" iif != lo ip daddr 127.0.0.1/8 counter limit rate 1/second log flags all prefix "nft_lo4 " drop iif != lo ip6 daddr ::1/128 counter limit rate 1/second log flags all prefix "nft_lo6 " drop } chain tcp_checks_sink { counter drop comment "tcp flags check sink" } chain tcp_checks { tcp flags & (syn) != (syn) ct state new counter goto tcp_checks_sink tcp flags & (fin|syn) == (fin|syn) counter goto tcp_checks_sink tcp flags & (syn|rst) == (syn|rst) counter goto tcp_checks_sink tcp flags & (syn|urg) == (syn|urg) counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == 0 counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|syn|rst|psh|ack|urg) counter goto tcp_checks_sink tcp flags & (fin|rst) == (fin|rst) counter goto tcp_checks_sink tcp flags & (fin|ack) == (fin) counter goto tcp_checks_sink tcp flags & (ack|psh) == (psh) counter goto tcp_checks_sink tcp flags & (ack|urg) == (urg) counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == (syn|fin|psh|urg) counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == (syn|rst|fin|psh|urg) counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|syn|rst|ack) counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == (syn|psh) counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == (syn|psh|ack) counter goto tcp_checks_sink tcp flags & (fin|psh|urg) == (fin|psh|urg) counter goto tcp_checks_sink tcp flags & (fin|syn|rst|psh|ack|urg) == (fin) counter goto tcp_checks_sink } set tcp_spam4 { type ipv4_addr; flags dynamic; } set tcp_spam6 { type ipv6_addr; flags dynamic; } set ssh_spam4 { type ipv4_addr; flags dynamic; } set ssh_spam6 { type ipv6_addr; flags dynamic; } chain tcp_input { jump tcp_checks tcp dport { $port_ssh, $port_ssh_alias } add @ssh_spam4 { ip saddr limit rate over 3/second } log prefix "nft_sshspam4 " set add ip saddr timeout 60s @blacklist4 drop tcp dport { $port_ssh, $port_ssh_alias } add @ssh_spam6 { ip6 saddr limit rate over 3/second } log prefix "nft_sshspam6 " set add ip6 saddr timeout 60s @blacklist6 drop tcp dport @tcp_accepted tcp sport 1024-65535 accept add @tcp_spam4 { ip saddr limit rate over 3/second } log prefix "nft_tcpspam4 " set add ip saddr timeout 60s @blacklist4 drop add @tcp_spam6 { ip6 saddr limit rate over 3/second } log prefix "nft_tcpspam6 " set add ip6 saddr timeout 60s @blacklist6 drop counter limit rate 50/second reject with icmpx type port-unreachable comment "tcp closed port reject" counter limit rate 1/second log flags all prefix "nft_tcpchainend " drop } set udp_spam4 { type ipv4_addr; flags dynamic; } set udp_spam6 { type ipv6_addr; flags dynamic; } chain udp_input { udp dport @udp_accepted udp sport 1024-65535 accept add @udp_spam4 { ip saddr limit rate over 3/second } log prefix "nft_udpspam4 " set add ip saddr timeout 60s @blacklist4 drop add @udp_spam6 { ip6 saddr limit rate over 3/second } log prefix "nft_udpspam6 " set add ip6 saddr timeout 60s @blacklist6 drop counter limit rate 500/second reject with icmpx type port-unreachable comment "udp closed port reject" counter limit rate 1/second log flags all prefix "nft_udpchainend " drop } chain icmpv4_input { ip protocol icmp icmp type { echo-request, echo-reply, time-exceeded, parameter-problem, destination-unreachable } counter limit rate 100/second accept comment "icmpv4 accept" ip protocol icmp icmp type { timestamp-request } drop counter limit rate 1/second log flags all prefix "nft_icmp4chainend " drop } chain icmpv6_input { ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, time-exceeded, parameter-problem, destination-unreachable, packet-too-big, nd-router-solicit, mld-listener-query } counter limit rate 100/second accept comment "icmpv6 accept" ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-advert, nd-neighbor-solicit, nd-router-advert } ip6 hoplimit 1 limit rate 100/second accept ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-advert, nd-neighbor-solicit, nd-router-advert } ip6 hoplimit 255 limit rate 100/second accept counter limit rate 1/second log flags all prefix "nft_icmpv6chainend " drop } chain output { type filter hook output priority 0; policy accept; } chain forward { type filter hook forward priority 0; policy drop; counter ip saddr $addrv4_vpnnet oif $interface_inet accept comment "forward ipv4 for net" #ip6 saddr $addrv6_vpnnet oif $interface_inet accept counter ip daddr $addrv4_vpngateway oif $interface_inet accept comment "forward ipv4 to gateway" #ip6 daddr $addrv6_vpngateway oif $interface_inet accept ip6 nexthdr icmpv6 icmpv6 type { echo-request } counter limit rate 100/second accept comment "forward icmpv6 accept" counter limit rate 1/second log flags all prefix "nft_fwdchainend " reject } chain input { type filter hook input priority 0; policy drop; counter comment "input" jump base_checks ip protocol vmap { tcp : goto tcp_input, udp : goto udp_input, icmp : goto icmpv4_input } ip6 nexthdr vmap { tcp : goto tcp_input, udp : goto udp_input, icmpv6 : goto icmpv6_input } ip protocol 4 counter drop comment "drop encapsulated ipv4" ip protocol 41 counter drop comment "drop encapsulated ipv6" counter limit rate 1/second log flags all prefix "nft_inputendchain " drop } } table ip nat { chain prerouting { type nat hook prerouting priority 0; policy accept; tcp dport $port_ssh_alias redirect to $port_ssh comment "ipv4 ssh port redirection for public networks" } chain postrouting { type nat hook postrouting priority 0; policy accept; ip saddr $addrv4_vpnnet oif $interface_inet counter masquerade fully-random comment "masquerade ipv4" } } table ip6 nat6 { chain prerouting { type nat hook prerouting priority 0; policy accept; tcp dport $port_ssh_alias redirect to $port_ssh comment "ipv6 ssh port redirection for public networks" } chain postrouting { type nat hook postrouting priority 0; policy accept; #ip saddr $addrv6_vpnnet oif $interface_inet counter masquerade fully-random comment "masquerade ipv6" } } table inet mysecmark { secmark ssh_server { "system_u:object_r:ssh_server_packet_t:s0" } secmark dns_client { "system_u:object_r:dns_client_packet_t:s0" } secmark http_client { "system_u:object_r:http_client_packet_t:s0" } secmark https_client { "system_u:object_r:http_client_packet_t:s0" } secmark ntp_client { "system_u:object_r:ntp_client_packet_t:s0" } secmark icmp_client { "system_u:object_r:icmp_client_packet_t:s0" } secmark icmp_server { "system_u:object_r:icmp_server_packet_t:s0" } secmark ssh_client { "system_u:object_r:ssh_client_packet_t:s0" } secmark git_client { "system_u:object_r:git_client_packet_t:s0" } secmark quassel_server { "system_u:object_r:quassel_server_packet_t:s0" } secmark http_server { "system_u:object_r:http_server_packet_t:s0" } secmark ircd_client { "system_u:object_r:ircd_client_packet_t:s0" } secmark pop_client { "system_u:object_r:pop_client_packet_t:s0" } secmark mysql_client { "system_u:object_r:mysqld_client_packet_t:s0" } secmark mysql_server { "system_u:object_r:mysqld_server_packet_t:s0" } secmark isakmp_server { "system_u:object_r:isakmp_server_packet_t:s0" } secmark isakmp_client { "system_u:object_r:isakmp_client_packet_t:s0" } secmark ipsecnat_server { "system_u:object_r:ipsecnat_server_packet_t:s0" } secmark ipsecnat_client { "system_u:object_r:ipsecnat_client_packet_t:s0" } secmark pop_server { "system_u:object_r:pop_server_packet_t:s0" } secmark sieve_server { "system_u:object_r:sieve_server_packet_t:s0" } secmark smtp_server { "system_u:object_r:smtp_server_packet_t:s0" } secmark smtp_client { "system_u:object_r:smtp_client_packet_t:s0" } secmark monit_server { "system_u:object_r:monit_server_packet_t:s0" } secmark monit_client { "system_u:object_r:monit_client_packet_t:s0" } secmark spamd_server { "system_u:object_r:spamd_server_packet_t:s0" } secmark spamd_client { "system_u:object_r:spamd_client_packet_t:s0" } map secmapping_in { type inet_service : secmark elements = { $port_ssh : "ssh_server", $port_quassel : "quassel_server", http : "http_server", https : "http_server", mysql : "mysql_server", isakmp : "isakmp_server", ipsec-nat-t : "ipsecnat_server", imaps : "pop_server", sieve : "sieve_server", smtp : "smtp_server", submission : "smtp_server", $port_monit : "monit_server", spamd : "spamd_server", } } map secmapping_out { type inet_service : secmark elements = { ssh : "ssh_client", domain : "dns_client", http : "http_client", ntp : "ntp_client", https : "http_client", git : "git_client", 6665 : "ircd_client", ircd : "ircd_client", imaps : "pop_client", mysql : "mysql_client", smtp : "smtp_client", isakmp : "isakmp_client", ipsec-nat-t : "ipsecnat_client", submission : "smtp_client", smtp : "smtp_client", $port_monit : "monit_client", spamd : "spamd_client", } } chain input { type filter hook input priority -225; # get label for est/rel packets from connection ct state established,related meta secmark set ct secmark # label new incoming packets ct state new meta secmark set tcp dport map @secmapping_in ct state new meta secmark set udp dport map @secmapping_in ct state new ip protocol icmp meta secmark set "icmp_server" ct state new ip6 nexthdr icmpv6 meta secmark set "icmp_server" # fix loopback labels iif lo meta secmark set tcp dport map @secmapping_in iif lo meta secmark set udp dport map @secmapping_in iif lo meta secmark set tcp sport map @secmapping_out iif lo meta secmark set udp sport map @secmapping_out iif lo ip protocol icmp meta secmark set "icmp_client" iif lo ip6 nexthdr icmpv6 meta secmark set "icmp_client" # save label onto connection ct state new ct secmark set meta secmark #iif lo ct secmark set meta secmark } chain output { type filter hook output priority 255; # get label for est/rel packets from connection ct state established,related meta secmark set ct secmark # label new outgoing packets ct state new meta secmark set tcp dport map @secmapping_out ct state new meta secmark set udp dport map @secmapping_out ct state new ip protocol icmp meta secmark set "icmp_client" ct state new ip6 nexthdr icmpv6 meta secmark set "icmp_client" # fix loopback labels oif lo meta secmark set tcp dport map @secmapping_out oif lo meta secmark set udp dport map @secmapping_out oif lo meta secmark set tcp sport map @secmapping_in oif lo meta secmark set udp sport map @secmapping_in oif lo ip protocol icmp meta secmark set "icmp_client" oif lo ip6 nexthdr icmpv6 meta secmark set "icmp_client" # save label onto connection ct state new ct secmark set meta secmark #oif lo ct secmark set meta secmark } }