network.ncdi 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. include_guard "network"
  2. include "pppoe.ncdi"
  3. include "dhcp_server.ncdi"
  4. include "unbound.ncdi"
  5. include "network_control_server.ncdi"
  6. include "port_forwarding.ncdi"
  7. template network_main {
  8. log("notice", "NCD starting");
  9. log_r("notice", "NCD stopped");
  10. # Load ipv6 module so we can disable ipv6.
  11. runonce({"/sbin/modprobe", "ipv6"});
  12. # Set some sysctl's.
  13. runonce({"/sbin/sysctl", "net.ipv4.ip_forward=1"});
  14. runonce({"/sbin/sysctl", "net.ipv6.conf.all.disable_ipv6=1"});
  15. # Setup iptables INPUT chain.
  16. net.iptables.policy("filter", "INPUT", "ACCEPT", "ACCEPT");
  17. net.iptables.append("filter", "INPUT", "-i", "lo", "-j", "ACCEPT");
  18. net.iptables.append("filter", "INPUT", "-m", "conntrack", "--ctstate", "ESTABLISHED", "-j", "ACCEPT");
  19. # Setup iptables OUTPUT chain.
  20. net.iptables.policy("filter", "OUTPUT", "ACCEPT", "ACCEPT");
  21. # Setup iptables FORWARD chain.
  22. net.iptables.policy("filter", "FORWARD", "DROP", "ACCEPT");
  23. net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "ESTABLISHED", "-j", "ACCEPT");
  24. net.iptables.append("filter", "FORWARD", "-m", "connmark", "--mark", "0x1/0x1", "-j", "ACCEPT");
  25. # Create dependency scope.
  26. depend_scope() depsc;
  27. # Start processes.
  28. process_manager() mgr;
  29. mgr->start("network_lan", {});
  30. mgr->start("network_serverif", {});
  31. mgr->start("network_internet", {});
  32. mgr->start("network_lan_internet_rules", {});
  33. mgr->start("network_serverif_internet_rules", {});
  34. mgr->start("network_lan_serverif_rules", {});
  35. mgr->start("network_lan_dhcp_server", {});
  36. mgr->start("network_unbound", {});
  37. mgr->start("network_port_forwarding", {});
  38. mgr->start("network_start_control_server", {});
  39. }
  40. template network_weak_hostmodel_rules {
  41. alias("_arg0") dev;
  42. alias("_arg1") addr;
  43. concat("INPUT_hostmodel_drop_", dev) drop_chain;
  44. net.iptables.newchain("filter", drop_chain);
  45. net.iptables.append("filter", drop_chain, "-j", "DROP");
  46. net.iptables.append("filter", "INPUT", "-d", addr, "!", "-i", dev, "-j", drop_chain);
  47. }
  48. template network_weak_hostmodel_exception {
  49. alias("_arg0") dev;
  50. alias("_arg1") match;
  51. concat("INPUT_hostmodel_drop_", dev) drop_chain;
  52. listfrom({"filter", drop_chain}, match, {"-j", "RETURN"}) args;
  53. net.iptables.insert(args);
  54. }
  55. template network_lan {
  56. alias("_caller") main;
  57. # Some configuration.
  58. var("enp1s0") dev;
  59. var("192.168.111.1") addr;
  60. var("24") prefix;
  61. var("192.168.111.100") dhcp_start;
  62. var("192.168.111.149") dhcp_end;
  63. main.depsc->provide("lan_config");
  64. # Wait for device, set up, wait for link.
  65. net.backend.waitdevice(dev);
  66. net.up(dev);
  67. net.backend.waitlink(dev);
  68. # Weak host model.
  69. call("network_weak_hostmodel_rules", {dev, addr});
  70. # Assign IP address.
  71. net.ipv4.addr(dev, addr, prefix);
  72. # Do SNAT for port forwardings when connections originate from the inside.
  73. net.iptables.append("nat", "POSTROUTING", "-m", "connmark", "--mark", "0x2/0x2", "-j", "SNAT", "--to-source", addr, "--random");
  74. main.depsc->provide("lan");
  75. }
  76. template network_serverif {
  77. alias("_caller") main;
  78. # Some configuration.
  79. var("enp3s0") dev;
  80. var("192.168.113.1") addr;
  81. var("24") prefix;
  82. main.depsc->provide("serverif_config");
  83. # Wait for device, set up, wait for link.
  84. net.backend.waitdevice(dev);
  85. net.up(dev);
  86. net.backend.waitlink(dev);
  87. # Weak host model.
  88. call("network_weak_hostmodel_rules", {dev, addr});
  89. # Assign IP address.
  90. net.ipv4.addr(dev, addr, prefix);
  91. # Do SNAT for port forwardings when connections originate from the inside.
  92. net.iptables.append("nat", "POSTROUTING", "-m", "connmark", "--mark", "0x4/0x4", "-j", "SNAT", "--to-source", addr, "--random");
  93. main.depsc->provide("serverif");
  94. }
  95. template network_internet {
  96. alias("_caller") main;
  97. # Some configuration.
  98. var("enp2s0") pppoe_dev;
  99. var("MISSING") pppoe_username;
  100. var("MISSING") pppoe_password;
  101. # Wait for device, set up, wait for link.
  102. net.backend.waitdevice(pppoe_dev);
  103. net.up(pppoe_dev);
  104. net.backend.waitlink(pppoe_dev);
  105. log("notice", "PPPoE started");
  106. log_r("notice", "PPPoE stopped");
  107. # Start PPPoE.
  108. call("pppoe", {pppoe_dev, pppoe_username, pppoe_password, "network_internet_pppoe_preup"}) pppoe;
  109. # Grab configuration.
  110. var(pppoe.ifname) dev;
  111. var(pppoe.local_ip) addr;
  112. var(pppoe.remote_ip) remote_addr;
  113. var(pppoe.dns_servers) dns_servers;
  114. to_string(dns_servers) dns_str;
  115. log("notice", "PPPoE up dev=", dev, " local=", addr, " remote=", remote_addr, " dns=", dns_str);
  116. log_r("notice", "PPPoE down");
  117. # Add default route.
  118. net.ipv4.route("0.0.0.0/0", remote_addr, "20", dev);
  119. main.depsc->provide("internet");
  120. }
  121. template network_internet_pppoe_preup {
  122. alias("_arg0") dev;
  123. alias("_arg1") addr;
  124. alias("_arg2") remote_ip;
  125. alias("_arg3") dns_servers;
  126. # Weak host model.
  127. call("network_weak_hostmodel_rules", {dev, addr});
  128. # Drop packets to this system, except some things.
  129. net.iptables.newchain("filter", "INPUT_internet_drop");
  130. #net.iptables.append("filter", "INPUT_internet_drop", "-p", "tcp", "--dport", "22", "-j", "RETURN");
  131. net.iptables.append("filter", "INPUT_internet_drop", "-j", "DROP");
  132. net.iptables.append("filter", "INPUT", "-i", dev, "-j", "INPUT_internet_drop");
  133. # Do SNAT for packets going out.
  134. net.iptables.append("nat", "POSTROUTING", "-o", dev, "-j", "SNAT", "--to-source", addr, "--random");
  135. # Do MMS clamping.
  136. net.iptables.append("mangle", "OUTPUT", "-o", dev, "-p", "tcp", "--tcp-flags", "SYN,RST", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu");
  137. net.iptables.append("mangle", "FORWARD", "-o", dev, "-p", "tcp", "--tcp-flags", "SYN,RST", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu");
  138. }
  139. template network_lan_internet_rules {
  140. alias("_caller") main;
  141. main.depsc->depend({"lan"}) lan;
  142. main.depsc->depend({"internet"}) internet;
  143. # Add exception to weak host model of internet interface.
  144. call("network_weak_hostmodel_exception", {internet.dev, {"-i", lan.dev}});
  145. net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "NEW", "-i", lan.dev, "-o", internet.dev, "-j", "ACCEPT");
  146. }
  147. template network_serverif_internet_rules {
  148. alias("_caller") main;
  149. main.depsc->depend({"serverif"}) serverif;
  150. main.depsc->depend({"internet"}) internet;
  151. # Allow traffic from LAN to Internet.
  152. call("network_weak_hostmodel_exception", {internet.dev, {"-i", serverif.dev}});
  153. net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "NEW", "-i", serverif.dev, "-o", internet.dev, "-j", "ACCEPT");
  154. }
  155. template network_lan_serverif_rules {
  156. alias("_caller") main;
  157. main.depsc->depend({"lan"}) lan;
  158. main.depsc->depend({"serverif"}) serverif;
  159. # Allow traffic from serverif to LAN.
  160. call("network_weak_hostmodel_exception", {serverif.dev, {"-i", lan.dev}});
  161. net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "NEW", "-i", lan.dev, "-o", serverif.dev, "-j", "ACCEPT");
  162. # Allow traffic from LAN to serverif.
  163. call("network_weak_hostmodel_exception", {lan.dev, {"-i", serverif.dev}});
  164. net.iptables.append("filter", "FORWARD", "-m", "conntrack", "--ctstate", "NEW", "-i", serverif.dev, "-o", lan.dev, "-j", "ACCEPT");
  165. }
  166. template network_lan_dhcp_server {
  167. alias("_caller") main;
  168. main.depsc->depend({"lan"}) lan;
  169. # Start DHCP server.
  170. call("dhcp_server", {lan.addr, lan.prefix, lan.dhcp_start, lan.dhcp_end, {lan.addr}, {lan.addr}});
  171. }
  172. template network_unbound {
  173. alias("_caller") main;
  174. main.depsc->depend({"lan_config"}) lan_config;
  175. main.depsc->depend({"serverif_config"}) serverif_config;
  176. # Add DNS servers.
  177. net.dns({"127.0.0.1"}, "20");
  178. # Build configuration.
  179. ipv4_net_from_addr_and_prefix(lan_config.addr, lan_config.prefix) lan_network;
  180. ipv4_net_from_addr_and_prefix(serverif_config.addr, serverif_config.prefix) serverif_network;
  181. var({
  182. {lan_network, lan_config.prefix, "allow"},
  183. {serverif_network, serverif_config.prefix, "allow"}
  184. }) access_control_rules;
  185. # Start Unbound.
  186. call("unbound", {"lan", access_control_rules});
  187. }
  188. template network_port_forwarding {
  189. alias("_caller") main;
  190. # Start forwarding.
  191. call("port_forwarding", {"/var/lib/ncd-port-forwardings.ncdvalue", "network_port_forwarding_rules"}) pf;
  192. main.depsc->provide("port_forwarding");
  193. }
  194. template network_port_forwarding_rules {
  195. alias("_caller.main") main;
  196. alias("_arg0") protocol;
  197. alias("_arg1") port_start;
  198. alias("_arg2") port_end;
  199. alias("_arg3") dest_addr;
  200. # Get access to lan and serverif configuration.
  201. main.depsc->depend({"lan_config"}) lan;
  202. main.depsc->depend({"serverif_config"}) serverif;
  203. # Wait for Internet interface.
  204. main.depsc->depend({"internet"}) internet;
  205. # Build port range string.
  206. concat(port_start, ":", port_end) port_range;
  207. # Add rules.
  208. net.iptables.append("nat", "PREROUTING", "-d", internet.addr, "-p", protocol, "--dport", port_range, "-i", lan.dev, "-j", "CONNMARK", "--set-xmark", "0x3/0x3");
  209. net.iptables.append("nat", "PREROUTING", "-d", internet.addr, "-p", protocol, "--dport", port_range, "-i", serverif.dev, "-j", "CONNMARK", "--set-xmark", "0x5/0x5");
  210. net.iptables.append("nat", "PREROUTING", "-d", internet.addr, "-p", protocol, "--dport", port_range, "-i", internet.dev, "-j", "CONNMARK", "--set-xmark", "0x1/0x1");
  211. net.iptables.append("nat", "PREROUTING", "-d", internet.addr, "-p", protocol, "--dport", port_range, "-j", "DNAT", "--to-destination", dest_addr);
  212. }
  213. template network_start_control_server {
  214. alias("_caller") main;
  215. main.depsc->depend({"lan_config"}) lan_config;
  216. # Start control server.
  217. call("network_control_server", {"/run/ncd-control.socket",
  218. "network_control_list_port_forwardings",
  219. "network_control_add_port_forwarding",
  220. "network_control_remove_port_forwarding"});
  221. }
  222. template network_control_list_port_forwardings {
  223. alias("_caller.main") main;
  224. main.depsc->depend({"port_forwarding"}) port_forwarding;
  225. var(port_forwarding.pf.map.keys) port_forwardings;
  226. }
  227. template network_control_add_port_forwarding {
  228. alias("_caller.main") main;
  229. alias("_arg0") protocol;
  230. alias("_arg1") port_start;
  231. alias("_arg2") port_end;
  232. alias("_arg3") dest_addr;
  233. var("") try_error_text;
  234. try("network_verify_port_forwarding_try", {}) verify_try;
  235. If (verify_try.succeeded) {
  236. main.depsc->depend({"port_forwarding"}) port_forwarding;
  237. call("port_forwarding_add", {"_caller.port_forwarding.pf", protocol, port_start, port_end, dest_addr}) call;
  238. alias("call.succeeded") succeeded;
  239. alias("call.error_text") error_text;
  240. } Else {
  241. var("false") succeeded;
  242. alias("try_error_text") error_text;
  243. } branch;
  244. alias("branch.succeeded") succeeded;
  245. alias("branch.error_text") error_text;
  246. }
  247. template network_control_remove_port_forwarding {
  248. alias("_caller.main") main;
  249. alias("_arg0") protocol;
  250. alias("_arg1") port_start;
  251. alias("_arg2") port_end;
  252. alias("_arg3") dest_addr;
  253. main.depsc->depend({"port_forwarding"}) port_forwarding;
  254. call("port_forwarding_remove", {"_caller.port_forwarding.pf", protocol, port_start, port_end, dest_addr}) call;
  255. alias("call.succeeded") succeeded;
  256. alias("call.error_text") error_text;
  257. }
  258. template network_verify_port_forwarding_try {
  259. alias("_caller") c;
  260. c.main.depsc->depend({"lan_config"}) lan;
  261. c.main.depsc->depend({"serverif_config"}) serverif;
  262. net.ipv4.addr_in_network(c.dest_addr, lan.addr, lan.prefix) in_lan;
  263. net.ipv4.addr_in_network(c.dest_addr, serverif.addr, serverif.prefix) in_serverif;
  264. If (in_lan) {
  265. print();
  266. }
  267. Elif (in_serverif) {
  268. print();
  269. }
  270. Else {
  271. c.try_error_text->set("Destination address does not belong to any permitted network.");
  272. _try->assert("false");
  273. };
  274. }