diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..791a93b --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,10 @@ +keys: + - &admin_jalr 3044E71E3DEFF49B586CF5809BF4FCCB90854DA9 + - &host_pbx age16s0cyttcsp40jup9vnreck6mw500ae8j4ayrmf0tg79ukhgua3vsf4m5j4 +creation_rules: + - path_regex: hosts/pbx/secrets\.yaml$ + key_groups: + - pgp: + - *admin_jalr + age: + - *host_pbx diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index c544387..d17bc4a 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -1,3 +1,4 @@ # Weinturm Open Air Infrastructure +* [fieldpoc](fieldpoc.md) * [HP Switch](hp-switch.md) diff --git a/docs/fieldpoc.md b/docs/fieldpoc.md new file mode 100644 index 0000000..f16a239 --- /dev/null +++ b/docs/fieldpoc.md @@ -0,0 +1,29 @@ +# FieldPOC + +A simple to use, good enough phone system for medium sized DECT networks. + +## Setup + +### Open AXI port on OMM + +```text +ssh omm@$omm +ommconsole +cnf sys uap on +``` + +### Generate secrets + +example `secrets.yaml`: + +```yaml +fieldpoc: + omm: s0m3Pa55w0rd + sip: 000102030405060708090a0b0c0d0e0f +``` + +sipsecret **must** be a 32 character long hexadecimal string. + +```bash +nix run nixpkgs#openssl -- rand -hex 16 +``` diff --git a/docs/hp-switch.md b/docs/hp-switch.md index aaf524b..be66b38 100644 --- a/docs/hp-switch.md +++ b/docs/hp-switch.md @@ -16,16 +16,76 @@ To execute the factory default reset on the switch, perform these steps: The switch will then complete its self test and begin operating with its configuration restored to the factory default settings. +The factory default uses a baud rate of 9600. + ## Serial console Recommendation: use `sio` to access the serial terminal. ```sh -sudo tio --baudrate 9600 /dev/ttyS0 +sudo tio --baudrate 115200 /dev/ttyS0 ``` Quit with CTRL+t, q Turn pager off: `no page` -Change screen length: `screen length 50` +Change screen length: `screen-length 50` + +## Configuration + +### Bauwagen + +#### Ports + +```text +console baud-rate 115200 +write memory +reload + +conf t + +vlan 2 name jugendtreff +vlan 2 qos priority 1 +vlan 2 tagged 23,24 + +vlan 6 name public-event +vlan 6 qos priority 0 +vlan 6 tagged 21-24 + +vlan 7 name weinturm +vlan 7 qos priority 1 +vlan 7 tagged 21-23 +vlan 7 untagged 1-12,24 + +vlan 8 name voice +vlan 8 qos priority 5 +vlan 8 tagged 21-24 +vlan 8 untagged 17,19 +vlan 8 voice + +interface ethernet 1-12 enable + +interface ethernet 17,19 enable +interface ethernet 17,19 name dect + +interface ethernet 21 name kleinturm-copper +interface ethernet 22 name kleinturm-fiber +interface ethernet 22 speed-duplex 1000-full + +interface ethernet 23 name pbx +interface ethernet 23 enable +interface ethernet 23 speed-duplex auto-1000 + +interface ethernet 24 name uplink +interface ethernet 24 speed-duplex auto + +vlan 1 forbid 1-12,17,19,21-24 + +``` + +* WLAN AP +* DECT OMM +* Kleinturmbühne +* Photoprism-Server +* Laptops, Drucker usw. diff --git a/flake.lock b/flake.lock index 44bf3fc..2eefced 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,26 @@ { "nodes": { + "devshell": { + "inputs": { + "nixpkgs": [ + "nix-topology", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1728330715, + "narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=", + "owner": "numtide", + "repo": "devshell", + "rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, "disko": { "inputs": { "nixpkgs": [ @@ -7,11 +28,11 @@ ] }, "locked": { - "lastModified": 1752541678, - "narHash": "sha256-dyhGzkld6jPqnT/UfGV2oqe7tYn7hppAqFvF3GZTyXY=", + "lastModified": 1753140376, + "narHash": "sha256-7lrVrE0jSvZHrxEzvnfHFE/Wkk9DDqb+mYCodI5uuB8=", "owner": "nix-community", "repo": "disko", - "rev": "2bf3421f7fed5c84d9392b62dcb9d76ef09796a7", + "rev": "545aba02960caa78a31bd9a8709a0ad4b6320a5c", "type": "github" }, "original": { @@ -26,17 +47,17 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1711287766, - "narHash": "sha256-2roymGPfsQZC1Lg/i3iffBQ8c86DLEXmuoKQIlbOg5o=", + "lastModified": 1753060267, + "narHash": "sha256-BiVGkJ7CPA85Oc8jsx2ObMVN+pb/IqsgaWEWGhKtA1o=", "ref": "refs/heads/main", - "rev": "f707f212378f9d8de103ac96abcd9d377a2605a8", - "revCount": 56, + "rev": "4b99a84e1b1fe50c364ad6e163f3df4e5e75e10b", + "revCount": 64, "type": "git", - "url": "https://git.clerie.de/clerie/fieldpoc.git" + "url": "https://git.jalr.de/jalr/fieldpoc.git" }, "original": { "type": "git", - "url": "https://git.clerie.de/clerie/fieldpoc.git" + "url": "https://git.jalr.de/jalr/fieldpoc.git" } }, "flake-compat": { @@ -101,11 +122,11 @@ ] }, "locked": { - "lastModified": 1752544374, - "narHash": "sha256-ReX0NG6nIAEtQQjLqeu1vUU2jjZuMlpymNtb4VQYeus=", + "lastModified": 1753055804, + "narHash": "sha256-KerePGJYX47ex6OY3CWsid4AltO2gDtQROunYJ0eCEE=", "owner": "nix-community", "repo": "home-manager", - "rev": "2e00ed310c218127e02ffcf28ddd4e0f669fde3e", + "rev": "adf195f021a8cbb0c317f75b52e96c82616526f9", "type": "github" }, "original": { @@ -197,6 +218,33 @@ "type": "github" } }, + "nix-topology": { + "inputs": { + "devshell": "devshell", + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": [ + "nix-pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1752093877, + "narHash": "sha256-P0TySh6sQl1EhfxjW9ZqGxEyUBSsEpdnchOe1QB0pLA=", + "owner": "oddlama", + "repo": "nix-topology", + "rev": "6a536c4b686ee4bcf07a7b0f8b823584560e2633", + "type": "github" + }, + "original": { + "owner": "oddlama", + "repo": "nix-topology", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1665732960, @@ -215,11 +263,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1752620740, - "narHash": "sha256-f3pO+9lg66mV7IMmmIqG4PL3223TYMlnlw+pnpelbss=", + "lastModified": 1753115646, + "narHash": "sha256-yLuz5cz5Z+sn8DRAfNkrd2Z1cV6DaYO9JMrEz4KZo/c=", "owner": "nixos", "repo": "nixpkgs", - "rev": "32a4e87942101f1c9f9865e04dc3ddb175f5f32e", + "rev": "92c2e04a475523e723c67ef872d8037379073681", "type": "github" }, "original": { @@ -238,6 +286,7 @@ "impermanence": "impermanence", "krops": "krops", "nix-pre-commit-hooks": "nix-pre-commit-hooks", + "nix-topology": "nix-topology", "nixpkgs": "nixpkgs_2", "sops-nix": "sops-nix" } diff --git a/flake.nix b/flake.nix index 43d26da..a861696 100644 --- a/flake.nix +++ b/flake.nix @@ -5,8 +5,8 @@ inputs.nixpkgs.follows = "nixpkgs"; }; - fieldpoc.url = "git+https://git.clerie.de/clerie/fieldpoc.git"; - + fieldpoc.url = "git+https://git.jalr.de/jalr/fieldpoc.git"; + flake-utils.url = "github:numtide/flake-utils"; home-manager = { @@ -16,17 +16,26 @@ impermanence.url = "github:nix-community/impermanence"; + nix-topology = { + url = "github:oddlama/nix-topology"; + inputs = { + flake-utils.follows = "flake-utils"; + nixpkgs.follows = "nixpkgs"; + pre-commit-hooks.follows = "nix-pre-commit-hooks"; + }; + }; + krops = { url = "github:Mic92/krops"; inputs.flake-utils.follows = "flake-utils"; inputs.nixpkgs.follows = "nixpkgs"; }; - + nix-pre-commit-hooks = { url = "github:cachix/git-hooks.nix/master"; inputs.nixpkgs.follows = "nixpkgs"; }; - + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; sops-nix = { @@ -52,6 +61,9 @@ checks = { pre-commit-check = nix-pre-commit-hooks.lib.${system}.run { src = ./.; + excludes = [ + ".envrc" + ]; hooks = { alejandra.enable = true; black.enable = true; @@ -67,8 +79,6 @@ enable = true; settings.ignore = [".direnv"]; }; - tflint.enable = true; - terraform-format.enable = true; }; }; }; @@ -166,7 +176,7 @@ overlays.default = import ./pkgs inputs; nixosConfigurations = let - domain = "lan.weinturm-open-air.net"; + domain = "lan.weinturm.de"; in nixpkgs.lib.mapAttrs (hostname: { diff --git a/hosts/default.nix b/hosts/default.nix index 9f86f5b..40bae16 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -1,5 +1,6 @@ _inputs: { pbx = { system = "x86_64-linux"; + targetHost = "tel.weinturm.de"; }; } diff --git a/hosts/pbx/configuration.nix b/hosts/pbx/configuration.nix index b6ba483..15d1460 100644 --- a/hosts/pbx/configuration.nix +++ b/hosts/pbx/configuration.nix @@ -1,11 +1,9 @@ -{ - config, - lib, - ... -}: { +{config, ...}: { imports = [ ./disko.nix ../../users/jalr + ./networking.nix + ./services ]; weinturm = { @@ -16,9 +14,9 @@ zram.enable = true; }; - networking = { - hostName = "pbx"; - useDHCP = lib.mkDefault true; + security.acme = { + acceptTerms = true; + defaults.email = "it@weinturm-open-air.de"; }; boot = { diff --git a/hosts/pbx/networking.nix b/hosts/pbx/networking.nix new file mode 100644 index 0000000..363d878 --- /dev/null +++ b/hosts/pbx/networking.nix @@ -0,0 +1,173 @@ +{pkgs, ...}: { + networking = { + hostName = "pbx"; + useDHCP = false; + + # Fix Intel NIC e1000e hardware unit hang + localCommands = "${pkgs.ethtool}/bin/ethtool -K enp0s25 tso off gso off"; + + firewall.interfaces = { + weinturm.allowedUDPPorts = [53 67]; + public-event.allowedUDPPorts = [53 67]; + }; + + vlans = { + weinturm = { + id = 7; + interface = "enp0s25"; + }; + public-event = { + id = 6; + interface = "enp0s25"; + }; + voice = { + id = 8; + interface = "enp0s25"; + }; + jugendtreff = { + id = 2; + interface = "enp0s25"; + }; + }; + interfaces = { + weinturm = { + ipv4.addresses = [ + { + address = "192.168.96.1"; + prefixLength = 24; + } + ]; + }; + public-event = { + ipv4.addresses = [ + { + address = "10.10.0.1"; + prefixLength = 20; + } + ]; + }; + voice = { + ipv4.addresses = [ + { + address = "192.168.98.1"; + prefixLength = 24; + } + ]; + }; + jugendtreff = { + useDHCP = true; + }; + }; + dhcpcd.extraConfig = '' + noipv6rs + waitip 6 + denyinterfaces voice + interface jugendtreff + ipv6rs + ia_na 1 + ia_pd 2 weinturm/0 public-event/1 + ''; + nat = { + enable = true; + externalInterface = "jugendtreff"; + internalInterfaces = [ + "weinturm" + "public-event" + "voice" + ]; + }; + defaultGateway.address = "192.168.100.1"; + nameservers = [ + "9.9.9.9" + "149.112.112.112" + "2620:fe::fe" + "2620:fe::9" + ]; + }; + + boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1; + + services = { + dnscache = { + enable = true; + clientIps = [ + "10.10" + "192.168.96" + "192.168.98" + ]; + }; + + radvd = { + enable = true; + config = '' + interface weinturm { + AdvSendAdvert on; + prefix ::/64 { + AdvOnLink on; + AdvAutonomous on; + AdvRouterAddr on; + }; + }; + interface public-event { + AdvSendAdvert on; + prefix ::/64 { + AdvOnLink on; + AdvAutonomous on; + AdvRouterAddr on; + }; + }; + ''; + }; + + kea.dhcp4.settings = { + interfaces-config.interfaces = ["weinturm" "public-event"]; + subnet4 = [ + { + id = 2; + subnet = "192.168.96.0/24"; + pools = [{pool = "192.168.96.20-192.168.96.250";}]; + option-data = [ + { + name = "routers"; + data = "192.168.96.1"; + } + { + name = "domain-name-servers"; + data = "192.168.96.1"; + } + ]; + } + { + id = 3; + subnet = "10.10.0.0/20"; + pools = [{pool = "10.10.1.0-10.10.15.250";}]; + option-data = [ + { + name = "routers"; + data = "10.10.0.1"; + } + { + name = "domain-name-servers"; + data = "10.10.0.1"; + } + ]; + } + ]; + }; + }; + + environment.persistence."/persist".directories = [ + { + directory = "/var/lib/dhcpcd"; + user = "dhcpcd"; + group = "dhcpcd"; + mode = "u=rwx,g=rx,o=rx"; + } + { + directory = "/var/lib/private/kea"; + user = "nobody"; + group = "nogroup"; + mode = "u=rwx,g=rx,o=rx"; + } + ]; +} diff --git a/hosts/pbx/secrets.yaml b/hosts/pbx/secrets.yaml new file mode 100644 index 0000000..bb57413 --- /dev/null +++ b/hosts/pbx/secrets.yaml @@ -0,0 +1,42 @@ +fieldpoc: + omm: ENC[AES256_GCM,data:vOoow2CTJKfCiml5t0k=,iv:BTnf2ASndaNgjYtikTl/B3a5wSRh37epSDT0eGZpLkI=,tag:XOFlh+Ut3JKPd5AUPtrBMw==,type:str] + sip: ENC[AES256_GCM,data:B82q2sD5I6NUa+RphJL+f1IT5qpZYlpMunZUaN5JJ5I=,iv:YzDg/g1C1z7kV2R5LLNMhe2UvaRaurQKaq4SbGfFKmQ=,tag:NuWn3D8u6jiJFZFTaFvv3g==,type:str] +wireguard: + public-ip4: ENC[AES256_GCM,data:NifuhsgDA+/4c+Op9CAg4jhizFdup7FL9jQt4VLGqGzOaY9lMpAFvrWiW2o=,iv:zKN7QTIEo8+KjwtNPxhUVwD+6Xmz48gp9nDAg3bOazo=,tag:GQCBEFAD2en33gKXraXArw==,type:str] +yate: + accounts: + easybell-2: ENC[AES256_GCM,data:jPyZY87r++dNLZCv,iv:BMVICnZujyIbE4IYi+Z9tqn5rbWwnEcoHm9/jWAAhsc=,tag:tk/Vs0tOt6p+a3vD0bJMfw==,type:str] + easybell-3: ENC[AES256_GCM,data:JNQKClwQtYm4GMRp,iv:WsYzrY4vDPQ5voGkQsnOTFTeo09XbE1SfOT6cPv6NJw=,tag:M0hvDGUnFM8lRxRiXNMOUA==,type:str] + easybell-4: ENC[AES256_GCM,data:+bvA76qDKPfSwF/j,iv:Dtnn8JOnIHEXfwjqIWnNlAWdCVIzDbuz1VT6YVPo62w=,tag:NQrKHSV93u5ZAnwYu8EDHQ==,type:str] + easybell-5: ENC[AES256_GCM,data:yj8BuiShAb7gRapp,iv:R0Rj6+Bd54nb4vGfv2yD+H5miWaxLIiMwozgsq/cGN8=,tag:/iQ0r1rTOvDsb+Ik1Rg6oA==,type:str] + easybell-6: ENC[AES256_GCM,data:aAgbSrXbReqUkFq0,iv:VcAsb+246Qys0BJGpTwxTaj5LpQ5fuyJNys3EOMzt5k=,tag:7zXTQNtdsadRiZ/7DrtnHg==,type:str] + easybell-7: ENC[AES256_GCM,data:XU+9wmOTck+xXedv,iv:2ehV8RDzGY68BmlJf5u1oCG/G80uDtFBiA4MGotrFgU=,tag:+mGKoOBjmrB70iOoBTTsKA==,type:str] + easybell-8: ENC[AES256_GCM,data:mVjh6ybvPnT8YhXy,iv:l6RXSdK7Jq/ObOc0gx2fw/9SoZNyGaIAjsl9wBiI7UI=,tag:eIOi54s6RsmYHvrG15pPYQ==,type:str] + easybell-9: ENC[AES256_GCM,data:v0fo8FFrfQQn1H29,iv:jmDFvuRb4W12D9Gh6CLArymyf7efMvsQiELGksTa6Lk=,tag:wylK++mO98LZCsWd1DIT1Q==,type:str] +sops: + age: + - recipient: age16s0cyttcsp40jup9vnreck6mw500ae8j4ayrmf0tg79ukhgua3vsf4m5j4 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzYWFhQUIwVXpRYmtPVlpC + VGF1VnhqcU9DWFVnbEI3dU44KytGeWV0ZERvCnpxd2c2MWlOYzlhNW85OG1ySy95 + UXk4Um4vV29IdmNTb0FGNmw5ZGtIQ0EKLS0tIDFXK2RsMjFwSFRVR0V3S0FTcVBk + TFN1ZFJ2cEZmcHoxSmU1c3o0Q0w1cnMKkT8uBrgL9zyL5PAcqJqQerUdJN8yieVO + JwJvcU3I6reHuVkeNKGCZXdYrNMGeFPWwL88yHJW9MYjhO6xfDo8WQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-23T09:35:37Z" + mac: ENC[AES256_GCM,data:e1hoBiXA1BrLVTaf/siFWwjDSPvgaWYmfzMBjoIqShj1MnUg8vXBfPR89bhsPNtOkW7s0HVsgFeKBMFm0++xkDOb/Xy7gdzPltF4f8P0D5SrlcEoeHgRQWLCgxJLB4suKUBhUauccKKg1NlIVXw3MgizBjG7+bTfGDXZfVGGJy4=,iv:O0JE5V6rVkPnCpxVsGJUpeQZsmJF4ZxPTnqnLwZZnlg=,tag:AnejfZw44+8CnoDHS1KIsg==,type:str] + pgp: + - created_at: "2025-07-18T23:14:45Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4DY/xpNY5WhB0SAQdA5BD/2H3ei7/9sJa1ANVXMF1hqugGXCVnQl818nkziRww + 0WVMtGXiGpwlNYmDX6XVX7s232/PhGPWfpgjjlC/FVnj8wfgs5+LEc/qjRPFD0Vg + 0lwBbdyMeq1B5GeyHwlHLsl1T2PZR5401gyoUH0cvdUGby3NKLNNStJBSVCeUjKP + 5lyRdroUp3e9qqLrItgZylyXY5I3c8MUjYSRc9/LWi6rXr9gvw2VHQITuRe1GQ== + =0PlX + -----END PGP MESSAGE----- + fp: 3044E71E3DEFF49B586CF5809BF4FCCB90854DA9 + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/hosts/pbx/services/default.nix b/hosts/pbx/services/default.nix new file mode 100644 index 0000000..d22355b --- /dev/null +++ b/hosts/pbx/services/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./fieldpoc + ./public-ip4-tunnel.nix + ./webserver.nix + ]; +} diff --git a/hosts/pbx/services/fieldpoc/accounts.nix b/hosts/pbx/services/fieldpoc/accounts.nix new file mode 100644 index 0000000..39a4a97 --- /dev/null +++ b/hosts/pbx/services/fieldpoc/accounts.nix @@ -0,0 +1,63 @@ +{ + config, + lib, + pkgs, + ... +}: { + sops.secrets = lib.listToAttrs ( + map + (number: + lib.nameValuePair "yate/accounts/easybell-${toString number}" { + sopsFile = ../../secrets.yaml; + owner = "yate"; + }) + (lib.lists.range 2 9) + ); + + environment.etc."yate/accfile.conf" = { + mode = "symlink"; + source = "/var/run/yate/accfile.conf"; + }; + + systemd.services.yate.serviceConfig = let + easybellAccount = name: username: let + title = "easybell-${toString name}"; + secretPath = config.sops.secrets."yate/accounts/${title}".path; + in '' + [${title}] + enabled=yes + protocol=sip + username=${username} + password=$(cat "${secretPath}") + registrar=pbx.easybell.de + ''; + accounts = [ + (easybellAccount 2 "CPBX-61tkfwsx-000004") + (easybellAccount 3 "CPBX-61tkfwsx-000005") + (easybellAccount 4 "CPBX-61tkfwsx-000006") + (easybellAccount 5 "CPBX-61tkfwsx-000007") + (easybellAccount 6 "CPBX-61tkfwsx-000008") + (easybellAccount 7 "CPBX-61tkfwsx-000009") + (easybellAccount 8 "CPBX-61tkfwsx-000010") + (easybellAccount 9 "CPBX-61tkfwsx-000011") + ]; + in { + RuntimeDirectory = "yate"; + RuntimeDirectoryMode = lib.mkForce "2750"; + ExecStartPre = pkgs.writeShellScript "yate-pre-start" '' + cat > "$RUNTIME_DIRECTORY/accfile.conf" << EOF + ${lib.concatStringsSep "\n" accounts} + EOF + ''; + }; + + services.yate.config = { + yate.modules."regexroute.yate" = "enable"; + regexroute.default = let + matchCalled = account: ''''${called}^${account}$''; + in { + "${matchCalled "CPBX-61tkfwsx-000003"}" = "sip/sip:2001@192.168.98.11"; + #"^.*$" = ''echo REGEXROUTE DEBUG called=''${called} address=''${address} callsource=''${callsource} formats=''${formats} id=''${id} peerid=''${peerid} ip_host=''${ip_host} ip_port=''${ip_port} overlapped=''${overlapped} rtp_forward=''${rtp_forward} type=''${type} username=''${username} line=''${line} account=''${account} caller=''${caller} called=''${called} module=''${module}''; + }; + }; +} diff --git a/hosts/pbx/services/fieldpoc/default.nix b/hosts/pbx/services/fieldpoc/default.nix new file mode 100644 index 0000000..17c9af7 --- /dev/null +++ b/hosts/pbx/services/fieldpoc/default.nix @@ -0,0 +1,98 @@ +{config, ...}: let + ommIp = "192.168.98.11"; + rtpPorts = { + from = 11000; + to = 11250; + }; +in { + imports = [ + ./accounts.nix + ]; + + sops.secrets."fieldpoc/omm" = { + sopsFile = ../../secrets.yaml; + owner = "fieldpoc"; + }; + sops.secrets."fieldpoc/sip" = { + sopsFile = ../../secrets.yaml; + owner = "fieldpoc"; + }; + + networking.firewall = { + allowedUDPPorts = [5060]; + allowedUDPPortRanges = [ + { + inherit (rtpPorts) from; + inherit (rtpPorts) to; + } + ]; + interfaces.voice.allowedUDPPorts = [53]; + }; + + environment.persistence."/persist".directories = [ + { + directory = "/var/lib/fieldpoc"; + user = "fieldpoc"; + group = "fieldpoc"; + mode = "u=rwx,g=,o="; + } + { + directory = "/var/lib/postgresql"; + user = "postgres"; + group = "postgres"; + mode = "u=rwx,g=rx,o="; + } + ]; + + services = { + yate.config.yrtpchan.general = { + minport = rtpPorts.from; + maxport = rtpPorts.to; + }; + + fieldpoc = { + enable = true; + inherit ommIp; + ommUser = "omm"; + ommPasswordPath = config.sops.secrets."fieldpoc/omm".path; + sipsecretPath = config.sops.secrets."fieldpoc/sip".path; + + dhcp = { + enable = true; + interface = "voice"; + subnet = "192.168.98.0/24"; + pool = "192.168.98.100 - 192.168.98.250"; + router = "192.168.98.1"; + dnsServers = "192.168.98.1"; + omm = ommIp; + reservations = [ + { + name = "rfp-01"; + macAddress = "00:30:42:1b:23:ed"; + ipAddress = ommIp; + } + { + name = "rfp-02"; + macAddress = "00:30:42:1b:21:c1"; + ipAddress = "192.168.98.12"; + } + { + name = "rfp-03"; + macAddress = "00:30:42:1b:26:f6"; + ipAddress = "192.168.98.13"; + } + { + name = "rfp-04"; + macAddress = "00:30:42:1b:22:3b"; + ipAddress = "192.168.98.14"; + } + { + name = "rfp-05"; + macAddress = "00:30:42:1b:22:7c"; + ipAddress = "192.168.98.15"; + } + ]; + }; + }; + }; +} diff --git a/hosts/pbx/services/public-ip4-tunnel.nix b/hosts/pbx/services/public-ip4-tunnel.nix new file mode 100644 index 0000000..ffef316 --- /dev/null +++ b/hosts/pbx/services/public-ip4-tunnel.nix @@ -0,0 +1,51 @@ +{ + config, + pkgs, + ... +}: let + remoteHost = "pretix1.hosts.production.digitaler-dienst.net"; + remotePort = 51000; + publicKey = "e4QfcYmicW2NUMyyjP7PcLgOxiqf3IdvCKeMRWt4zlY="; + externalIp = "5.75.219.20"; + interface = "public-ip4"; + rtTable = { + id = 1000; + name = interface; + }; +in { + sops.secrets."wireguard/${interface}" = { + sopsFile = ../secrets.yaml; + }; + + networking = { + iproute2 = { + enable = true; + rttablesExtraConfig = '' + ${toString rtTable.id} ${rtTable.name} + ''; + }; + wireguard.interfaces."${interface}" = { + ips = ["${externalIp}/32"]; + privateKeyFile = config.sops.secrets."wireguard/${interface}".path; + table = rtTable.name; + postSetup = '' + ${pkgs.iproute2}/bin/ip rule add from ${externalIp} to 192.168.0.0/16 table main priority 10 + ${pkgs.iproute2}/bin/ip rule add from ${externalIp} table ${rtTable.name} priority 20 + ''; + postShutdown = '' + ${pkgs.iproute2}/bin/ip rule del from ${externalIp} to 192.168.0.0/16 table main priority 10 + ${pkgs.iproute2}/bin/ip rule del from ${externalIp} table ${rtTable.name} priority 20 + ''; + peers = [ + { + inherit publicKey; + endpoint = "${remoteHost}:${toString remotePort}"; + persistentKeepalive = 25; + allowedIPs = [ + "0.0.0.0/0" + ]; + } + ]; + }; + }; +} diff --git a/hosts/pbx/services/webserver.nix b/hosts/pbx/services/webserver.nix new file mode 100644 index 0000000..583b446 --- /dev/null +++ b/hosts/pbx/services/webserver.nix @@ -0,0 +1,33 @@ +{config, ...}: let + domain = "tel.weinturm.de"; +in { + networking.firewall.allowedTCPPorts = [ + config.services.nginx.defaultHTTPListenPort + config.services.nginx.defaultSSLListenPort + ]; + services.nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + commonHttpConfig = '' + map $scheme $hsts_header { + https "max-age=31536000"; + } + add_header Strict-Transport-Security $hsts_header; + + add_header Referrer-Policy strict-origin; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options SAMEORIGIN; + ''; + virtualHosts = { + "${domain}" = { + serverAliases = ["tel.weinturm-open-air.de"]; + enableACME = true; + forceSSL = true; + root = "/persist/html"; + }; + }; + }; +} diff --git a/mikrotik/schneiderscheune-weinturm-ap.cfg b/mikrotik/schneiderscheune-weinturm-ap.cfg new file mode 100644 index 0000000..2d4cdb5 --- /dev/null +++ b/mikrotik/schneiderscheune-weinturm-ap.cfg @@ -0,0 +1,46 @@ +/system identity set name="schneiderscheune-weinturm-ap" + +/ip firewall filter remove [find comment~"defconf"] +/ip firewall nat remove [find comment~"defconf"] +/ip dhcp-client remove [find comment~"defconf"] +/ip dhcp-server remove [find name~"defconf"] +/interface wireless disable wlan1 + +/interface bridge add name=bridge1 mtu=1500 protocol-mode=rstp +/interface bridge port add bridge=bridge1 interface=ether1 +/interface bridge port add bridge=bridge1 interface=wlan1 + +/ip address add address=192.168.96.2/24 interface=bridge1 +/ip route add gateway=192.168.96.1 +/ip dns set servers=192.168.96.1 + +/interface wireless set wlan1 country="germany 5.8 fixed p-p" +/interface wireless set wlan1 frequency=auto +/interface wireless set wlan1 skip-dfs-channels=all +/interface wireless set wlan1 installation=outdoor +/interface wireless set wlan1 mode=bridge +/interface wireless set wlan1 ssid=Schneiderscheune-Weinturm +/interface wireless set wlan1 frequency-mode regulatory-domain +/interface wireless set wlan1 band=5ghz-onlyac +/interface wireless set wlan1 channel-width=20/40/80mhz-Ceee +/interface wireless set wlan1 rate-set=configured +/interface wireless set wlan1 ht-basic-mcs="" ht-supported-mcs="" +/interface wireless set wlan1 vht-basic-mcs="mcs0-7,mcs0-7,mcs0-7" +/interface wireless set wlan1 vht-supported-mcs="mcs0-9,mcs0-9,mcs0-9" +/interface wireless set wlan1 wireless-protocol=nv2 +# distance to the farthest client, in km +/interface wireless set wlan1 nv2-cell-radius=10 +# higher values increase bandwidth, but also latency +/interface wireless set wlan1 tdma-period-size=1 +/interface wireless set wlan1 nv2-mode=dynamic-downlink +/interface wireless set wlan1 nv2-downlink-ratio=20 +/interface wireless set wlan1 nv2-security=enabled +/interface wireless set wlan1 update-stats-interval=00:00:10 +/interface wireless set wlan1 wps-mode=disabled +/interface wireless nstreme set wlan1 enable-nstreme=yes + +/interface wireless enable wlan1 + +/tool bandwidth-server set enabled=yes + +/ip address remove [find comment~"defconf"] diff --git a/mikrotik/schneiderscheune-weinturm-sta.cfg b/mikrotik/schneiderscheune-weinturm-sta.cfg new file mode 100644 index 0000000..df6d563 --- /dev/null +++ b/mikrotik/schneiderscheune-weinturm-sta.cfg @@ -0,0 +1,44 @@ +/system identity set name="schneiderscheune-weinturm-sta" + +/ip firewall filter remove [find comment~"defconf"] +/ip firewall nat remove [find comment~"defconf"] +/ip dhcp-client remove [find comment~"defconf"] +/ip dhcp-server remove [find name~"defconf"] +/interface wireless disable wlan1 + +/interface bridge add name=bridge1 mtu=1500 protocol-mode=rstp +/interface bridge port add bridge=bridge1 interface=ether1 +/interface bridge port add bridge=bridge1 interface=wlan1 + +/ip address add address=192.168.96.3/24 interface=bridge1 +/ip route add gateway=192.168.96.1 +/ip dns set servers=192.168.96.1 + +/interface wireless set wlan1 country="germany 5.8 fixed p-p" +/interface wireless set wlan1 frequency=auto +/interface wireless set wlan1 skip-dfs-channels=all +/interface wireless set wlan1 installation=outdoor +/interface wireless set wlan1 mode=station-bridge +/interface wireless set wlan1 ssid=Schneiderscheune-Weinturm +/interface wireless set wlan1 frequency-mode regulatory-domain +/interface wireless set wlan1 band=5ghz-onlyac +/interface wireless set wlan1 channel-width=20/40/80mhz-Ceee +/interface wireless set wlan1 rate-set=configured +/interface wireless set wlan1 ht-basic-mcs="" ht-supported-mcs="" +/interface wireless set wlan1 vht-basic-mcs="mcs0-7,mcs0-7,mcs0-7" +/interface wireless set wlan1 vht-supported-mcs="mcs0-9,mcs0-9,mcs0-9" +/interface wireless set wlan1 wireless-protocol=nv2 +# distance to the farthest client, in km +/interface wireless set wlan1 nv2-cell-radius=10 +# higher values increase bandwidth, but also latency +/interface wireless set wlan1 tdma-period-size=1 +/interface wireless set wlan1 nv2-mode=dynamic-downlink +/interface wireless set wlan1 nv2-downlink-ratio=20 +/interface wireless set wlan1 nv2-security=enabled +/interface wireless set wlan1 update-stats-interval=00:00:10 +/interface wireless set wlan1 wps-mode=disabled +/interface wireless nstreme set wlan1 enable-nstreme=yes + +/interface wireless enable wlan1 + +/ip address remove [find comment~"defconf"] diff --git a/mikrotik/wechselbruecke-router.cfg b/mikrotik/wechselbruecke-router.cfg new file mode 100644 index 0000000..0c838bf --- /dev/null +++ b/mikrotik/wechselbruecke-router.cfg @@ -0,0 +1,43 @@ +/system identity set name="wechselbruecke-router" + +/ip firewall filter remove [find comment~"defconf"] +/ip firewall nat remove [find comment~"defconf"] +/ip dhcp-client remove [find comment~"defconf"] +/ip dhcp-server remove [find name~"defconf"] + +/ip address add address=192.168.96.4/24 interface=bridge +/ip route add gateway=192.168.96.1 +/ip dns set servers=192.168.96.1 + +/interface bridge port add bridge=bridge interface=ether1 hw=yes + +# VLAN +# weinturm +/interface ethernet switch vlan add switch=switch1 vlan-id=7 ports=ether1,ether2,ether3,ether4,switch1-cpu comment=weinturm +# voice +/interface ethernet switch vlan add switch=switch1 vlan-id=8 ports=ether2,ether5,switch1-cpu comment=voice +# public-event +/interface ethernet switch vlan add switch=switch1 vlan-id=6 ports=ether2,ether3,ether4,switch1-cpu +# jugendtreff +/interface ethernet switch vlan add switch=switch1 vlan-id=2 ports=ether2 comment=jugendtreff,switch1-cpu + +# ether1 is free (debug) port +/interface ethernet switch port set ether1 vlan-mode=secure vlan-header=add-if-missing default-vlan-id=7 + +# ether2 is uplink port +/interface ethernet switch port set ether2 vlan-mode=secure vlan-header=add-if-missing default-vlan-id=7 + +# ether3 is access point +/interface ethernet switch port set ether3 vlan-mode=secure vlan-header=add-if-missing default-vlan-id=7 + +# ether4 is access point +/interface ethernet switch port set ether4 vlan-mode=secure vlan-header=add-if-missing default-vlan-id=7 + +# ether5 is mitel rfp +/interface ethernet switch port set ether5 vlan-mode=secure vlan-header=always-strip default-vlan-id=8 + +/interface ethernet switch port set switch1-cpu vlan-header=leave-as-is vlan-mode=secure default-vlan-id=7 + +#/interface ethernet poe set ether2 poe-out=forced-on + +/ip address remove [find comment~"defconf"] diff --git a/pkgs/default.nix b/pkgs/default.nix index 5c90043..1b363a9 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -1,4 +1,2 @@ -inputs: _final: prev: let - inherit (prev) callPackage system; -in { +_: _final: _: { }