@@ -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,45 @@ 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 = [p [0 ].split ("/" ) for p in ports ]
264
+ reset_command = ["nixos-firewall-tool" , "reset" ]
265
+ elif shutil .which ("ufw" ) is not None :
266
+ command_prefix = ["ufw" , "allow" ]
267
+ reset_command = ["ufw" , "reload" ]
268
+ elif shutil .which ("firewall-cmd" ) is not None :
269
+ command_prefix = ["firewall-cmd" , "--add-port" ]
270
+ reset_command = ["firewall-cmd" , "--reload" ]
271
+ else :
272
+ print (
273
+ 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" ,
274
+ file = sys .stderr ,
275
+ )
276
+ yield
277
+ return
278
+
279
+ try :
280
+ for port in ports :
281
+ subprocess .run ([* command_prefix , * port ], check = True )
282
+ yield
283
+ finally :
284
+ if subprocess .run (reset_command , check = True ).returncode != 0 :
285
+ print (
286
+ "failed to reset firewall rules, see above for details" , file = sys .stderr
287
+ )
288
+
289
+
250
290
def die (msg : str ) -> NoReturn :
251
291
print (msg , file = sys .stderr )
252
292
sys .exit (1 )
@@ -287,6 +327,11 @@ def parse_args(args: list[str]) -> Options:
287
327
help = "Whether to wait for user confirmation before tearing down the network setup once the installation completed" ,
288
328
action = "store_true" ,
289
329
)
330
+ parser .add_argument (
331
+ "--skip-firewall" ,
332
+ help = "Skip opening firewall ports" ,
333
+ action = "store_true" ,
334
+ )
290
335
291
336
parsed , unknown_args = parser .parse_known_args (args )
292
337
try :
@@ -318,6 +363,7 @@ def parse_args(args: list[str]) -> Options:
318
363
319
364
return Options (
320
365
flake = parsed .flake ,
366
+ skip_firewall = parsed .skip_firewall ,
321
367
netboot_image_flake = parsed .netboot_image_flake ,
322
368
dhcp_server_ip = dhcp_server_ip ,
323
369
dhcp_subnet = dhcp_subnet .prefixlen ,
@@ -464,6 +510,7 @@ def run_nixos_anywhere(options: Options) -> None:
464
510
f"{ options .dhcp_server_ip } /{ options .dhcp_subnet } " ,
465
511
),
466
512
ssh_private_key () as ssh_key ,
513
+ open_firewall (options ),
467
514
start_pixiecore (
468
515
options .dhcp_server_ip ,
469
516
options .pixiecore_http_port ,
0 commit comments