configurations of hq services
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

configuration.nix 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. { config, pkgs, lib, modulesPath, ... }:
  2. let
  3. coreAddress = "172.20.72.40";
  4. corePrefixlen = 26;
  5. meshInterface = "bmx";
  6. meshLoopback = "bmx_prime";
  7. ddmeshRegisterUrl = "https://register.freifunk-dresden.de/bot.php";
  8. secrets = import <secrets/hosts/freifunk>;
  9. ddmeshRegisterKey = secrets.ddmeshRegisterKey;
  10. ddmeshNode = 51073;
  11. ddmeshAddrPart = "200.74";
  12. rt_table = 7;
  13. bmxd = import ../../../lib/pkgs/bmxd.nix { inherit pkgs; };
  14. sysinfo-json =
  15. import ./sysinfo-json.nix { inherit pkgs bmxd ddmeshNode; };
  16. in {
  17. imports = [
  18. (modulesPath + "/profiles/minimal.nix")
  19. ../../../lib
  20. ../../../lib/lxc-container.nix
  21. ../../../lib/shared.nix
  22. ];
  23. boot.tmpOnTmpfs = true;
  24. c3d2 = {
  25. isInHq = false;
  26. enableHail = false;
  27. hq.statistics.enable = true;
  28. };
  29. services.collectd.plugins.protocols = "";
  30. networking.hostName = "freifunk";
  31. networking.useNetworkd = true;
  32. networking.nameservers = [ "172.20.73.8" "9.9.9.9" ];
  33. networking.firewall.enable = false;
  34. networking.nat = {
  35. enable = true;
  36. # This doesn't really work, hence the `extraCommands`
  37. externalInterface = meshInterface;
  38. #internalInterfaces = [ "core" ];
  39. # Setup routing into Freifunk,
  40. # masquerading anything that isn't already their IP range
  41. extraCommands = ''
  42. ${pkgs.iproute}/bin/ip rule del priority 300 || true
  43. ${pkgs.iproute}/bin/ip rule add to 10.200.0.0/16 table bmx priority 300
  44. ${pkgs.iptables}/bin/iptables -t nat -F POSTROUTING
  45. ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING \
  46. \! --source 10.200.0.0/15 -o ${meshInterface} -j SNAT --to 10.200.${ddmeshAddrPart}
  47. set -e
  48. '';
  49. forwardPorts = [ {
  50. destination = "172.20.73.8";
  51. proto = "udp";
  52. sourcePort = 53;
  53. } {
  54. destination = "172.20.73.8";
  55. proto = "tcp";
  56. sourcePort = 53;
  57. } ];
  58. };
  59. # Configure rt_table name
  60. networking.iproute2 = {
  61. enable = true;
  62. rttablesExtraConfig = "${toString rt_table} bmx";
  63. };
  64. # Required for krops: ssh git
  65. services.openssh.enable = true;
  66. environment.systemPackages = with pkgs; [ git tcpdump ];
  67. systemd.network = {
  68. netdevs = {
  69. # Dummy interface for primary (10.200) address
  70. bmx_prime = {
  71. enable = true;
  72. netdevConfig = {
  73. Kind = "bridge";
  74. Name = meshLoopback;
  75. };
  76. };
  77. };
  78. networks = {
  79. # Wired mesh interface
  80. "10-bmx" = {
  81. enable = true;
  82. matchConfig = { Name = meshInterface; };
  83. addresses = [ {
  84. addressConfig = {
  85. Address = "10.201.${ddmeshAddrPart}/16";
  86. Broadcast = "10.255.255.255";
  87. };
  88. } ];
  89. };
  90. # Dummy interface for primary (10.200) address
  91. "11-bmx-loopback" = {
  92. enable = true;
  93. matchConfig = { Name = meshLoopback; };
  94. addresses = [ {
  95. addressConfig = {
  96. Address = "10.200.${ddmeshAddrPart}/32";
  97. Broadcast = "10.255.255.255";
  98. };
  99. } ];
  100. };
  101. # ZW
  102. "20-core" = {
  103. enable = true;
  104. matchConfig = { Name = "core"; };
  105. addresses = map (Address: { addressConfig = { inherit Address; }; }) [
  106. "${coreAddress}/${toString corePrefixlen}"
  107. "2a02:8106:208:5281:8000::1/64"
  108. "fd23:42:c3d2:581:8000::1/64"
  109. ];
  110. routes = map (Gateway: { routeConfig = { inherit Gateway; }; }) [
  111. # upstream1
  112. "2a02:8106:208:5281::b:0"
  113. # anon1
  114. "172.20.72.7"
  115. ];
  116. };
  117. };
  118. };
  119. # Freifunk Dresden routing daemon
  120. systemd.services.bmxd = {
  121. after = [ "systemd-networkd.service" ];
  122. wantedBy = [ "network.target" ];
  123. serviceConfig = {
  124. ExecStart = ''
  125. ${bmxd}/sbin/bmxd \
  126. --rt_table_offset=${toString rt_table} \
  127. --no_fork 1 \
  128. --throw-rules 0 \
  129. --prio-rules 0 \
  130. --gateway_tunnel_network 10.200.0.0/16 \
  131. --purge_timeout 20 \
  132. --one_way_tunnel 1 \
  133. -g 500000/50000 \
  134. dev=bmx_prime /linklayer 0 \
  135. dev=${meshInterface} /linklayer 1
  136. '';
  137. Restart = "always";
  138. };
  139. };
  140. # Re-register periodically
  141. systemd.services.ddmesh-register-node = {
  142. script = ''
  143. ${pkgs.curl}/bin/curl \
  144. -o /tmp/ddmesh-registration.json \
  145. '${ddmeshRegisterUrl}?registerkey=${ddmeshRegisterKey}&node=${toString ddmeshNode}'
  146. '';
  147. serviceConfig = {
  148. User = "nobody";
  149. Group = "nogroup";
  150. };
  151. };
  152. systemd.timers.ddmesh-register-node = {
  153. partOf = [ "ddmesh-register-node.service" ];
  154. wantedBy = [ "timers.target" ];
  155. timerConfig.OnCalendar = "daily";
  156. };
  157. environment.etc."freifunk-server-version".text = "Custom NixOS configuration: 0.0.0";
  158. # Refresh sysinfo.json
  159. systemd.services.sysinfo-json = {
  160. script = ''
  161. ${sysinfo-json}/bin/bmxddump.sh
  162. ${sysinfo-json}/bin/sysinfo-json.cgi > /tmp/sysinfo.json
  163. '';
  164. };
  165. systemd.timers.sysinfo-json = {
  166. partOf = [ "sysinfo-json.service" ];
  167. wantedBy = [ "timers.target" ];
  168. timerConfig.OnCalendar = "minutely";
  169. };
  170. # Advertise Freifunk routes to ZW core
  171. services.bird2 = {
  172. enable = true;
  173. config = ''
  174. protocol kernel K4 {
  175. ipv4 {
  176. export all;
  177. };
  178. }
  179. protocol kernel K6 {
  180. ipv6 {
  181. export all;
  182. };
  183. }
  184. protocol device {
  185. scan time 10;
  186. }
  187. protocol ospf v2 ZW4 {
  188. area 0 {
  189. networks {
  190. 172.20.72.0/21;
  191. };
  192. stubnet 10.200.0.0/15;
  193. interface "core" {
  194. authentication cryptographic;
  195. password "${import <secrets/shared/ospf/message-digest-key.nix>}";
  196. };
  197. };
  198. }
  199. protocol ospf v3 ZW6 {
  200. area 0 {
  201. networks {
  202. fd23:42:c3d2:500::/56;
  203. 2a02:8106:208:5200::/56;
  204. 2a02:8106:211:e900::/56;
  205. };
  206. interface "core" {
  207. #authentication cryptographic;
  208. #password "${import <secrets/shared/ospf/message-digest-key.nix>}";
  209. };
  210. };
  211. }
  212. router id ${coreAddress};
  213. '';
  214. };
  215. # HTTP Reverse Proxy to provide services into Freifunk
  216. services.nginx = {
  217. enable = true;
  218. recommendedOptimisation = true;
  219. recommendedGzipSettings = true;
  220. appendHttpConfig = ''
  221. proxy_buffering off;
  222. '';
  223. virtualHosts = {
  224. "c3d2.ffdd" = {
  225. default = true;
  226. root = <this-host/assets>;
  227. locations =
  228. let
  229. sysinfo-json = {
  230. alias = "/tmp/sysinfo.json";
  231. extraConfig = ''
  232. add_header Content-Type "application/json;charset=UTF-8";
  233. '';
  234. };
  235. in {
  236. "/" = {
  237. index = "index.html";
  238. extraConfig = ''
  239. etag off;
  240. add_header etag "\"${builtins.substring 11 32 (<this-host> + "/assets")}\"";
  241. '';
  242. };
  243. "=/sysinfo-json.cgi" = sysinfo-json;
  244. "=/sysinfo.json" = sysinfo-json;
  245. };
  246. };
  247. "storage.hq.c3d2.ffdd".locations."/".proxyPass = "http://storage.hq.c3d2.de/";
  248. "grafana.hq.c3d2.ffdd".locations."/" = {
  249. proxyPass = "https://grafana.hq.c3d2.de/";
  250. extraConfig = ''
  251. proxy_ssl_server_name on;
  252. '';
  253. };
  254. "influxdb.hq.c3d2.ffdd".locations."/".proxyPass = "http://grafana.hq.c3d2.de:8086/";
  255. };
  256. };
  257. # This value determines the NixOS release with which your system is to be
  258. # compatible, in order to avoid breaking some software such as database
  259. # servers. You should change this only after NixOS release notes say you
  260. # should.
  261. system.stateVersion = "20.03"; # Did you read the comment?
  262. }