mirror of
https://github.com/mirage/qubes-mirage-firewall.git
synced 2024-06-26 14:12:23 +00:00
Allow naming hosts and add examples to rules.ml
Previously we passed in the interface, from which it was possible (but a little difficult) to extract the IP address and compare with some predefined ones. Now, we allow the user to list IP addresses and named tags for them, which can be matched on easily. Added example rules showing how to block access to an external service or allow SSH between AppVMs. Requested at https://groups.google.com/d/msg/qubes-users/BnL0nZGpJOE/61HOBg1rCgAJ.
This commit is contained in:
parent
433f3e8f01
commit
acf46b4231
14
firewall.ml
14
firewall.ml
|
@ -125,9 +125,21 @@ let nat_to t ~host ~port packet =
|
|||
|
||||
(* Handle incoming packets *)
|
||||
|
||||
let parse_ips ips = List.map (fun (ip_str, id) -> (Ipaddr.of_string_exn ip_str, id)) ips
|
||||
|
||||
let clients = parse_ips Rules.clients
|
||||
let externals = parse_ips Rules.externals
|
||||
|
||||
let resolve_host = function
|
||||
| `Client c -> `Client (try List.assoc (Ipaddr.V4 c#other_ip) clients with Not_found -> `Unknown)
|
||||
| `External ip -> `External (try List.assoc ip externals with Not_found -> `Unknown)
|
||||
| (`Client_gateway | `Firewall_uplink | `NetVM) as x -> x
|
||||
|
||||
let apply_rules t rules info =
|
||||
let packet = info.packet in
|
||||
match rules info, info.dst with
|
||||
let resolved_info = { info with src = resolve_host info.src;
|
||||
dst = resolve_host info.dst } in
|
||||
match rules resolved_info, info.dst with
|
||||
| `Accept, `Client client_link -> transmit_ipv4 packet client_link
|
||||
| `Accept, (`External _ | `NetVM) -> transmit_ipv4 packet t.Router.uplink
|
||||
| `Accept, (`Firewall_uplink | `Client_gateway) ->
|
||||
|
|
12
packet.ml
12
packet.ml
|
@ -13,9 +13,15 @@ type ports = {
|
|||
type host =
|
||||
[ `Client of client_link | `Client_gateway | `Firewall_uplink | `NetVM | `External of Ipaddr.t ]
|
||||
|
||||
type info = {
|
||||
(* Note: 'a is either [host], or the result of applying [Rules.clients] and [Rules.externals] to a host. *)
|
||||
type 'a info = {
|
||||
packet : Nat_packet.t;
|
||||
src : host;
|
||||
dst : host;
|
||||
src : 'a;
|
||||
dst : 'a;
|
||||
proto : [ `UDP of ports | `TCP of ports | `ICMP | `Unknown ];
|
||||
}
|
||||
|
||||
(* 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
|
||||
|
|
26
rules.ml
26
rules.ml
|
@ -25,13 +25,37 @@ open Packet
|
|||
- [`Drop reason] drop the packet and log the reason.
|
||||
*)
|
||||
|
||||
(* List your AppVM IP addresses here if you want to match on them in the rules below.
|
||||
Any client not listed here will appear as [`Client `Unknown]. *)
|
||||
let clients = [
|
||||
(*
|
||||
"10.137.0.12", `Dev;
|
||||
"10.137.0.14", `Untrusted;
|
||||
*)
|
||||
]
|
||||
|
||||
(* List your external (non-AppVM) IP addresses here if you want to match on them in the rules below.
|
||||
Any external machine not listed here will appear as [`External `Unknown]. *)
|
||||
let externals = [
|
||||
(*
|
||||
"8.8.8.8", `GoogleDNS;
|
||||
*)
|
||||
]
|
||||
|
||||
(** Decide what to do with a packet from a client VM.
|
||||
Note: If the packet matched an existing NAT rule then this isn't called. *)
|
||||
let from_client = function
|
||||
(* Examples (add your own rules here): *)
|
||||
(*
|
||||
| { src = `Client `Dev; dst = `Client `Untrusted; proto = `TCP { dport = 22 } } -> `Accept
|
||||
| { src = `Client _; dst = `Client _; proto = `TCP _; packet }
|
||||
when not (is_tcp_start packet) -> `Accept
|
||||
| { dst = `External `GoogleDNS } -> `Drop "block Google DNS"
|
||||
*)
|
||||
| { dst = (`External _ | `NetVM) } -> `NAT
|
||||
| { dst = `Client_gateway; proto = `UDP { dport = 53 } } -> `NAT_to (`NetVM, 53)
|
||||
| { dst = (`Client_gateway | `Firewall_uplink) } -> `Drop "packet addressed to firewall itself"
|
||||
| { dst = `Client _ } -> `Drop "prevent communication between client VMs"
|
||||
| { dst = `Client _ } -> `Drop "prevent communication between client VMs by default"
|
||||
|
||||
(** Decide what to do with a packet received from the outside world.
|
||||
Note: If the packet matched an existing NAT rule then this isn't called. *)
|
||||
|
|
Loading…
Reference in New Issue
Block a user