GithubHelp home page GithubHelp logo

mirage / mirage-nat Goto Github PK

View Code? Open in Web Editor NEW
31.0 31.0 14.0 955 KB

library for network address translation intended for use with mirage unikernels

License: ISC License

Makefile 0.10% OCaml 99.90%

mirage-nat's Introduction

What is this?

mirage-nat is a library for network address translation. It is intended for use in MirageOS and makes extensive use of tcpip, the network stack used by default in MirageOS unikernels.

Organization

mirage-nat contains module type definitions for a data store. Given a data store fulfilling that module type, mirage-nat also can generate modules for useful network address translation operations (e.g. adding entries based on incoming packets and translating packets if matching entries are present).

mirage-nat also contains an implementation of such a data store based on the lru library. Currently Mirage_nat_lru is the only implementation; historical implementations using irmin as a backing store have been deprecated, but could be revived given sufficient interest.

Features and Limitations

mirage-nat allows users to add both source NAT (NAT) and destination NAT (Redirect) rules.

mirage-nat currently supports translations between many addresses on a private IPv4 network and a single public IPv4 address. It is not capable of translating between IPv4 and IPv6, nor is it capable of translating IPv6 packets between networks.

mirage-nat knows how to translate TCP and UDP packets. It can also translate some ICMP types:

  • timestamp requests and replies
  • information requests and replies
  • echo requests and replies (in other words, ping should work)

mirage-nat makes no attempt to track connection state and currently does not expire rules based on time's passage. Mirage_nat_lru expires the least recently used rules in response to memory pressure. In practice, this means rules will stick around as long as there's space for them, with no consideration for whether communication between hosts is still occurring. Notably, remote hosts which have been contacted by a host on the private network may be able to send traffic back through the NAT long after the host thinks the connection has been terminated.

Getting Started

The included example/ directory contains an example MirageOS unikernel which uses Mirage_nat_lru to provide source NATting between a private network and a public one. Try mirage configure --help in that directory for information on configuration parameters, and read unikernel.ml for more on how it works.

Network Setup

To get started, you'll need a "public" network (one from which the Internet is accessible) and a "private" network (one which doesn't have outside access; this will be provided by the unikernel once it's online). Configure the unikernel with the correct public network information, and an IP address on the private network. For example, to set up a unikernel with a public network on 192.168.3.1/24, and a private 10.0.0.0/24 network, if configured for Xen:

mirage configure -t xen --public-ipv4=192.168.3.1/24 --public-ipv4-gateway=192.168.3.254 --private-ipv4=10.0.0.1/24

Then follow the usual MirageOS workflow:

make depend
make

and start the unikernel as appropriate for the hypervisor:

sudo xl create simple_nat.xl -c

To see more console output, try increasing the log level with the -l argument to mirage configure.

Users

qubes-mirage-firewall, the unikernel firewall for QubesOS, uses mirage-nat to provide network address translation for guest domains.

mirage-nat's People

Contributors

craigfe avatar hannesm avatar linse avatar pqwy avatar samoht avatar seveneng avatar talex5 avatar yallop avatar yomimono avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mirage-nat's Issues

mirage-nat doesn't install with latest mirage tool (3.7.2)

The current version of mirage (3.7.2) depends on "mirage-clock-freestanding" { >= "3.0.0" & < "4.0.0"}, which depends on mirage-clock with the same version (i.e. at least 3).

However, the current mirage-nat (1.2.0) depends on mirage-clock-lwt, which I think is now obsolete and depends on mirage-clock < 3.

Is this repository ready for a new release?

NAT should use a fixed-size lookup table

The NAT table tends to become large, and being a hashtable it grows suddenly. On systems without virtual memory (e.g. mirage-xen) this can lead to out-of-memory problems. It might be better to allow preallocating a fixed-size table and expiring entries when it becomes full.

I'm currently trying this as a work-around:

talex5/qubes-mirage-firewall@62aec06

The tests do not pass

ocaml setup.ml -test
...OK, passed 100 tests.

Ran: 3 tests in: 0.16 seconds.
OK
..TT...
Ran: 7 tests in: 0.11 seconds.
FAILED: Cases: 7 Tried: 7 Errors: 0 Failures: 0 Skip:  0 Todo: 2 Timeouts: 0.
W: Test 'test_rewrite' fails: Command '/Users/thomas/git/ocaml-nat/_build/lib_test/test_rewrite.byte' terminated with error code 1

I guess there are still TODO, but opening an issue to keep track of it.

IPv4 fragmentation and reassembly

hello,

when working on fixing mirage/qubes-mirage-firewall#73, I looked into the interaction between mirage-nat and qubes-mirage-firewall. If I understand correctly:

  • every incoming piece of data is decoded into a Nat_packet.t (by of_ipv4_packet)
  • every outgoing Nat_packet.t is encoded into a cstruct (by into_cstruct)

This works fine for complete IPv4 segments, but it fails for fragmented ones (on the receiving side, the transport header length exceeds the segment length (leading to an error message); on the sending side the buffer is smaller than the to-be-transmitted packet - leading to an error message).

(a) Since mirage-nat does encoding and decoding, I assume it should as well be responsible for handling fragmentation (otherwise, as seen in the branches linked here, qubes-mirage-firewall needs to decode, check fragmentation cache, and encode the full frame before passing it to mirage-nat). For doing this:

  • of_ipv4_packet needs to take a Fragments.Cache.t (from mirage-tcpip/src/ipv4/fragments.ml), and return a Fragments.Cache.t * t option
  • into_cstruct is a bit more involved: it needs the interface mtu to slice the data into multiple segments (and then either return a list of IPv4 segments (to_cstruct), or a way to get more buffers (into_cstruct))

(b) As alternative, mirage-nat could expect the first segment (which contains the transport header) to arrive first (since IP is not reliable, its fine to drop segments), decode (only) the transport header to do the NAT, and keep the IPv4 ID (which must be the same in all subsequent segments) in a table to NAT the subsequent segments. The upside is that no caches are necessary. The downside is that this only works if the MTU on the receive and send interface are the same.

NB: the to_cstruct / into_cstruct should preserve (and respect!) the don't fragment bit, and instead of fragmenting a segment send back an ICMP error.
NB: the branches linked above neither implement (a) or (b) (in the branches, qubes-mirage-firewall does the reassembly, the fragmentation is done by a weird interaction between q-m-f and mirage-nat), I'd prefer (a) (though (b) has its charme as well).

Tl;DR: What do you think, would you be happy with a PR that does (a) [and adapts your very fine example unikernel]?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.