github.com/xuyutom/docker@v1.6.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{
    43  		"!", "-i", filterChain.Bridge,
    44  		"-d", ip.String(),
    45  		"-p", proto,
    46  		"--dport", strconv.Itoa(port),
    47  		"-j", "DNAT",
    48  		"--to-destination", dstAddr + ":" + strconv.Itoa(dstPort),
    49  	}
    50  
    51  	if !Exists(natChain.Table, natChain.Name, dnatRule...) {
    52  		t.Fatalf("DNAT rule does not exist")
    53  	}
    54  
    55  	filterRule := []string{
    56  		"!", "-i", filterChain.Bridge,
    57  		"-o", filterChain.Bridge,
    58  		"-d", dstAddr,
    59  		"-p", proto,
    60  		"--dport", strconv.Itoa(dstPort),
    61  		"-j", "ACCEPT",
    62  	}
    63  
    64  	if !Exists(filterChain.Table, filterChain.Name, filterRule...) {
    65  		t.Fatalf("filter rule does not exist")
    66  	}
    67  
    68  	masqRule := []string{
    69  		"-d", dstAddr,
    70  		"-s", dstAddr,
    71  		"-p", proto,
    72  		"--dport", strconv.Itoa(dstPort),
    73  		"-j", "MASQUERADE",
    74  	}
    75  
    76  	if !Exists(natChain.Table, "POSTROUTING", masqRule...) {
    77  		t.Fatalf("MASQUERADE rule does not exist")
    78  	}
    79  }
    80  
    81  func TestLink(t *testing.T) {
    82  	var err error
    83  
    84  	ip1 := net.ParseIP("192.168.1.1")
    85  	ip2 := net.ParseIP("192.168.1.2")
    86  	port := 1234
    87  	proto := "tcp"
    88  
    89  	err = filterChain.Link(Append, ip1, ip2, port, proto)
    90  	if err != nil {
    91  		t.Fatal(err)
    92  	}
    93  
    94  	rule1 := []string{
    95  		"-i", filterChain.Bridge,
    96  		"-o", filterChain.Bridge,
    97  		"-p", proto,
    98  		"-s", ip1.String(),
    99  		"-d", ip2.String(),
   100  		"--dport", strconv.Itoa(port),
   101  		"-j", "ACCEPT"}
   102  
   103  	if !Exists(filterChain.Table, filterChain.Name, rule1...) {
   104  		t.Fatalf("rule1 does not exist")
   105  	}
   106  
   107  	rule2 := []string{
   108  		"-i", filterChain.Bridge,
   109  		"-o", filterChain.Bridge,
   110  		"-p", proto,
   111  		"-s", ip2.String(),
   112  		"-d", ip1.String(),
   113  		"--sport", strconv.Itoa(port),
   114  		"-j", "ACCEPT"}
   115  
   116  	if !Exists(filterChain.Table, filterChain.Name, rule2...) {
   117  		t.Fatalf("rule2 does not exist")
   118  	}
   119  }
   120  
   121  func TestPrerouting(t *testing.T) {
   122  	args := []string{
   123  		"-i", "lo",
   124  		"-d", "192.168.1.1"}
   125  
   126  	err := natChain.Prerouting(Insert, args...)
   127  	if err != nil {
   128  		t.Fatal(err)
   129  	}
   130  
   131  	rule := []string{
   132  		"-j", natChain.Name}
   133  
   134  	rule = append(rule, args...)
   135  
   136  	if !Exists(natChain.Table, "PREROUTING", rule...) {
   137  		t.Fatalf("rule does not exist")
   138  	}
   139  
   140  	delRule := append([]string{"-D", "PREROUTING", "-t", string(Nat)}, rule...)
   141  	if _, err = Raw(delRule...); err != nil {
   142  		t.Fatal(err)
   143  	}
   144  }
   145  
   146  func TestOutput(t *testing.T) {
   147  	args := []string{
   148  		"-o", "lo",
   149  		"-d", "192.168.1.1"}
   150  
   151  	err := natChain.Output(Insert, args...)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	rule := []string{
   157  		"-j", natChain.Name}
   158  
   159  	rule = append(rule, args...)
   160  
   161  	if !Exists(natChain.Table, "OUTPUT", rule...) {
   162  		t.Fatalf("rule does not exist")
   163  	}
   164  
   165  	delRule := append([]string{"-D", "OUTPUT", "-t",
   166  		string(natChain.Table)}, rule...)
   167  	if _, err = Raw(delRule...); err != nil {
   168  		t.Fatal(err)
   169  	}
   170  }
   171  
   172  func TestCleanup(t *testing.T) {
   173  	var err error
   174  	var rules []byte
   175  
   176  	// Cleanup filter/FORWARD first otherwise output of iptables-save is dirty
   177  	link := []string{"-t", string(filterChain.Table),
   178  		string(Delete), "FORWARD",
   179  		"-o", filterChain.Bridge,
   180  		"-j", filterChain.Name}
   181  	if _, err = Raw(link...); err != nil {
   182  		t.Fatal(err)
   183  	}
   184  	filterChain.Remove()
   185  
   186  	err = RemoveExistingChain(chainName, Nat)
   187  	if err != nil {
   188  		t.Fatal(err)
   189  	}
   190  
   191  	rules, err = exec.Command("iptables-save").Output()
   192  	if err != nil {
   193  		t.Fatal(err)
   194  	}
   195  	if strings.Contains(string(rules), chainName) {
   196  		t.Fatalf("Removing chain failed. %s found in iptables-save", chainName)
   197  	}
   198  }