Convert a string (with an OCaml list) into list

Hi,

I’m trying to do https://github.com/talex5/qubes-mirage-firewall working with dynamic rules.

I have now them stored in a string KeyMap with the OCaml list syntax i.e.:
[
{ src = None; dst = Some NetVM; sport = None; dport = None; proto = None ; action =NAT };
{ src = None; dst = Some Client_gateway; sport = None; dport = Some 53; proto = SomeUDP; action = NAT_to (NetVM,53) };
{ src = None; dst = Some Client_gateway; sport = None; dport = None; proto = None; action =Drop “packet addressed to firewall itself” };
{ src = None; dst = Some Firewall_uplink; sport = None; dport = None; proto = None; action =Drop “packet addressed to firewall itself” };
{ src = None; dst = None; sport = None; dport = None; proto = None; action = `NAT };
]

I suppose that I could do a func to parse the string into a list, but since it has the same syntax as OCaml list is there a simple way for doing it?

Well, as I read from irc channel it seems that I need to write a func to parse it or use some other tool like yojson.

Indeed, a serializer/deserializer like yojson (with ppx) or jsonm/ezjsonm (with ocplib-json-typed) could be useful for your use case to describe a JSON format and, by this way, make a serializer/deserializer easily. sexplib is an other solution used at some points in the MirageOS’s project.

Note that Qubes 4 now defines a format for the rules (see https://github.com/talex5/qubes-mirage-firewall/issues/24). Would be good to support that if possible…

2 Likes

Ey hi @talex5

Yes my intention is supporting Qubes 4 format but since I’m currently using Qubes 3.2 and I’m very noob in OCaml I preferred to try with something pretty simple first that works for 3.2. I hope that with the experience doing it I will migrate later to Qubes 4.

I tried yesterday using my own parsing function, but unfortunately I was using Str.split and then I discovered that Str module was removed from MirageOS. I saw that there are some alternatives, I will try some of them.

Update:

After reading the Qubes 4 rules format, I think that I should change my approach. Instead of maintaining my own list of rules and doing a parser from qubesdb to the list, maybe a best solution would be directly parsing qubesdb entries to the firewall logic. Maybe it has some performance penalty (parsing string to rule/action will be done for each packet), but since the rules are indexed by source ip address, in most cases the rules amount will be very low. As advantage it will remove the need of mutability in the firewall itself.

What do you think?

Hey Donoban!

Nice to see someone else who wants this! :slight_smile:

I implemented a parser for a json format for exactly this purpose using the yojson format, the code is here:
https://github.com/cfcs/qubes-mirage-firewall/commit/4446556757e5cd51caddc5d3293aedd3ebe3386b#diff-29351353369de238c3c8ee1126ab4a27R205
(this was my first time using yojson, and I am a bit scared of the dependencies that using ppx (which @dinosaure suggested above), so I tried to keep it simple and stupid).

An example of the format it parses can be found here: https://github.com/cfcs/qubes-mirage-firewall/commit/4446556757e5cd51caddc5d3293aedd3ebe3386b#diff-e4e347f34468208cc42e811863eb5077R1

As outlined in the issue in @talex5’s Github repository linked to above, I believe the best approach for implementing user-supplied firewall rules would be to have a separate pure library (that can be used for other purposes as well, and most notably can be unit-tested and fuzzed without requiring OS-level c stubs for interfacing with hardware or external IP stacks).
Having pure library code separate from the application code (which contains impure side-effects that makes the aforementioned things harder) is a design concept I’ve come to love, but it may sound a bit foreign if you’re not used to functional programming.
I’d also like to have a general mirage-firewall that could be used in Tails, SubgraphOS (from normal operating systems not built on top of Xen, that is).
The Usenix paper linked to from here https://nqsb.io/ may do a better job of explaining the concepts than I can here, and maybe if we ask @hannes nicely he’ll have some more references worth checking out. :slight_smile:

I started this effort here: https://github.com/cfcs/ocaml-pf (which currently only implements a parser, not the rule engine). I’ve been working a tiny bit on a rule engine, but while I have been kept up with other things the past month or so, it is in no way a dead project, and I still intend to implement that part.

My approach to parsing the new Qubes 4 rule format is to use the angstrom parser-combinator library to parse the data, and then return it using the types defined by the pf library (since the new rules can be translated to a subset of the pf syntax). I have a local branch for that, I’ll try to push it today or tomorrow and post a link here.

Since it sounds like we’re trying to do almost exactly the same thing, I’d be happy to describe what I’m doing more in-depth, and work together if we can find some common ground, but I am a little bit exhausted after a long day and can’t think of more to write right now. :slight_smile:

2 Likes

@donoban:

Here is the Angstrom-based parser: https://github.com/cfcs/ocaml-pf/commit/3fbb2b6eae8b34b7bbe666f6058eeb557ef0d347#diff-5bc7821c6a931f281c6db04ec3dbe307R1

Here is my attempt to transfer @talex5’s default ruleset to pf syntax: https://github.com/cfcs/ocaml-pf/commit/3fbb2b6eae8b34b7bbe666f6058eeb557ef0d347#diff-52229fd6f27774a2b79698b830e4adb8R1 (if someone reading this who has experience with pf could have a look at it and compare it to Thomas’ rules, that would be much appreciated!)

There are some (* TODOs *) and so on - think of it more like a proof of concept than a production-ready implementation :slight_smile:

Hi @cfcs

I know your version. I looked at it before doing anything but since I am new to OCaml and I don’t know pf I thought it was more simple to work on talex’s version.

This thread has lost it’s purpose, please mail me (donoban@riseup.net) and we could talk about working on this :slight_smile:

1 Like

Just to be clear I am also working on @talex5’s version (not just forking), and I hope that he will like the work and merge it when it is ready. :slight_smile:

I wrote you an email!