summaryrefslogtreecommitdiffhomepage
path: root/test/iptables/nat.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/iptables/nat.go')
-rw-r--r--test/iptables/nat.go491
1 files changed, 0 insertions, 491 deletions
diff --git a/test/iptables/nat.go b/test/iptables/nat.go
deleted file mode 100644
index 149dec2bb..000000000
--- a/test/iptables/nat.go
+++ /dev/null
@@ -1,491 +0,0 @@
-// Copyright 2020 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package iptables
-
-import (
- "errors"
- "fmt"
- "net"
- "time"
-)
-
-const (
- redirectPort = 42
-)
-
-func init() {
- RegisterTestCase(NATPreRedirectUDPPort{})
- RegisterTestCase(NATPreRedirectTCPPort{})
- RegisterTestCase(NATPreRedirectTCPOutgoing{})
- RegisterTestCase(NATOutRedirectTCPIncoming{})
- RegisterTestCase(NATOutRedirectUDPPort{})
- RegisterTestCase(NATOutRedirectTCPPort{})
- RegisterTestCase(NATDropUDP{})
- RegisterTestCase(NATAcceptAll{})
- RegisterTestCase(NATPreRedirectIP{})
- RegisterTestCase(NATPreDontRedirectIP{})
- RegisterTestCase(NATPreRedirectInvert{})
- RegisterTestCase(NATOutRedirectIP{})
- RegisterTestCase(NATOutDontRedirectIP{})
- RegisterTestCase(NATOutRedirectInvert{})
- RegisterTestCase(NATRedirectRequiresProtocol{})
- RegisterTestCase(NATLoopbackSkipsPrerouting{})
-}
-
-// NATPreRedirectUDPPort tests that packets are redirected to different port.
-type NATPreRedirectUDPPort struct{}
-
-// Name implements TestCase.Name.
-func (NATPreRedirectUDPPort) Name() string {
- return "NATPreRedirectUDPPort"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATPreRedirectUDPPort) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "PREROUTING", "-p", "udp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", redirectPort)); err != nil {
- return err
- }
-
- if err := listenUDP(redirectPort, sendloopDuration); err != nil {
- return fmt.Errorf("packets on port %d should be allowed, but encountered an error: %v", redirectPort, err)
- }
-
- return nil
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATPreRedirectUDPPort) LocalAction(ip net.IP) error {
- return sendUDPLoop(ip, acceptPort, sendloopDuration)
-}
-
-// NATPreRedirectTCPPort tests that connections are redirected on specified ports.
-type NATPreRedirectTCPPort struct{}
-
-// Name implements TestCase.Name.
-func (NATPreRedirectTCPPort) Name() string {
- return "NATPreRedirectTCPPort"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATPreRedirectTCPPort) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "PREROUTING", "-p", "tcp", "-m", "tcp", "--dport", fmt.Sprintf("%d", dropPort), "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", acceptPort)); err != nil {
- return err
- }
-
- // Listen for TCP packets on redirect port.
- return listenTCP(acceptPort, sendloopDuration)
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATPreRedirectTCPPort) LocalAction(ip net.IP) error {
- return connectTCP(ip, dropPort, sendloopDuration)
-}
-
-// NATPreRedirectTCPOutgoing verifies that outgoing TCP connections aren't
-// affected by PREROUTING connection tracking.
-type NATPreRedirectTCPOutgoing struct{}
-
-// Name implements TestCase.Name.
-func (NATPreRedirectTCPOutgoing) Name() string {
- return "NATPreRedirectTCPOutgoing"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATPreRedirectTCPOutgoing) ContainerAction(ip net.IP) error {
- // Redirect all incoming TCP traffic to a closed port.
- if err := natTable("-A", "PREROUTING", "-p", "tcp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", dropPort)); err != nil {
- return err
- }
-
- // Establish a connection to the host process.
- return connectTCP(ip, acceptPort, sendloopDuration)
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATPreRedirectTCPOutgoing) LocalAction(ip net.IP) error {
- return listenTCP(acceptPort, sendloopDuration)
-}
-
-// NATOutRedirectTCPIncoming verifies that incoming TCP connections aren't
-// affected by OUTPUT connection tracking.
-type NATOutRedirectTCPIncoming struct{}
-
-// Name implements TestCase.Name.
-func (NATOutRedirectTCPIncoming) Name() string {
- return "NATOutRedirectTCPIncoming"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATOutRedirectTCPIncoming) ContainerAction(ip net.IP) error {
- // Redirect all outgoing TCP traffic to a closed port.
- if err := natTable("-A", "OUTPUT", "-p", "tcp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", dropPort)); err != nil {
- return err
- }
-
- // Establish a connection to the host process.
- return listenTCP(acceptPort, sendloopDuration)
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATOutRedirectTCPIncoming) LocalAction(ip net.IP) error {
- return connectTCP(ip, acceptPort, sendloopDuration)
-}
-
-// NATOutRedirectUDPPort tests that packets are redirected to different port.
-type NATOutRedirectUDPPort struct{}
-
-// Name implements TestCase.Name.
-func (NATOutRedirectUDPPort) Name() string {
- return "NATOutRedirectUDPPort"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATOutRedirectUDPPort) ContainerAction(ip net.IP) error {
- dest := []byte{200, 0, 0, 1}
- return loopbackTest(dest, "-A", "OUTPUT", "-p", "udp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", acceptPort))
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATOutRedirectUDPPort) LocalAction(ip net.IP) error {
- // No-op.
- return nil
-}
-
-// NATDropUDP tests that packets are not received in ports other than redirect
-// port.
-type NATDropUDP struct{}
-
-// Name implements TestCase.Name.
-func (NATDropUDP) Name() string {
- return "NATDropUDP"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATDropUDP) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "PREROUTING", "-p", "udp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", redirectPort)); err != nil {
- return err
- }
-
- if err := listenUDP(acceptPort, sendloopDuration); err == nil {
- return fmt.Errorf("packets on port %d should have been redirected to port %d", acceptPort, redirectPort)
- }
-
- return nil
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATDropUDP) LocalAction(ip net.IP) error {
- return sendUDPLoop(ip, acceptPort, sendloopDuration)
-}
-
-// NATAcceptAll tests that all UDP packets are accepted.
-type NATAcceptAll struct{}
-
-// Name implements TestCase.Name.
-func (NATAcceptAll) Name() string {
- return "NATAcceptAll"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATAcceptAll) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "PREROUTING", "-p", "udp", "-j", "ACCEPT"); err != nil {
- return err
- }
-
- if err := listenUDP(acceptPort, sendloopDuration); err != nil {
- return fmt.Errorf("packets on port %d should be allowed, but encountered an error: %v", acceptPort, err)
- }
-
- return nil
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATAcceptAll) LocalAction(ip net.IP) error {
- return sendUDPLoop(ip, acceptPort, sendloopDuration)
-}
-
-// NATOutRedirectIP uses iptables to select packets based on destination IP and
-// redirects them.
-type NATOutRedirectIP struct{}
-
-// Name implements TestCase.Name.
-func (NATOutRedirectIP) Name() string {
- return "NATOutRedirectIP"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATOutRedirectIP) ContainerAction(ip net.IP) error {
- // Redirect OUTPUT packets to a listening localhost port.
- dest := net.IP([]byte{200, 0, 0, 2})
- return loopbackTest(dest, "-A", "OUTPUT", "-d", dest.String(), "-p", "udp", "-j", "REDIRECT", "--to-port", fmt.Sprintf("%d", acceptPort))
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATOutRedirectIP) LocalAction(ip net.IP) error {
- // No-op.
- return nil
-}
-
-// NATOutDontRedirectIP tests that iptables matching with "-d" does not match
-// packets it shouldn't.
-type NATOutDontRedirectIP struct{}
-
-// Name implements TestCase.Name.
-func (NATOutDontRedirectIP) Name() string {
- return "NATOutDontRedirectIP"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATOutDontRedirectIP) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "OUTPUT", "-d", localIP, "-p", "udp", "-j", "REDIRECT", "--to-port", fmt.Sprintf("%d", dropPort)); err != nil {
- return err
- }
- return sendUDPLoop(ip, acceptPort, sendloopDuration)
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATOutDontRedirectIP) LocalAction(ip net.IP) error {
- return listenUDP(acceptPort, sendloopDuration)
-}
-
-// NATOutRedirectInvert tests that iptables can match with "! -d".
-type NATOutRedirectInvert struct{}
-
-// Name implements TestCase.Name.
-func (NATOutRedirectInvert) Name() string {
- return "NATOutRedirectInvert"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATOutRedirectInvert) ContainerAction(ip net.IP) error {
- // Redirect OUTPUT packets to a listening localhost port.
- dest := []byte{200, 0, 0, 3}
- destStr := "200.0.0.2"
- return loopbackTest(dest, "-A", "OUTPUT", "!", "-d", destStr, "-p", "udp", "-j", "REDIRECT", "--to-port", fmt.Sprintf("%d", acceptPort))
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATOutRedirectInvert) LocalAction(ip net.IP) error {
- // No-op.
- return nil
-}
-
-// NATPreRedirectIP tests that we can use iptables to select packets based on
-// destination IP and redirect them.
-type NATPreRedirectIP struct{}
-
-// Name implements TestCase.Name.
-func (NATPreRedirectIP) Name() string {
- return "NATPreRedirectIP"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATPreRedirectIP) ContainerAction(ip net.IP) error {
- addrs, err := localAddrs(false)
- if err != nil {
- return err
- }
-
- var rules [][]string
- for _, addr := range addrs {
- rules = append(rules, []string{"-A", "PREROUTING", "-p", "udp", "-d", addr, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", acceptPort)})
- }
- if err := natTableRules(rules); err != nil {
- return err
- }
- return listenUDP(acceptPort, sendloopDuration)
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATPreRedirectIP) LocalAction(ip net.IP) error {
- return sendUDPLoop(ip, dropPort, sendloopDuration)
-}
-
-// NATPreDontRedirectIP tests that iptables matching with "-d" does not match
-// packets it shouldn't.
-type NATPreDontRedirectIP struct{}
-
-// Name implements TestCase.Name.
-func (NATPreDontRedirectIP) Name() string {
- return "NATPreDontRedirectIP"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATPreDontRedirectIP) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "PREROUTING", "-p", "udp", "-d", localIP, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", dropPort)); err != nil {
- return err
- }
- return listenUDP(acceptPort, sendloopDuration)
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATPreDontRedirectIP) LocalAction(ip net.IP) error {
- return sendUDPLoop(ip, acceptPort, sendloopDuration)
-}
-
-// NATPreRedirectInvert tests that iptables can match with "! -d".
-type NATPreRedirectInvert struct{}
-
-// Name implements TestCase.Name.
-func (NATPreRedirectInvert) Name() string {
- return "NATPreRedirectInvert"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATPreRedirectInvert) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "PREROUTING", "-p", "udp", "!", "-d", localIP, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", acceptPort)); err != nil {
- return err
- }
- return listenUDP(acceptPort, sendloopDuration)
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATPreRedirectInvert) LocalAction(ip net.IP) error {
- return sendUDPLoop(ip, dropPort, sendloopDuration)
-}
-
-// NATRedirectRequiresProtocol tests that use of the --to-ports flag requires a
-// protocol to be specified with -p.
-type NATRedirectRequiresProtocol struct{}
-
-// Name implements TestCase.Name.
-func (NATRedirectRequiresProtocol) Name() string {
- return "NATRedirectRequiresProtocol"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATRedirectRequiresProtocol) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "PREROUTING", "-d", localIP, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", acceptPort)); err == nil {
- return errors.New("expected an error using REDIRECT --to-ports without a protocol")
- }
- return nil
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATRedirectRequiresProtocol) LocalAction(ip net.IP) error {
- // No-op.
- return nil
-}
-
-// NATOutRedirectTCPPort tests that connections are redirected on specified ports.
-type NATOutRedirectTCPPort struct{}
-
-// Name implements TestCase.Name.
-func (NATOutRedirectTCPPort) Name() string {
- return "NATOutRedirectTCPPort"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATOutRedirectTCPPort) ContainerAction(ip net.IP) error {
- if err := natTable("-A", "OUTPUT", "-p", "tcp", "-m", "tcp", "--dport", fmt.Sprintf("%d", dropPort), "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", acceptPort)); err != nil {
- return err
- }
-
- timeout := 20 * time.Second
- dest := []byte{127, 0, 0, 1}
- localAddr := net.TCPAddr{
- IP: dest,
- Port: acceptPort,
- }
-
- // Starts listening on port.
- lConn, err := net.ListenTCP("tcp", &localAddr)
- if err != nil {
- return err
- }
- defer lConn.Close()
-
- // Accept connections on port.
- lConn.SetDeadline(time.Now().Add(timeout))
- err = connectTCP(ip, dropPort, timeout)
- if err != nil {
- return err
- }
-
- conn, err := lConn.AcceptTCP()
- if err != nil {
- return err
- }
- conn.Close()
-
- return nil
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATOutRedirectTCPPort) LocalAction(ip net.IP) error {
- return nil
-}
-
-// NATLoopbackSkipsPrerouting tests that packets sent via loopback aren't
-// affected by PREROUTING rules.
-type NATLoopbackSkipsPrerouting struct{}
-
-// Name implements TestCase.Name.
-func (NATLoopbackSkipsPrerouting) Name() string {
- return "NATLoopbackSkipsPrerouting"
-}
-
-// ContainerAction implements TestCase.ContainerAction.
-func (NATLoopbackSkipsPrerouting) ContainerAction(ip net.IP) error {
- // Redirect anything sent to localhost to an unused port.
- dest := []byte{127, 0, 0, 1}
- if err := natTable("-A", "PREROUTING", "-p", "tcp", "-j", "REDIRECT", "--to-port", fmt.Sprintf("%d", dropPort)); err != nil {
- return err
- }
-
- // Establish a connection via localhost. If the PREROUTING rule did apply to
- // loopback traffic, the connection would fail.
- sendCh := make(chan error)
- go func() {
- sendCh <- connectTCP(dest, acceptPort, sendloopDuration)
- }()
-
- if err := listenTCP(acceptPort, sendloopDuration); err != nil {
- return err
- }
- return <-sendCh
-}
-
-// LocalAction implements TestCase.LocalAction.
-func (NATLoopbackSkipsPrerouting) LocalAction(ip net.IP) error {
- // No-op.
- return nil
-}
-
-// loopbackTests runs an iptables rule and ensures that packets sent to
-// dest:dropPort are received by localhost:acceptPort.
-func loopbackTest(dest net.IP, args ...string) error {
- if err := natTable(args...); err != nil {
- return err
- }
- sendCh := make(chan error)
- listenCh := make(chan error)
- go func() {
- sendCh <- sendUDPLoop(dest, dropPort, sendloopDuration)
- }()
- go func() {
- listenCh <- listenUDP(acceptPort, sendloopDuration)
- }()
- select {
- case err := <-listenCh:
- if err != nil {
- return err
- }
- case <-time.After(sendloopDuration):
- return errors.New("timed out")
- }
- // sendCh will always take the full sendloop time.
- return <-sendCh
-}