@@ -22,10 +22,13 @@ type Firewall struct {
2222 table * nftables.Table
2323 chain * nftables.Chain
2424
25- blockInternetTraffic bool
26- denySet set.Set
27- allowSet set.Set
28- tapInterface string
25+ predefinedDenySet set.Set
26+ predefinedAllowSet set.Set
27+
28+ userDenySet set.Set
29+ userAllowSet set.Set
30+
31+ tapInterface string
2932
3033 allowedRanges []string
3134}
@@ -51,6 +54,15 @@ func NewFirewall(tapIf string, hyperloopIP string) (*Firewall, error) {
5154 })
5255
5356 // Create deny-set and allow-set
57+ alwaysDenySet , err := set .New (conn , table , "filtered_always_denylist" , nftables .TypeIPAddr )
58+ if err != nil {
59+ return nil , fmt .Errorf ("new deny set: %w" , err )
60+ }
61+ alwaysAllowSet , err := set .New (conn , table , "filtered_always_allowlist" , nftables .TypeIPAddr )
62+ if err != nil {
63+ return nil , fmt .Errorf ("new allow set: %w" , err )
64+ }
65+
5466 denySet , err := set .New (conn , table , "filtered_denylist" , nftables .TypeIPAddr )
5567 if err != nil {
5668 return nil , fmt .Errorf ("new deny set: %w" , err )
@@ -61,14 +73,15 @@ func NewFirewall(tapIf string, hyperloopIP string) (*Firewall, error) {
6173 }
6274
6375 fw := & Firewall {
64- conn : conn ,
65- table : table ,
66- chain : chain ,
67- blockInternetTraffic : false ,
68- denySet : denySet ,
69- allowSet : allowSet ,
70- tapInterface : tapIf ,
71- allowedRanges : []string {fmt .Sprintf ("%s/32" , hyperloopIP )},
76+ conn : conn ,
77+ table : table ,
78+ chain : chain ,
79+ predefinedDenySet : alwaysDenySet ,
80+ predefinedAllowSet : alwaysAllowSet ,
81+ userDenySet : denySet ,
82+ userAllowSet : allowSet ,
83+ tapInterface : tapIf ,
84+ allowedRanges : []string {fmt .Sprintf ("%s/32" , hyperloopIP )},
7285 }
7386
7487 // Add firewall rules to the chain
@@ -77,9 +90,9 @@ func NewFirewall(tapIf string, hyperloopIP string) (*Firewall, error) {
7790 }
7891
7992 // Populate the sets with initial data
80- err = fw .ResetAllCustom ()
93+ err = fw .ResetAllSets ()
8194 if err != nil {
82- return nil , fmt .Errorf ("error while configuring initial deny set : %w" , err )
95+ return nil , fmt .Errorf ("error while configuring initial data : %w" , err )
8396 }
8497
8598 return fw , nil
@@ -119,26 +132,52 @@ func (fw *Firewall) installRules() error {
119132 ),
120133 })
121134
122- // Allow anything in allowSet
135+ // The order should be
136+ // 1. Allow anything in predefinedAllowSet
137+ // 2. Deny anything in predefinedDenySet
138+ // 3. Allow anything in userAllowSet
139+ // 4. Deny anything in userDenySet
140+
141+ // Allow anything in userAllowSet
123142 fw .conn .InsertRule (& nftables.Rule {
124143 Table : fw .table , Chain : fw .chain ,
125144 Exprs : append (ifaceMatch ,
126145 expressions .IPv4DestinationAddress (1 ),
127- expressions .IPSetLookUp (fw .allowSet .Set (), 1 ),
146+ expressions .IPSetLookUp (fw .userAllowSet .Set (), 1 ),
128147 expressions .Accept (),
129148 ),
130149 })
131150
132- // Drop anything in denySet
151+ // Drop anything in userDenySet
133152 fw .conn .AddRule (& nftables.Rule {
134153 Table : fw .table , Chain : fw .chain ,
135154 Exprs : append (ifaceMatch ,
136155 expressions .IPv4DestinationAddress (1 ),
137- expressions .IPSetLookUp (fw .denySet .Set (), 1 ),
156+ expressions .IPSetLookUp (fw .userDenySet .Set (), 1 ),
138157 expressions .Drop (),
139158 ),
140159 })
141160
161+ // Drop anything in predefinedDenySet
162+ fw .conn .InsertRule (& nftables.Rule {
163+ Table : fw .table , Chain : fw .chain ,
164+ Exprs : append (ifaceMatch ,
165+ expressions .IPv4DestinationAddress (1 ),
166+ expressions .IPSetLookUp (fw .predefinedDenySet .Set (), 1 ),
167+ expressions .Drop (),
168+ ),
169+ })
170+
171+ // Accept anything in predefinedAllowSet
172+ fw .conn .InsertRule (& nftables.Rule {
173+ Table : fw .table , Chain : fw .chain ,
174+ Exprs : append (ifaceMatch ,
175+ expressions .IPv4DestinationAddress (1 ),
176+ expressions .IPSetLookUp (fw .predefinedAllowSet .Set (), 1 ),
177+ expressions .Accept (),
178+ ),
179+ })
180+
142181 if err := fw .conn .Flush (); err != nil {
143182 return fmt .Errorf ("flush nftables changes: %w" , err )
144183 }
@@ -148,118 +187,117 @@ func (fw *Firewall) installRules() error {
148187
149188// AddDeniedCIDR adds a single CIDR to the deny set at runtime.
150189func (fw * Firewall ) AddDeniedCIDR (cidr string ) error {
151- if fw .blockInternetTraffic {
152- // If internet is denied, we don't need to add any other addresses to the deny set.
153- // Because 0.0.0.0/0 is not valid IP per GoLang, we can't add new addresses to the deny set.
154- return nil
155- }
156-
157- // 0.0.0.0/0 is not valid IP per GoLang, so we handle it as a special case
158- if cidr == sandbox_network .AllInternetTrafficCIDR {
159- fw .blockInternetTraffic = true
160-
161- fw .conn .FlushSet (fw .denySet .Set ())
162-
163- toAppend := []nftables.SetElement {
164- {Key : netip .MustParseAddr ("0.0.0.0" ).AsSlice ()},
165- {
166- Key : netip .MustParseAddr ("255.255.255.255" ).AsSlice (),
167- IntervalEnd : true ,
168- },
169- }
170-
171- if err := fw .conn .SetAddElements (fw .denySet .Set (), toAppend ); err != nil {
172- return fmt .Errorf ("add elements to denied set: %w" , err )
173- }
174- } else {
175- current , err := fw .denySet .Elements (fw .conn )
176- if err != nil {
177- return err
178- }
179-
180- data , err := set .AddressStringsToSetData ([]string {cidr })
181- if err != nil {
182- return err
183- }
184- merged := append (current , data ... )
185- if err := fw .denySet .ClearAndAddElements (fw .conn , merged ); err != nil {
186- return err
187- }
190+ err := addCIDRToSet (fw .conn , fw .userDenySet , cidr )
191+ if err != nil {
192+ return fmt .Errorf ("add denied CIDR to set: %w" , err )
188193 }
189194
190- err : = fw .conn .Flush ()
195+ err = fw .conn .Flush ()
191196 if err != nil {
192- return fmt .Errorf ("flush add denied cidr changes: %w" , err )
197+ return fmt .Errorf ("flush add denied changes: %w" , err )
193198 }
194199
195200 return nil
196201}
197202
198203// AddAllowedCIDR adds a single CIDR to the allow set at runtime.
199204func (fw * Firewall ) AddAllowedCIDR (cidr string ) error {
200- err := sandbox_network . CanAllowCIDR ( cidr )
205+ err := addCIDRToSet ( fw . conn , fw . userAllowSet , cidr )
201206 if err != nil {
202- return err
203- }
204-
205- data , err := set .AddressStringsToSetData ([]string {cidr })
206- if err != nil {
207- return err
208- }
209- current , err := fw .allowSet .Elements (fw .conn )
210- if err != nil {
211- return err
212- }
213- merged := append (current , data ... )
214- if err := fw .allowSet .ClearAndAddElements (fw .conn , merged ); err != nil {
215- return err
207+ return fmt .Errorf ("add allowed CIDR to set: %w" , err )
216208 }
217209
218210 err = fw .conn .Flush ()
219211 if err != nil {
220- return fmt .Errorf ("flush add allowed IP changes: %w" , err )
212+ return fmt .Errorf ("flush add allowed changes: %w" , err )
221213 }
222214
223215 return nil
224216}
225217
226- func (fw * Firewall ) ResetAllCustom () error {
227- if err := fw .ResetDeniedCustom (); err != nil {
228- return fmt .Errorf ("clear block set: %w" , err )
218+ func (fw * Firewall ) ResetAllSets () error {
219+ if err := fw .ResetDeniedSets (); err != nil {
220+ return fmt .Errorf ("clear denied set: %w" , err )
229221 }
230- if err := fw .ResetAllowedCustom (); err != nil {
222+ if err := fw .ResetAllowedSets (); err != nil {
231223 return fmt .Errorf ("clear allow set: %w" , err )
232224 }
233225
234226 return nil
235227}
236228
237- // ResetDeniedCustom resets the deny set back to original ranges.
238- func (fw * Firewall ) ResetDeniedCustom () error {
239- initData , err := set . AddressStringsToSetData ( sandbox_network . DeniedSandboxCIDRs )
240- if err != nil {
241- return fmt . Errorf ( "parse initial denied CIDRs: %w" , err )
229+ // ResetDeniedSets resets the deny set back to original ranges.
230+ func (fw * Firewall ) ResetDeniedSets () error {
231+ // Always deny the default ranges
232+ if err := fw . predefinedDenySet . ClearAndAddElements ( fw . conn , sandbox_network . DeniedSandboxSetData ); err != nil {
233+ return err
242234 }
243235
244- if err := fw .denySet .ClearAndAddElements (fw .conn , initData ); err != nil {
236+ // User defined denied ranges
237+ if err := fw .userDenySet .ClearAndAddElements (fw .conn , nil ); err != nil {
245238 return err
246239 }
247240
248- fw .blockInternetTraffic = false
249-
250241 return fw .conn .Flush ()
251242}
252243
253- // ResetAllowedCustom resets allow set back to original ranges.
254- func (fw * Firewall ) ResetAllowedCustom () error {
244+ // ResetAllowedSets resets allow set back to original ranges.
245+ func (fw * Firewall ) ResetAllowedSets () error {
246+ // Always allowed ranges
255247 initData , err := set .AddressStringsToSetData (fw .allowedRanges )
256248 if err != nil {
257249 return fmt .Errorf ("parse initial allowed CIDRs: %w" , err )
258250 }
251+ if err := fw .predefinedAllowSet .ClearAndAddElements (fw .conn , initData ); err != nil {
252+ return err
253+ }
259254
260- if err := fw .allowSet .ClearAndAddElements (fw .conn , initData ); err != nil {
255+ // User defined allowed ranges
256+ if err := fw .userAllowSet .ClearAndAddElements (fw .conn , nil ); err != nil {
261257 return err
262258 }
263259
264260 return fw .conn .Flush ()
265261}
262+
263+ func addCIDRToSet (conn * nftables.Conn , ipset set.Set , cidr string ) error {
264+ current , err := ipset .Elements (conn )
265+ if err != nil {
266+ return err
267+ }
268+
269+ if len (current ) == 1 && current [0 ].AddressRangeStart == netip .MustParseAddr ("0.0.0.0" ) && current [0 ].AddressRangeEnd == netip .MustParseAddr ("255.255.255.255" ) {
270+ // Because 0.0.0.0/0 is not valid IP per GoLang, we can't add new addresses to the set.
271+ return nil
272+ }
273+
274+ // 0.0.0.0/0 is not valid IP per GoLang, so we handle it as a special case
275+ if cidr == sandbox_network .AllInternetTrafficCIDR {
276+ conn .FlushSet (ipset .Set ())
277+
278+ toAppend := []nftables.SetElement {
279+ {
280+ Key : netip .MustParseAddr ("0.0.0.0" ).AsSlice (),
281+ },
282+ {
283+ Key : netip .MustParseAddr ("255.255.255.255" ).AsSlice (),
284+ IntervalEnd : true ,
285+ },
286+ }
287+
288+ if err := conn .SetAddElements (ipset .Set (), toAppend ); err != nil {
289+ return fmt .Errorf ("add elements to denied set: %w" , err )
290+ }
291+
292+ return nil
293+ }
294+
295+ data , err := set .AddressStringsToSetData ([]string {cidr })
296+ if err != nil {
297+ return err
298+ }
299+
300+ merged := append (current , data ... )
301+
302+ return ipset .ClearAndAddElements (conn , merged )
303+ }
0 commit comments