github.com/dougm/docker@v1.5.0/pkg/iptables/iptables_test.go (about)

     1  package iptables
     2  
     3  import (
     4  	"net"
     5  	"os/exec"
     6  	"strconv"
     7  	"strings"
     8  	"testing"
     9  )
    10  
    11  const chainName = "DOCKERTEST"
    12  
    13  var natChain *Chain
    14  var filterChain *Chain
    15  
    16  func TestNewChain(t *testing.T) {
    17  	var err error
    18  
    19  	natChain, err = NewChain(chainName, "lo", Nat)
    20  	if err != nil {
    21  		t.Fatal(err)
    22  	}
    23  
    24  	filterChain, err = NewChain(chainName, "lo", Filter)
    25  	if err != nil {
    26  		t.Fatal(err)
    27  	}
    28  }
    29  
    30  func TestForward(t *testing.T) {
    31  	ip := net.ParseIP("192.168.1.1")
    32  	port := 1234
    33  	dstAddr := "172.17.0.1"
    34  	dstPort := 4321
    35  	proto := "tcp"
    36  
    37  	err := natChain.Forward(Insert, ip, port, proto, dstAddr, dstPort)
    38  	if err != nil {
    39  		t.Fatal(err)
    40  	}
    41  
    42  	dnatRule := []string{natChain.Name,
    43  		"-t", string(natChain.Table),
    44  		"!", "-i", filterChain.Bridge,
    45  		"-d", ip.String(),
    46  		"-p", proto,
    47  		"--dport", strconv.Itoa(port),
    48  		"-j", "DNAT",
    49  		"--to-destination", dstAddr + ":" + strconv.Itoa(dstPort),
    50  	}
    51  
    52  	if !Exists(dnatRule...) {
    53  		t.Fatalf("DNAT rule does not exist")
    54  	}
    55  
    56  	filterRule := []string{filterChain.Name,
    57  		"-t", string(filterChain.Table),
    58  		"!", "-i", filterChain.Bridge,
    59  		"-o", filterChain.Bridge,
    60  		"-d", dstAddr,
    61  		"-p", proto,
    62  		"--dport", strconv.Itoa(dstPort),
    63  		"-j", "ACCEPT",
    64  	}
    65  
    66  	if !Exists(filterRule...) {
    67  		t.Fatalf("filter rule does not exist")
    68  	}
    69  
    70  	masqRule := []string{"POSTROUTING",
    71  		"-t", string(natChain.Table),
    72  		"-d", dstAddr,
    73  		"-s", dstAddr,
    74  		"-p", proto,
    75  		"--dport", strconv.Itoa(dstPort),
    76  		"-j", "MASQUERADE",
    77  	}
    78  
    79  	if !Exists(masqRule...) {
    80  		t.Fatalf("MASQUERADE rule does not exist")
    81  	}
    82  }
    83  
    84  func TestLink(t *testing.T) {
    85  	var err error
    86  
    87  	ip1 := net.ParseIP("192.168.1.1")
    88  	ip2 := net.ParseIP("192.168.1.2")
    89  	port := 1234
    90  	proto := "tcp"
    91  
    92  	err = filterChain.Link(Append, ip1, ip2, port, proto)
    93  	if err != nil {
    94  		t.Fatal(err)
    95  	}
    96  
    97  	rule1 := []string{filterChain.Name,
    98  		"-t", string(filterChain.Table),
    99  		"-i", filterChain.Bridge,
   100  		"-o", filterChain.Bridge,
   101  		"-p", proto,
   102  		"-s", ip1.String(),
   103  		"-d", ip2.String(),
   104  		"--dport", strconv.Itoa(port),
   105  		"-j", "ACCEPT"}
   106  
   107  	if !Exists(rule1...) {
   108  		t.Fatalf("rule1 does not exist")
   109  	}
   110  
   111  	rule2 := []string{filterChain.Name,
   112  		"-t", string(filterChain.Table),
   113  		"-i", filterChain.Bridge,
   114  		"-o", filterChain.Bridge,
   115  		"-p", proto,
   116  		"-s", ip2.String(),
   117  		"-d", ip1.String(),
   118  		"--sport", strconv.Itoa(port),
   119  		"-j", "ACCEPT"}
   120  
   121  	if !Exists(rule2...) {
   122  		t.Fatalf("rule2 does not exist")
   123  	}
   124  }
   125  
   126  func TestPrerouting(t *testing.T) {
   127  	args := []string{
   128  		"-i", "lo",
   129  		"-d", "192.168.1.1"}
   130  
   131  	err := natChain.Prerouting(Insert, args...)
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  
   136  	rule := []string{"PREROUTING",
   137  		"-t", string(Nat),
   138  		"-j", natChain.Name}
   139  
   140  	rule = append(rule, args...)
   141  
   142  	if !Exists(rule...) {
   143  		t.Fatalf("rule does not exist")
   144  	}
   145  
   146  	delRule := append([]string{"-D"}, rule...)
   147  	if _, err = Raw(delRule...); err != nil {
   148  		t.Fatal(err)
   149  	}
   150  }
   151  
   152  func TestOutput(t *testing.T) {
   153  	args := []string{
   154  		"-o", "lo",
   155  		"-d", "192.168.1.1"}
   156  
   157  	err := natChain.Output(Insert, args...)
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  
   162  	rule := []string{"OUTPUT",
   163  		"-t", string(natChain.Table),
   164  		"-j", natChain.Name}
   165  
   166  	rule = append(rule, args...)
   167  
   168  	if !Exists(rule...) {
   169  		t.Fatalf("rule does not exist")
   170  	}
   171  
   172  	delRule := append([]string{"-D"}, rule...)
   173  	if _, err = Raw(delRule...); err != nil {
   174  		t.Fatal(err)
   175  	}
   176  }
   177  
   178  func TestCleanup(t *testing.T) {
   179  	var err error
   180  	var rules []byte
   181  
   182  	// Cleanup filter/FORWARD first otherwise output of iptables-save is dirty
   183  	link := []string{"-t", string(filterChain.Table),
   184  		string(Delete), "FORWARD",
   185  		"-o", filterChain.Bridge,
   186  		"-j", filterChain.Name}
   187  	if _, err = Raw(link...); err != nil {
   188  		t.Fatal(err)
   189  	}
   190  	filterChain.Remove()
   191  
   192  	err = RemoveExistingChain(chainName, Nat)
   193  	if err != nil {
   194  		t.Fatal(err)
   195  	}
   196  
   197  	rules, err = exec.Command("iptables-save").Output()
   198  	if err != nil {
   199  		t.Fatal(err)
   200  	}
   201  	if strings.Contains(string(rules), chainName) {
   202  		t.Fatalf("Removing chain failed. %s found in iptables-save", chainName)
   203  	}
   204  }