liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

default.nix (2852B)


      1 ## Firewall
      2 ## ========
      3 ##
      4 ## Provides a service to create an nftables ruleset based on
      5 ## configuration supplied to it.
      6 
      7 {
      8   lib,
      9   pkgs,
     10   config,
     11   ...
     12 }:
     13 let
     14   inherit (lib) mkOption types;
     15   inherit (pkgs) liminix;
     16 
     17   kmodules = pkgs.kmodloader.override {
     18     inherit (config.system.outputs) kernel;
     19     targets = [
     20       "nft_fib_ipv4"
     21       "nft_fib_ipv6"
     22       "nf_log_syslog"
     23 
     24       "nf_conntrack"
     25       "nf_defrag_ipv4"
     26       "nf_defrag_ipv6"
     27       "nf_log_syslog"
     28       "nf_nat"
     29       "nf_reject_ipv4"
     30       "nf_reject_ipv6"
     31       "nf_tables"
     32       "nft_chain_nat"
     33       "nft_ct"
     34       "nft_fib"
     35       "nft_fib_ipv4"
     36       "nft_fib_ipv6"
     37       "nft_limit"
     38       "nft_log"
     39       "nft_masq"
     40       "nft_nat"
     41       "nft_reject"
     42       "nft_reject_inet"
     43       "nft_reject_ipv4"
     44       "nft_reject_ipv6"
     45     ];
     46   };
     47 in
     48 {
     49   # we use the secrets subscriber to restart when interfaces change
     50   imports = [ ../secrets ];
     51 
     52   options = {
     53     system.service.firewall = mkOption {
     54       type = liminix.lib.types.serviceDefn;
     55     };
     56   };
     57   config = {
     58     system.service.firewall =
     59       let
     60         svc = config.system.callService ./service.nix {
     61           extraRules = mkOption {
     62             type = types.attrsOf types.attrs;
     63             description = "firewall ruleset";
     64             default = { };
     65           };
     66           zones = mkOption {
     67             type = types.attrsOf (types.listOf liminix.lib.types.service);
     68             default = { };
     69             example = lib.literalExpression ''
     70               {
     71                 lan = with config.hardware.networkInterfaces; [ int ];
     72                 wan = [ config.services.ppp0 ];
     73               }
     74             '';
     75           };
     76           rules = mkOption {
     77             type = types.attrsOf types.attrs; # we could usefully tighten this a bit :-)
     78             default = import ./default-rules.nix;
     79             description = "firewall ruleset";
     80           };
     81         };
     82       in
     83       svc
     84       // {
     85         build =
     86           args:
     87           let
     88             args' = args // {
     89               dependencies = (args.dependencies or [ ]) ++ [ kmodules ];
     90             };
     91           in
     92           svc.build args';
     93       };
     94     programs.busybox.applets = [
     95       "insmod"
     96       "rmmod"
     97     ];
     98     kernel.config = {
     99       NETFILTER = "y";
    100       NETFILTER_ADVANCED = "y";
    101       NETFILTER_NETLINK = "m";
    102       NF_CONNTRACK = "m";
    103 
    104       NETLINK_DIAG = "y";
    105 
    106       NFT_CT = "m";
    107       NFT_FIB_IPV4 = "m";
    108       NFT_FIB_IPV6 = "m";
    109       NFT_LIMIT = "m";
    110       NFT_LOG = "m";
    111       NFT_MASQ = "m";
    112       NFT_NAT = "m";
    113       NFT_REJECT = "m";
    114       NFT_REJECT_INET = "m";
    115 
    116       NF_CT_PROTO_SCTP = "y";
    117       NF_CT_PROTO_UDPLITE = "y";
    118       NF_LOG_SYSLOG = "m";
    119       NF_NAT = "m";
    120       NF_NAT_MASQUERADE = "y";
    121       NF_TABLES = "m";
    122       NF_TABLES_INET = "y";
    123       NF_TABLES_IPV4 = "y";
    124       NF_TABLES_IPV6 = "y";
    125     };
    126   };
    127 }