summaryrefslogtreecommitdiffhomepage
path: root/test/iptables
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2020-02-07 11:21:07 -0800
committerKevin Krakauer <krakauer@google.com>2020-02-12 15:02:47 -0800
commit6fdf2c53a1d084b70602170b660242036fd8fe4f (patch)
treed9de9c93d474529c7fb71d07f143545c860c3836 /test/iptables
parent0dd9ee0d1e08d4207f78ab032a5fde171343c4b4 (diff)
iptables: User chains
- Adds creation of user chains via `-N <chainname>` - Adds `-j RETURN` support for built-in chains, which triggers the chain's underflow rule (usually the default policy). - Adds tests for chain creation, default policies, and `-j RETURN' from built-in chains.
Diffstat (limited to 'test/iptables')
-rw-r--r--test/iptables/filter_input.go117
-rw-r--r--test/iptables/iptables_test.go24
2 files changed, 140 insertions, 1 deletions
diff --git a/test/iptables/filter_input.go b/test/iptables/filter_input.go
index bd6059921..e26d6a7d2 100644
--- a/test/iptables/filter_input.go
+++ b/test/iptables/filter_input.go
@@ -36,6 +36,10 @@ func init() {
RegisterTestCase(FilterInputDropTCPSrcPort{})
RegisterTestCase(FilterInputDropUDPPort{})
RegisterTestCase(FilterInputDropUDP{})
+ RegisterTestCase(FilterInputCreateUserChain{})
+ RegisterTestCase(FilterInputDefaultPolicyAccept{})
+ RegisterTestCase(FilterInputDefaultPolicyDrop{})
+ RegisterTestCase(FilterInputReturnUnderflow{})
}
// FilterInputDropUDP tests that we can drop UDP traffic.
@@ -295,8 +299,119 @@ func (FilterInputRequireProtocolUDP) ContainerAction(ip net.IP) error {
return nil
}
-// LocalAction implements TestCase.LocalAction.
func (FilterInputRequireProtocolUDP) LocalAction(ip net.IP) error {
// No-op.
return nil
}
+
+// FilterInputCreateUserChain tests chain creation.
+type FilterInputCreateUserChain struct{}
+
+// Name implements TestCase.Name.
+func (FilterInputCreateUserChain) Name() string {
+ return "FilterInputCreateUserChain"
+}
+
+// ContainerAction implements TestCase.ContainerAction.
+func (FilterInputCreateUserChain) ContainerAction(ip net.IP) error {
+ // Create a chain.
+ const chainName = "foochain"
+ if err := filterTable("-N", chainName); err != nil {
+ return err
+ }
+
+ // Add a simple rule to the chain.
+ return filterTable("-A", chainName, "-j", "DROP")
+}
+
+// LocalAction implements TestCase.LocalAction.
+func (FilterInputCreateUserChain) LocalAction(ip net.IP) error {
+ // No-op.
+ return nil
+}
+
+// FilterInputDefaultPolicyAccept tests the default ACCEPT policy.
+type FilterInputDefaultPolicyAccept struct{}
+
+// Name implements TestCase.Name.
+func (FilterInputDefaultPolicyAccept) Name() string {
+ return "FilterInputDefaultPolicyAccept"
+}
+
+// ContainerAction implements TestCase.ContainerAction.
+func (FilterInputDefaultPolicyAccept) ContainerAction(ip net.IP) error {
+ // Set the default policy to accept, then receive a packet.
+ if err := filterTable("-P", "INPUT", "ACCEPT"); err != nil {
+ return err
+ }
+ return listenUDP(acceptPort, sendloopDuration)
+}
+
+// LocalAction implements TestCase.LocalAction.
+func (FilterInputDefaultPolicyAccept) LocalAction(ip net.IP) error {
+ return sendUDPLoop(ip, acceptPort, sendloopDuration)
+}
+
+// FilterInputDefaultPolicyDrop tests the default DROP policy.
+type FilterInputDefaultPolicyDrop struct{}
+
+// Name implements TestCase.Name.
+func (FilterInputDefaultPolicyDrop) Name() string {
+ return "FilterInputDefaultPolicyDrop"
+}
+
+// ContainerAction implements TestCase.ContainerAction.
+func (FilterInputDefaultPolicyDrop) ContainerAction(ip net.IP) error {
+ if err := filterTable("-P", "INPUT", "DROP"); err != nil {
+ return err
+ }
+
+ // Listen for UDP packets on dropPort.
+ if err := listenUDP(dropPort, sendloopDuration); err == nil {
+ return fmt.Errorf("packets on port %d should have been dropped, but got a packet", dropPort)
+ } else if netErr, ok := err.(net.Error); !ok || !netErr.Timeout() {
+ return fmt.Errorf("error reading: %v", err)
+ }
+
+ // At this point we know that reading timed out and never received a
+ // packet.
+ return nil
+}
+
+// LocalAction implements TestCase.LocalAction.
+func (FilterInputDefaultPolicyDrop) LocalAction(ip net.IP) error {
+ return sendUDPLoop(ip, acceptPort, sendloopDuration)
+}
+
+// FilterInputReturnUnderflow tests that -j RETURN in a built-in chain causes
+// the underflow rule (i.e. default policy) to be executed.
+type FilterInputReturnUnderflow struct{}
+
+// Name implements TestCase.Name.
+func (FilterInputReturnUnderflow) Name() string {
+ return "FilterInputReturnUnderflow"
+}
+
+// ContainerAction implements TestCase.ContainerAction.
+func (FilterInputReturnUnderflow) ContainerAction(ip net.IP) error {
+ // Add a RETURN rule followed by an unconditional accept, and set the
+ // default policy to DROP.
+ if err := filterTable("-A", "INPUT", "-j", "RETURN"); err != nil {
+ return err
+ }
+ if err := filterTable("-A", "INPUT", "-j", "DROP"); err != nil {
+ return err
+ }
+ if err := filterTable("-P", "INPUT", "ACCEPT"); err != nil {
+ return err
+ }
+
+ // We should receive packets, as the RETURN rule will trigger the default
+ // ACCEPT policy.
+ return listenUDP(acceptPort, sendloopDuration)
+}
+
+// LocalAction implements TestCase.LocalAction.
+func (FilterInputReturnUnderflow) LocalAction(ip net.IP) error {
+ return sendUDPLoop(ip, acceptPort, sendloopDuration)
+}
diff --git a/test/iptables/iptables_test.go b/test/iptables/iptables_test.go
index 41909582a..46a7c99b0 100644
--- a/test/iptables/iptables_test.go
+++ b/test/iptables/iptables_test.go
@@ -214,6 +214,30 @@ func TestFilterInputDropTCPSrcPort(t *testing.T) {
}
}
+func TestFilterInputCreateUserChain(t *testing.T) {
+ if err := singleTest(FilterInputCreateUserChain{}); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestFilterInputDefaultPolicyAccept(t *testing.T) {
+ if err := singleTest(FilterInputDefaultPolicyAccept{}); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestFilterInputDefaultPolicyDrop(t *testing.T) {
+ if err := singleTest(FilterInputDefaultPolicyDrop{}); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestFilterInputReturnUnderflow(t *testing.T) {
+ if err := singleTest(FilterInputReturnUnderflow{}); err != nil {
+ t.Fatal(err)
+ }
+}
+
func TestFilterOutputDropTCPDestPort(t *testing.T) {
if err := singleTest(FilterOutputDropTCPDestPort{}); err != nil {
t.Fatal(err)