gennetfilter: generate nft tables with --nft

Optionally generate Netfilter NFT tables. Sample output:

```#!/usr/sbin/nft -f
flush ruleset
table inet security {
        secmark default_input_packet {
                "system_u:object_r:server_packet_t:s0"
        }
        secmark default_output_packet {
                "system_u:object_r:client_packet_t:s0"
        }
        secmark afs_bos_input {
                "system_u:object_r:afs_bos_server_packet_t:s0"
        }
        secmark afs_bos_output {
                "system_u:object_r:afs_bos_client_packet_t:s0"
        }
...
        chain INPUT {
                type filter hook input priority 0; policy accept;
                ct state new meta secmark set "default_input_packet"
                ct state new udp dport 7007 meta secmark set "afs_bos_input"
...
                ct state new ct secmark set meta secmark
                ct state established,related meta secmark set ct secmark
        }
        chain FORWARD {
                type filter hook forward priority 0; policy accept;
        }
        chain OUTPUT {
                type filter hook output priority 0; policy accept;
                ct state new meta secmark set "default_output_packet"
                ct state new udp dport 7007 meta secmark set "afs_bos_output"
...
                ct state new ct secmark set meta secmark
                ct state established,related meta secmark set ct secmark
        }
}
```

The labels are applied to TCP and/or UDP as needed. MCS and MLS are
not really handled.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
This commit is contained in:
Topi Miettinen 2020-04-16 19:08:02 +03:00
parent 766dedecdd
commit 25f29bcfa4
No known key found for this signature in database
GPG Key ID: 87E1A51C590B0577
1 changed files with 65 additions and 3 deletions

View File

@ -42,6 +42,38 @@ class Packet:
# A list of Ports # A list of Ports
self.ports = ports self.ports = ports
def print_nft_secmarks(packets,mls,mcs):
line = '\tsecmark default_input_packet {\n\t\t"system_u:object_r:'+DEFAULT_INPUT_PACKET
if mcs:
line += ":"+DEFAULT_MCS
elif mls:
line += ":"+DEFAULT_MLS
line += '"\n\t}\n\tsecmark default_output_packet {\n\t\t"system_u:object_r:'+DEFAULT_OUTPUT_PACKET
if mcs:
line += ":"+DEFAULT_MCS
elif mls:
line += ":"+DEFAULT_MLS
line += '"\n\t}'
print(line)
for i in packets:
line = "\tsecmark "+i.prefix+'_input {\n\t\t"system_u:object_r:'+i.prefix+PACKET_INPUT
if mcs:
line += ":"+DEFAULT_MCS
elif mls:
line += ":"+DEFAULT_MLS
line += '"\n\t}\n\tsecmark '+i.prefix+'_output {\n\t\t"system_u:object_r:'+i.prefix+PACKET_OUTPUT
if mcs:
line += ":"+DEFAULT_MCS
elif mls:
line += ":"+DEFAULT_MLS
line += '"\n\t}'
print(line)
def print_nft_rules(packets,mls,mcs,direction):
for i in packets:
for j in i.ports:
print("\t\tct state new "+j.proto+" dport "+j.num+' meta secmark set "'+i.prefix+'_'+direction+'"')
def print_input_rules(packets,mls,mcs): def print_input_rules(packets,mls,mcs):
line = "base -A selinux_new_input -j SECMARK --selctx system_u:object_r:"+DEFAULT_INPUT_PACKET line = "base -A selinux_new_input -j SECMARK --selctx system_u:object_r:"+DEFAULT_INPUT_PACKET
if mls: if mls:
@ -117,7 +149,31 @@ def parse_corenet(file_name):
return packets return packets
def print_netfilter_config(packets,mls,mcs): def print_netfilter_config_nft(packets,mls,mcs):
print("#!/usr/sbin/nft -f")
print("flush ruleset")
print("table inet security {")
print_nft_secmarks(packets,mls,mcs)
print("\tchain INPUT {")
print("\t\ttype filter hook input priority 0; policy accept;")
print('\t\tct state new meta secmark set "default_input_packet"')
print_nft_rules(packets,mls,mcs,'input')
print("\t\tct state new ct secmark set meta secmark")
print("\t\tct state established,related meta secmark set ct secmark")
print("\t}")
print("\tchain FORWARD {")
print("\t\ttype filter hook forward priority 0; policy accept;")
print("\t}")
print("\tchain OUTPUT {")
print("\t\ttype filter hook output priority 0; policy accept;")
print('\t\tct state new meta secmark set "default_output_packet"')
print_nft_rules(packets,mls,mcs,'output')
print("\t\tct state new ct secmark set meta secmark")
print("\t\tct state established,related meta secmark set ct secmark")
print("\t}")
print("}")
def print_netfilter_config_iptables(packets,mls,mcs):
print("pre *mangle") print("pre *mangle")
print("pre :PREROUTING ACCEPT [0:0]") print("pre :PREROUTING ACCEPT [0:0]")
print("pre :INPUT ACCEPT [0:0]") print("pre :INPUT ACCEPT [0:0]")
@ -140,9 +196,10 @@ def print_netfilter_config(packets,mls,mcs):
mls = False mls = False
mcs = False mcs = False
nft = False
try: try:
opts, paths = getopt.getopt(sys.argv[1:],'mc',['mls','mcs']) opts, paths = getopt.getopt(sys.argv[1:],'mcn',['mls','mcs','nft'])
except getopt.GetoptError: except getopt.GetoptError:
print("Invalid options.") print("Invalid options.")
sys.exit(1) sys.exit(1)
@ -152,6 +209,8 @@ for o, a in opts:
mcs = True mcs = True
if o in ("-m","--mls"): if o in ("-m","--mls"):
mls = True mls = True
if o in ("-n","--nft"):
nft = True
if len(paths) == 0: if len(paths) == 0:
sys.stderr.write("Need a path for corenetwork.te.in!\n") sys.stderr.write("Need a path for corenetwork.te.in!\n")
@ -160,4 +219,7 @@ elif len(paths) > 1:
sys.stderr.write("Ignoring extra specified paths\n") sys.stderr.write("Ignoring extra specified paths\n")
packets=parse_corenet(paths[0]) packets=parse_corenet(paths[0])
print_netfilter_config(packets,mls,mcs) if nft:
print_netfilter_config_nft(packets,mls,mcs)
else:
print_netfilter_config_iptables(packets,mls,mcs)