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 }