github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/network/iptables/iptables_test.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package iptables_test
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/core/network"
    14  	"github.com/juju/juju/core/network/firewall"
    15  	"github.com/juju/juju/network/iptables"
    16  )
    17  
    18  type IptablesSuite struct {
    19  	testing.IsolationSuite
    20  }
    21  
    22  var _ = gc.Suite(&IptablesSuite{})
    23  
    24  func (*IptablesSuite) TestDropCommand(c *gc.C) {
    25  	assertRender(c,
    26  		iptables.DropCommand{},
    27  		"sudo iptables -I INPUT -m state --state NEW -j DROP -m comment --comment 'juju internal'",
    28  	)
    29  	assertRender(c,
    30  		iptables.DropCommand{DestinationAddress: "1.2.3.4"},
    31  		"sudo iptables -I INPUT -m state --state NEW -j DROP -m comment --comment 'juju internal' -d 1.2.3.4",
    32  	)
    33  	assertRender(c,
    34  		iptables.DropCommand{Interface: "eth0"},
    35  		"sudo iptables -I INPUT -m state --state NEW -j DROP -m comment --comment 'juju internal' -i eth0",
    36  	)
    37  }
    38  
    39  func (*IptablesSuite) TestAcceptInternalPortCommand(c *gc.C) {
    40  	assertRender(c,
    41  		iptables.AcceptInternalCommand{},
    42  		"sudo iptables -I INPUT -j ACCEPT -m comment --comment 'juju internal'",
    43  	)
    44  	assertRender(c,
    45  		iptables.AcceptInternalCommand{
    46  			DestinationAddress: "1.2.3.4",
    47  			DestinationPort:    17070,
    48  			Protocol:           "tcp",
    49  		},
    50  		"sudo iptables -I INPUT -j ACCEPT -m comment --comment 'juju internal' -p tcp -d 1.2.3.4 --dport 17070",
    51  	)
    52  }
    53  
    54  func (*IptablesSuite) TestIngressRuleCommand(c *gc.C) {
    55  	assertRender(c,
    56  		iptables.IngressRuleCommand{
    57  			Rule: firewall.NewIngressRule(network.MustParsePortRange("icmp")),
    58  		},
    59  		"(sudo iptables -C INPUT -j ACCEPT -p icmp --icmp-type 8 -m comment --comment 'juju ingress') || "+
    60  			"(sudo iptables -I INPUT -j ACCEPT -p icmp --icmp-type 8 -m comment --comment 'juju ingress')",
    61  	)
    62  
    63  	// Same as above, but with "Delete: true". The only difference in
    64  	// output is that "-D" is specified in place of "-I".
    65  	assertRender(c,
    66  		iptables.IngressRuleCommand{
    67  			Rule:   firewall.NewIngressRule(network.MustParsePortRange("icmp")),
    68  			Delete: true,
    69  		},
    70  		"(sudo iptables -C INPUT -j ACCEPT -p icmp --icmp-type 8 -m comment --comment 'juju ingress') && "+
    71  			"(sudo iptables -D INPUT -j ACCEPT -p icmp --icmp-type 8 -m comment --comment 'juju ingress')",
    72  	)
    73  
    74  	// If SourceCIDRs is non-empty, then the CIDRs will be
    75  	// specified in the rule with "-s". Multiple CIDRs are
    76  	// joined with a comma.
    77  	assertRender(c,
    78  		iptables.IngressRuleCommand{
    79  			Rule: firewall.NewIngressRule(network.MustParsePortRange("icmp"), "1.2.3.4", "5.6.7.8"),
    80  		},
    81  		"(sudo iptables -C INPUT -j ACCEPT -p icmp --icmp-type 8 -s 1.2.3.4,5.6.7.8 -m comment --comment 'juju ingress') || "+
    82  			"(sudo iptables -I INPUT -j ACCEPT -p icmp --icmp-type 8 -s 1.2.3.4,5.6.7.8 -m comment --comment 'juju ingress')",
    83  	)
    84  
    85  	// UDP, single port.
    86  	assertRender(c,
    87  		iptables.IngressRuleCommand{
    88  			Rule: firewall.NewIngressRule(network.MustParsePortRange("53/udp")),
    89  		},
    90  		"(sudo iptables -C INPUT -j ACCEPT -p udp --dport 53 -m comment --comment 'juju ingress') || "+
    91  			"(sudo iptables -I INPUT -j ACCEPT -p udp --dport 53 -m comment --comment 'juju ingress')",
    92  	)
    93  
    94  	// TCP, port range.
    95  	assertRender(c,
    96  		iptables.IngressRuleCommand{
    97  			Rule: firewall.NewIngressRule(network.MustParsePortRange("6001-6007/tcp")),
    98  		},
    99  		"(sudo iptables -C INPUT -j ACCEPT -p tcp -m multiport --dports 6001:6007 -m comment --comment 'juju ingress') || "+
   100  			"(sudo iptables -I INPUT -j ACCEPT -p tcp -m multiport --dports 6001:6007 -m comment --comment 'juju ingress')",
   101  	)
   102  }
   103  
   104  func (*IptablesSuite) TestParseIngressRulesEmpty(c *gc.C) {
   105  	assertParseIngressRules(c, ``, firewall.IngressRules{})
   106  }
   107  
   108  func (*IptablesSuite) TestParseIngressRulesGarbage(c *gc.C) {
   109  	assertParseIngressRules(c, `a
   110  b
   111  ACCEPT zing
   112  blargh
   113  
   114  `, firewall.IngressRules{})
   115  }
   116  
   117  func (*IptablesSuite) TestParseIngressRulesChecksComment(c *gc.C) {
   118  	assertParseIngressRules(c, `
   119  Chain INPUT (policy ACCEPT)
   120  target     prot opt source               destination         
   121  ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:53 /* managed by lxd-bridge */
   122  ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:53 /* juju ingress */
   123  ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53 /* managed by lxd-bridge */
   124  ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:67
   125  `[1:], firewall.IngressRules{
   126  		firewall.NewIngressRule(network.MustParsePortRange("53/tcp"), firewall.AllNetworksIPV4CIDR),
   127  	})
   128  }
   129  
   130  func (*IptablesSuite) TestParseIngressRules(c *gc.C) {
   131  	assertParseIngressRules(c, `
   132  Chain INPUT (policy ACCEPT)
   133  target     prot opt source               destination         
   134  ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0    multiport dports 3456:3458 /* juju ingress */
   135  ACCEPT     tcp  --  1.2.3.4/20           0.0.0.0/0    tcp dpt:12345 /* juju ingress */
   136  ACCEPT     udp  --  1.2.3.4/20           0.0.0.0/0    udp dpt:12345 /* juju ingress */
   137  ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0    icmptype 8 /* juju ingress */
   138  `[1:],
   139  		firewall.IngressRules{
   140  			firewall.NewIngressRule(network.MustParsePortRange("3456-3458/tcp"), firewall.AllNetworksIPV4CIDR),
   141  			firewall.NewIngressRule(network.MustParsePortRange("12345/tcp"), "1.2.3.4/20"),
   142  			firewall.NewIngressRule(network.MustParsePortRange("12345/udp"), "1.2.3.4/20"),
   143  			firewall.NewIngressRule(network.MustParsePortRange("icmp"), firewall.AllNetworksIPV4CIDR),
   144  		},
   145  	)
   146  }
   147  
   148  func assertParseIngressRules(c *gc.C, in string, expect firewall.IngressRules) {
   149  	rules, err := iptables.ParseIngressRules(strings.NewReader(in))
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	c.Assert(rules, jc.DeepEquals, expect)
   152  }
   153  
   154  type renderer interface {
   155  	Render() string
   156  }
   157  
   158  func assertRender(c *gc.C, r renderer, expect string) {
   159  	c.Assert(r.Render(), gc.Equals, expect)
   160  }