diff mbox series

[V4] selinux-testsuite: Add nftables to inet_socket and sctp tests

Message ID 20200520122546.30442-1-richard_c_haines@btinternet.com (mailing list archive)
State Superseded
Delegated to: Ondrej Mosnáček
Headers show
Series [V4] selinux-testsuite: Add nftables to inet_socket and sctp tests | expand

Commit Message

Richard Haines May 20, 2020, 12:25 p.m. UTC
Support secmark tests that require nftables version 9.3 or greater and
kernel 4.20 or greater.

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
---
V2 Change:
Use common tests for iptables/nftables
V3 Change:
Use function
V4 Changes:
Add nftables to README for Debian
Use nft -c to determine if SECMARK supported

 README.md                        |  7 ++-
 tests/inet_socket/nftables-flush |  2 +
 tests/inet_socket/nftables-load  | 74 ++++++++++++++++++++++++
 tests/inet_socket/test           | 99 ++++++++++++++++++++------------
 tests/sctp/nftables-flush        |  2 +
 tests/sctp/nftables-load         | 68 ++++++++++++++++++++++
 tests/sctp/test                  | 90 ++++++++++++++++++-----------
 7 files changed, 270 insertions(+), 72 deletions(-)
 create mode 100644 tests/inet_socket/nftables-flush
 create mode 100644 tests/inet_socket/nftables-load
 create mode 100644 tests/sctp/nftables-flush
 create mode 100644 tests/sctp/nftables-load

Comments

Ondrej Mosnacek May 21, 2020, 10 a.m. UTC | #1
On Wed, May 20, 2020 at 2:25 PM Richard Haines
<richard_c_haines@btinternet.com> wrote:
> Support secmark tests that require nftables version 9.3 or greater and
> kernel 4.20 or greater.
>
> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> ---
> V2 Change:
> Use common tests for iptables/nftables
> V3 Change:
> Use function
> V4 Changes:
> Add nftables to README for Debian
> Use nft -c to determine if SECMARK supported
>
>  README.md                        |  7 ++-
>  tests/inet_socket/nftables-flush |  2 +
>  tests/inet_socket/nftables-load  | 74 ++++++++++++++++++++++++
>  tests/inet_socket/test           | 99 ++++++++++++++++++++------------
>  tests/sctp/nftables-flush        |  2 +
>  tests/sctp/nftables-load         | 68 ++++++++++++++++++++++
>  tests/sctp/test                  | 90 ++++++++++++++++++-----------
>  7 files changed, 270 insertions(+), 72 deletions(-)
>  create mode 100644 tests/inet_socket/nftables-flush
>  create mode 100644 tests/inet_socket/nftables-load
>  create mode 100644 tests/sctp/nftables-flush
>  create mode 100644 tests/sctp/nftables-load
[...]
> diff --git a/tests/inet_socket/test b/tests/inet_socket/test
> index 47ce106..6c82719 100755
> --- a/tests/inet_socket/test
> +++ b/tests/inet_socket/test
> @@ -27,6 +27,19 @@ BEGIN {
>          $test_calipso_stream = 1;
>      }
>
> +    # Determine if nftables has secmark support and kernel >= 4.20
> +    $test_nft = 0;
> +
> +    $rc = system("nft -c -f $basedir/nftables-load 2>/dev/null");
> +    if ( $rc == 0 ) {
> +        $kverminstream = "4.20";
> +        $rc            = `$basedir/../kvercmp $kvercur $kverminstream`;
> +        if ( $rc > 0 ) {
> +            $test_count += 8;
> +            $test_nft = 1;
> +        }
> +    }
> +
>      plan tests => $test_count;
>  }

Sorry for bothering you again, but I believe we can drop the kernel
version check here as well (as I said in the previous reply). When I
strace the nft -c -f ... command, I can see it actually sending
netlink messages to the kernel, so it should be able to transparently
detect missing kernel support as well. I just tried it on a RHEL-7 box
with nftables v0.9.4 compiled from source and the command failed with
many errors so I think that confirms it. I'd like us to avoid
hard-coded kernel version checks (they may be unreliable on kernels
with backports) when there is an easy way to detect support directly.

Thanks,
Richard Haines May 21, 2020, 10:56 a.m. UTC | #2
On Thu, 2020-05-21 at 12:00 +0200, Ondrej Mosnacek wrote:
> On Wed, May 20, 2020 at 2:25 PM Richard Haines
> <richard_c_haines@btinternet.com> wrote:
> > Support secmark tests that require nftables version 9.3 or greater
> > and
> > kernel 4.20 or greater.
> > 
> > Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > ---
> > V2 Change:
> > Use common tests for iptables/nftables
> > V3 Change:
> > Use function
> > V4 Changes:
> > Add nftables to README for Debian
> > Use nft -c to determine if SECMARK supported
> > 
> >  README.md                        |  7 ++-
> >  tests/inet_socket/nftables-flush |  2 +
> >  tests/inet_socket/nftables-load  | 74 ++++++++++++++++++++++++
> >  tests/inet_socket/test           | 99 ++++++++++++++++++++------
> > ------
> >  tests/sctp/nftables-flush        |  2 +
> >  tests/sctp/nftables-load         | 68 ++++++++++++++++++++++
> >  tests/sctp/test                  | 90 ++++++++++++++++++--------
> > ---
> >  7 files changed, 270 insertions(+), 72 deletions(-)
> >  create mode 100644 tests/inet_socket/nftables-flush
> >  create mode 100644 tests/inet_socket/nftables-load
> >  create mode 100644 tests/sctp/nftables-flush
> >  create mode 100644 tests/sctp/nftables-load
> [...]
> > diff --git a/tests/inet_socket/test b/tests/inet_socket/test
> > index 47ce106..6c82719 100755
> > --- a/tests/inet_socket/test
> > +++ b/tests/inet_socket/test
> > @@ -27,6 +27,19 @@ BEGIN {
> >          $test_calipso_stream = 1;
> >      }
> > 
> > +    # Determine if nftables has secmark support and kernel >= 4.20
> > +    $test_nft = 0;
> > +
> > +    $rc = system("nft -c -f $basedir/nftables-load 2>/dev/null");
> > +    if ( $rc == 0 ) {
> > +        $kverminstream = "4.20";
> > +        $rc            = `$basedir/../kvercmp $kvercur
> > $kverminstream`;
> > +        if ( $rc > 0 ) {
> > +            $test_count += 8;
> > +            $test_nft = 1;
> > +        }
> > +    }
> > +
> >      plan tests => $test_count;
> >  }
> 
> Sorry for bothering you again, but I believe we can drop the kernel
> version check here as well (as I said in the previous reply). When I
> strace the nft -c -f ... command, I can see it actually sending
> netlink messages to the kernel, so it should be able to transparently
> detect missing kernel support as well. I just tried it on a RHEL-7
> box
> with nftables v0.9.4 compiled from source and the command failed with
> many errors so I think that confirms it. I'd like us to avoid
> hard-coded kernel version checks (they may be unreliable on kernels
> with backports) when there is an easy way to detect support directly.
> 

No problem, I should read, digest and take note etc. !!!!

> Thanks,
>
diff mbox series

Patch

diff --git a/README.md b/README.md
index 1f7e5d9..81475d7 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,7 @@  similar dependencies):
 * keyutils-libs-devel _(tools used by the keys tests)_
 * kernel-devel _(used by the kernel module tests)_
 * quota, xfsprogs-devel and libuuid-devel _(used by the filesystem tests)_
+* nftables _(used by inet_socket and sctp tests if ver >= 9.3 for secmark testing )_
 
 On a modern Fedora system you can install these dependencies with the
 following command:
@@ -77,7 +78,8 @@  following command:
 		kernel-devel \
 		quota \
 		xfsprogs-devel \
-		libuuid-devel
+		libuuid-devel \
+		nftables
 
 #### Debian
 
@@ -118,7 +120,8 @@  command:
 		quota \
 		xfsprogs \
 		xfslibs-dev \
-		uuid-dev
+		uuid-dev \
+		nftables
 
 On Debian, you need to build and install netlabel_tools manually since
 it is not yet packaged for Debian
diff --git a/tests/inet_socket/nftables-flush b/tests/inet_socket/nftables-flush
new file mode 100644
index 0000000..7d62b8d
--- /dev/null
+++ b/tests/inet_socket/nftables-flush
@@ -0,0 +1,2 @@ 
+delete table ip security
+delete table ip6 security
diff --git a/tests/inet_socket/nftables-load b/tests/inet_socket/nftables-load
new file mode 100644
index 0000000..11ec382
--- /dev/null
+++ b/tests/inet_socket/nftables-load
@@ -0,0 +1,74 @@ 
+# Based on NFT project example. Requires kernel >= 4.20 and nft >= 0.9.3
+
+add table ip security
+add table ip6 security
+
+table ip security {
+
+	secmark inet_server {
+		"system_u:object_r:test_server_packet_t:s0"
+	}
+
+	map secmapping_in_out {
+		type inet_service : secmark
+		elements = { 65535 : "inet_server" }
+	}
+
+	chain input {
+		type filter hook input priority 0;
+
+		# label new incoming packets and add to connection
+		ct state new meta secmark set tcp dport map @secmapping_in_out
+		ct state new meta secmark set udp dport map @secmapping_in_out
+		ct state new ct secmark set meta secmark
+
+		# set label for est/rel packets from connection
+		ct state established,related meta secmark set ct secmark
+	}
+
+	chain output {
+		type filter hook output priority 0;
+
+		# label new outgoing packets and add to connection
+		ct state new meta secmark set tcp dport map @secmapping_in_out
+		# 'established' is used here so that the error return is the
+		# same as the 'iptables-load' tests (no reply from server)
+		ct state established meta secmark set udp dport map @secmapping_in_out
+		ct state new ct secmark set meta secmark
+
+		# set label for est/rel packets from connection
+		ct state established,related meta secmark set ct secmark
+	}
+}
+
+table ip6 security {
+
+	secmark inet_server {
+		"system_u:object_r:test_server_packet_t:s0"
+	}
+
+	map secmapping_in_out {
+		type inet_service : secmark
+		elements = { 65535 : "inet_server" }
+	}
+
+	chain input {
+		type filter hook input priority 0;
+
+		ct state new meta secmark set tcp dport map @secmapping_in_out
+		ct state new meta secmark set udp dport map @secmapping_in_out
+		ct state new ct secmark set meta secmark
+
+		ct state established,related meta secmark set ct secmark
+	}
+
+	chain output {
+		type filter hook output priority 0;
+
+		ct state new meta secmark set tcp dport map @secmapping_in_out
+		ct state established meta secmark set udp dport map @secmapping_in_out
+		ct state new ct secmark set meta secmark
+
+		ct state established,related meta secmark set ct secmark
+	}
+}
diff --git a/tests/inet_socket/test b/tests/inet_socket/test
index 47ce106..6c82719 100755
--- a/tests/inet_socket/test
+++ b/tests/inet_socket/test
@@ -27,6 +27,19 @@  BEGIN {
         $test_calipso_stream = 1;
     }
 
+    # Determine if nftables has secmark support and kernel >= 4.20
+    $test_nft = 0;
+
+    $rc = system("nft -c -f $basedir/nftables-load 2>/dev/null");
+    if ( $rc == 0 ) {
+        $kverminstream = "4.20";
+        $rc            = `$basedir/../kvercmp $kvercur $kverminstream`;
+        if ( $rc > 0 ) {
+            $test_count += 8;
+            $test_nft = 1;
+        }
+    }
+
     plan tests => $test_count;
 }
 
@@ -348,64 +361,76 @@  if ($test_ipsec) {
     system "/bin/sh $basedir/ipsec-flush";
 }
 
-# Load iptables (IPv4 & IPv6) configuration.
-system "/bin/sh $basedir/iptables-load";
+#
+################## Test iptables/nftables configuration ######################
+#
+sub test_tables {
 
-# Start the stream server.
-$pid = server_start( "-t test_inet_server_t", "-n stream 65535" );
+    # Start the stream server.
+    $pid = server_start( "-t test_inet_server_t", "-n stream 65535" );
 
-# Verify that authorized client can communicate with the server.
-$result = system
+    # Verify that authorized client can communicate with the server.
+    $result = system
 "runcon -t test_inet_client_t -- $basedir/client -e nopeer stream 127.0.0.1 65535";
-ok( $result eq 0 );
+    ok( $result eq 0 );
 
-# Verify that unauthorized client cannot communicate with the server.
-$result = system
+    # Verify that unauthorized client cannot communicate with the server.
+    $result = system
 "runcon -t test_inet_bad_client_t -- $basedir/client -e nopeer stream 127.0.0.1 65535 2>&1";
-ok( $result >> 8 eq 5 );
+    ok( $result >> 8 eq 5 );
 
-# Verify that authorized client can communicate with the server.
-$result = system
-  "runcon -t test_inet_client_t -- $basedir/client -e nopeer stream ::1 65535";
-ok( $result eq 0 );
+    # Verify that authorized client can communicate with the server.
+    $result = system
+"runcon -t test_inet_client_t -- $basedir/client -e nopeer stream ::1 65535";
+    ok( $result eq 0 );
 
-# Verify that unauthorized client cannot communicate with the server.
-$result = system
+    # Verify that unauthorized client cannot communicate with the server.
+    $result = system
 "runcon -t test_inet_bad_client_t -- $basedir/client -e nopeer stream ::1 65535 2>&1";
-ok( $result >> 8 eq 5 );
+    ok( $result >> 8 eq 5 );
 
-# Kill the server.
-server_end($pid);
+    # Kill the server.
+    server_end($pid);
 
-# Start the dgram server.
-$pid = server_start( "-t test_inet_server_t", "-n dgram 65535" );
+    # Start the dgram server.
+    $pid = server_start( "-t test_inet_server_t", "-n dgram 65535" );
 
-# Verify that authorized client can communicate with the server.
-$result = system
+    # Verify that authorized client can communicate with the server.
+    $result = system
 "runcon -t test_inet_client_t $basedir/client -e nopeer dgram 127.0.0.1 65535";
-ok( $result eq 0 );
+    ok( $result eq 0 );
 
-# Verify that unauthorized client cannot communicate with the server.
-$result = system
+    # Verify that unauthorized client cannot communicate with the server.
+    $result = system
 "runcon -t test_inet_bad_client_t -- $basedir/client -e nopeer dgram 127.0.0.1 65535 2>&1";
-ok( $result >> 8 eq 8 );
+    ok( $result >> 8 eq 8 );
 
-# Verify that authorized client can communicate with the server.
-$result = system
-  "runcon -t test_inet_client_t $basedir/client -e nopeer dgram ::1 65535";
-ok( $result eq 0 );
+    # Verify that authorized client can communicate with the server.
+    $result = system
+      "runcon -t test_inet_client_t $basedir/client -e nopeer dgram ::1 65535";
+    ok( $result eq 0 );
 
-# Verify that unauthorized client cannot communicate with the server.
-$result = system
+    # Verify that unauthorized client cannot communicate with the server.
+    $result = system
 "runcon -t test_inet_bad_client_t -- $basedir/client -e nopeer dgram ::1 65535 2>&1";
-ok( $result >> 8 eq 8 );
+    ok( $result >> 8 eq 8 );
 
-# Kill the server.
-server_end($pid);
+    # Kill the server.
+    server_end($pid);
+}
 
-# Flush iptables configuration.
+print "Testing iptables (IPv4/IPv6).\n";
+system "/bin/sh $basedir/iptables-load";
+test_tables();
 system "/bin/sh $basedir/iptables-flush";
 
+if ($test_nft) {
+    print "Testing nftables (IPv4/IPv6).\n";
+    system "nft -f $basedir/nftables-load";
+    test_tables();
+    system "nft -f $basedir/nftables-flush";
+}
+
 if ($test_calipso_stream) {
 
     # Load NetLabel configuration for CALIPSO/IPv6 labeling over loopback.
diff --git a/tests/sctp/nftables-flush b/tests/sctp/nftables-flush
new file mode 100644
index 0000000..7d62b8d
--- /dev/null
+++ b/tests/sctp/nftables-flush
@@ -0,0 +1,2 @@ 
+delete table ip security
+delete table ip6 security
diff --git a/tests/sctp/nftables-load b/tests/sctp/nftables-load
new file mode 100644
index 0000000..2cac3bb
--- /dev/null
+++ b/tests/sctp/nftables-load
@@ -0,0 +1,68 @@ 
+# Based on NFT project example. Requires kernel >= 4.20 and nft >= 0.9.3
+
+add table ip security
+add table ip6 security
+
+table ip security {
+
+	secmark sctp_server {
+		"system_u:object_r:test_sctp_server_packet_t:s0"
+	}
+
+	map secmapping_in_out {
+		type inet_service : secmark
+		elements = { 1035 : "sctp_server" }
+	}
+
+	chain input {
+		type filter hook input priority 0;
+
+		# label new incoming packets and add to connection
+		ct state new meta secmark set sctp dport map @secmapping_in_out
+		ct state new ct secmark set meta secmark
+
+		# set label for est/rel packets from connection
+		ct state established,related meta secmark set ct secmark
+	}
+
+	chain output {
+		type filter hook output priority 0;
+
+		# label new outgoing packets and add to connection
+		ct state new meta secmark set sctp dport map @secmapping_in_out
+		ct state new ct secmark set meta secmark
+
+		# set label for est/rel packets from connection
+		ct state established,related meta secmark set ct secmark
+	}
+}
+
+table ip6 security {
+
+	secmark sctp_server {
+		"system_u:object_r:test_sctp_server_packet_t:s0"
+	}
+
+	map secmapping_in_out {
+		type inet_service : secmark
+		elements = { 1035 : "sctp_server" }
+	}
+
+	chain input {
+		type filter hook input priority 0;
+
+		ct state new meta secmark set sctp dport map @secmapping_in_out
+		ct state new ct secmark set meta secmark
+
+		ct state established,related meta secmark set ct secmark
+	}
+
+	chain output {
+		type filter hook output priority 0;
+
+		ct state new meta secmark set sctp dport map @secmapping_in_out
+		ct state new ct secmark set meta secmark
+
+		ct state established,related meta secmark set ct secmark
+	}
+}
diff --git a/tests/sctp/test b/tests/sctp/test
index 6631da4..fa401fb 100755
--- a/tests/sctp/test
+++ b/tests/sctp/test
@@ -56,6 +56,19 @@  BEGIN {
             $test_calipso = 1;
         }
 
+        # Determine if nftables has secmark support and kernel >= 4.20
+        $test_nft = 0;
+
+        $rc = system("nft -c -f $basedir/nftables-load 2>/dev/null");
+        if ( $rc == 0 ) {
+            $kverminstream = "4.20";
+            $rc            = `$basedir/../kvercmp $kvercur $kverminstream`;
+            if ( $rc > 0 ) {
+                $test_count += 8;
+                $test_nft = 1;
+            }
+        }
+
         plan tests => $test_count;
     }
 }
@@ -749,64 +762,75 @@  if ($test_calipso) {
 }
 
 #
-##################### Test iptables configuration ############################
+################## Test iptables/nftables configuration ######################
 #
-print "# Testing iptables (IPv4/IPv6).\n";
-system "/bin/sh $basedir/iptables-load";
+sub test_tables {
 
-# Start the stream server.
-$pid =
-  server_start( "-t test_sctp_server_t", "sctp_server", "$v -n stream 1035" );
+    # Start the stream server.
+    $pid = server_start( "-t test_sctp_server_t",
+        "sctp_server", "$v -n stream 1035" );
 
-# Verify that authorized client can communicate with the server STREAM->STREAM.
-$result = system
+ # Verify that authorized client can communicate with the server STREAM->STREAM.
+    $result = system
 "runcon -t test_sctp_client_t $basedir/sctp_client $v -e nopeer stream 127.0.0.1 1035";
-ok( $result eq 0 );
+    ok( $result eq 0 );
 
 # Verify that a client without peer { recv } permission cannot communicate with the server STREAM->STREAM.
-$result = system
+    $result = system
 "runcon -t test_sctp_deny_peer_client_t -- $basedir/sctp_client $v -e nopeer stream 127.0.0.1 1035 2>&1";
-ok( $result >> 8 eq 6 );
+    ok( $result >> 8 eq 6 );
 
-# Verify that authorized client can communicate with the server STREAM->STREAM.
-$result = system
+ # Verify that authorized client can communicate with the server STREAM->STREAM.
+    $result = system
 "runcon -t test_sctp_client_t $basedir/sctp_client $v -e nopeer stream ::1 1035";
-ok( $result eq 0 );
+    ok( $result eq 0 );
 
 # Verify that a client without peer { recv } permission cannot communicate with the server STREAM->STREAM.
-$result = system
+    $result = system
 "runcon -t test_sctp_deny_peer_client_t -- $basedir/sctp_client $v -e nopeer stream ::1 1035 2>&1";
-ok( $result >> 8 eq 6 );
+    ok( $result >> 8 eq 6 );
 
-# Kill the stream server.
-server_end($pid);
+    # Kill the stream server.
+    server_end($pid);
 
-# Start the seq server.
-$pid = server_start( "-t test_sctp_server_t", "sctp_server", "$v -n seq 1035" );
+    # Start the seq server.
+    $pid =
+      server_start( "-t test_sctp_server_t", "sctp_server", "$v -n seq 1035" );
 
-# Verify that authorized client can communicate with the server SEQ->SEQ.
-$result = system
+    # Verify that authorized client can communicate with the server SEQ->SEQ.
+    $result = system
 "runcon -t test_sctp_client_t $basedir/sctp_client $v -e nopeer seq 127.0.0.1 1035";
-ok( $result eq 0 );
+    ok( $result eq 0 );
 
 # Verify that a client without peer { recv } permission cannot communicate with the server SEQ->SEQ.
-$result = system
+    $result = system
 "runcon -t test_sctp_deny_peer_client_t -- $basedir/sctp_client $v -e nopeer seq 127.0.0.1 1035 2>&1";
-ok( $result >> 8 eq 6 );
+    ok( $result >> 8 eq 6 );
 
-# Verify that authorized client can communicate with the server SEQ->SEQ.
-$result = system
-  "runcon -t test_sctp_client_t $basedir/sctp_client $v -e nopeer seq ::1 1035";
-ok( $result eq 0 );
+    # Verify that authorized client can communicate with the server SEQ->SEQ.
+    $result = system
+"runcon -t test_sctp_client_t $basedir/sctp_client $v -e nopeer seq ::1 1035";
+    ok( $result eq 0 );
 
 # Verify that a client without peer { recv } permission cannot communicate with the server SEQ->SEQ.
-$result = system
+    $result = system
 "runcon -t test_sctp_deny_peer_client_t -- $basedir/sctp_client $v -e nopeer seq ::1 1035 2>&1";
-ok( $result >> 8 eq 6 );
+    ok( $result >> 8 eq 6 );
 
-# Kill the seq server.
-server_end($pid);
+    # Kill the seq server.
+    server_end($pid);
+}
 
+print "# Testing iptables (IPv4/IPv6).\n";
+system "/bin/sh $basedir/iptables-load";
+test_tables();
 system "/bin/sh $basedir/iptables-flush";
 
+if ($test_nft) {
+    print "# Testing nftables (IPv4/IPv6).\n";
+    system "nft -f $basedir/nftables-load";
+    test_tables();
+    system "nft -f $basedir/nftables-flush";
+}
+
 exit;