diff --git a/vm.py b/vm.py index 16185340350ea5db9b94c32842cca7a92a8e4f27..0cdad9671388ad6cddde3c061cf4e22281860c0a 100755 --- a/vm.py +++ b/vm.py @@ -356,9 +356,12 @@ def has_write_acces(ucred, vm: str): ######################## @internal_cmd -def get_ip(vm: str) -> str: +def get_ip(vm: str) -> Optional[str]: network_dir = vm_dir(vm)+"network/" - net_id = open(network_dir+"net_id").read().strip() + try: + net_id = open(network_dir+"net_id").read().strip() + except FileNotFoundError: + return None return f'{net_prefix}.{net_id}.150' @internal_cmd @@ -503,8 +506,8 @@ def kill(ucred, vm: str): @cmd @daemon() -def pause(ucred, vm: str): - vm = name_to_id(vm) +def pause(ucred, vm: Identification): + vm, user = ident assert has_write_acces(ucred, vm) if backend == backend_vbox: @@ -515,8 +518,8 @@ def pause(ucred, vm: str): raise NotImplementedError() @cmd @daemon() -def resume(ucred, vm: str): - vm = name_to_id(vm) +def resume(ucred, ident: Identification): + vm, user = ident assert has_write_acces(ucred, vm) if backend == backend_vbox: @@ -739,10 +742,11 @@ def create_net(ucred, vm: str): add chain inet filter input_from_{interface} add chain inet filter forward_from_{interface} add chain inet filter forward_to_{interface} + add chain inet filter forward_from_{interface} - insert rule inet filter input iifname {interface} jump input_from_{interface} - insert rule inet filter forward iifname {interface} jump forward_from_{interface} - insert rule inet filter forward oifname {interface} jump forward_to_{interface} + insert rule inet filter input_from_vm iifname {interface} jump input_from_{interface} + insert rule inet filter forward_from_vm iifname {interface} jump forward_from_{interface} + insert rule inet filter forward_to_vm oifname {interface} jump forward_to_{interface} """) modify_net(ucred, vm) #nft("add rule inet filter forward iifname wlp1s0 accept") @@ -769,6 +773,7 @@ def create_net(ucred, vm: str): f.write(S-f""" #!/bin/sh ifconfig {interface} {net_prefix}.{net_id}.1 netmask 255.255.255.0 up + ip route add {net_prefix}.{net_id}.0/24 dev {interface} table 38 dhcpd -4 -cf network/dhcp.config -pf network/dhcp.pid -lf network/dhcp.lp {interface} """) with open(network_dir+"down.sh", "w") as f: @@ -779,7 +784,7 @@ def create_net(ucred, vm: str): @internal_cmd @daemon() -def modify_net(ucred, vm: str, wan: bool = False, lan: bool = False, pc: bool = False, pc_all: bool = False): +def modify_net(ucred, vm: str, wan: bool = False, lan: bool = False, pc: bool = False, pc_all: bool = False, route_table: int = 6, route_blackhole: bool = True): vm = name_to_id(vm) assert has_write_acces(ucred, vm) assert not (pc_all and not pc) @@ -793,7 +798,9 @@ def modify_net(ucred, vm: str, wan: bool = False, lan: bool = False, pc: bool = pass todo = [f"flush chain inet filter input_from_{interface}", f"flush chain inet filter forward_from_{interface}", - f"flush chain inet filter forward_to_{interface}"] + f"flush chain inet filter forward_to_{interface}", + # f"flush chain inet route forward_from_{interface}", + ] todo.append(f"add rule inet filter input_from_{interface} ct state {{ established, related }} accept") if not pc: todo.append(f"add rule inet filter input_from_{interface} drop") @@ -816,8 +823,12 @@ def modify_net(ucred, vm: str, wan: bool = False, lan: bool = False, pc: bool = todo.append(f"add rule inet filter forward_from_{interface} drop") todo.append(f"add rule inet filter forward_to_{interface} drop") + + # todo.append(f"add rule inet route forward_from_{interface} meta mark set {fwmark}") nft("\n".join(todo)) + r("ip-man", "replace_rule", "--iif", interface, *[ "--blackhole" for _ in [1] if route_blackhole], "--priority_base", "100", str(route_table)) + ######################## # Using vm # @@ -938,7 +949,7 @@ def vncapp(ident: Identification, cmd: str, wayland: bool = False): unit_id = random.randint(100000, 999999) vnc_server, ident = start_vnc_server(ident, f"vncapp-vnc-{unit_id}", wayland=wayland) time.sleep(1) - app = subprocess.Popen(ssh_args(ident, f"systemd-run --unit vncapp-app-{unit_id} --user -P -E DISPLAY={ident.display} -E WAYLAND_DISPLAY={ident.wayland_display} bash -c {escape_sh(cmd)}")); + app = subprocess.Popen(ssh_args(ident, f"{'swaymsg' if wayland else 'i3-msg'} bar mode invisible; systemd-run --unit vncapp-app-{unit_id} --user -P -E DISPLAY={ident.display} -E WAYLAND_DISPLAY={ident.wayland_display} bash -c {escape_sh(cmd)}")); vnc_client = start_vnc_client(ident) def on_terminate(proc): @@ -1022,7 +1033,6 @@ def get_ident_by_window(win_id: int = None): ######################## def terminal_len(val: str) -> int: - # TODO return len(val) def format_table(table): @@ -1047,7 +1057,7 @@ def index(color: bool = True): else: out_state += " (NO PING)" out_rw = ('w' if has_write_acces(vm) else 'r') if has_read_acces(vm) else '-' - out.append([vm, out_rw, name(vm), out_state, get_permanency(vm)]) + out.append([vm, out_rw, name(vm), out_state, get_permanency(vm), get_ip(vm) or "None"]) return format_table(out) @@ -1257,7 +1267,13 @@ def extended_name(name: str) -> tuple[str, str]: else: resume(vm) if net_options is not None: - modify_net(vm, wan="w" in net_options, lan="l" in net_options, pc="p" in net_options or "P" in net_options, pc_all="P" in net_options) + if any(ch.isnumeric() for ch in net_options): + route_table_ind = min(i for i, ch in enumerate(net_options) if ch.isnumeric()) + route_table = int(net_options[route_table_ind:]) + net_options = net_options[:route_table_ind] + else: + route_table = 6 + modify_net(vm, wan="w" in net_options, lan="l" in net_options, pc="p" in net_options or "P" in net_options, pc_all="P" in net_options, route_table=route_table, route_blackhole="B" not in net_options) if permanency is not None: set_permanency(vm, permanency or "stable")