iptables_test.go 3.8 KB

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