@@ -7,15 +7,19 @@ import (
7
7
"github.com/coreos/go-iptables/iptables"
8
8
)
9
9
10
+ // Table describes an ip(6)tables table
10
11
type Table string
11
12
13
+ // All ip(6)tables tables we use
12
14
const (
13
15
TableFilter = "filter"
14
16
TableNat = "nat"
15
17
)
16
18
19
+ // Chain describes an ip(6)tables chain
17
20
type Chain string
18
21
22
+ // All ip(6)tables chains we use
19
23
const (
20
24
ChainInput = "INPUT"
21
25
ChainOutput = "OUTPUT"
@@ -28,58 +32,65 @@ const (
28
32
ChainDockerIsolation2 = "DOCKER-ISOLATION-STAGE-2"
29
33
)
30
34
35
+ // TableChain references a combination of an ip(6)tables table and chain
31
36
type TableChain struct {
32
37
table Table
33
38
chain Chain
34
39
}
35
40
36
- type rule struct {
41
+ // Rule represents a unique firewall rule
42
+ type Rule struct {
37
43
tc TableChain
38
44
spec []string
39
45
prepend bool
40
46
}
41
47
42
- func NewRule (table Table , chain Chain , spec ... string ) * rule {
43
- return & rule {
48
+ // NewRule constructs a new (non prepended) Rule
49
+ func NewRule (table Table , chain Chain , spec ... string ) * Rule {
50
+ return & Rule {
44
51
tc : TableChain {table , chain },
45
52
spec : spec ,
46
53
prepend : false ,
47
54
}
48
55
}
49
56
50
- func NewPrependRule (table Table , chain Chain , spec ... string ) * rule {
51
- return & rule {
57
+ // NewPrependRule constructs a new Rule with prepend set to true
58
+ func NewPrependRule (table Table , chain Chain , spec ... string ) * Rule {
59
+ return & Rule {
52
60
tc : TableChain {table , chain },
53
61
spec : spec ,
54
62
prepend : true ,
55
63
}
56
64
}
57
65
58
- func (r * rule ) hash () string {
66
+ func (r * Rule ) hash () string {
59
67
return strings .Join (r .spec , "#" )
60
68
}
61
69
62
- func (r1 * rule ) Equal (r2 * rule ) bool {
63
- if r1 .tc != r2 .tc {
70
+ // Equal compares 2 Rules
71
+ func (r * Rule ) Equal (other * Rule ) bool {
72
+ if r .tc != other .tc {
64
73
return false
65
74
}
66
75
67
- if len (r1 .spec ) != len (r2 .spec ) {
76
+ if len (r .spec ) != len (other .spec ) {
68
77
return false
69
78
}
70
79
71
- for index := range r1 .spec {
72
- if r1 .spec [index ] != r2 .spec [index ] {
80
+ for index := range r .spec {
81
+ if r .spec [index ] != other .spec [index ] {
73
82
return false
74
83
}
75
84
}
76
85
77
86
return true
78
87
}
79
88
80
- type Ruleset []* rule
89
+ // Ruleset contains a list of unique rules
90
+ type Ruleset []* Rule
81
91
82
- func (s * Ruleset ) Contains (r * rule ) bool {
92
+ // Contains checks if a Rule is part of the Ruleset
93
+ func (s * Ruleset ) Contains (r * Rule ) bool {
83
94
for _ , sr := range * s {
84
95
if r .Equal (sr ) {
85
96
return true
@@ -89,54 +100,58 @@ func (s *Ruleset) Contains(r *rule) bool {
89
100
return false
90
101
}
91
102
92
- func (s1 * Ruleset ) Diff (s2 * Ruleset ) * Ruleset {
93
- if len (* s2 ) == 0 {
94
- return s1
103
+ // Diff returns a new Ruleset with only the rules that are not part of other
104
+ func (s * Ruleset ) Diff (other * Ruleset ) * Ruleset {
105
+ if len (* other ) == 0 {
106
+ return s
95
107
}
96
108
97
- s := make (Ruleset , 0 , len (* s1 ))
98
- for _ , r := range * s1 {
99
- if ! s2 .Contains (r ) {
100
- s = append (s , r )
109
+ diffed := make (Ruleset , 0 , len (* s ))
110
+ for _ , r := range * s {
111
+ if ! other .Contains (r ) {
112
+ diffed = append (diffed , r )
101
113
}
102
114
}
103
115
104
- return & s
116
+ return & diffed
105
117
}
106
118
107
- type firewall struct {
119
+ // Firewall keeps track of the active rules, in order to perform proper appends/prepends
120
+ type Firewall struct {
108
121
ipt * iptables.IPTables
109
122
activeRules map [TableChain ]map [string ]bool
110
123
debug bool
111
- userChainJumpRule * rule
124
+ userChainJumpRule * Rule
112
125
}
113
126
114
- func NewFirewall (debug bool ) (* firewall , error ) {
127
+ // NewFirewall constructs a new Firewall
128
+ func NewFirewall (debug bool ) (* Firewall , error ) {
115
129
ipt , err := iptables .NewWithProtocol (iptables .ProtocolIPv6 )
116
130
if err != nil {
117
131
return nil , err
118
132
}
119
133
120
- return & firewall {
134
+ return & Firewall {
121
135
ipt : ipt ,
122
136
activeRules : make (map [TableChain ]map [string ]bool ),
123
137
debug : debug ,
124
138
userChainJumpRule : NewRule (TableFilter , ChainForward , "-j" , ChainDockerUser ),
125
139
}, nil
126
140
}
127
141
128
- func (fw * firewall ) activateRule (r * rule ) {
142
+ func (fw * Firewall ) activateRule (r * Rule ) {
129
143
if _ , exists := fw .activeRules [r .tc ]; ! exists {
130
144
fw .activeRules [r .tc ] = make (map [string ]bool )
131
145
}
132
146
fw .activeRules [r .tc ][r .hash ()] = true
133
147
}
134
148
135
- func (fw * firewall ) deactivateRule (r * rule ) {
149
+ func (fw * Firewall ) deactivateRule (r * Rule ) {
136
150
delete (fw .activeRules [r .tc ], r .hash ())
137
151
}
138
152
139
- func (fw * firewall ) EnsureTableChains (tableChains []TableChain ) error {
153
+ // EnsureTableChains creates (and clears!) the given TableChains
154
+ func (fw * Firewall ) EnsureTableChains (tableChains []TableChain ) error {
140
155
for _ , tc := range tableChains {
141
156
if err := fw .ipt .ClearChain (string (tc .table ), string (tc .chain )); err != nil {
142
157
return err
@@ -147,7 +162,8 @@ func (fw *firewall) EnsureTableChains(tableChains []TableChain) error {
147
162
return nil
148
163
}
149
164
150
- func (fw * firewall ) RemoveTableChains (tableChains []TableChain ) error {
165
+ // RemoveTableChains deletes the given TableChains
166
+ func (fw * Firewall ) RemoveTableChains (tableChains []TableChain ) error {
151
167
for _ , tc := range tableChains {
152
168
fw .ipt .ClearChain (string (tc .table ), string (tc .chain ))
153
169
fw .ipt .DeleteChain (string (tc .table ), string (tc .chain ))
@@ -157,7 +173,8 @@ func (fw *firewall) RemoveTableChains(tableChains []TableChain) error {
157
173
return nil
158
174
}
159
175
160
- func (fw * firewall ) EnsureRules (rules * Ruleset ) error {
176
+ // EnsureRules makes sure the Rules in the given Ruleset exist or it creates them
177
+ func (fw * Firewall ) EnsureRules (rules * Ruleset ) error {
161
178
// A regular loop to append only the non-prepend rules
162
179
for _ , rule := range * rules {
163
180
if rule .prepend {
@@ -206,7 +223,8 @@ func (fw *firewall) EnsureRules(rules *Ruleset) error {
206
223
return nil
207
224
}
208
225
209
- func (fw * firewall ) RemoveRules (rules * Ruleset ) error {
226
+ // RemoveRules makes sure the Rules in the given Ruleset don't exist or removes them
227
+ func (fw * Firewall ) RemoveRules (rules * Ruleset ) error {
210
228
for _ , rule := range * rules {
211
229
if rule .Equal (fw .userChainJumpRule ) {
212
230
continue
@@ -231,7 +249,8 @@ func (fw *firewall) RemoveRules(rules *Ruleset) error {
231
249
return nil
232
250
}
233
251
234
- func (fw * firewall ) EnsureUserFilterChain () error {
252
+ // EnsureUserFilterChain makes sure the DOCKER-USER chain exists, without clearing it
253
+ func (fw * Firewall ) EnsureUserFilterChain () error {
235
254
chains , err := fw .ipt .ListChains (TableFilter )
236
255
if err != nil {
237
256
return err
0 commit comments