After searching around I literally failed to find anything that could help me know how I'm gonna edit rules.ml in the mirage-firewall VM
The VM as it is right now is running on fedora-29 and trying to launch gnome-terminal/xterm in the VM using qvm-run returns with the error code that I usually get when it doesn't recognize the command/command does not exist in the VM at all
May I ask for any leads in getting through this?
mirage-firewall doesn't use a hard disk, so being based on the fedora-29 template doesn't make any difference (it won't load anything from it). It's not Linux. There's no terminal, no graphics system, and no bash. Not even /bin/sh. In fact, there's no filesystem, so no "/" at all.
Commands are handled here: https://github.com/mirage/qubes-mirage-firewall/blob/master/command.ml - as you can (maybe) see, it only supports SetDateTime and WaitForSession commands by default.
To change the rules, you edit rules.ml, rebuild and redeploy (this should only take a couple of seconds after the first build).
Rules.from_client is an OCaml function that takes one argument giving information about an IP packet as input, and returns an action saying what to do about it. The type of this argument is specified in https://github.com/mirage/qubes-mirage-firewall/blob/master/packet.ml
To get a quick overview of OCaml syntax, try https://try.ocamlpro.com/
For lots of details: http://dev.realworldocaml.org/
I believe some people are planning to add support for reading the rules from QubesDB so you can instead configure the firewall interactively with the dom0 GUI, like you can for sys-firewall. I'm not sure what the status of that work is, though.
To change the rules, you edit rules.ml, rebuild and redeploy (this should only take a couple of seconds after the first build).
(...)
I've added some examples at https://github.com/mirage/qubes-mirage-firewall/pull/54 (see the changes to rules.ml).
The Dev->Untrusted:ssh rule allows TCP packets from Dev to Untrusted:ssh, but you also need to allow packets in the other direction. There are various ways to do that; this example rule allows any TCP packet that isn't trying to start a new TCP connection to go between AppVMs, which should do the trick.
You don't need this for external sites because the `NAT action also adds a rule that translates the responses, and that automatically allows the responses through. But `Accept just lets the packet through without remembering anything about the new connection.
is_tcp_start is defined in packet.ml. It means the same as Packet.is_tcp_start, but we can leave off the module name because of the "open Packet" at the top of rules.ml.
(* The first message in a TCP connection has SYN set and ACK clear. *)
let is_tcp_start = function
| `IPv4 (_ip, `TCP (hdr, _body)) -> Tcp.Tcp_packet.(hdr.syn && not hdr.ack)
| _ -> false
People who know more than me about TCP can probably suggest better ways to do this.