[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MirageOS-devel] A Unikernel Firewall for QubesOS

On 2 January 2016 at 14:35, Mindy <mindy@xxxxxxxxxxxxxxxxxxx> wrote:
> On 01/02/2016 12:14 PM, Anil Madhavapeddy wrote:
>> On 2 Jan 2016, at 12:07, Thomas Leonard <talex5@xxxxxxxxx> wrote:
>>> I have a Mirage firewall running now under Qubes:
>>> http://roscidus.com/blog/blog/2016/01/01/a-unikernel-firewall-for-qubesos/
>> Awesome!
> Seconded!  This is very cool; I look forward to using it myself. :)
>>> There are some things that need fixing though:
>>> - I'm using an old version of mirage-nat, as the current version
>>> requires Irmin. I think there were some plans to factor this out -
>>> what's the status of this?
> In progress.  I've been distracted by other things but hope to have it
> finished soon.  Having users for this library is a huge motivator, so in
> combination with the points you raise below mirage-nat is probably headed
> for a 1.0 re

Great :-) Having this library saved me a huge amount of work!

>>> I think only the new version has code to
>>> expire entries, right?
> Yes, but with some very stupid and broken logic; rather than doing anything
> intelligent with state tracking there's a simple wall-clock-based timeout
> with a much longer horizon for TCP connections than UDP ones.  It really
> ought to do something smarter before release.

As a quick workaround, mirage-firewall now drops the entire NAT table
if it runs out of memory or takes too long to find a free port.

>>> - You need to generate an unused port for NAT. I copied simple-nat's
>>> system of picking a random number and retrying but (as the TODO there
>>> says) this will eventually run out of ports and hang. I assume we
>>> should add some kind of free-port tracking to tcpip, right? pcb.ml's
>>> getid has a better strategy of searching forward from the last port it
>>> used, but it will also hang if it runs out (as noted by another TODO).
>>> The UDP code doesn't seem to track free ports at all (fails with a
>>> TODO if you ask it to pick a free one).
>> Yes, we need a standalone free-port picking datastructure for a few
>> things:
>> - udp source port selection
>> - tcp/ip source port selection
>> - ipv4 id selection also needs some form of non-repeating selector
>>    but we don't currently fragment outbound at the moment.
>> For randomising this, a linear congruential generator is what the
>> OpenBSD stack uses.
> Agreed with all above.
>>> - I'm not sure what the protocol is for disconnecting netback clients.
>>> Currently I just set the interface state to Closed, but the XenStore
>>> directory in "backend/vif" remains - is this documented somewhere?
>> Good question, not sure.
>>> - Mirage allows you to access memory after unmapping it. This isn't
>>> safe (may page-fault or give access to someone else's data). I've
>>> added checks in mirage-net-xen to make sure we don't try to access a
>>> ring after unmapping it [1], but I think this should be fixed at the
>>> Bigarray level [2].
>> Did that Bigarray patch get committed into OCaml 4.03dev?  I dont
>> have a checkout handy here and it's hard to map a commit to the
>> associated PRs in the web UI.

I haven't submitted a PR yet. Need to update it to master and test.

>>> - mirage-nat doesn't do NAT for ICMP packets, so ping doesn't work yet.
>> Presumably this also means that UDP NAT doesnt work?

UDP NAT seems to be working fine. mirage-firewall uses it to redirect
DNS requests.

> Since most firewalls implement default-drop for incoming packets which don't
> match a rule, most stacks are quite used to not receiving ICMP errors for
> attempted UDP connections that aren't to open ports.  Or possibly I
> misunderstand?  At any rate, mirage-nat creates rules for UDP connections
> and rewrites headers just as it does for TCP.
>>> - mirage-nat mutates packets in-place. It might be cleaner if it made
>>> a copy instead (it could copy just the header and return [new_header;
>>> old_payload]). Since mirage-net copies the data into the shared ring
>>> anyway, there should be very little overhead to doing it this way
> I had assumed there would be high overhead to a copying approach, but what
> you say merits trying it out.  I agree that a copy would be cleaner.
>>> - mirage-nat works on whole Ethernet frames. I believe NAT only
>>> applies to the IP layer - it would make my code cleaner if I could
>>> strip off the Ethernet header when the frame arrives and just work
>>> with the IP layer. It might simplify the mirage-nat API too.
> I'll think about this a bit.
>>> - I don't validate checksums on incoming packets, and always
>>> recalculate after NAT before sending. We should probably track this
>>> properly and support checksum offload. This will require an interface
>>> change to NETWORK.
>> Yeah, there's a general need for feature flags to be added to the
>> NETWORK device interfaces...
>> Looking forward to trying this out on my Cubieboard at home soon!

Dr Thomas Leonard        http://roscidus.com/blog/
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

MirageOS-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.