@@ -238,6 +238,7 @@ def start_pixiecore(
238
238
class Options :
239
239
flake : str
240
240
netboot_image_flake : str
241
+ skip_firewall : bool
241
242
dhcp_interface : str
242
243
dhcp_server_ip : ipaddress .IPv4Address
243
244
dhcp_subnet : int
@@ -247,6 +248,50 @@ class Options:
247
248
nixos_anywhere_args : list [str ]
248
249
249
250
251
+ @contextmanager
252
+ def open_firewall (options : Options ) -> Iterator [None ]:
253
+ if options .skip_firewall :
254
+ yield
255
+ return
256
+
257
+ ports = [
258
+ [p ]
259
+ for p in [f"tcp/{ options .pixiecore_http_port } " , "67/udp" , "69/udp" , "4011/udp" ]
260
+ ]
261
+ if shutil .which ("nixos-firewall-tool" ) is not None :
262
+ command_prefix = ["nixos-firewall-tool" , "open" ]
263
+ ports = [
264
+ ["tcp" , str (options .pixiecore_http_port )],
265
+ ["udp" , "67" ],
266
+ ["udp" , "69" ],
267
+ ["udp" , "4011" ],
268
+ ]
269
+ reset_command = ["nixos-firewall-tool" , "reset" ]
270
+ elif shutil .which ("ufw" ) is not None :
271
+ command_prefix = ["ufw" , "allow" ]
272
+ reset_command = ["ufw" , "reload" ]
273
+ elif shutil .which ("firewall-cmd" ) is not None :
274
+ command_prefix = ["firewall-cmd" , "--add-port" ]
275
+ reset_command = ["firewall-cmd" , "--reload" ]
276
+ else :
277
+ print (
278
+ f"No firewall tool found. Please make sure that the following ports are open: 67/udp, 69/udp, 4011/udp, and { options .pixiecore_http_port } /tcp" ,
279
+ file = sys .stderr ,
280
+ )
281
+ yield
282
+ return
283
+
284
+ try :
285
+ for port in ports :
286
+ subprocess .run ([* command_prefix , * port ], check = True )
287
+ yield
288
+ finally :
289
+ if subprocess .run (reset_command , check = True ).returncode != 0 :
290
+ print (
291
+ "failed to reset firewall rules, see above for details" , file = sys .stderr
292
+ )
293
+
294
+
250
295
def die (msg : str ) -> NoReturn :
251
296
print (msg , file = sys .stderr )
252
297
sys .exit (1 )
@@ -287,6 +332,11 @@ def parse_args(args: list[str]) -> Options:
287
332
help = "Whether to wait for user confirmation before tearing down the network setup once the installation completed" ,
288
333
action = "store_true" ,
289
334
)
335
+ parser .add_argument (
336
+ "--skip-firewall" ,
337
+ help = "Skip opening firewall ports" ,
338
+ action = "store_true" ,
339
+ )
290
340
291
341
parsed , unknown_args = parser .parse_known_args (args )
292
342
try :
@@ -318,6 +368,7 @@ def parse_args(args: list[str]) -> Options:
318
368
319
369
return Options (
320
370
flake = parsed .flake ,
371
+ skip_firewall = parsed .skip_firewall ,
321
372
netboot_image_flake = parsed .netboot_image_flake ,
322
373
dhcp_server_ip = dhcp_server_ip ,
323
374
dhcp_subnet = dhcp_subnet .prefixlen ,
@@ -464,6 +515,7 @@ def run_nixos_anywhere(options: Options) -> None:
464
515
f"{ options .dhcp_server_ip } /{ options .dhcp_subnet } " ,
465
516
),
466
517
ssh_private_key () as ssh_key ,
518
+ open_firewall (options ),
467
519
start_pixiecore (
468
520
options .dhcp_server_ip ,
469
521
options .pixiecore_http_port ,
0 commit comments