├── .gitignore ├── LICENSE.md ├── README.md ├── gokrazy └── monitnerr-1 │ ├── Makefile │ ├── breakglass.authorized_keys │ ├── builddir │ ├── github.com │ │ ├── gokrazy │ │ │ ├── breakglass │ │ │ │ ├── go.mod │ │ │ │ └── go.sum │ │ │ ├── firmware │ │ │ │ ├── go.mod │ │ │ │ └── go.sum │ │ │ ├── gokrazy │ │ │ │ ├── cmd │ │ │ │ │ ├── dhcp │ │ │ │ │ │ ├── go.mod │ │ │ │ │ │ └── go.sum │ │ │ │ │ ├── heartbeat │ │ │ │ │ │ ├── go.mod │ │ │ │ │ │ └── go.sum │ │ │ │ │ ├── ntp │ │ │ │ │ │ ├── go.mod │ │ │ │ │ │ └── go.sum │ │ │ │ │ └── randomd │ │ │ │ │ │ ├── go.mod │ │ │ │ │ │ └── go.sum │ │ │ │ ├── go.mod │ │ │ │ └── go.sum │ │ │ ├── kernel │ │ │ │ ├── go.mod │ │ │ │ └── go.sum │ │ │ ├── rpi-eeprom │ │ │ │ ├── go.mod │ │ │ │ └── go.sum │ │ │ └── serial-busybox │ │ │ │ ├── go.mod │ │ │ │ └── go.sum │ │ ├── mdlayher │ │ │ └── consrv │ │ │ │ ├── go.mod │ │ │ │ └── go.sum │ │ └── prometheus │ │ │ └── node_exporter │ │ │ ├── go.mod │ │ │ └── go.sum │ ├── init │ │ ├── go.mod │ │ └── go.sum │ └── tailscale.com │ │ ├── go.mod │ │ └── go.sum │ ├── config.tmpl.json │ └── consrv.toml ├── grafana ├── coredns.json ├── corerad.json ├── network.json ├── node.json ├── obs.json └── wgipamd.json ├── nixos ├── README.md ├── lib │ ├── modules │ │ └── zedhook.nix │ ├── pkgs │ │ └── zedhook.nix │ ├── system.nix │ ├── vargen │ │ ├── README.md │ │ ├── go.mod │ │ ├── go.sum │ │ └── main.go │ ├── vars.json │ └── vars.nix ├── routnerr-3 │ ├── README.md │ ├── caddy.nix │ ├── configuration.nix │ ├── coredns.nix │ ├── corerad.nix │ ├── hardware-configuration.nix │ ├── lib │ ├── networking.nix │ └── nftables.nix └── servnerr-4 │ ├── README.md │ ├── configuration.nix │ ├── containers.nix │ ├── hardware-configuration.nix │ ├── lib │ ├── networking.nix │ ├── prometheus-alerts.nix │ ├── prometheus.nix │ └── storage.nix └── obs ├── README.md ├── profiles └── Programming │ ├── basic.ini │ ├── recordEncoder.json │ └── streamEncoder.json ├── scenes └── Programming.json └── stream ├── banner.txt └── terminal.gif /.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | *.bak 3 | secrets.nix 4 | gokrazy/monitnerr-1/config.json 5 | obs/profiles/Programming/service.json 6 | nixos/lib/vargen/vargen 7 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (C) 2019-2022 Matt Layher 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # homelab 2 | 3 | Configuration management for Matt Layher's machines. MIT Licensed. 4 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/Makefile: -------------------------------------------------------------------------------- 1 | GOK := sed 's,"HTTPPassword": "","HTTPPassword": "$(GOKRAZY_PASSWORD)",g' config.tmpl.json > config.json && gok -i monitnerr-1 --parent_dir=/home/mdlayher/src/github.com/mdlayher/homelab/gokrazy 2 | 3 | all: 4 | 5 | .PHONY: get update overwrite root 6 | 7 | get: 8 | ${GOK} get --update_all 9 | 10 | update: 11 | ${GOK} update 12 | 13 | overwrite: 14 | ${GOK} overwrite --full /dev/sdx 15 | 16 | root: 17 | ${GOK} overwrite --root /tmp/root.squashfs 18 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/breakglass.authorized_keys: -------------------------------------------------------------------------------- 1 | # This authorized_keys(5) file allows access from keys on nerr-4 2 | 3 | # /home/matt/.ssh/id_ed25519.pub 4 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5i5d0mRKAf02m+ju+I1KrAYw3Ny2IHXy88mgyragBN Matt Layher (mdlayher@gmail.com) 5 | 6 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/breakglass/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.21 4 | 5 | toolchain go1.21.0 6 | 7 | require ( 8 | github.com/creack/pty v1.1.18 // indirect 9 | github.com/gokrazy/breakglass v0.0.0-20241212072241-6c59aaaf2868 // indirect 10 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83 // indirect 11 | github.com/gokrazy/internal v0.0.0-20230211171410-9608422911d0 // indirect 12 | github.com/google/renameio/v2 v2.0.0 // indirect 13 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect 14 | github.com/kenshaw/evdev v0.1.0 // indirect 15 | github.com/kr/fs v0.1.0 // indirect 16 | github.com/kr/pty v1.1.8 // indirect 17 | github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5 // indirect 18 | github.com/pkg/sftp v1.13.5 // indirect 19 | golang.org/x/crypto v0.31.0 // indirect 20 | golang.org/x/sys v0.28.0 // indirect 21 | ) 22 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/breakglass/go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 2 | github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= 3 | github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/gokrazy/breakglass v0.0.0-20230225152058-158f63b4afb1 h1:4CFF1WGa83wFLEL7Ip30ETQMlkIF7mmVYdlGwKNQZv4= 6 | github.com/gokrazy/breakglass v0.0.0-20230225152058-158f63b4afb1/go.mod h1:JhOAecOvIUmRWTiDJSZgZ90DIJf+FymskyMaP6Acr5E= 7 | github.com/gokrazy/breakglass v0.0.0-20230812093049-e771a5894bd2 h1:M8VcJV7iuGE/1WJ+YXU7wEvsesMsUpHln1dHsF64TTo= 8 | github.com/gokrazy/breakglass v0.0.0-20230812093049-e771a5894bd2/go.mod h1:g6AIXw9nTAj54jl9ZlcvZ19TJXlz0bFsavGpqQLTAxU= 9 | github.com/gokrazy/breakglass v0.0.0-20231219075147-eacd5a447e73 h1:QYNDFiU8WENHBvsZWwAUOpMJDe/C/CNejsG7JartT5A= 10 | github.com/gokrazy/breakglass v0.0.0-20231219075147-eacd5a447e73/go.mod h1:4Yffo2Z5w3q2eDvo3HDR8eDnmkDpMAkX0Tn7b/9upgs= 11 | github.com/gokrazy/breakglass v0.0.0-20240609201123-0327ae332c84 h1:IRFVW6k3XkbfpUxfnb8L95GmwiwsB6HmbYEowDO2U5o= 12 | github.com/gokrazy/breakglass v0.0.0-20240609201123-0327ae332c84/go.mod h1:4Yffo2Z5w3q2eDvo3HDR8eDnmkDpMAkX0Tn7b/9upgs= 13 | github.com/gokrazy/breakglass v0.0.0-20241212072241-6c59aaaf2868 h1:114tDU1zRitK0q5KUHV3qX19tjsUKyKmx9sv47r6QXE= 14 | github.com/gokrazy/breakglass v0.0.0-20241212072241-6c59aaaf2868/go.mod h1:YovJgF1gxXzgHQts0TV1KT/LV1j7NnCo6sC89RyMjkQ= 15 | github.com/gokrazy/gokrazy v0.0.0-20230219142620-73892ad2388a h1:FVdd+wf07vVnxDsF7A/MAwVUxHY3NQuC2eMwzuMt4fg= 16 | github.com/gokrazy/gokrazy v0.0.0-20230219142620-73892ad2388a/go.mod h1:v4yQTOzEIpUmkKHYGMfqhktZXwvaxUpc2VfFTMyHAYI= 17 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83 h1:Y4sADvUYd/c0eqnqebipHHl0GMpAxOQeTzPnwI4ievM= 18 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 19 | github.com/gokrazy/internal v0.0.0-20230211171410-9608422911d0 h1:QTi0skQ/OM7he/5jEWA9k/DYgdwGAhw3hrUoiPGGZHM= 20 | github.com/gokrazy/internal v0.0.0-20230211171410-9608422911d0/go.mod h1:ddHcxXZ/VVQOSAWcRBbkYY58+QOw4L145ye6phyDmRA= 21 | github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= 22 | github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= 23 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= 24 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= 25 | github.com/kenshaw/evdev v0.1.0 h1:wmtceEOFfilChgdNT+c/djPJ2JineVsQ0N14kGzFRUo= 26 | github.com/kenshaw/evdev v0.1.0/go.mod h1:B/fErKCihUyEobz0mjn2qQbHgyJKFQAxkXSvkeeA/Wo= 27 | github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= 28 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 29 | github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= 30 | github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 31 | github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5 h1:80FAK3TW5lVymfHu3kvB1QvTZvy9Kmx1lx6sT5Ep16s= 32 | github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5/go.mod h1:z0QjVpjpK4jksEkffQwS3+abQ3XFTm1bnimyDzWyUk0= 33 | github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go= 34 | github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= 35 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 36 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 37 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 38 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 39 | golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= 40 | golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= 41 | golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= 42 | golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 43 | golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= 44 | golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= 45 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 46 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 47 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 48 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 49 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 50 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 51 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 52 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 53 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 54 | golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= 55 | golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 56 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 57 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 58 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 59 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 60 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 61 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/firmware/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.21 4 | 5 | toolchain go1.21.0 6 | 7 | require github.com/gokrazy/firmware v0.0.0-20241206035113-14ca74ffca9d // indirect 8 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/firmware/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gokrazy/firmware v0.0.0-20230426033153-87439d42d999 h1:0p74v4oVTcDNzKNFlOrmUqD1CO7e+LHMPChj2ZxHlvI= 2 | github.com/gokrazy/firmware v0.0.0-20230426033153-87439d42d999/go.mod h1:nbEte1HMYHF4is+rAadA57SWBONRn7N3kXmafjkusFY= 3 | github.com/gokrazy/firmware v0.0.0-20230812164343-bd4d0cb7d693 h1:6NhSWnxynTdiVrX8pjJXhwrsB8+LGhgKi+L6XciYr74= 4 | github.com/gokrazy/firmware v0.0.0-20230812164343-bd4d0cb7d693/go.mod h1:nbEte1HMYHF4is+rAadA57SWBONRn7N3kXmafjkusFY= 5 | github.com/gokrazy/firmware v0.0.0-20230922033133-d46a09648231 h1:GohIVqOiId3x+1ao20qPqtzkSaaox5PGT1/YjtumOr8= 6 | github.com/gokrazy/firmware v0.0.0-20230922033133-d46a09648231/go.mod h1:nbEte1HMYHF4is+rAadA57SWBONRn7N3kXmafjkusFY= 7 | github.com/gokrazy/firmware v0.0.0-20231213075030-b645049ebf9e h1:kRsUCCiuQJBNWddqATo6pXmxcoTjBvfn/ux5z3yShpo= 8 | github.com/gokrazy/firmware v0.0.0-20231213075030-b645049ebf9e/go.mod h1:x8Lwd/ZFqJTBWUGW7yt/qwgxO8/AHh5KGFYJ4yfH+FE= 9 | github.com/gokrazy/firmware v0.0.0-20240215033144-5d2bb06bdee4 h1:WUqqjnq/Z9ok4J/DSGbZ03kkqM0KiF2bY1veR5lJ55o= 10 | github.com/gokrazy/firmware v0.0.0-20240215033144-5d2bb06bdee4/go.mod h1:x8Lwd/ZFqJTBWUGW7yt/qwgxO8/AHh5KGFYJ4yfH+FE= 11 | github.com/gokrazy/firmware v0.0.0-20240322033010-578c28103900 h1:SbTkLkVjbfrtmrRJm7T4mhTz8h05mt07cHKyZKa1JoQ= 12 | github.com/gokrazy/firmware v0.0.0-20240322033010-578c28103900/go.mod h1:x8Lwd/ZFqJTBWUGW7yt/qwgxO8/AHh5KGFYJ4yfH+FE= 13 | github.com/gokrazy/firmware v0.0.0-20240726033924-16d02c007fd4 h1:67bWNuostKQmPiRK8YjIGMK3LjULg+Canmbb7jmlXtQ= 14 | github.com/gokrazy/firmware v0.0.0-20240726033924-16d02c007fd4/go.mod h1:x8Lwd/ZFqJTBWUGW7yt/qwgxO8/AHh5KGFYJ4yfH+FE= 15 | github.com/gokrazy/firmware v0.0.0-20241206035113-14ca74ffca9d h1:5w4TDUGoNrAaXGiI+y+4Co2aazDH9VUNPDxVBwm4sZ0= 16 | github.com/gokrazy/firmware v0.0.0-20241206035113-14ca74ffca9d/go.mod h1:x8Lwd/ZFqJTBWUGW7yt/qwgxO8/AHh5KGFYJ4yfH+FE= 17 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 18 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/cmd/dhcp/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.22 4 | 5 | toolchain go1.23.0 6 | 7 | require ( 8 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 // indirect 9 | github.com/google/gopacket v1.1.19 // indirect 10 | github.com/google/renameio/v2 v2.0.0 // indirect 11 | github.com/josharian/native v1.0.0 // indirect 12 | github.com/mdlayher/packet v1.0.0 // indirect 13 | github.com/mdlayher/socket v0.2.3 // indirect 14 | github.com/rtr7/dhcp4 v0.0.0-20220302171438-18c84d089b46 // indirect 15 | github.com/vishvananda/netlink v1.1.0 // indirect 16 | github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect 17 | golang.org/x/net v0.23.0 // indirect 18 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect 19 | golang.org/x/sys v0.20.0 // indirect 20 | ) 21 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/cmd/dhcp/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9 h1:OJ4b0Z8OPgTIn6i/Iq+Y0AcnsiFiT4vXMnLXclPwPVg= 2 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 3 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad h1:bwnwA8Qb3etCdE4f5G3LMJwmzbMtX//wOCCm4SHap48= 4 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 5 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83 h1:Y4sADvUYd/c0eqnqebipHHl0GMpAxOQeTzPnwI4ievM= 6 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 7 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb h1:H7TXNm0IGcp6APwVN1wi83JwEpPFdNXAb8uJ+TC8kQw= 8 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 9 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df h1:0/lguTUs8Z3OYP0oAUVD0HzJYoLI0gr02GSs9FmXpjU= 10 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 11 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830 h1:olWHeYpWo/9Mb8o968yJshzZKCnPjb69iUJnryypXaU= 12 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 13 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8 h1:Y1wFJsJvRykf2yttMkMvk4lPAGWiRBVseyrAMO6uRRU= 14 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 15 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35 h1:/vto7EZFxjlb2gM6K+3/apYLaff7yvA3tEtf0GsvFw0= 16 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 17 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e h1:pGH+YVcfF0oIYAPYuTEmbunQ4J//MgSs062GohEjfTQ= 18 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e/go.mod h1:+/WWMckeuQt+DG6690A6H8IgC+HpBFq2fmwRKcSbxdk= 19 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 h1:RaqiSBCZcnebrloq3lqWj21UmvXV4v2a7JsSXeh+EY8= 20 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366/go.mod h1:1yOdp952OIkgR9lBNUzV+mBSIcvPV0RCaCmBq9WKTJw= 21 | github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= 22 | github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= 23 | github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= 24 | github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= 25 | github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk= 26 | github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= 27 | github.com/mdlayher/packet v1.0.0 h1:InhZJbdShQYt6XV2GPj5XHxChzOfhJJOMbvnGAmOfQ8= 28 | github.com/mdlayher/packet v1.0.0/go.mod h1:eE7/ctqDhoiRhQ44ko5JZU2zxB88g+JH/6jmnjzPjOU= 29 | github.com/mdlayher/socket v0.2.3 h1:XZA2X2TjdOwNoNPVPclRCURoX/hokBY8nkTmRZFEheM= 30 | github.com/mdlayher/socket v0.2.3/go.mod h1:bz12/FozYNH/VbvC3q7TRIK/Y6dH1kCKsXaUeXi/FmY= 31 | github.com/rtr7/dhcp4 v0.0.0-20220302171438-18c84d089b46 h1:3psQveH4RUiv5yc3p7kRySilf1nSXLQhAvJFwg4fgnE= 32 | github.com/rtr7/dhcp4 v0.0.0-20220302171438-18c84d089b46/go.mod h1:Ng1F/s+z0zCMsbEFEneh+30LJa9DrTfmA+REbEqcTPk= 33 | github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= 34 | github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= 35 | github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= 36 | github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= 37 | github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= 38 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 39 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 40 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 41 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 42 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 43 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 44 | golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= 45 | golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 46 | golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= 47 | golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 48 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= 49 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 50 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 51 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= 52 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 53 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 54 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 55 | golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 56 | golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 57 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 58 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 59 | golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= 60 | golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 61 | golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 62 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 63 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 64 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 65 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 66 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/cmd/heartbeat/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.22 4 | 5 | toolchain go1.23.0 6 | 7 | require ( 8 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 // indirect 9 | github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5 // indirect 10 | github.com/google/renameio/v2 v2.0.0 // indirect 11 | github.com/kenshaw/evdev v0.1.0 // indirect 12 | github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b // indirect 13 | github.com/spf13/pflag v1.0.5 // indirect 14 | golang.org/x/sys v0.20.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/cmd/heartbeat/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9 h1:OJ4b0Z8OPgTIn6i/Iq+Y0AcnsiFiT4vXMnLXclPwPVg= 2 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 3 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad h1:bwnwA8Qb3etCdE4f5G3LMJwmzbMtX//wOCCm4SHap48= 4 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 5 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83 h1:Y4sADvUYd/c0eqnqebipHHl0GMpAxOQeTzPnwI4ievM= 6 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 7 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb h1:H7TXNm0IGcp6APwVN1wi83JwEpPFdNXAb8uJ+TC8kQw= 8 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 9 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df h1:0/lguTUs8Z3OYP0oAUVD0HzJYoLI0gr02GSs9FmXpjU= 10 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 11 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830 h1:olWHeYpWo/9Mb8o968yJshzZKCnPjb69iUJnryypXaU= 12 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 13 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8 h1:Y1wFJsJvRykf2yttMkMvk4lPAGWiRBVseyrAMO6uRRU= 14 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 15 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35 h1:/vto7EZFxjlb2gM6K+3/apYLaff7yvA3tEtf0GsvFw0= 16 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 17 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e h1:pGH+YVcfF0oIYAPYuTEmbunQ4J//MgSs062GohEjfTQ= 18 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e/go.mod h1:+/WWMckeuQt+DG6690A6H8IgC+HpBFq2fmwRKcSbxdk= 19 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 h1:RaqiSBCZcnebrloq3lqWj21UmvXV4v2a7JsSXeh+EY8= 20 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366/go.mod h1:1yOdp952OIkgR9lBNUzV+mBSIcvPV0RCaCmBq9WKTJw= 21 | github.com/gokrazy/internal v0.0.0-20220129150711-9ed298107648 h1:kBuLicM0xJw3xEe4607WlnzGL+qSwPqdyh5/LUiCdq0= 22 | github.com/gokrazy/internal v0.0.0-20220129150711-9ed298107648/go.mod h1:Gc9sU6yJ/qxg3gJZ1pjfcTAULa0swdTa4TH51g1e00E= 23 | github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5 h1:XDklMxV0pE5jWiNaoo5TzvWfqdoiRRScmr4ZtDzE4Uw= 24 | github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5/go.mod h1:t3ZirVhcs9bH+fPAJuGh51rzT7sVCZ9yfXvszf0ZjF0= 25 | github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= 26 | github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= 27 | github.com/kenshaw/evdev v0.1.0 h1:wmtceEOFfilChgdNT+c/djPJ2JineVsQ0N14kGzFRUo= 28 | github.com/kenshaw/evdev v0.1.0/go.mod h1:B/fErKCihUyEobz0mjn2qQbHgyJKFQAxkXSvkeeA/Wo= 29 | github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b h1:7tUBfsEEBWfFeHOB7CUfoOamak+Gx/BlirfXyPk1WjI= 30 | github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b/go.mod h1:bmoJUS6qOA3uKFvF3KVuhf7mU1KQirzQMeHXtPyKEqg= 31 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 32 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 33 | golang.org/x/sys v0.0.0-20201005065044-765f4ea38db3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 34 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 35 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 36 | golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= 37 | golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 38 | golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 39 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 40 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/cmd/ntp/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.22 4 | 5 | toolchain go1.23.0 6 | 7 | require ( 8 | github.com/beevik/ntp v0.3.0 // indirect 9 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 // indirect 10 | golang.org/x/net v0.23.0 // indirect 11 | golang.org/x/sys v0.20.0 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/cmd/ntp/go.sum: -------------------------------------------------------------------------------- 1 | github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw= 2 | github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= 3 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9 h1:OJ4b0Z8OPgTIn6i/Iq+Y0AcnsiFiT4vXMnLXclPwPVg= 4 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 5 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad h1:bwnwA8Qb3etCdE4f5G3LMJwmzbMtX//wOCCm4SHap48= 6 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 7 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83 h1:Y4sADvUYd/c0eqnqebipHHl0GMpAxOQeTzPnwI4ievM= 8 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 9 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb h1:H7TXNm0IGcp6APwVN1wi83JwEpPFdNXAb8uJ+TC8kQw= 10 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 11 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df h1:0/lguTUs8Z3OYP0oAUVD0HzJYoLI0gr02GSs9FmXpjU= 12 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 13 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830 h1:olWHeYpWo/9Mb8o968yJshzZKCnPjb69iUJnryypXaU= 14 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 15 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8 h1:Y1wFJsJvRykf2yttMkMvk4lPAGWiRBVseyrAMO6uRRU= 16 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 17 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35 h1:/vto7EZFxjlb2gM6K+3/apYLaff7yvA3tEtf0GsvFw0= 18 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 19 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e h1:pGH+YVcfF0oIYAPYuTEmbunQ4J//MgSs062GohEjfTQ= 20 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e/go.mod h1:+/WWMckeuQt+DG6690A6H8IgC+HpBFq2fmwRKcSbxdk= 21 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 h1:RaqiSBCZcnebrloq3lqWj21UmvXV4v2a7JsSXeh+EY8= 22 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366/go.mod h1:1yOdp952OIkgR9lBNUzV+mBSIcvPV0RCaCmBq9WKTJw= 23 | golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= 24 | golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 25 | golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= 26 | golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 27 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= 28 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 29 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 30 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 31 | golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= 32 | golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 33 | golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 34 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 35 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/cmd/randomd/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.22 4 | 5 | toolchain go1.23.0 6 | 7 | require ( 8 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 // indirect 9 | golang.org/x/sys v0.20.0 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/cmd/randomd/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9 h1:OJ4b0Z8OPgTIn6i/Iq+Y0AcnsiFiT4vXMnLXclPwPVg= 2 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 3 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad h1:bwnwA8Qb3etCdE4f5G3LMJwmzbMtX//wOCCm4SHap48= 4 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 5 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83 h1:Y4sADvUYd/c0eqnqebipHHl0GMpAxOQeTzPnwI4ievM= 6 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 7 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb h1:H7TXNm0IGcp6APwVN1wi83JwEpPFdNXAb8uJ+TC8kQw= 8 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 9 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df h1:0/lguTUs8Z3OYP0oAUVD0HzJYoLI0gr02GSs9FmXpjU= 10 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 11 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830 h1:olWHeYpWo/9Mb8o968yJshzZKCnPjb69iUJnryypXaU= 12 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 13 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8 h1:Y1wFJsJvRykf2yttMkMvk4lPAGWiRBVseyrAMO6uRRU= 14 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 15 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35 h1:/vto7EZFxjlb2gM6K+3/apYLaff7yvA3tEtf0GsvFw0= 16 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 17 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e h1:pGH+YVcfF0oIYAPYuTEmbunQ4J//MgSs062GohEjfTQ= 18 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e/go.mod h1:+/WWMckeuQt+DG6690A6H8IgC+HpBFq2fmwRKcSbxdk= 19 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 h1:RaqiSBCZcnebrloq3lqWj21UmvXV4v2a7JsSXeh+EY8= 20 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366/go.mod h1:1yOdp952OIkgR9lBNUzV+mBSIcvPV0RCaCmBq9WKTJw= 21 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 22 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 23 | golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= 24 | golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 25 | golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 26 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 27 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.22 4 | 5 | toolchain go1.23.0 6 | 7 | require ( 8 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 // indirect 9 | github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5 // indirect 10 | github.com/google/renameio/v2 v2.0.0 // indirect 11 | github.com/kenshaw/evdev v0.1.0 // indirect 12 | github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b // indirect 13 | github.com/spf13/pflag v1.0.5 // indirect 14 | golang.org/x/sys v0.20.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/gokrazy/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9 h1:OJ4b0Z8OPgTIn6i/Iq+Y0AcnsiFiT4vXMnLXclPwPVg= 2 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 3 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad h1:bwnwA8Qb3etCdE4f5G3LMJwmzbMtX//wOCCm4SHap48= 4 | github.com/gokrazy/gokrazy v0.0.0-20230723153554-331c98011aad/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 5 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83 h1:Y4sADvUYd/c0eqnqebipHHl0GMpAxOQeTzPnwI4ievM= 6 | github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 7 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb h1:H7TXNm0IGcp6APwVN1wi83JwEpPFdNXAb8uJ+TC8kQw= 8 | github.com/gokrazy/gokrazy v0.0.0-20230917165827-e4c2e89c78cb/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 9 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df h1:0/lguTUs8Z3OYP0oAUVD0HzJYoLI0gr02GSs9FmXpjU= 10 | github.com/gokrazy/gokrazy v0.0.0-20240107105656-620adabf26df/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 11 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830 h1:olWHeYpWo/9Mb8o968yJshzZKCnPjb69iUJnryypXaU= 12 | github.com/gokrazy/gokrazy v0.0.0-20240113151142-756b3b30b830/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 13 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8 h1:Y1wFJsJvRykf2yttMkMvk4lPAGWiRBVseyrAMO6uRRU= 14 | github.com/gokrazy/gokrazy v0.0.0-20240118072056-7acb85f429f8/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 15 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35 h1:/vto7EZFxjlb2gM6K+3/apYLaff7yvA3tEtf0GsvFw0= 16 | github.com/gokrazy/gokrazy v0.0.0-20240228074937-cbb1cdfc7d35/go.mod h1:FOTcHsN9okcM6wLX58MC33A8i5U3AI+sYD5wsuWee1U= 17 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e h1:pGH+YVcfF0oIYAPYuTEmbunQ4J//MgSs062GohEjfTQ= 18 | github.com/gokrazy/gokrazy v0.0.0-20240721075352-1d9057cee92e/go.mod h1:+/WWMckeuQt+DG6690A6H8IgC+HpBFq2fmwRKcSbxdk= 19 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366 h1:RaqiSBCZcnebrloq3lqWj21UmvXV4v2a7JsSXeh+EY8= 20 | github.com/gokrazy/gokrazy v0.0.0-20241106183216-3fd48c2b9366/go.mod h1:1yOdp952OIkgR9lBNUzV+mBSIcvPV0RCaCmBq9WKTJw= 21 | github.com/gokrazy/internal v0.0.0-20220129150711-9ed298107648 h1:kBuLicM0xJw3xEe4607WlnzGL+qSwPqdyh5/LUiCdq0= 22 | github.com/gokrazy/internal v0.0.0-20220129150711-9ed298107648/go.mod h1:Gc9sU6yJ/qxg3gJZ1pjfcTAULa0swdTa4TH51g1e00E= 23 | github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5 h1:XDklMxV0pE5jWiNaoo5TzvWfqdoiRRScmr4ZtDzE4Uw= 24 | github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5/go.mod h1:t3ZirVhcs9bH+fPAJuGh51rzT7sVCZ9yfXvszf0ZjF0= 25 | github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= 26 | github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= 27 | github.com/kenshaw/evdev v0.1.0 h1:wmtceEOFfilChgdNT+c/djPJ2JineVsQ0N14kGzFRUo= 28 | github.com/kenshaw/evdev v0.1.0/go.mod h1:B/fErKCihUyEobz0mjn2qQbHgyJKFQAxkXSvkeeA/Wo= 29 | github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b h1:7tUBfsEEBWfFeHOB7CUfoOamak+Gx/BlirfXyPk1WjI= 30 | github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b/go.mod h1:bmoJUS6qOA3uKFvF3KVuhf7mU1KQirzQMeHXtPyKEqg= 31 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 32 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 33 | golang.org/x/sys v0.0.0-20201005065044-765f4ea38db3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 34 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 35 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 36 | golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= 37 | golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 38 | golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 39 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 40 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/kernel/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.21 4 | 5 | toolchain go1.21.6 6 | 7 | require github.com/gokrazy/kernel v0.0.0-20241210041216-2888c1a9526f // indirect 8 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/kernel/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gokrazy/kernel v0.0.0-20230712041245-e563d7441232 h1:jNLCf3VxoDyfY84LBgEnb+OHqACbC+lWCyjBsp0wRoQ= 2 | github.com/gokrazy/kernel v0.0.0-20230712041245-e563d7441232/go.mod h1:9bunbYi8kxZow8AQJl4SiPmglzemYA/f3zrLgKrTmVI= 3 | github.com/gokrazy/kernel v0.0.0-20230721065804-1fc6db972814 h1:tB3zlxqLAk4nVDs9ch/SbHfQNS2hOmLqr8uYuDfFBYw= 4 | github.com/gokrazy/kernel v0.0.0-20230721065804-1fc6db972814/go.mod h1:9bunbYi8kxZow8AQJl4SiPmglzemYA/f3zrLgKrTmVI= 5 | github.com/gokrazy/kernel v0.0.0-20230817035607-3fd001b743cb h1:/Fql5+it0end0fDZH2XbRojW47JQJKz+NN+yz62lYfs= 6 | github.com/gokrazy/kernel v0.0.0-20230817035607-3fd001b743cb/go.mod h1:9bunbYi8kxZow8AQJl4SiPmglzemYA/f3zrLgKrTmVI= 7 | github.com/gokrazy/kernel v0.0.0-20230907062000-165f6de9072a h1:jopo2pzlP0kiKi147CPHR8XWWjsEhNoCKx6G2qNfCT8= 8 | github.com/gokrazy/kernel v0.0.0-20230907062000-165f6de9072a/go.mod h1:9bunbYi8kxZow8AQJl4SiPmglzemYA/f3zrLgKrTmVI= 9 | github.com/gokrazy/kernel v0.0.0-20230920040557-40cc98addb83 h1:mpdL4ICf5l9xUejQcxl9VivaTCW0fWwQz5vcq102Ii8= 10 | github.com/gokrazy/kernel v0.0.0-20230920040557-40cc98addb83/go.mod h1:9bunbYi8kxZow8AQJl4SiPmglzemYA/f3zrLgKrTmVI= 11 | github.com/gokrazy/kernel v0.0.0-20240106034721-5e05d8f69034 h1:ym5ULAkt2eGrJHGicWb42HR0Gntu7TRVHdTwjkrNgaA= 12 | github.com/gokrazy/kernel v0.0.0-20240106034721-5e05d8f69034/go.mod h1:9bunbYi8kxZow8AQJl4SiPmglzemYA/f3zrLgKrTmVI= 13 | github.com/gokrazy/kernel v0.0.0-20240113100918-f46f91c6a4d5 h1:emT1HERyZmP3cI7zppD0jCZBUstVMLWc98J0GQawR8A= 14 | github.com/gokrazy/kernel v0.0.0-20240113100918-f46f91c6a4d5/go.mod h1:eySh+AYuSQ2bLhvSI3HtM20v9qfT7pjUR5U4ZqaCgzo= 15 | github.com/gokrazy/kernel v0.0.0-20240128094315-f53e00c991dd h1:Zg6es2zHZeAeKe81dubBUpzrItmPjftHi/9dR7T+MNw= 16 | github.com/gokrazy/kernel v0.0.0-20240128094315-f53e00c991dd/go.mod h1:eySh+AYuSQ2bLhvSI3HtM20v9qfT7pjUR5U4ZqaCgzo= 17 | github.com/gokrazy/kernel v0.0.0-20240217090636-37097fcdec4b h1:JaQzMA/BI5HX/FSWAkhQyzJklAqMuhGstE7+4uw3V7U= 18 | github.com/gokrazy/kernel v0.0.0-20240217090636-37097fcdec4b/go.mod h1:eySh+AYuSQ2bLhvSI3HtM20v9qfT7pjUR5U4ZqaCgzo= 19 | github.com/gokrazy/kernel v0.0.0-20240405035136-cd697478e9b1 h1:u10UJE4m0+A9V9Xu/J8Zdpl/+KqjqX4agCMrOVy4WDo= 20 | github.com/gokrazy/kernel v0.0.0-20240405035136-cd697478e9b1/go.mod h1:eySh+AYuSQ2bLhvSI3HtM20v9qfT7pjUR5U4ZqaCgzo= 21 | github.com/gokrazy/kernel v0.0.0-20240725035519-db6bea05ed76 h1:+p/eXaSSM5IndFLk1GXUnCa4Lf1LoRhcXOcI2bkkdBs= 22 | github.com/gokrazy/kernel v0.0.0-20240725035519-db6bea05ed76/go.mod h1:eySh+AYuSQ2bLhvSI3HtM20v9qfT7pjUR5U4ZqaCgzo= 23 | github.com/gokrazy/kernel v0.0.0-20241210041216-2888c1a9526f h1:0O/Fbt/9eKlrm1dFFIxbxWVYob7c2IuQRFPhiVJpFAE= 24 | github.com/gokrazy/kernel v0.0.0-20241210041216-2888c1a9526f/go.mod h1:eySh+AYuSQ2bLhvSI3HtM20v9qfT7pjUR5U4ZqaCgzo= 25 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/rpi-eeprom/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.20 4 | 5 | require github.com/gokrazy/rpi-eeprom v0.0.0-20241208034722-1b137ccff4a1 // indirect 6 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/rpi-eeprom/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gokrazy/rpi-eeprom v0.0.0-20230516032624-867a3d61458d h1:mNoB8gK7iQlKJXV55FNQSjW+ipH4Xk/wE+85N+G11pI= 2 | github.com/gokrazy/rpi-eeprom v0.0.0-20230516032624-867a3d61458d/go.mod h1:vabxV1M+i6S3rGuWoFieHxCJW3jlob3rqe0KV82j+0o= 3 | github.com/gokrazy/rpi-eeprom v0.0.0-20231120175629-4b8fc2187aac h1:fbO6kUpg5sAcI5trqKjOAxFLs1MfS/0AIjYicnlzSGY= 4 | github.com/gokrazy/rpi-eeprom v0.0.0-20231120175629-4b8fc2187aac/go.mod h1:vabxV1M+i6S3rGuWoFieHxCJW3jlob3rqe0KV82j+0o= 5 | github.com/gokrazy/rpi-eeprom v0.0.0-20240123032940-163731fa6d15 h1:rl5BFfxvLWtyBGeC3jBNRCjOMcGn3vVBOmhnNMfnkfc= 6 | github.com/gokrazy/rpi-eeprom v0.0.0-20240123032940-163731fa6d15/go.mod h1:vabxV1M+i6S3rGuWoFieHxCJW3jlob3rqe0KV82j+0o= 7 | github.com/gokrazy/rpi-eeprom v0.0.0-20240726033136-db04aca0e2f0 h1:D2koADPXYLOLXIch1sEgYzPr/2rNB88E6fJscKgZQnI= 8 | github.com/gokrazy/rpi-eeprom v0.0.0-20240726033136-db04aca0e2f0/go.mod h1:vabxV1M+i6S3rGuWoFieHxCJW3jlob3rqe0KV82j+0o= 9 | github.com/gokrazy/rpi-eeprom v0.0.0-20241208034722-1b137ccff4a1 h1:/tsZ0kHsb2wLNZdL2S5RrPd6RNqyUAZqCA+Y89tvDxY= 10 | github.com/gokrazy/rpi-eeprom v0.0.0-20241208034722-1b137ccff4a1/go.mod h1:vabxV1M+i6S3rGuWoFieHxCJW3jlob3rqe0KV82j+0o= 11 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 12 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/serial-busybox/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/gokrazy/gokrazy v0.0.0-20200501080617-f3445e01a904 // indirect 7 | github.com/gokrazy/internal v0.0.0-20200407075822-660ad467b7c9 // indirect 8 | github.com/gokrazy/serial-busybox v0.0.0-20240818092410-3d7f3f33f595 // indirect 9 | golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/gokrazy/serial-busybox/go.sum: -------------------------------------------------------------------------------- 1 | github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/gokrazy/gokrazy v0.0.0-20200501080617-f3445e01a904 h1:eqfH4A/LLgxv5RvqEXwVoFvfmpRa8+TokRjB5g6xBkk= 4 | github.com/gokrazy/gokrazy v0.0.0-20200501080617-f3445e01a904/go.mod h1:pq6rGHqxMRPSaTXaCMzIZy0wLDusAJyoVNyNo05RLs0= 5 | github.com/gokrazy/internal v0.0.0-20200407075822-660ad467b7c9 h1:x5jR/nNo4/kMSoNo/nwa2xbL7PN1an8S3oIn4OZJdec= 6 | github.com/gokrazy/internal v0.0.0-20200407075822-660ad467b7c9/go.mod h1:LA5TQy7LcvYGQOy75tkrYkFUhbV2nl5qEBP47PSi2JA= 7 | github.com/gokrazy/serial-busybox v0.0.0-20220918193710-d728912733ca h1:x0eSjuFy8qsRctVHeWm3EC474q3xm4h3OOOrYpcqyyA= 8 | github.com/gokrazy/serial-busybox v0.0.0-20220918193710-d728912733ca/go.mod h1:OYcG5tSb+QrelmUOO4EZVUFcIHyyZb0QDbEbZFUp1TA= 9 | github.com/gokrazy/serial-busybox v0.0.0-20240818092410-3d7f3f33f595 h1:UhDtHHWvM0GfdwV0wE77r6W9YIWlmo1tKBNQxn0VZFg= 10 | github.com/gokrazy/serial-busybox v0.0.0-20240818092410-3d7f3f33f595/go.mod h1:OYcG5tSb+QrelmUOO4EZVUFcIHyyZb0QDbEbZFUp1TA= 11 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 12 | github.com/google/gopacket v1.1.16/go.mod h1:UCLx9mCmAwsVbn6qQl1WIEt2SO7Nd2fD0th1TBAsqBw= 13 | github.com/mdlayher/raw v0.0.0-20190303161257-764d452d77af/go.mod h1:rC/yE65s/DoHB6BzVOUBNYBGTg772JVytyAytffIZkY= 14 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 15 | github.com/rtr7/dhcp4 v0.0.0-20181120124042-778e8c2e24a5/go.mod h1:FwstIpm6vX98QgtR8KEwZcVjiRn2WP76LjXAHj84fK0= 16 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 17 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 18 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 19 | golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 20 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 21 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 22 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 23 | golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4 h1:c1Sgqkh8v6ZxafNGG64r8C8UisIW2TKMJN8P86tKjr0= 24 | golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 25 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 26 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 27 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 28 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 29 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/mdlayher/consrv/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/github.com/mdlayher/consrv 2 | 3 | go 1.23 4 | 5 | toolchain go1.23.0 6 | 7 | require ( 8 | github.com/BurntSushi/toml v1.4.0 9 | github.com/dolmen-go/contextio v1.0.0 10 | github.com/gliderlabs/ssh v0.3.8 11 | github.com/google/go-cmp v0.6.0 12 | github.com/mdlayher/metricslite v0.0.0-20220406114248-d75c70dd4887 13 | github.com/prometheus/client_golang v1.20.5 14 | github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 15 | golang.org/x/crypto v0.31.0 16 | golang.org/x/net v0.32.0 17 | golang.org/x/sync v0.10.0 18 | ) 19 | 20 | require ( 21 | github.com/klauspost/compress v1.17.11 // indirect 22 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 23 | ) 24 | 25 | require ( 26 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect 27 | github.com/beorn7/perks v1.0.1 // indirect 28 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 29 | github.com/golang/protobuf v1.5.2 // indirect 30 | github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect 31 | github.com/mdlayher/consrv v1.2.1 32 | github.com/prometheus/client_model v0.6.1 // indirect 33 | github.com/prometheus/common v0.61.0 // indirect 34 | github.com/prometheus/procfs v0.15.1 // indirect 35 | golang.org/x/sys v0.28.0 // indirect 36 | google.golang.org/protobuf v1.35.2 // indirect 37 | ) 38 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/github.com/prometheus/node_exporter/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/github.com/prometheus/node_exporter 2 | 3 | go 1.21 4 | 5 | toolchain go1.22.0 6 | 7 | require ( 8 | github.com/alecthomas/kingpin/v2 v2.4.0 9 | github.com/beevik/ntp v1.3.1 10 | github.com/coreos/go-systemd/v22 v22.5.0 11 | github.com/dennwc/btrfs v0.0.0-20240418142341-0167142bde7a 12 | github.com/ema/qdisc v1.0.0 13 | github.com/go-kit/log v0.2.1 14 | github.com/godbus/dbus/v5 v5.1.0 15 | github.com/hashicorp/go-envparse v0.1.0 16 | github.com/hodgesds/perf-utils v0.7.0 17 | github.com/illumos/go-kstat v0.0.0-20210513183136-173c9b0a9973 18 | github.com/josharian/native v1.1.0 19 | github.com/jsimonetti/rtnetlink v1.4.1 20 | github.com/lufia/iostat v1.2.1 21 | github.com/mattn/go-xmlrpc v0.0.3 22 | github.com/mdlayher/ethtool v0.1.0 23 | github.com/mdlayher/netlink v1.7.2 24 | github.com/mdlayher/wifi v0.1.0 25 | github.com/opencontainers/selinux v1.11.0 26 | github.com/prometheus-community/go-runit v0.1.0 27 | github.com/prometheus/client_golang v1.19.0 28 | github.com/prometheus/client_model v0.6.1 29 | github.com/prometheus/common v0.53.0 30 | github.com/prometheus/exporter-toolkit v0.11.0 31 | github.com/prometheus/procfs v0.14.0 32 | github.com/safchain/ethtool v0.3.0 33 | golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f 34 | golang.org/x/sys v0.19.0 35 | howett.net/plist v1.0.1 36 | ) 37 | 38 | require github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect 39 | 40 | require ( 41 | github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect 42 | github.com/beorn7/perks v1.0.1 // indirect 43 | github.com/cespare/xxhash/v2 v2.2.0 // indirect 44 | github.com/davecgh/go-spew v1.1.1 // indirect 45 | github.com/dennwc/ioctl v1.0.0 // indirect 46 | github.com/go-logfmt/logfmt v0.5.1 // indirect 47 | github.com/golang/protobuf v1.5.3 // indirect 48 | github.com/google/go-cmp v0.6.0 // indirect 49 | github.com/jpillora/backoff v1.0.0 // indirect 50 | github.com/kr/text v0.2.0 // indirect 51 | github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect 52 | github.com/mdlayher/genetlink v1.3.2 // indirect 53 | github.com/mdlayher/socket v0.4.1 // indirect 54 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect 55 | github.com/prometheus/node_exporter v1.8.2 56 | github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973 // indirect 57 | github.com/xhit/go-str2duration/v2 v2.1.0 // indirect 58 | go.uber.org/atomic v1.7.0 // indirect 59 | go.uber.org/multierr v1.6.0 // indirect 60 | golang.org/x/crypto v0.21.0 // indirect 61 | golang.org/x/net v0.23.0 // indirect 62 | golang.org/x/oauth2 v0.18.0 // indirect 63 | golang.org/x/sync v0.7.0 // indirect 64 | golang.org/x/text v0.14.0 // indirect 65 | google.golang.org/appengine v1.6.7 // indirect 66 | google.golang.org/protobuf v1.33.0 // indirect 67 | gopkg.in/yaml.v2 v2.4.0 // indirect 68 | ) 69 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/init/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/monitnerr-1 2 | 3 | go 1.20 4 | 5 | require github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9 // indirect 6 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/init/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9 h1:OJ4b0Z8OPgTIn6i/Iq+Y0AcnsiFiT4vXMnLXclPwPVg= 2 | github.com/gokrazy/gokrazy v0.0.0-20230701125004-edba3d33ffa9/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c= 3 | github.com/gokrazy/internal v0.0.0-20220129150711-9ed298107648 h1:kBuLicM0xJw3xEe4607WlnzGL+qSwPqdyh5/LUiCdq0= 4 | github.com/gokrazy/internal v0.0.0-20220129150711-9ed298107648/go.mod h1:Gc9sU6yJ/qxg3gJZ1pjfcTAULa0swdTa4TH51g1e00E= 5 | github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= 6 | github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= 7 | github.com/kenshaw/evdev v0.1.0 h1:wmtceEOFfilChgdNT+c/djPJ2JineVsQ0N14kGzFRUo= 8 | github.com/kenshaw/evdev v0.1.0/go.mod h1:B/fErKCihUyEobz0mjn2qQbHgyJKFQAxkXSvkeeA/Wo= 9 | github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b h1:7tUBfsEEBWfFeHOB7CUfoOamak+Gx/BlirfXyPk1WjI= 10 | github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b/go.mod h1:bmoJUS6qOA3uKFvF3KVuhf7mU1KQirzQMeHXtPyKEqg= 11 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 12 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 13 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/builddir/tailscale.com/go.mod: -------------------------------------------------------------------------------- 1 | module gokrazy/build/tailscale.com 2 | 3 | go 1.23.1 4 | 5 | toolchain go1.23.4 6 | 7 | require ( 8 | filippo.io/mkcert v1.4.4 9 | github.com/Microsoft/go-winio v0.6.2 10 | github.com/akutz/memconn v0.1.0 11 | github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa 12 | github.com/andybalholm/brotli v1.1.0 13 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be 14 | github.com/aws/aws-sdk-go-v2 v1.24.1 15 | github.com/aws/aws-sdk-go-v2/config v1.26.5 16 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.64 17 | github.com/aws/aws-sdk-go-v2/service/s3 v1.33.0 18 | github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7 19 | github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 20 | github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf 21 | github.com/creack/pty v1.1.23 22 | github.com/dave/jennifer v1.7.0 23 | github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa 24 | github.com/dsnet/try v0.0.3 25 | github.com/evanw/esbuild v0.19.11 26 | github.com/frankban/quicktest v1.14.6 27 | github.com/fxamacker/cbor/v2 v2.6.0 28 | github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0 29 | github.com/go-logr/zapr v1.3.0 30 | github.com/go-ole/go-ole v1.3.0 31 | github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 32 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da 33 | github.com/golangci/golangci-lint v1.57.1 34 | github.com/google/go-cmp v0.6.0 35 | github.com/google/go-containerregistry v0.20.2 36 | github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 37 | github.com/google/uuid v1.6.0 38 | github.com/goreleaser/nfpm v1.10.3 39 | github.com/hdevalence/ed25519consensus v0.2.0 40 | github.com/iancoleman/strcase v0.3.0 41 | github.com/illarion/gonotify v1.0.1 42 | github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 43 | github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 44 | github.com/jsimonetti/rtnetlink v1.4.0 45 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 46 | github.com/klauspost/compress v1.17.11 47 | github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a 48 | github.com/mattn/go-colorable v0.1.13 49 | github.com/mattn/go-isatty v0.0.20 50 | github.com/mdlayher/genetlink v1.3.2 51 | github.com/mdlayher/netlink v1.7.2 52 | github.com/mdlayher/sdnotify v1.0.0 53 | github.com/miekg/dns v1.1.58 54 | github.com/mitchellh/go-ps v1.0.0 55 | github.com/peterbourgon/ff/v3 v3.4.0 56 | github.com/pkg/errors v0.9.1 57 | github.com/pkg/sftp v1.13.6 58 | github.com/prometheus/client_golang v1.19.1 59 | github.com/prometheus/common v0.48.0 60 | github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e 61 | github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e 62 | github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 63 | github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41 64 | github.com/tailscale/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4 65 | github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 66 | github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a 67 | github.com/tailscale/mkctr v0.0.0-20241111153353-1a38f6676f10 68 | github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 69 | github.com/tailscale/wireguard-go v0.0.0-20241113014420-4e883d38c8d3 70 | github.com/tc-hib/winres v0.2.1 71 | github.com/tcnksm/go-httpstat v0.2.0 72 | github.com/toqueteos/webbrowser v1.2.0 73 | github.com/u-root/u-root v0.12.0 74 | github.com/vishvananda/netlink v1.2.1-beta.2 75 | github.com/vishvananda/netns v0.0.4 76 | go.uber.org/zap v1.27.0 77 | go4.org/mem v0.0.0-20220726221520-4f986261bf13 78 | go4.org/netipx v0.0.0-20231129151722-fdeea329fbba 79 | golang.org/x/crypto v0.25.0 80 | golang.org/x/exp v0.0.0-20240119083558-1b970713d09a 81 | golang.org/x/mod v0.19.0 82 | golang.org/x/net v0.27.0 83 | golang.org/x/oauth2 v0.16.0 84 | golang.org/x/sync v0.9.0 85 | golang.org/x/sys v0.27.0 86 | golang.org/x/term v0.22.0 87 | golang.org/x/time v0.5.0 88 | golang.org/x/tools v0.23.0 89 | golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 90 | golang.zx2c4.com/wireguard/windows v0.5.3 91 | gvisor.dev/gvisor v0.0.0-20240722211153-64c016c92987 92 | honnef.co/go/tools v0.5.1 93 | inet.af/peercred v0.0.0-20210906144145-0893ea02156a 94 | inet.af/tcpproxy v0.0.0-20231102063150-2862066fc2a9 95 | inet.af/wf v0.0.0-20221017222439-36129f591884 96 | k8s.io/api v0.30.3 97 | k8s.io/apimachinery v0.30.3 98 | k8s.io/client-go v0.30.3 99 | nhooyr.io/websocket v1.8.10 100 | sigs.k8s.io/controller-runtime v0.18.4 101 | sigs.k8s.io/yaml v1.4.0 102 | software.sslmate.com/src/go-pkcs12 v0.4.0 103 | ) 104 | 105 | require ( 106 | github.com/bits-and-blooms/bitset v1.13.0 // indirect 107 | github.com/coder/websocket v1.8.12 // indirect 108 | github.com/coreos/go-systemd/v22 v22.5.0 // indirect 109 | github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect 110 | github.com/djherbis/times v1.6.0 // indirect 111 | github.com/gaissmai/bart v0.11.1 // indirect 112 | github.com/gorilla/csrf v1.7.2 // indirect 113 | github.com/gorilla/securecookie v1.1.2 // indirect 114 | github.com/illarion/gonotify/v2 v2.0.3 // indirect 115 | github.com/jellydator/ttlcache/v3 v3.1.0 // indirect 116 | github.com/prometheus-community/pro-bing v0.4.0 // indirect 117 | github.com/safchain/ethtool v0.3.0 // indirect 118 | github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect 119 | github.com/tailscale/gowebdav v0.0.0-20240130173557-d49b872b5126 // indirect 120 | github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4 // indirect 121 | github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 // indirect 122 | github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6 // indirect 123 | github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e // indirect 124 | ) 125 | 126 | require ( 127 | 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect 128 | 4d63.com/gochecknoglobals v0.2.1 // indirect 129 | filippo.io/edwards25519 v1.1.0 // indirect 130 | github.com/Abirdcfly/dupword v0.0.14 // indirect 131 | github.com/Antonboom/errname v0.1.12 // indirect 132 | github.com/Antonboom/nilnil v0.1.7 // indirect 133 | github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect 134 | github.com/Djarvur/go-err113 v0.1.0 // indirect 135 | github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect 136 | github.com/Masterminds/goutils v1.1.1 // indirect 137 | github.com/Masterminds/semver v1.5.0 // indirect 138 | github.com/Masterminds/semver/v3 v3.2.1 // indirect 139 | github.com/Masterminds/sprig v2.22.0+incompatible // indirect 140 | github.com/OpenPeeDeeP/depguard v1.1.1 // indirect 141 | github.com/ProtonMail/go-crypto v1.0.0 // indirect 142 | github.com/acomagu/bufpipe v1.0.4 // indirect 143 | github.com/alexkohler/prealloc v1.0.0 // indirect 144 | github.com/alingse/asasalint v0.0.11 // indirect 145 | github.com/ashanbrown/forbidigo v1.6.0 // indirect 146 | github.com/ashanbrown/makezero v1.1.1 // indirect 147 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect 148 | github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect 149 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect 150 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect 151 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect 152 | github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect 153 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.25 // indirect 154 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect 155 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.28 // indirect 156 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect 157 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.2 // indirect 158 | github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect 159 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect 160 | github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect 161 | github.com/aws/smithy-go v1.19.0 // indirect 162 | github.com/beorn7/perks v1.0.1 // indirect 163 | github.com/bkielbasa/cyclop v1.2.1 // indirect 164 | github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect 165 | github.com/blizzy78/varnamelen v0.8.0 // indirect 166 | github.com/bombsimon/wsl/v3 v3.4.0 // indirect 167 | github.com/breml/bidichk v0.2.7 // indirect 168 | github.com/breml/errchkjson v0.3.6 // indirect 169 | github.com/butuzov/ireturn v0.3.0 // indirect 170 | github.com/cavaliergopher/cpio v1.0.1 // indirect 171 | github.com/cespare/xxhash/v2 v2.2.0 // indirect 172 | github.com/charithe/durationcheck v0.0.10 // indirect 173 | github.com/chavacava/garif v0.1.0 // indirect 174 | github.com/cloudflare/circl v1.3.7 // indirect 175 | github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect 176 | github.com/curioswitch/go-reassign v0.2.0 // indirect 177 | github.com/daixiang0/gci v0.12.3 // indirect 178 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 179 | github.com/denis-tingaikin/go-header v0.5.0 // indirect 180 | github.com/docker/cli v27.3.1+incompatible // indirect 181 | github.com/docker/distribution v2.8.3+incompatible // indirect 182 | github.com/docker/docker v27.3.1+incompatible // indirect 183 | github.com/docker/docker-credential-helpers v0.8.2 // indirect 184 | github.com/emicklei/go-restful/v3 v3.11.2 // indirect 185 | github.com/emirpasic/gods v1.18.1 // indirect 186 | github.com/esimonov/ifshort v1.0.4 // indirect 187 | github.com/ettle/strcase v0.2.0 // indirect 188 | github.com/evanphx/json-patch v5.6.0+incompatible // indirect 189 | github.com/evanphx/json-patch/v5 v5.9.0 // indirect 190 | github.com/fatih/color v1.17.0 // indirect 191 | github.com/fatih/structtag v1.2.0 // indirect 192 | github.com/firefart/nonamedreturns v1.0.4 // indirect 193 | github.com/fsnotify/fsnotify v1.7.0 // indirect 194 | github.com/fzipp/gocyclo v0.6.0 // indirect 195 | github.com/go-critic/go-critic v0.11.2 // indirect 196 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect 197 | github.com/go-git/go-billy/v5 v5.5.0 // indirect 198 | github.com/go-git/go-git/v5 v5.11.0 // indirect 199 | github.com/go-logr/logr v1.4.2 // indirect 200 | github.com/go-openapi/jsonpointer v0.20.2 // indirect 201 | github.com/go-openapi/jsonreference v0.20.4 // indirect 202 | github.com/go-openapi/swag v0.22.7 // indirect 203 | github.com/go-toolsmith/astcast v1.1.0 // indirect 204 | github.com/go-toolsmith/astcopy v1.1.0 // indirect 205 | github.com/go-toolsmith/astequal v1.2.0 // indirect 206 | github.com/go-toolsmith/astfmt v1.1.0 // indirect 207 | github.com/go-toolsmith/astp v1.1.0 // indirect 208 | github.com/go-toolsmith/strparse v1.1.0 // indirect 209 | github.com/go-toolsmith/typep v1.1.0 // indirect 210 | github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect 211 | github.com/gobwas/glob v0.2.3 // indirect 212 | github.com/gofrs/flock v0.8.1 // indirect 213 | github.com/gogo/protobuf v1.3.2 // indirect 214 | github.com/golang/protobuf v1.5.4 // indirect 215 | github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect 216 | github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect 217 | github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect 218 | github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e // indirect 219 | github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect 220 | github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect 221 | github.com/golangci/misspell v0.4.1 // indirect 222 | github.com/golangci/revgrep v0.5.2 // indirect 223 | github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect 224 | github.com/google/btree v1.1.2 // indirect 225 | github.com/google/gnostic v0.6.9 // indirect 226 | github.com/google/gofuzz v1.2.0 // indirect 227 | github.com/google/goterm v0.0.0-20200907032337-555d40f16ae2 // indirect 228 | github.com/google/rpmpack v0.5.0 // indirect 229 | github.com/gordonklaus/ineffassign v0.1.0 // indirect 230 | github.com/goreleaser/chglog v0.5.0 // indirect 231 | github.com/goreleaser/fileglob v1.3.0 // indirect 232 | github.com/gostaticanalysis/analysisutil v0.7.1 // indirect 233 | github.com/gostaticanalysis/comment v1.4.2 // indirect 234 | github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect 235 | github.com/gostaticanalysis/nilerr v0.1.1 // indirect 236 | github.com/hashicorp/errwrap v1.1.0 // indirect 237 | github.com/hashicorp/go-multierror v1.1.1 // indirect 238 | github.com/hashicorp/go-version v1.6.0 // indirect 239 | github.com/hashicorp/hcl v1.0.0 // indirect 240 | github.com/hexops/gotextdiff v1.0.3 // indirect 241 | github.com/huandu/xstrings v1.5.0 // indirect 242 | github.com/imdario/mergo v0.3.16 // indirect 243 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 244 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect 245 | github.com/jgautheron/goconst v1.7.0 // indirect 246 | github.com/jingyugao/rowserrcheck v1.1.1 // indirect 247 | github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect 248 | github.com/jmespath/go-jmespath v0.4.0 // indirect 249 | github.com/josharian/intern v1.0.0 // indirect 250 | github.com/json-iterator/go v1.1.12 // indirect 251 | github.com/julz/importas v0.1.0 // indirect 252 | github.com/junk1tm/musttag v0.5.0 // indirect 253 | github.com/kevinburke/ssh_config v1.2.0 // indirect 254 | github.com/kisielk/errcheck v1.7.0 // indirect 255 | github.com/kisielk/gotool v1.0.0 // indirect 256 | github.com/kkHAIKE/contextcheck v1.1.4 // indirect 257 | github.com/klauspost/pgzip v1.2.6 // indirect 258 | github.com/kr/fs v0.1.0 // indirect 259 | github.com/kr/pretty v0.3.1 // indirect 260 | github.com/kr/text v0.2.0 // indirect 261 | github.com/kulti/thelper v0.6.3 // indirect 262 | github.com/kunwardeep/paralleltest v1.0.10 // indirect 263 | github.com/kyoh86/exportloopref v0.1.11 // indirect 264 | github.com/ldez/gomoddirectives v0.2.3 // indirect 265 | github.com/ldez/tagliatelle v0.5.0 // indirect 266 | github.com/leonklingele/grouper v1.1.1 // indirect 267 | github.com/lufeee/execinquery v1.2.1 // indirect 268 | github.com/magiconair/properties v1.8.7 // indirect 269 | github.com/mailru/easyjson v0.7.7 // indirect 270 | github.com/maratori/testableexamples v1.0.0 // indirect 271 | github.com/maratori/testpackage v1.1.1 // indirect 272 | github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect 273 | github.com/mattn/go-runewidth v0.0.14 // indirect 274 | github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect 275 | github.com/mbilski/exhaustivestruct v1.2.0 // indirect 276 | github.com/mdlayher/socket v0.5.0 // indirect 277 | github.com/mgechev/revive v1.3.7 // indirect 278 | github.com/mitchellh/copystructure v1.2.0 // indirect 279 | github.com/mitchellh/go-homedir v1.1.0 // indirect 280 | github.com/mitchellh/mapstructure v1.5.0 // indirect 281 | github.com/mitchellh/reflectwalk v1.0.2 // indirect 282 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 283 | github.com/modern-go/reflect2 v1.0.2 // indirect 284 | github.com/moricho/tparallel v0.3.1 // indirect 285 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 286 | github.com/nakabonne/nestif v0.3.1 // indirect 287 | github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect 288 | github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect 289 | github.com/nishanths/exhaustive v0.12.0 // indirect 290 | github.com/nishanths/predeclared v0.2.2 // indirect 291 | github.com/nunnatsa/ginkgolinter v0.16.1 // indirect 292 | github.com/olekukonko/tablewriter v0.0.5 // indirect 293 | github.com/opencontainers/go-digest v1.0.0 // indirect 294 | github.com/opencontainers/image-spec v1.1.0 // indirect 295 | github.com/pelletier/go-toml/v2 v2.2.0 // indirect 296 | github.com/pierrec/lz4/v4 v4.1.21 // indirect 297 | github.com/pjbgf/sha1cd v0.3.0 // indirect 298 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect 299 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 300 | github.com/polyfloyd/go-errorlint v1.4.8 // indirect 301 | github.com/prometheus/client_model v0.5.0 // indirect 302 | github.com/prometheus/procfs v0.12.0 // indirect 303 | github.com/quasilyte/go-ruleguard v0.4.2 // indirect 304 | github.com/quasilyte/gogrep v0.5.0 // indirect 305 | github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect 306 | github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect 307 | github.com/rivo/uniseg v0.4.4 // indirect 308 | github.com/rogpeppe/go-internal v1.12.0 // indirect 309 | github.com/ryancurrah/gomodguard v1.3.1 // indirect 310 | github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect 311 | github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect 312 | github.com/sashamelentyev/interfacebloat v1.1.0 // indirect 313 | github.com/sashamelentyev/usestdlibvars v1.25.0 // indirect 314 | github.com/sassoftware/go-rpmutils v0.2.0 // indirect 315 | github.com/securego/gosec/v2 v2.19.0 // indirect 316 | github.com/sergi/go-diff v1.3.1 // indirect 317 | github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect 318 | github.com/sirupsen/logrus v1.9.3 // indirect 319 | github.com/sivchari/containedctx v1.0.3 // indirect 320 | github.com/sivchari/nosnakecase v1.7.0 // indirect 321 | github.com/sivchari/tenv v1.7.1 // indirect 322 | github.com/skeema/knownhosts v1.2.1 // indirect 323 | github.com/sonatard/noctx v0.0.2 // indirect 324 | github.com/sourcegraph/go-diff v0.7.0 // indirect 325 | github.com/spf13/afero v1.11.0 // indirect 326 | github.com/spf13/cast v1.6.0 // indirect 327 | github.com/spf13/cobra v1.8.1 // indirect 328 | github.com/spf13/jwalterweatherman v1.1.0 // indirect 329 | github.com/spf13/pflag v1.0.5 // indirect 330 | github.com/spf13/viper v1.16.0 // indirect 331 | github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect 332 | github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect 333 | github.com/stretchr/objx v0.5.2 // indirect 334 | github.com/stretchr/testify v1.9.0 // indirect 335 | github.com/subosito/gotenv v1.4.2 // indirect 336 | github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect 337 | github.com/tdakkota/asciicheck v0.2.0 // indirect 338 | github.com/tetafro/godot v1.4.16 // indirect 339 | github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect 340 | github.com/timonwong/loggercheck v0.9.4 // indirect 341 | github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect 342 | github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect 343 | github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e // indirect 344 | github.com/ulikunitz/xz v0.5.11 // indirect 345 | github.com/ultraware/funlen v0.1.0 // indirect 346 | github.com/ultraware/whitespace v0.1.0 // indirect 347 | github.com/uudashr/gocognit v1.1.2 // indirect 348 | github.com/vbatts/tar-split v0.11.6 // indirect 349 | github.com/x448/float16 v0.8.4 // indirect 350 | github.com/xanzy/ssh-agent v0.3.3 // indirect 351 | github.com/yagipy/maintidx v1.0.0 // indirect 352 | github.com/yeya24/promlinter v0.2.0 // indirect 353 | gitlab.com/bosi/decorder v0.4.1 // indirect 354 | gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect 355 | go.uber.org/atomic v1.11.0 // indirect 356 | go.uber.org/multierr v1.11.0 // indirect 357 | golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect 358 | golang.org/x/image v0.18.0 // indirect 359 | golang.org/x/text v0.16.0 // indirect 360 | gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect 361 | google.golang.org/appengine v1.6.8 // indirect 362 | google.golang.org/protobuf v1.33.0 // indirect 363 | gopkg.in/inf.v0 v0.9.1 // indirect 364 | gopkg.in/ini.v1 v1.67.0 // indirect 365 | gopkg.in/warnings.v0 v0.1.2 // indirect 366 | gopkg.in/yaml.v2 v2.4.0 // indirect 367 | gopkg.in/yaml.v3 v3.0.1 // indirect 368 | howett.net/plist v1.0.0 // indirect 369 | k8s.io/apiextensions-apiserver v0.30.3 // indirect 370 | k8s.io/component-base v0.30.3 // indirect 371 | k8s.io/klog/v2 v2.130.1 // indirect 372 | k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect 373 | k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect 374 | mvdan.cc/gofumpt v0.6.0 // indirect 375 | mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect 376 | mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect 377 | mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 // indirect 378 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect 379 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect 380 | tailscale.com v1.78.3 381 | ) 382 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/config.tmpl.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hostname": "monitnerr-1", 3 | "Update": { 4 | "HTTPPassword": "" 5 | }, 6 | "Packages": [ 7 | "github.com/gokrazy/serial-busybox", 8 | "github.com/gokrazy/breakglass", 9 | "github.com/mdlayher/consrv/cmd/consrv", 10 | "github.com/prometheus/node_exporter", 11 | "tailscale.com/cmd/tailscaled", 12 | "tailscale.com/cmd/tailscale" 13 | ], 14 | "PackageConfig": { 15 | "github.com/gokrazy/breakglass": { 16 | "CommandLineFlags": [ 17 | "-authorized_keys=/etc/breakglass.authorized_keys" 18 | ], 19 | "ExtraFilePaths": { 20 | "/etc/breakglass.authorized_keys": "breakglass.authorized_keys" 21 | } 22 | }, 23 | "github.com/gokrazy/gokrazy/cmd/randomd": { 24 | "ExtraFileContents": { 25 | "/etc/machine-id": "f4eda07834ca40c6915deabb26f08b85\n" 26 | } 27 | }, 28 | "github.com/mdlayher/consrv/cmd/consrv": { 29 | "CommandLineFlags": [ 30 | "-c=/etc/consrv.toml", 31 | "-experimental-drop-privileges" 32 | ], 33 | "ExtraFilePaths": { 34 | "/etc/consrv.toml": "consrv.toml" 35 | } 36 | }, 37 | "tailscale.com/cmd/tailscale": { 38 | "CommandLineFlags": [ 39 | "up" 40 | ] 41 | } 42 | }, 43 | "SerialConsole": "disabled", 44 | "InternalCompatibilityFlags": {} 45 | } 46 | -------------------------------------------------------------------------------- /gokrazy/monitnerr-1/consrv.toml: -------------------------------------------------------------------------------- 1 | # Configuration for monitnerr-1. 2 | [[devices]] 3 | name = "router" 4 | serial = "Q3245527461" 5 | baud = 115200 6 | identities = ["mdlayher"] 7 | 8 | [[devices]] 9 | name = "server" 10 | serial = "A64NMAJS" 11 | baud = 115200 12 | identities = ["mdlayher"] 13 | 14 | [[identities]] 15 | name = "mdlayher" 16 | public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5i5d0mRKAf02m+ju+I1KrAYw3Ny2IHXy88mgyragBN Matt Layher (mdlayher@gmail.com)" 17 | 18 | [debug] 19 | address = ":9288" 20 | prometheus = true 21 | -------------------------------------------------------------------------------- /grafana/coredns.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": "-- Grafana --", 7 | "enable": true, 8 | "hide": true, 9 | "iconColor": "rgba(0, 211, 255, 1)", 10 | "name": "Annotations & Alerts", 11 | "type": "dashboard" 12 | } 13 | ] 14 | }, 15 | "editable": true, 16 | "gnetId": null, 17 | "graphTooltip": 0, 18 | "id": 10, 19 | "links": [], 20 | "panels": [ 21 | { 22 | "aliasColors": {}, 23 | "bars": false, 24 | "dashLength": 10, 25 | "dashes": false, 26 | "datasource": null, 27 | "fill": 1, 28 | "fillGradient": 0, 29 | "gridPos": { 30 | "h": 9, 31 | "w": 12, 32 | "x": 0, 33 | "y": 0 34 | }, 35 | "hiddenSeries": false, 36 | "id": 2, 37 | "legend": { 38 | "avg": false, 39 | "current": false, 40 | "max": false, 41 | "min": false, 42 | "show": true, 43 | "total": false, 44 | "values": false 45 | }, 46 | "lines": true, 47 | "linewidth": 1, 48 | "nullPointMode": "null", 49 | "options": { 50 | "dataLinks": [] 51 | }, 52 | "percentage": false, 53 | "pointradius": 2, 54 | "points": false, 55 | "renderer": "flot", 56 | "seriesOverrides": [], 57 | "spaceLength": 10, 58 | "stack": true, 59 | "steppedLine": false, 60 | "targets": [ 61 | { 62 | "expr": "rate(coredns_forward_request_count_total[1m])", 63 | "legendFormat": "{{to}}", 64 | "refId": "A" 65 | } 66 | ], 67 | "thresholds": [], 68 | "timeFrom": null, 69 | "timeRegions": [], 70 | "timeShift": null, 71 | "title": "DNS queries forwarded", 72 | "tooltip": { 73 | "shared": true, 74 | "sort": 0, 75 | "value_type": "individual" 76 | }, 77 | "type": "graph", 78 | "xaxis": { 79 | "buckets": null, 80 | "mode": "time", 81 | "name": null, 82 | "show": true, 83 | "values": [] 84 | }, 85 | "yaxes": [ 86 | { 87 | "format": "reqps", 88 | "label": null, 89 | "logBase": 1, 90 | "max": null, 91 | "min": null, 92 | "show": true 93 | }, 94 | { 95 | "format": "short", 96 | "label": null, 97 | "logBase": 1, 98 | "max": null, 99 | "min": null, 100 | "show": true 101 | } 102 | ], 103 | "yaxis": { 104 | "align": false, 105 | "alignLevel": null 106 | } 107 | }, 108 | { 109 | "aliasColors": {}, 110 | "bars": false, 111 | "dashLength": 10, 112 | "dashes": false, 113 | "datasource": null, 114 | "fill": 1, 115 | "fillGradient": 0, 116 | "gridPos": { 117 | "h": 9, 118 | "w": 12, 119 | "x": 12, 120 | "y": 0 121 | }, 122 | "hiddenSeries": false, 123 | "id": 3, 124 | "legend": { 125 | "avg": false, 126 | "current": false, 127 | "max": false, 128 | "min": false, 129 | "show": true, 130 | "total": false, 131 | "values": false 132 | }, 133 | "lines": true, 134 | "linewidth": 1, 135 | "nullPointMode": "null", 136 | "options": { 137 | "dataLinks": [] 138 | }, 139 | "percentage": false, 140 | "pointradius": 2, 141 | "points": false, 142 | "renderer": "flot", 143 | "seriesOverrides": [], 144 | "spaceLength": 10, 145 | "stack": true, 146 | "steppedLine": false, 147 | "targets": [ 148 | { 149 | "expr": "rate(coredns_cache_hits_total[5m])", 150 | "legendFormat": "hit: {{type}}", 151 | "refId": "A" 152 | }, 153 | { 154 | "expr": "rate(coredns_cache_misses_total[5m])", 155 | "legendFormat": "miss", 156 | "refId": "B" 157 | } 158 | ], 159 | "thresholds": [], 160 | "timeFrom": null, 161 | "timeRegions": [], 162 | "timeShift": null, 163 | "title": "DNS cache hit rate", 164 | "tooltip": { 165 | "shared": true, 166 | "sort": 0, 167 | "value_type": "individual" 168 | }, 169 | "type": "graph", 170 | "xaxis": { 171 | "buckets": null, 172 | "mode": "time", 173 | "name": null, 174 | "show": true, 175 | "values": [] 176 | }, 177 | "yaxes": [ 178 | { 179 | "format": "reqps", 180 | "label": null, 181 | "logBase": 1, 182 | "max": null, 183 | "min": null, 184 | "show": true 185 | }, 186 | { 187 | "format": "short", 188 | "label": null, 189 | "logBase": 1, 190 | "max": null, 191 | "min": null, 192 | "show": true 193 | } 194 | ], 195 | "yaxis": { 196 | "align": false, 197 | "alignLevel": null 198 | } 199 | } 200 | ], 201 | "refresh": false, 202 | "schemaVersion": 22, 203 | "style": "dark", 204 | "tags": [], 205 | "templating": { 206 | "list": [] 207 | }, 208 | "time": { 209 | "from": "now-90d", 210 | "to": "now" 211 | }, 212 | "timepicker": { 213 | "refresh_intervals": [ 214 | "5s", 215 | "10s", 216 | "30s", 217 | "1m", 218 | "5m", 219 | "15m", 220 | "30m", 221 | "1h", 222 | "2h", 223 | "1d" 224 | ] 225 | }, 226 | "timezone": "", 227 | "title": "CoreDNS", 228 | "uid": "6droFAQWk", 229 | "variables": { 230 | "list": [] 231 | }, 232 | "version": 4 233 | } 234 | -------------------------------------------------------------------------------- /grafana/network.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "$$hashKey": "object:39", 6 | "builtIn": 1, 7 | "datasource": "-- Grafana --", 8 | "enable": true, 9 | "hide": true, 10 | "iconColor": "rgba(0, 211, 255, 1)", 11 | "name": "Annotations & Alerts", 12 | "type": "dashboard" 13 | } 14 | ] 15 | }, 16 | "editable": true, 17 | "gnetId": null, 18 | "graphTooltip": 0, 19 | "id": null, 20 | "links": [], 21 | "panels": [ 22 | { 23 | "aliasColors": {}, 24 | "bars": false, 25 | "dashLength": 10, 26 | "dashes": false, 27 | "datasource": null, 28 | "fill": 1, 29 | "fillGradient": 0, 30 | "gridPos": { 31 | "h": 10, 32 | "w": 24, 33 | "x": 0, 34 | "y": 0 35 | }, 36 | "hiddenSeries": false, 37 | "id": 9, 38 | "legend": { 39 | "alignAsTable": true, 40 | "avg": false, 41 | "current": true, 42 | "max": false, 43 | "min": false, 44 | "rightSide": true, 45 | "show": true, 46 | "total": false, 47 | "values": true 48 | }, 49 | "lines": true, 50 | "linewidth": 1, 51 | "links": [], 52 | "nullPointMode": "null", 53 | "options": { 54 | "dataLinks": [] 55 | }, 56 | "percentage": false, 57 | "pointradius": 5, 58 | "points": false, 59 | "renderer": "flot", 60 | "seriesOverrides": [ 61 | { 62 | "alias": "/transmit/", 63 | "stack": "B", 64 | "transform": "negative-Y" 65 | } 66 | ], 67 | "spaceLength": 10, 68 | "stack": true, 69 | "steppedLine": false, 70 | "targets": [ 71 | { 72 | "expr": "irate(node_network_receive_bytes_total{instance=~\"routnerr.*\",device!~\"lo|docker.*|virbr.*\"}[5m]) * 8", 73 | "format": "time_series", 74 | "hide": false, 75 | "interval": "", 76 | "intervalFactor": 1, 77 | "legendFormat": "receive: {{device}}", 78 | "refId": "A" 79 | }, 80 | { 81 | "expr": "irate(node_network_transmit_bytes_total{instance=~\"routnerr.*\",device!~\"lo|docker.*|virbr.*\"}[5m]) * 8", 82 | "format": "time_series", 83 | "interval": "", 84 | "intervalFactor": 1, 85 | "legendFormat": "transmit: {{device}}", 86 | "refId": "B" 87 | }, 88 | { 89 | "expr": "irate(wireguard_peer_receive_bytes_total{instance=~\"routnerr.*\"}[5m]) * on (public_key) group_left(name) wireguard_peer_info * on (instance) group_left(device) wireguard_device_info * 8", 90 | "interval": "", 91 | "legendFormat": "receive: {{device}}: {{name}}", 92 | "refId": "C" 93 | }, 94 | { 95 | "expr": "irate(wireguard_peer_transmit_bytes_total{instance=~\"routnerr.*\"}[5m]) * on (public_key) group_left(name) wireguard_peer_info * on (instance) group_left(device) wireguard_device_info * 8", 96 | "interval": "", 97 | "legendFormat": "transmit: {{device}}: {{name}}", 98 | "refId": "D" 99 | } 100 | ], 101 | "thresholds": [], 102 | "timeFrom": null, 103 | "timeRegions": [], 104 | "timeShift": null, 105 | "title": "WAN", 106 | "tooltip": { 107 | "shared": true, 108 | "sort": 0, 109 | "value_type": "individual" 110 | }, 111 | "type": "graph", 112 | "xaxis": { 113 | "buckets": null, 114 | "mode": "time", 115 | "name": null, 116 | "show": true, 117 | "values": [] 118 | }, 119 | "yaxes": [ 120 | { 121 | "format": "bps", 122 | "label": null, 123 | "logBase": 1, 124 | "max": null, 125 | "min": null, 126 | "show": true 127 | }, 128 | { 129 | "format": "short", 130 | "label": null, 131 | "logBase": 1, 132 | "max": null, 133 | "min": null, 134 | "show": true 135 | } 136 | ], 137 | "yaxis": { 138 | "align": false, 139 | "alignLevel": null 140 | } 141 | }, 142 | { 143 | "aliasColors": {}, 144 | "bars": false, 145 | "dashLength": 10, 146 | "dashes": false, 147 | "datasource": null, 148 | "fill": 1, 149 | "fillGradient": 0, 150 | "gridPos": { 151 | "h": 11, 152 | "w": 24, 153 | "x": 0, 154 | "y": 10 155 | }, 156 | "hiddenSeries": false, 157 | "id": 7, 158 | "legend": { 159 | "alignAsTable": true, 160 | "avg": false, 161 | "current": true, 162 | "max": false, 163 | "min": false, 164 | "rightSide": true, 165 | "show": true, 166 | "total": false, 167 | "values": true 168 | }, 169 | "lines": true, 170 | "linewidth": 1, 171 | "links": [], 172 | "nullPointMode": "null", 173 | "options": { 174 | "dataLinks": [] 175 | }, 176 | "percentage": false, 177 | "pointradius": 5, 178 | "points": false, 179 | "renderer": "flot", 180 | "seriesOverrides": [ 181 | { 182 | "alias": "/to/", 183 | "stack": "B", 184 | "transform": "negative-Y" 185 | } 186 | ], 187 | "spaceLength": 10, 188 | "stack": false, 189 | "steppedLine": false, 190 | "targets": [ 191 | { 192 | "expr": "rate(ifInOctets{ifAlias!=\"\",instance=\"switch-livingroom01\",job=\"snmp\"}[5m]) and on(instance, job, ifName) ifAdminStatus != 2 * 8", 193 | "format": "time_series", 194 | "interval": "", 195 | "intervalFactor": 1, 196 | "legendFormat": "from: {{ifAlias}}", 197 | "refId": "A" 198 | }, 199 | { 200 | "expr": "rate(ifOutOctets{ifAlias!=\"\",instance=\"switch-livingroom01\",job=\"snmp\"}[5m]) and on(instance, job, ifName) ifAdminStatus != 2 * 8", 201 | "format": "time_series", 202 | "interval": "", 203 | "intervalFactor": 1, 204 | "legendFormat": "to: {{ifAlias}}", 205 | "refId": "B" 206 | } 207 | ], 208 | "thresholds": [], 209 | "timeFrom": null, 210 | "timeRegions": [], 211 | "timeShift": null, 212 | "title": "Core switch", 213 | "tooltip": { 214 | "shared": true, 215 | "sort": 0, 216 | "value_type": "individual" 217 | }, 218 | "type": "graph", 219 | "xaxis": { 220 | "buckets": null, 221 | "mode": "time", 222 | "name": null, 223 | "show": true, 224 | "values": [] 225 | }, 226 | "yaxes": [ 227 | { 228 | "format": "bps", 229 | "label": null, 230 | "logBase": 1, 231 | "max": null, 232 | "min": null, 233 | "show": true 234 | }, 235 | { 236 | "format": "short", 237 | "label": null, 238 | "logBase": 1, 239 | "max": null, 240 | "min": null, 241 | "show": true 242 | } 243 | ], 244 | "yaxis": { 245 | "align": false, 246 | "alignLevel": null 247 | } 248 | }, 249 | { 250 | "aliasColors": {}, 251 | "bars": false, 252 | "dashLength": 10, 253 | "dashes": false, 254 | "datasource": null, 255 | "fill": 1, 256 | "fillGradient": 0, 257 | "gridPos": { 258 | "h": 10, 259 | "w": 24, 260 | "x": 0, 261 | "y": 21 262 | }, 263 | "hiddenSeries": false, 264 | "id": 6, 265 | "legend": { 266 | "alignAsTable": true, 267 | "avg": false, 268 | "current": true, 269 | "max": false, 270 | "min": false, 271 | "rightSide": true, 272 | "show": true, 273 | "total": false, 274 | "values": true 275 | }, 276 | "lines": true, 277 | "linewidth": 1, 278 | "links": [], 279 | "nullPointMode": "null", 280 | "options": { 281 | "dataLinks": [] 282 | }, 283 | "percentage": false, 284 | "pointradius": 5, 285 | "points": false, 286 | "renderer": "flot", 287 | "seriesOverrides": [ 288 | { 289 | "alias": "/to/", 290 | "stack": "B", 291 | "transform": "negative-Y" 292 | } 293 | ], 294 | "spaceLength": 10, 295 | "stack": false, 296 | "steppedLine": false, 297 | "targets": [ 298 | { 299 | "expr": "rate(ifInOctets{ifAlias!=\"\",instance=\"switch-office01\",job=\"snmp\"}[5m]) and on(instance, job, ifName) ifAdminStatus != 2 * 8", 300 | "format": "time_series", 301 | "interval": "", 302 | "intervalFactor": 1, 303 | "legendFormat": "from: {{ifAlias}}", 304 | "refId": "A" 305 | }, 306 | { 307 | "expr": "rate(ifOutOctets{ifAlias!=\"\",instance=\"switch-office01\",job=\"snmp\"}[5m]) and on(instance, job, ifName) ifAdminStatus != 2 * 8", 308 | "format": "time_series", 309 | "interval": "", 310 | "intervalFactor": 1, 311 | "legendFormat": "to: {{ifAlias}}", 312 | "refId": "B" 313 | } 314 | ], 315 | "thresholds": [], 316 | "timeFrom": null, 317 | "timeRegions": [], 318 | "timeShift": null, 319 | "title": "Office switch", 320 | "tooltip": { 321 | "shared": true, 322 | "sort": 0, 323 | "value_type": "individual" 324 | }, 325 | "type": "graph", 326 | "xaxis": { 327 | "buckets": null, 328 | "mode": "time", 329 | "name": null, 330 | "show": true, 331 | "values": [] 332 | }, 333 | "yaxes": [ 334 | { 335 | "format": "bps", 336 | "label": null, 337 | "logBase": 1, 338 | "max": null, 339 | "min": null, 340 | "show": true 341 | }, 342 | { 343 | "format": "short", 344 | "label": null, 345 | "logBase": 1, 346 | "max": null, 347 | "min": null, 348 | "show": true 349 | } 350 | ], 351 | "yaxis": { 352 | "align": false, 353 | "alignLevel": null 354 | } 355 | } 356 | ], 357 | "schemaVersion": 22, 358 | "style": "dark", 359 | "tags": [], 360 | "templating": { 361 | "list": [] 362 | }, 363 | "time": { 364 | "from": "now-24h", 365 | "to": "now" 366 | }, 367 | "timepicker": { 368 | "refresh_intervals": [ 369 | "5s", 370 | "10s", 371 | "30s", 372 | "1m", 373 | "5m", 374 | "15m", 375 | "30m", 376 | "1h", 377 | "2h", 378 | "1d" 379 | ], 380 | "time_options": [ 381 | "5m", 382 | "15m", 383 | "1h", 384 | "6h", 385 | "12h", 386 | "24h", 387 | "2d", 388 | "7d", 389 | "30d" 390 | ] 391 | }, 392 | "timezone": "", 393 | "title": "Network", 394 | "uid": "e1K4fWrmz", 395 | "variables": { 396 | "list": [] 397 | }, 398 | "version": 4 399 | } 400 | -------------------------------------------------------------------------------- /grafana/obs.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "$$hashKey": "object:37", 6 | "builtIn": 1, 7 | "datasource": "-- Grafana --", 8 | "enable": true, 9 | "hide": true, 10 | "iconColor": "rgba(0, 211, 255, 1)", 11 | "name": "Annotations & Alerts", 12 | "type": "dashboard" 13 | } 14 | ] 15 | }, 16 | "editable": true, 17 | "gnetId": null, 18 | "graphTooltip": 0, 19 | "id": null, 20 | "links": [], 21 | "panels": [ 22 | { 23 | "columns": [ 24 | { 25 | "$$hashKey": "object:1220", 26 | "text": "Current", 27 | "value": "current" 28 | } 29 | ], 30 | "datasource": null, 31 | "fontSize": "100%", 32 | "gridPos": { 33 | "h": 9, 34 | "w": 8, 35 | "x": 0, 36 | "y": 0 37 | }, 38 | "id": 9, 39 | "pageSize": null, 40 | "showHeader": true, 41 | "sort": { 42 | "col": 0, 43 | "desc": true 44 | }, 45 | "styles": [ 46 | { 47 | "$$hashKey": "object:1046", 48 | "alias": "Time", 49 | "align": "auto", 50 | "dateFormat": "YYYY-MM-DD HH:mm:ss", 51 | "pattern": "Time", 52 | "type": "date" 53 | }, 54 | { 55 | "$$hashKey": "object:1047", 56 | "alias": "", 57 | "align": "", 58 | "colorMode": "value", 59 | "colors": [ 60 | "rgba(245, 54, 54, 0.9)", 61 | "rgba(237, 129, 40, 0.89)", 62 | "rgba(50, 172, 45, 0.97)" 63 | ], 64 | "decimals": 2, 65 | "mappingType": 1, 66 | "pattern": "Current", 67 | "thresholds": [ 68 | "0", 69 | " 1" 70 | ], 71 | "type": "string", 72 | "unit": "short", 73 | "valueMaps": [ 74 | { 75 | "$$hashKey": "object:1269", 76 | "text": "false", 77 | "value": "0" 78 | }, 79 | { 80 | "$$hashKey": "object:1292", 81 | "text": "true", 82 | "value": "1" 83 | } 84 | ] 85 | } 86 | ], 87 | "targets": [ 88 | { 89 | "expr": "obs_output_active", 90 | "instant": true, 91 | "interval": "", 92 | "legendFormat": "output: {{output_id}}: {{output_name}}", 93 | "refId": "A" 94 | } 95 | ], 96 | "timeFrom": null, 97 | "timeShift": null, 98 | "title": "Output Activity", 99 | "transform": "timeseries_aggregations", 100 | "type": "table" 101 | }, 102 | { 103 | "aliasColors": {}, 104 | "bars": false, 105 | "dashLength": 10, 106 | "dashes": false, 107 | "datasource": null, 108 | "fill": 1, 109 | "fillGradient": 0, 110 | "gridPos": { 111 | "h": 9, 112 | "w": 8, 113 | "x": 8, 114 | "y": 0 115 | }, 116 | "hiddenSeries": false, 117 | "id": 7, 118 | "legend": { 119 | "avg": false, 120 | "current": false, 121 | "max": false, 122 | "min": false, 123 | "show": true, 124 | "total": false, 125 | "values": false 126 | }, 127 | "lines": true, 128 | "linewidth": 1, 129 | "nullPointMode": "null", 130 | "options": { 131 | "dataLinks": [] 132 | }, 133 | "percentage": false, 134 | "pointradius": 2, 135 | "points": false, 136 | "renderer": "flot", 137 | "seriesOverrides": [], 138 | "spaceLength": 10, 139 | "stack": false, 140 | "steppedLine": false, 141 | "targets": [ 142 | { 143 | "expr": "obs_source_channel_magnitude{source_id=\"pulse_input_capture\"}", 144 | "interval": "", 145 | "legendFormat": "Average: {{source_name}}: channel {{channel_id}}", 146 | "refId": "A" 147 | }, 148 | { 149 | "expr": "obs_source_channel_peak{source_id=\"pulse_input_capture\"}", 150 | "interval": "", 151 | "legendFormat": "Peak: {{source_name}}: channel {{channel_id}}", 152 | "refId": "B" 153 | } 154 | ], 155 | "thresholds": [], 156 | "timeFrom": null, 157 | "timeRegions": [], 158 | "timeShift": null, 159 | "title": "Microphone Output", 160 | "tooltip": { 161 | "shared": true, 162 | "sort": 0, 163 | "value_type": "individual" 164 | }, 165 | "type": "graph", 166 | "xaxis": { 167 | "buckets": null, 168 | "mode": "time", 169 | "name": null, 170 | "show": true, 171 | "values": [] 172 | }, 173 | "yaxes": [ 174 | { 175 | "$$hashKey": "object:762", 176 | "format": "dB", 177 | "label": null, 178 | "logBase": 1, 179 | "max": null, 180 | "min": null, 181 | "show": true 182 | }, 183 | { 184 | "$$hashKey": "object:763", 185 | "format": "short", 186 | "label": null, 187 | "logBase": 1, 188 | "max": null, 189 | "min": null, 190 | "show": true 191 | } 192 | ], 193 | "yaxis": { 194 | "align": false, 195 | "alignLevel": null 196 | } 197 | }, 198 | { 199 | "aliasColors": {}, 200 | "bars": false, 201 | "dashLength": 10, 202 | "dashes": false, 203 | "datasource": null, 204 | "fill": 1, 205 | "fillGradient": 0, 206 | "gridPos": { 207 | "h": 9, 208 | "w": 8, 209 | "x": 16, 210 | "y": 0 211 | }, 212 | "hiddenSeries": false, 213 | "id": 6, 214 | "legend": { 215 | "avg": false, 216 | "current": false, 217 | "max": false, 218 | "min": false, 219 | "show": true, 220 | "total": false, 221 | "values": false 222 | }, 223 | "lines": true, 224 | "linewidth": 1, 225 | "nullPointMode": "null", 226 | "options": { 227 | "dataLinks": [] 228 | }, 229 | "percentage": false, 230 | "pointradius": 2, 231 | "points": false, 232 | "renderer": "flot", 233 | "seriesOverrides": [], 234 | "spaceLength": 10, 235 | "stack": false, 236 | "steppedLine": false, 237 | "targets": [ 238 | { 239 | "expr": "obs_global_average_frame_time_ns", 240 | "interval": "", 241 | "legendFormat": "Average", 242 | "refId": "A" 243 | } 244 | ], 245 | "thresholds": [], 246 | "timeFrom": null, 247 | "timeRegions": [], 248 | "timeShift": null, 249 | "title": "Average Frame Rendering Time", 250 | "tooltip": { 251 | "shared": true, 252 | "sort": 0, 253 | "value_type": "individual" 254 | }, 255 | "type": "graph", 256 | "xaxis": { 257 | "buckets": null, 258 | "mode": "time", 259 | "name": null, 260 | "show": true, 261 | "values": [] 262 | }, 263 | "yaxes": [ 264 | { 265 | "$$hashKey": "object:762", 266 | "format": "ns", 267 | "label": null, 268 | "logBase": 1, 269 | "max": null, 270 | "min": null, 271 | "show": true 272 | }, 273 | { 274 | "$$hashKey": "object:763", 275 | "format": "short", 276 | "label": null, 277 | "logBase": 1, 278 | "max": null, 279 | "min": null, 280 | "show": true 281 | } 282 | ], 283 | "yaxis": { 284 | "align": false, 285 | "alignLevel": null 286 | } 287 | }, 288 | { 289 | "aliasColors": {}, 290 | "bars": false, 291 | "dashLength": 10, 292 | "dashes": false, 293 | "datasource": null, 294 | "fill": 1, 295 | "fillGradient": 0, 296 | "gridPos": { 297 | "h": 9, 298 | "w": 8, 299 | "x": 0, 300 | "y": 9 301 | }, 302 | "hiddenSeries": false, 303 | "id": 2, 304 | "legend": { 305 | "avg": false, 306 | "current": false, 307 | "max": false, 308 | "min": false, 309 | "show": true, 310 | "total": false, 311 | "values": false 312 | }, 313 | "lines": true, 314 | "linewidth": 1, 315 | "nullPointMode": "null", 316 | "options": { 317 | "dataLinks": [] 318 | }, 319 | "percentage": false, 320 | "pointradius": 2, 321 | "points": false, 322 | "renderer": "flot", 323 | "seriesOverrides": [], 324 | "spaceLength": 10, 325 | "stack": false, 326 | "steppedLine": false, 327 | "targets": [ 328 | { 329 | "expr": "irate(obs_output_frames[5m])", 330 | "interval": "", 331 | "legendFormat": "{{output_id}}: {{output_name}}", 332 | "refId": "A" 333 | } 334 | ], 335 | "thresholds": [], 336 | "timeFrom": null, 337 | "timeRegions": [], 338 | "timeShift": null, 339 | "title": "Output Frames Per Second", 340 | "tooltip": { 341 | "shared": true, 342 | "sort": 0, 343 | "value_type": "individual" 344 | }, 345 | "type": "graph", 346 | "xaxis": { 347 | "buckets": null, 348 | "mode": "time", 349 | "name": null, 350 | "show": true, 351 | "values": [] 352 | }, 353 | "yaxes": [ 354 | { 355 | "$$hashKey": "object:96", 356 | "format": "ops", 357 | "label": null, 358 | "logBase": 1, 359 | "max": null, 360 | "min": null, 361 | "show": true 362 | }, 363 | { 364 | "$$hashKey": "object:97", 365 | "format": "short", 366 | "label": null, 367 | "logBase": 1, 368 | "max": null, 369 | "min": null, 370 | "show": true 371 | } 372 | ], 373 | "yaxis": { 374 | "align": false, 375 | "alignLevel": null 376 | } 377 | }, 378 | { 379 | "aliasColors": {}, 380 | "bars": false, 381 | "dashLength": 10, 382 | "dashes": false, 383 | "datasource": null, 384 | "fill": 1, 385 | "fillGradient": 0, 386 | "gridPos": { 387 | "h": 9, 388 | "w": 8, 389 | "x": 8, 390 | "y": 9 391 | }, 392 | "hiddenSeries": false, 393 | "id": 4, 394 | "legend": { 395 | "avg": false, 396 | "current": false, 397 | "max": false, 398 | "min": false, 399 | "show": true, 400 | "total": false, 401 | "values": false 402 | }, 403 | "lines": true, 404 | "linewidth": 1, 405 | "nullPointMode": "null", 406 | "options": { 407 | "dataLinks": [] 408 | }, 409 | "percentage": false, 410 | "pointradius": 2, 411 | "points": false, 412 | "renderer": "flot", 413 | "seriesOverrides": [], 414 | "spaceLength": 10, 415 | "stack": true, 416 | "steppedLine": false, 417 | "targets": [ 418 | { 419 | "expr": "irate(obs_global_lagged_frames_total[5m])", 420 | "interval": "", 421 | "legendFormat": "lagged", 422 | "refId": "A" 423 | }, 424 | { 425 | "expr": "irate(obs_global_video_skipped_frames_total[5m])", 426 | "interval": "", 427 | "legendFormat": "skipped", 428 | "refId": "B" 429 | }, 430 | { 431 | "expr": "irate(obs_output_dropped_frames_total[5m])", 432 | "interval": "", 433 | "legendFormat": "dropped: {{output_id}}: {{output_name}}", 434 | "refId": "C" 435 | } 436 | ], 437 | "thresholds": [], 438 | "timeFrom": null, 439 | "timeRegions": [], 440 | "timeShift": null, 441 | "title": "Problematic Frames Per Second", 442 | "tooltip": { 443 | "shared": true, 444 | "sort": 0, 445 | "value_type": "individual" 446 | }, 447 | "type": "graph", 448 | "xaxis": { 449 | "buckets": null, 450 | "mode": "time", 451 | "name": null, 452 | "show": true, 453 | "values": [] 454 | }, 455 | "yaxes": [ 456 | { 457 | "$$hashKey": "object:96", 458 | "format": "ops", 459 | "label": null, 460 | "logBase": 1, 461 | "max": null, 462 | "min": null, 463 | "show": true 464 | }, 465 | { 466 | "$$hashKey": "object:97", 467 | "format": "short", 468 | "label": null, 469 | "logBase": 1, 470 | "max": null, 471 | "min": null, 472 | "show": true 473 | } 474 | ], 475 | "yaxis": { 476 | "align": false, 477 | "alignLevel": null 478 | } 479 | }, 480 | { 481 | "aliasColors": {}, 482 | "bars": false, 483 | "dashLength": 10, 484 | "dashes": false, 485 | "datasource": null, 486 | "fill": 1, 487 | "fillGradient": 0, 488 | "gridPos": { 489 | "h": 9, 490 | "w": 8, 491 | "x": 16, 492 | "y": 9 493 | }, 494 | "hiddenSeries": false, 495 | "id": 3, 496 | "legend": { 497 | "avg": false, 498 | "current": false, 499 | "max": false, 500 | "min": false, 501 | "show": true, 502 | "total": false, 503 | "values": false 504 | }, 505 | "lines": true, 506 | "linewidth": 1, 507 | "nullPointMode": "null", 508 | "options": { 509 | "dataLinks": [] 510 | }, 511 | "percentage": false, 512 | "pointradius": 2, 513 | "points": false, 514 | "renderer": "flot", 515 | "seriesOverrides": [], 516 | "spaceLength": 10, 517 | "stack": false, 518 | "steppedLine": false, 519 | "targets": [ 520 | { 521 | "expr": "irate(obs_output_bytes_total[5m]) * 8", 522 | "interval": "", 523 | "legendFormat": "{{output_id}}: {{output_name}}", 524 | "refId": "A" 525 | }, 526 | { 527 | "expr": "", 528 | "interval": "", 529 | "legendFormat": "", 530 | "refId": "B" 531 | } 532 | ], 533 | "thresholds": [], 534 | "timeFrom": null, 535 | "timeRegions": [], 536 | "timeShift": null, 537 | "title": "Output Data Rate", 538 | "tooltip": { 539 | "shared": true, 540 | "sort": 0, 541 | "value_type": "individual" 542 | }, 543 | "type": "graph", 544 | "xaxis": { 545 | "buckets": null, 546 | "mode": "time", 547 | "name": null, 548 | "show": true, 549 | "values": [] 550 | }, 551 | "yaxes": [ 552 | { 553 | "$$hashKey": "object:96", 554 | "format": "bps", 555 | "label": null, 556 | "logBase": 1, 557 | "max": null, 558 | "min": null, 559 | "show": true 560 | }, 561 | { 562 | "$$hashKey": "object:97", 563 | "format": "short", 564 | "label": null, 565 | "logBase": 1, 566 | "max": null, 567 | "min": null, 568 | "show": true 569 | } 570 | ], 571 | "yaxis": { 572 | "align": false, 573 | "alignLevel": null 574 | } 575 | } 576 | ], 577 | "refresh": false, 578 | "schemaVersion": 22, 579 | "style": "dark", 580 | "tags": [], 581 | "templating": { 582 | "list": [] 583 | }, 584 | "time": { 585 | "from": "now-7d", 586 | "to": "now" 587 | }, 588 | "timepicker": {}, 589 | "timezone": "", 590 | "title": "OBS", 591 | "uid": "zFbd6TRGk", 592 | "variables": { 593 | "list": [] 594 | }, 595 | "version": 6 596 | } 597 | -------------------------------------------------------------------------------- /grafana/wgipamd.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": "-- Grafana --", 7 | "enable": true, 8 | "hide": true, 9 | "iconColor": "rgba(0, 211, 255, 1)", 10 | "name": "Annotations & Alerts", 11 | "type": "dashboard" 12 | } 13 | ] 14 | }, 15 | "editable": true, 16 | "gnetId": null, 17 | "graphTooltip": 0, 18 | "id": 8, 19 | "links": [], 20 | "panels": [ 21 | { 22 | "cacheTimeout": null, 23 | "colorBackground": false, 24 | "colorValue": false, 25 | "colors": [ 26 | "#299c46", 27 | "rgba(237, 129, 40, 0.89)", 28 | "#d44a3a" 29 | ], 30 | "datasource": null, 31 | "format": "s", 32 | "gauge": { 33 | "maxValue": 100, 34 | "minValue": 0, 35 | "show": false, 36 | "thresholdLabels": false, 37 | "thresholdMarkers": true 38 | }, 39 | "gridPos": { 40 | "h": 9, 41 | "w": 4, 42 | "x": 0, 43 | "y": 0 44 | }, 45 | "id": 6, 46 | "interval": null, 47 | "links": [], 48 | "mappingType": 1, 49 | "mappingTypes": [ 50 | { 51 | "name": "value to text", 52 | "value": 1 53 | }, 54 | { 55 | "name": "range to text", 56 | "value": 2 57 | } 58 | ], 59 | "maxDataPoints": 100, 60 | "nullPointMode": "connected", 61 | "nullText": null, 62 | "postfix": "", 63 | "postfixFontSize": "50%", 64 | "prefix": "", 65 | "prefixFontSize": "50%", 66 | "rangeMaps": [ 67 | { 68 | "from": "null", 69 | "text": "N/A", 70 | "to": "null" 71 | } 72 | ], 73 | "sparkline": { 74 | "fillColor": "rgba(31, 118, 189, 0.18)", 75 | "full": false, 76 | "lineColor": "rgb(31, 120, 193)", 77 | "show": false, 78 | "ymax": null, 79 | "ymin": null 80 | }, 81 | "tableColumn": "", 82 | "targets": [ 83 | { 84 | "expr": "time() - wgipamd_store_last_purge", 85 | "refId": "A" 86 | } 87 | ], 88 | "thresholds": "", 89 | "timeFrom": null, 90 | "timeShift": null, 91 | "title": "Time since last Purge", 92 | "type": "singlestat", 93 | "valueFontSize": "80%", 94 | "valueMaps": [ 95 | { 96 | "op": "=", 97 | "text": "N/A", 98 | "value": "null" 99 | } 100 | ], 101 | "valueName": "avg" 102 | }, 103 | { 104 | "aliasColors": {}, 105 | "bars": false, 106 | "dashLength": 10, 107 | "dashes": false, 108 | "datasource": null, 109 | "fill": 1, 110 | "fillGradient": 0, 111 | "gridPos": { 112 | "h": 9, 113 | "w": 10, 114 | "x": 4, 115 | "y": 0 116 | }, 117 | "hiddenSeries": false, 118 | "id": 2, 119 | "legend": { 120 | "avg": false, 121 | "current": false, 122 | "max": false, 123 | "min": false, 124 | "show": true, 125 | "total": false, 126 | "values": false 127 | }, 128 | "lines": true, 129 | "linewidth": 1, 130 | "nullPointMode": "null", 131 | "options": { 132 | "dataLinks": [] 133 | }, 134 | "percentage": false, 135 | "pointradius": 2, 136 | "points": false, 137 | "renderer": "flot", 138 | "seriesOverrides": [], 139 | "spaceLength": 10, 140 | "stack": false, 141 | "steppedLine": false, 142 | "targets": [ 143 | { 144 | "expr": "rate(wgipamd_server_requests_total[1m])", 145 | "legendFormat": "{{interface}}: {{operation}}", 146 | "refId": "A" 147 | } 148 | ], 149 | "thresholds": [], 150 | "timeFrom": null, 151 | "timeRegions": [], 152 | "timeShift": null, 153 | "title": "wg-dynamic Requests", 154 | "tooltip": { 155 | "shared": true, 156 | "sort": 0, 157 | "value_type": "individual" 158 | }, 159 | "type": "graph", 160 | "xaxis": { 161 | "buckets": null, 162 | "mode": "time", 163 | "name": null, 164 | "show": true, 165 | "values": [] 166 | }, 167 | "yaxes": [ 168 | { 169 | "format": "reqps", 170 | "label": null, 171 | "logBase": 1, 172 | "max": null, 173 | "min": null, 174 | "show": true 175 | }, 176 | { 177 | "format": "short", 178 | "label": null, 179 | "logBase": 1, 180 | "max": null, 181 | "min": null, 182 | "show": true 183 | } 184 | ], 185 | "yaxis": { 186 | "align": false, 187 | "alignLevel": null 188 | } 189 | }, 190 | { 191 | "aliasColors": {}, 192 | "bars": false, 193 | "dashLength": 10, 194 | "dashes": false, 195 | "datasource": null, 196 | "fill": 1, 197 | "fillGradient": 0, 198 | "gridPos": { 199 | "h": 9, 200 | "w": 10, 201 | "x": 14, 202 | "y": 0 203 | }, 204 | "hiddenSeries": false, 205 | "id": 4, 206 | "legend": { 207 | "avg": false, 208 | "current": false, 209 | "max": false, 210 | "min": false, 211 | "show": true, 212 | "total": false, 213 | "values": false 214 | }, 215 | "lines": true, 216 | "linewidth": 1, 217 | "nullPointMode": "null", 218 | "options": { 219 | "dataLinks": [] 220 | }, 221 | "percentage": false, 222 | "pointradius": 2, 223 | "points": false, 224 | "renderer": "flot", 225 | "seriesOverrides": [], 226 | "spaceLength": 10, 227 | "stack": false, 228 | "steppedLine": false, 229 | "targets": [ 230 | { 231 | "expr": "wgipamd_store_ips_allocated / wgipamd_store_subnet_allocatable_size", 232 | "legendFormat": "{{subnet}}", 233 | "refId": "A" 234 | } 235 | ], 236 | "thresholds": [], 237 | "timeFrom": null, 238 | "timeRegions": [], 239 | "timeShift": null, 240 | "title": "Subnet utilization", 241 | "tooltip": { 242 | "shared": true, 243 | "sort": 0, 244 | "value_type": "individual" 245 | }, 246 | "type": "graph", 247 | "xaxis": { 248 | "buckets": null, 249 | "mode": "time", 250 | "name": null, 251 | "show": true, 252 | "values": [] 253 | }, 254 | "yaxes": [ 255 | { 256 | "format": "percentunit", 257 | "label": null, 258 | "logBase": 1, 259 | "max": null, 260 | "min": null, 261 | "show": true 262 | }, 263 | { 264 | "format": "short", 265 | "label": null, 266 | "logBase": 1, 267 | "max": null, 268 | "min": null, 269 | "show": true 270 | } 271 | ], 272 | "yaxis": { 273 | "align": false, 274 | "alignLevel": null 275 | } 276 | } 277 | ], 278 | "schemaVersion": 22, 279 | "style": "dark", 280 | "tags": [], 281 | "templating": { 282 | "list": [] 283 | }, 284 | "time": { 285 | "from": "now-5m", 286 | "to": "now" 287 | }, 288 | "timepicker": { 289 | "refresh_intervals": [ 290 | "5s", 291 | "10s", 292 | "30s", 293 | "1m", 294 | "5m", 295 | "15m", 296 | "30m", 297 | "1h", 298 | "2h", 299 | "1d" 300 | ] 301 | }, 302 | "timezone": "", 303 | "title": "wgipamd", 304 | "uid": "-rOu1LfWk", 305 | "variables": { 306 | "list": [] 307 | }, 308 | "version": 1 309 | } 310 | -------------------------------------------------------------------------------- /nixos/README.md: -------------------------------------------------------------------------------- 1 | # nixos 2 | 3 | NixOS configurations for my machines. I cannot say whether or not these configs 4 | are truly idiomatic, but they work well enough for my needs. Individual 5 | machines have their own directories, such as `routnerr-3/` or `servnerr-4/`. 6 | Shared Nix configurations are stored in `lib/`. 7 | -------------------------------------------------------------------------------- /nixos/lib/modules/zedhook.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | with lib; 9 | 10 | let 11 | cfg = config.services.zedhook; 12 | in 13 | { 14 | options.services.zedhook = { 15 | enable = mkEnableOption "zedhook ZFS event monitoring system"; 16 | 17 | package = mkOption { 18 | default = pkgs.zedhook; 19 | defaultText = "pkgs.zedhook"; 20 | type = types.package; 21 | description = "zedhook package to use."; 22 | }; 23 | }; 24 | 25 | config = mkIf cfg.enable { 26 | # TODO: drop in all-zedhookd ZEDLET. 27 | 28 | users.groups.zedhookd = { }; 29 | users.users.zedhookd = { 30 | description = "zedhookd daemon user"; 31 | group = "zedhookd"; 32 | isSystemUser = true; 33 | }; 34 | 35 | systemd.services.zedhook = { 36 | description = "zedhook ZFS event monitoring system"; 37 | after = [ "network-online.target" ]; 38 | wantedBy = [ "multi-user.target" ]; 39 | serviceConfig = { 40 | PermissionsStartOnly = true; 41 | LimitNPROC = 512; 42 | LimitNOFILE = 1048576; 43 | NoNewPrivileges = true; 44 | ExecStart = "${getBin cfg.package}/bin/zedhookd -d /var/lib/zedhookd/zedhookd.db"; 45 | User = "zedhookd"; 46 | Restart = "always"; 47 | RuntimeDirectory = "zedhookd"; 48 | RuntimeDirectoryMode = "0700"; 49 | WorkingDirectory = "/var/lib/zedhookd"; 50 | StateDirectory = "zedhookd"; 51 | StateDirectoryMode = "0700"; 52 | }; 53 | }; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /nixos/lib/pkgs/zedhook.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | buildGoModule, 4 | fetchFromGitHub, 5 | }: 6 | 7 | buildGoModule rec { 8 | pname = "zedhook"; 9 | version = "unstable-2022-04-29"; 10 | 11 | src = fetchFromGitHub { 12 | owner = "mdlayher"; 13 | repo = "zedhook"; 14 | rev = "a44f053f8f1eea1d7a21ad7ec321dedc0fb819c6"; 15 | sha256 = "sha256-2eGd4Yejz7iLRNISYUqSxFIQwg1PJ7q2/WUsP/5wEew="; 16 | }; 17 | 18 | # TODO: workaround for buildGoModule using 1.17. 19 | modBuildPhase = '' 20 | go mod edit -go=1.18 21 | go mod tidy 22 | ''; 23 | 24 | vendorSha256 = "sha256-AI08Y/QQR62SZSgSguPrtzxmSmCZvhHnj0+phZuLi3E="; 25 | 26 | meta = with lib; { 27 | homepage = "github.com/mdlayher/zedhook"; 28 | description = "zedhook ZFS event monitoring system."; 29 | license = licenses.asl20; 30 | maintainers = with maintainers; [ mdlayher ]; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /nixos/lib/system.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | secrets = import ./secrets.nix; 5 | unstable = import { }; 6 | 7 | in 8 | { 9 | boot = { 10 | # Explicitly enable drivetemp for SATA drive temperature reporting in hwmon. 11 | kernelModules = [ "drivetemp" ]; 12 | 13 | # 2025 LTS kernel. 14 | kernelPackages = pkgs.linuxPackages_6_12; 15 | }; 16 | 17 | # Console configuration. 18 | console = { 19 | font = "Lat2-Terminus16"; 20 | keyMap = "us"; 21 | }; 22 | 23 | # Locale and time. 24 | i18n.defaultLocale = "en_US.UTF-8"; 25 | time.timeZone = "America/Detroit"; 26 | 27 | environment = { 28 | # Put ~/bin in PATH. 29 | homeBinInPath = true; 30 | 31 | # Packages which should be installed on every machine. 32 | systemPackages = with pkgs; [ 33 | age 34 | atuin 35 | bc 36 | bintools-unwrapped 37 | btop 38 | byobu 39 | comma 40 | dmidecode 41 | ethtool 42 | file 43 | fio 44 | fish 45 | fwupd 46 | gcc 47 | git 48 | gnumake 49 | gptfdisk 50 | htop 51 | iftop 52 | iotop 53 | iperf3 54 | jq 55 | killall 56 | lm_sensors 57 | lshw 58 | lsof 59 | lsscsi 60 | magic-wormhole 61 | minicom 62 | mkpasswd 63 | mtr 64 | nano 65 | ndisc6 66 | neofetch 67 | nixfmt-rfc-style 68 | nmap 69 | nmon 70 | nvme-cli 71 | pciutils 72 | pkg-config 73 | pv 74 | ripgrep 75 | smartmontools 76 | sysstat 77 | tcpdump 78 | tmux 79 | tree 80 | unixtools.xxd 81 | unzip 82 | usbutils 83 | wget 84 | xterm 85 | 86 | # Unstable packages. 87 | unstable.go 88 | ]; 89 | }; 90 | 91 | # Enable firmware updates when possible. 92 | hardware.enableRedistributableFirmware = true; 93 | 94 | nix = { 95 | # Automatic Nix GC. 96 | gc = { 97 | automatic = true; 98 | dates = "04:00"; 99 | options = "--delete-older-than 7d"; 100 | }; 101 | extraOptions = '' 102 | min-free = ${toString (500 * 1024 * 1024)} 103 | experimental-features = nix-command flakes 104 | ''; 105 | 106 | # Automatic store optimization. 107 | settings.auto-optimise-store = true; 108 | }; 109 | 110 | # Programs installed on every machine. 111 | programs = { 112 | fish.enable = true; 113 | nano.enable = true; 114 | }; 115 | 116 | # Services which run on all deployed machines. 117 | services = { 118 | fstrim.enable = true; 119 | fwupd.enable = true; 120 | prometheus.exporters.node = { 121 | enable = true; 122 | enabledCollectors = [ 123 | "ethtool" 124 | "systemd" 125 | ]; 126 | }; 127 | }; 128 | 129 | system.autoUpgrade.enable = true; 130 | 131 | # Make systemd manage the hardware watchdog. 132 | systemd.watchdog.runtimeTime = "60s"; 133 | 134 | users = { 135 | # Force declarative user configuration. 136 | mutableUsers = false; 137 | 138 | # Set up matt's account, enable sudo and SSH login. 139 | users.matt = { 140 | isNormalUser = true; 141 | uid = 1000; 142 | extraGroups = [ 143 | "dialout" 144 | "libvirtd" 145 | "networkmanager" 146 | "wheel" 147 | ]; 148 | hashedPassword = secrets.users.matt_password_hash; 149 | shell = pkgs.fish; 150 | 151 | openssh.authorizedKeys.keys = [ 152 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5i5d0mRKAf02m+ju+I1KrAYw3Ny2IHXy88mgyragBN Matt Layher (mdlayher@gmail.com)" 153 | ]; 154 | }; 155 | 156 | # Set up root login for emergency console access. 157 | users.root.hashedPassword = secrets.users.root_password_hash; 158 | }; 159 | } 160 | -------------------------------------------------------------------------------- /nixos/lib/vargen/README.md: -------------------------------------------------------------------------------- 1 | # vargen 2 | 3 | This is a pretty hacky Go program that generates a `vars.json` which sets a lot 4 | of computed values in `vars.nix`. It's very specific to my setup and could use 5 | a lot more work. 6 | -------------------------------------------------------------------------------- /nixos/lib/vargen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mdlayher/homelab/nixos/lib/vargen 2 | 3 | go 1.20 4 | 5 | require github.com/mdlayher/netx v0.0.0-20230430222610-7e21880baee8 6 | -------------------------------------------------------------------------------- /nixos/lib/vargen/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 2 | github.com/mdlayher/netx v0.0.0-20230430222610-7e21880baee8 h1:HMgSn3c16SXca3M+n6fLK2hXJLd4mhKAsZZh7lQfYmQ= 3 | github.com/mdlayher/netx v0.0.0-20230430222610-7e21880baee8/go.mod h1:qhZhwMDNWwZglKfwuWm0U9pCr/YKX1QAEwwJk9qfiTQ= 4 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 5 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 6 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 7 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 8 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 9 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 10 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 11 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 12 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 13 | golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 14 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 15 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 16 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 17 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 18 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 19 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 20 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 21 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 22 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 23 | golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 24 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 25 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 26 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 27 | golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 28 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 29 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 30 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 31 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 32 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 33 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 34 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 35 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 36 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 37 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 38 | -------------------------------------------------------------------------------- /nixos/lib/vargen/main.go: -------------------------------------------------------------------------------- 1 | // Command vargen produces computed JSON data for use in vars.nix. 2 | package main 3 | 4 | import ( 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "log" 9 | "net" 10 | "net/http" 11 | "net/netip" 12 | "os" 13 | "strings" 14 | 15 | "github.com/mdlayher/netx/eui64" 16 | ) 17 | 18 | //go:generate /usr/bin/env bash -c "go run main.go > ../vars.json" 19 | 20 | const ( 21 | // pdLen is the length of the IPv6 prefix delegated to my router by Charter. 22 | pdLen = 56 23 | ) 24 | 25 | // A preference is the preference of a given network interface. 26 | type preference int 27 | 28 | const ( 29 | _ preference = iota 30 | low 31 | medium 32 | high 33 | ) 34 | 35 | func (p preference) MarshalText() ([]byte, error) { 36 | switch p { 37 | case low: 38 | return []byte("low"), nil 39 | case medium: 40 | return []byte("medium"), nil 41 | case high: 42 | return []byte("high"), nil 43 | } 44 | 45 | panic("unhandled preference") 46 | } 47 | 48 | func main() { 49 | // Fetch IPv6 prefix for use elsewhere. 50 | gua6 := wanIPv6Prefix() 51 | 52 | const trusted = true 53 | 54 | // The primary subnet: all servers and network infrastructure live here. 55 | var ( 56 | // Trusted subnets which will have internal DNS and other services 57 | // deployed on them. 58 | mgmt0 = newSubnet("mgmt0", 0, gua6, trusted) 59 | lan0 = newSubnet("lan0", 10, gua6, trusted) 60 | wg0 = newSubnet("wg0", 20, gua6, trusted) 61 | 62 | // Untrusted subnets which do not necessarily, have internal DNS records 63 | // and other services deployed on them. The lab subnet is a bit of a 64 | // special case but it's probably best to treat it as hostile. 65 | lab0 = newSubnet("lab0", 2, gua6, !trusted) 66 | guest0 = newSubnet("guest0", 9, gua6, !trusted) 67 | iot0 = newSubnet("iot0", 66, gua6, !trusted) 68 | 69 | server = mgmt0.newHost( 70 | "servnerr-4", 71 | netip.MustParseAddr("192.168.1.10"), 72 | mac("04:d9:f5:7e:1c:47"), 73 | ) 74 | 75 | desktop = mgmt0.newHost( 76 | "nerr-4", 77 | netip.MustParseAddr("192.168.1.7"), 78 | mac("74:56:3c:43:73:37"), 79 | ) 80 | ) 81 | 82 | // Set up the output structure and create host/infra records. 83 | out := output{ 84 | // TODO: this is a hack, we should make a Service type or similar. 85 | ServerIPv4: server.IPv4, 86 | ServerIPv6: server.IPv6.GUA, 87 | DesktopIPv4: desktop.IPv4, 88 | DesktopIPv6: desktop.IPv6.GUA, 89 | Hosts: hosts{ 90 | Servers: []host{ 91 | server, 92 | desktop, 93 | mgmt0.newHost( 94 | "monitnerr-1", 95 | netip.MustParseAddr("192.168.1.8"), 96 | mac("dc:a6:32:1e:66:94"), 97 | ), 98 | lan0.newHost( 99 | "matt-3", 100 | netip.MustParseAddr("192.168.10.12"), 101 | mac("c4:bd:e5:1b:8a:e6"), 102 | ), 103 | lan0.newHost( 104 | "matt-4", 105 | netip.MustParseAddr("192.168.10.13"), 106 | mac("14:ac:60:46:8d:91"), 107 | ), 108 | lan0.newHost( 109 | "theatnerr-2", 110 | netip.MustParseAddr("192.168.10.14"), 111 | mac("18:c0:4d:91:04:d8"), 112 | ), 113 | }, 114 | Infra: []host{ 115 | mgmt0.newHost( 116 | "switch-core", 117 | netip.MustParseAddr("192.168.1.2"), 118 | mac("44:5b:ed:f7:ce:da"), 119 | ), 120 | mgmt0.newHost( 121 | "switch-livingroom", 122 | netip.MustParseAddr("192.168.1.3"), 123 | mac("ec:50:aa:42:0e:83"), 124 | ), 125 | mgmt0.newHost( 126 | "switch-office", 127 | netip.MustParseAddr("192.168.1.4"), 128 | mac("74:ac:b9:e2:4e:a5"), 129 | ), 130 | mgmt0.newHost( 131 | "pdu01", 132 | netip.MustParseAddr("192.168.1.5"), 133 | mac("00:0c:15:41:33:5e"), 134 | ), 135 | mgmt0.newHost( 136 | "ap-livingroom", 137 | netip.MustParseAddr("192.168.1.6"), 138 | mac("34:3a:20:c8:a9:de"), 139 | ), 140 | // desktop: 192.168.1.7 141 | // monitor: 192.168.1.8 142 | mgmt0.newHost( 143 | "ap-basement", 144 | netip.MustParseAddr("192.168.1.9"), 145 | mac("d0:4d:c6:c1:72:96"), 146 | ), 147 | // server: 192.168.1.10 148 | mgmt0.newHost( 149 | "ups01", 150 | netip.MustParseAddr("192.168.1.11"), 151 | mac("00:0c:15:05:1e:e6"), 152 | ), 153 | mgmt0.newHost( 154 | "hass", 155 | netip.MustParseAddr("192.168.1.12"), 156 | mac("52:54:00:22:db:4d"), 157 | ), 158 | iot0.newHost( 159 | "keylight", 160 | netip.MustParseAddr("192.168.66.10"), 161 | mac("3c:6a:9d:12:c4:dc"), 162 | ), 163 | iot0.newHost( 164 | "living-room-hue-hub.iot", 165 | netip.MustParseAddr("192.168.66.14"), 166 | mac("ec:b5:fa:1d:4f:c2"), 167 | ), 168 | iot0.newHost( 169 | "living-room-myq-hub.iot", 170 | netip.MustParseAddr("192.168.66.15"), 171 | mac("cc:6a:10:0a:61:7f"), 172 | ), 173 | iot0.newHost( 174 | "office-printer.iot", 175 | netip.MustParseAddr("192.168.66.16"), 176 | mac("40:b8:9a:27:d4:fd"), 177 | ), 178 | }, 179 | }, 180 | } 181 | 182 | // Attach interface definitions from subnet definitions. 183 | out.addInterface("mgmt0", mgmt0) 184 | out.addInterface("lan0", lan0) 185 | out.addInterface("guest0", guest0) 186 | out.addInterface("iot0", iot0) 187 | out.addInterface("lab0", lab0) 188 | out.addInterface("wg0", wg0) 189 | 190 | // Marshal human-readable JSON for nicer git diffs. 191 | e := json.NewEncoder(os.Stdout) 192 | e.SetIndent("", "\t") 193 | if err := e.Encode(out); err != nil { 194 | log.Fatalf("failed to encode JSON: %v", err) 195 | } 196 | } 197 | 198 | func wanIPv6Prefix() netip.Prefix { 199 | res, err := http.Get("https://ipv6.icanhazip.com") 200 | if err != nil { 201 | log.Fatalf("failed to perform HTTP request: %v", err) 202 | } 203 | defer res.Body.Close() 204 | 205 | b, err := io.ReadAll(res.Body) 206 | if err != nil { 207 | log.Fatalf("failed to read HTTP body: %v", err) 208 | } 209 | 210 | // We want to determine the WAN IPv6 prefix so we can use that elsewhere 211 | // when the ISP decides to change it after some period of time. The prefix 212 | // length is hardcoded so it can be used elsewhere. 213 | ip := netip.MustParseAddr(strings.TrimSpace(string(b))) 214 | pfx, err := ip.Prefix(pdLen) 215 | if err != nil { 216 | log.Fatalf("failed to create prefix from IP: %v", err) 217 | } 218 | 219 | return pfx 220 | } 221 | 222 | type output struct { 223 | ServerIPv4 netip.Addr `json:"server_ipv4"` 224 | ServerIPv6 netip.Addr `json:"server_ipv6"` 225 | DesktopIPv4 netip.Addr `json:"desktop_ipv4"` 226 | DesktopIPv6 netip.Addr `json:"desktop_ipv6"` 227 | Hosts hosts `json:"hosts"` 228 | Interfaces map[string]iface `json:"interfaces"` 229 | } 230 | 231 | type hosts struct { 232 | Servers []host `json:"servers"` 233 | Infra []host `json:"infra"` 234 | } 235 | 236 | type iface struct { 237 | Name string `json:"name"` 238 | Preference preference `json:"preference"` 239 | InternalDNS bool `json:"internal_dns"` 240 | IPv4 netip.Addr `json:"ipv4"` 241 | IPv6 ipv6Addresses `json:"ipv6"` 242 | Hosts []host `json:"hosts"` 243 | } 244 | 245 | type ipv6Addresses struct { 246 | GUA netip.Addr `json:"gua"` 247 | ULA netip.Addr `json:"ula"` 248 | LLA netip.Addr `json:"lla"` 249 | } 250 | 251 | func newSubnet(iface string, vlan int, gua netip.Prefix, trusted bool) subnet { 252 | // The GUA prefix passed is a larger prefix such as a /48 or /56 and must 253 | // be combined with the VLAN identifier to create a single /64 subnet for 254 | // use with machines. 255 | sub6 := gua.Addr().As16() 256 | sub6[pdLen/8] = byte(vlan) 257 | gua = netip.PrefixFrom(netip.AddrFrom16(sub6), 64) 258 | 259 | // A hack to continue using 192.168.1.0/24 for the management network. 260 | v4Subnet := vlan 261 | if vlan == 0 { 262 | v4Subnet = 1 263 | } 264 | 265 | return subnet{ 266 | Name: iface, 267 | // All subnets have medium preference by default. 268 | Preference: medium, 269 | Trusted: trusted, 270 | IPv4: netip.MustParsePrefix(fmt.Sprintf("192.168.%d.0/24", v4Subnet)), 271 | IPv6: ipv6Prefixes{ 272 | GUA: gua, 273 | LLA: netip.MustParsePrefix("fe80::/64"), 274 | ULA: netip.MustParsePrefix(fmt.Sprintf("fd9e:1a04:f01d:%d::/64", vlan)), 275 | }, 276 | Hosts: []host{}, 277 | } 278 | } 279 | 280 | func newInterface(s subnet) iface { 281 | // Router always has a .1 or ::1 suffix. 282 | ip4 := s.IPv4.Addr().As4() 283 | ip4[3] = 1 284 | 285 | gua := s.IPv6.GUA.Addr().As16() 286 | gua[15] = 1 287 | 288 | ula := s.IPv6.ULA.Addr().As16() 289 | ula[15] = 1 290 | 291 | lla := s.IPv6.LLA.Addr().As16() 292 | lla[15] = 1 293 | 294 | return iface{ 295 | Name: s.Name, 296 | Preference: s.Preference, 297 | // Only trusted subnets get internal DNS records. 298 | InternalDNS: s.Trusted, 299 | IPv4: netip.AddrFrom4(ip4), 300 | IPv6: ipv6Addresses{ 301 | GUA: netip.AddrFrom16(gua), 302 | ULA: netip.AddrFrom16(ula), 303 | LLA: netip.AddrFrom16(lla), 304 | }, 305 | Hosts: s.Hosts, 306 | } 307 | } 308 | 309 | func (o *output) addInterface(name string, s subnet) { 310 | if o.Interfaces == nil { 311 | o.Interfaces = make(map[string]iface) 312 | } 313 | 314 | o.Interfaces[name] = newInterface(s) 315 | } 316 | 317 | func newHost(hostname string, sub subnet, ip4 netip.Addr, mac net.HardwareAddr) host { 318 | // ip must belong to the input subnet. 319 | if !sub.IPv4.Contains(ip4) { 320 | panicf("subnet %q does not contain %q", sub.IPv4, ip4) 321 | } 322 | 323 | return host{ 324 | Name: hostname, 325 | IPv4: ip4, 326 | IPv6: ipv6Addresses{ 327 | // For now we use EUI-64 to compute all IPv6 addresses. 328 | GUA: mustEUI64(sub.IPv6.GUA, mac), 329 | ULA: mustEUI64(sub.IPv6.ULA, mac), 330 | LLA: mustEUI64(sub.IPv6.LLA, mac), 331 | }, 332 | MAC: mac.String(), 333 | } 334 | } 335 | 336 | func (s *subnet) newHost(hostname string, ip4 netip.Addr, mac net.HardwareAddr) host { 337 | h := newHost(hostname, *s, ip4, mac) 338 | s.Hosts = append(s.Hosts, h) 339 | 340 | return h 341 | } 342 | 343 | type subnet struct { 344 | Name string `json:"name"` 345 | Preference preference `json:"preference"` 346 | Trusted bool `json:"trusted"` 347 | IPv4 netip.Prefix `json:"ipv4"` 348 | IPv6 ipv6Prefixes `json:"ipv6"` 349 | Hosts []host `json:"hosts"` 350 | } 351 | 352 | type host struct { 353 | Name string `json:"name"` 354 | IPv4 netip.Addr `json:"ipv4"` 355 | IPv6 ipv6Addresses `json:"ipv6"` 356 | MAC string `json:"mac"` 357 | } 358 | 359 | type ipv6Prefixes struct { 360 | GUA netip.Prefix `json:"gua"` 361 | ULA netip.Prefix `json:"ula"` 362 | LLA netip.Prefix `json:"lla"` 363 | } 364 | 365 | func mustStdIP(ip net.IP) netip.Addr { 366 | out, ok := netip.AddrFromSlice(ip) 367 | if !ok { 368 | panicf("bad IP: %q", ip) 369 | } 370 | 371 | return out 372 | } 373 | 374 | func mustEUI64(prefix netip.Prefix, mac net.HardwareAddr) netip.Addr { 375 | ip, err := eui64.ParseMAC(prefix.Addr().AsSlice(), mac) 376 | if err != nil { 377 | panicf("failed to make EUI64: %v", err) 378 | } 379 | 380 | return mustStdIP(ip) 381 | } 382 | 383 | func mac(s string) net.HardwareAddr { 384 | mac, err := net.ParseMAC(s) 385 | if err != nil { 386 | panicf("failed to parse MAC: %v", err) 387 | } 388 | 389 | return mac 390 | } 391 | 392 | func panicf(format string, a ...interface{}) { 393 | panic(fmt.Sprintf(format, a...)) 394 | } 395 | -------------------------------------------------------------------------------- /nixos/lib/vars.json: -------------------------------------------------------------------------------- 1 | { 2 | "server_ipv4": "192.168.1.10", 3 | "server_ipv6": "2600:6c4a:783f:7800:6d9:f5ff:fe7e:1c47", 4 | "desktop_ipv4": "192.168.1.7", 5 | "desktop_ipv6": "2600:6c4a:783f:7800:7656:3cff:fe43:7337", 6 | "hosts": { 7 | "servers": [ 8 | { 9 | "name": "servnerr-4", 10 | "ipv4": "192.168.1.10", 11 | "ipv6": { 12 | "gua": "2600:6c4a:783f:7800:6d9:f5ff:fe7e:1c47", 13 | "ula": "fd9e:1a04:f01d:0:6d9:f5ff:fe7e:1c47", 14 | "lla": "fe80::6d9:f5ff:fe7e:1c47" 15 | }, 16 | "mac": "04:d9:f5:7e:1c:47" 17 | }, 18 | { 19 | "name": "nerr-4", 20 | "ipv4": "192.168.1.7", 21 | "ipv6": { 22 | "gua": "2600:6c4a:783f:7800:7656:3cff:fe43:7337", 23 | "ula": "fd9e:1a04:f01d:0:7656:3cff:fe43:7337", 24 | "lla": "fe80::7656:3cff:fe43:7337" 25 | }, 26 | "mac": "74:56:3c:43:73:37" 27 | }, 28 | { 29 | "name": "monitnerr-1", 30 | "ipv4": "192.168.1.8", 31 | "ipv6": { 32 | "gua": "2600:6c4a:783f:7800:dea6:32ff:fe1e:6694", 33 | "ula": "fd9e:1a04:f01d:0:dea6:32ff:fe1e:6694", 34 | "lla": "fe80::dea6:32ff:fe1e:6694" 35 | }, 36 | "mac": "dc:a6:32:1e:66:94" 37 | }, 38 | { 39 | "name": "matt-3", 40 | "ipv4": "192.168.10.12", 41 | "ipv6": { 42 | "gua": "2600:6c4a:783f:780a:c6bd:e5ff:fe1b:8ae6", 43 | "ula": "fd9e:1a04:f01d:10:c6bd:e5ff:fe1b:8ae6", 44 | "lla": "fe80::c6bd:e5ff:fe1b:8ae6" 45 | }, 46 | "mac": "c4:bd:e5:1b:8a:e6" 47 | }, 48 | { 49 | "name": "matt-4", 50 | "ipv4": "192.168.10.13", 51 | "ipv6": { 52 | "gua": "2600:6c4a:783f:780a:16ac:60ff:fe46:8d91", 53 | "ula": "fd9e:1a04:f01d:10:16ac:60ff:fe46:8d91", 54 | "lla": "fe80::16ac:60ff:fe46:8d91" 55 | }, 56 | "mac": "14:ac:60:46:8d:91" 57 | }, 58 | { 59 | "name": "theatnerr-2", 60 | "ipv4": "192.168.10.14", 61 | "ipv6": { 62 | "gua": "2600:6c4a:783f:780a:1ac0:4dff:fe91:4d8", 63 | "ula": "fd9e:1a04:f01d:10:1ac0:4dff:fe91:4d8", 64 | "lla": "fe80::1ac0:4dff:fe91:4d8" 65 | }, 66 | "mac": "18:c0:4d:91:04:d8" 67 | } 68 | ], 69 | "infra": [ 70 | { 71 | "name": "switch-core", 72 | "ipv4": "192.168.1.2", 73 | "ipv6": { 74 | "gua": "2600:6c4a:783f:7800:465b:edff:fef7:ceda", 75 | "ula": "fd9e:1a04:f01d:0:465b:edff:fef7:ceda", 76 | "lla": "fe80::465b:edff:fef7:ceda" 77 | }, 78 | "mac": "44:5b:ed:f7:ce:da" 79 | }, 80 | { 81 | "name": "switch-livingroom", 82 | "ipv4": "192.168.1.3", 83 | "ipv6": { 84 | "gua": "2600:6c4a:783f:7800:ee50:aaff:fe42:e83", 85 | "ula": "fd9e:1a04:f01d:0:ee50:aaff:fe42:e83", 86 | "lla": "fe80::ee50:aaff:fe42:e83" 87 | }, 88 | "mac": "ec:50:aa:42:0e:83" 89 | }, 90 | { 91 | "name": "switch-office", 92 | "ipv4": "192.168.1.4", 93 | "ipv6": { 94 | "gua": "2600:6c4a:783f:7800:76ac:b9ff:fee2:4ea5", 95 | "ula": "fd9e:1a04:f01d:0:76ac:b9ff:fee2:4ea5", 96 | "lla": "fe80::76ac:b9ff:fee2:4ea5" 97 | }, 98 | "mac": "74:ac:b9:e2:4e:a5" 99 | }, 100 | { 101 | "name": "pdu01", 102 | "ipv4": "192.168.1.5", 103 | "ipv6": { 104 | "gua": "2600:6c4a:783f:7800:20c:15ff:fe41:335e", 105 | "ula": "fd9e:1a04:f01d:0:20c:15ff:fe41:335e", 106 | "lla": "fe80::20c:15ff:fe41:335e" 107 | }, 108 | "mac": "00:0c:15:41:33:5e" 109 | }, 110 | { 111 | "name": "ap-livingroom", 112 | "ipv4": "192.168.1.6", 113 | "ipv6": { 114 | "gua": "2600:6c4a:783f:7800:363a:20ff:fec8:a9de", 115 | "ula": "fd9e:1a04:f01d:0:363a:20ff:fec8:a9de", 116 | "lla": "fe80::363a:20ff:fec8:a9de" 117 | }, 118 | "mac": "34:3a:20:c8:a9:de" 119 | }, 120 | { 121 | "name": "ap-basement", 122 | "ipv4": "192.168.1.9", 123 | "ipv6": { 124 | "gua": "2600:6c4a:783f:7800:d24d:c6ff:fec1:7296", 125 | "ula": "fd9e:1a04:f01d:0:d24d:c6ff:fec1:7296", 126 | "lla": "fe80::d24d:c6ff:fec1:7296" 127 | }, 128 | "mac": "d0:4d:c6:c1:72:96" 129 | }, 130 | { 131 | "name": "ups01", 132 | "ipv4": "192.168.1.11", 133 | "ipv6": { 134 | "gua": "2600:6c4a:783f:7800:20c:15ff:fe05:1ee6", 135 | "ula": "fd9e:1a04:f01d:0:20c:15ff:fe05:1ee6", 136 | "lla": "fe80::20c:15ff:fe05:1ee6" 137 | }, 138 | "mac": "00:0c:15:05:1e:e6" 139 | }, 140 | { 141 | "name": "hass", 142 | "ipv4": "192.168.1.12", 143 | "ipv6": { 144 | "gua": "2600:6c4a:783f:7800:5054:ff:fe22:db4d", 145 | "ula": "fd9e:1a04:f01d:0:5054:ff:fe22:db4d", 146 | "lla": "fe80::5054:ff:fe22:db4d" 147 | }, 148 | "mac": "52:54:00:22:db:4d" 149 | }, 150 | { 151 | "name": "keylight", 152 | "ipv4": "192.168.66.10", 153 | "ipv6": { 154 | "gua": "2600:6c4a:783f:7842:3e6a:9dff:fe12:c4dc", 155 | "ula": "fd9e:1a04:f01d:66:3e6a:9dff:fe12:c4dc", 156 | "lla": "fe80::3e6a:9dff:fe12:c4dc" 157 | }, 158 | "mac": "3c:6a:9d:12:c4:dc" 159 | }, 160 | { 161 | "name": "living-room-hue-hub.iot", 162 | "ipv4": "192.168.66.14", 163 | "ipv6": { 164 | "gua": "2600:6c4a:783f:7842:eeb5:faff:fe1d:4fc2", 165 | "ula": "fd9e:1a04:f01d:66:eeb5:faff:fe1d:4fc2", 166 | "lla": "fe80::eeb5:faff:fe1d:4fc2" 167 | }, 168 | "mac": "ec:b5:fa:1d:4f:c2" 169 | }, 170 | { 171 | "name": "living-room-myq-hub.iot", 172 | "ipv4": "192.168.66.15", 173 | "ipv6": { 174 | "gua": "2600:6c4a:783f:7842:ce6a:10ff:fe0a:617f", 175 | "ula": "fd9e:1a04:f01d:66:ce6a:10ff:fe0a:617f", 176 | "lla": "fe80::ce6a:10ff:fe0a:617f" 177 | }, 178 | "mac": "cc:6a:10:0a:61:7f" 179 | }, 180 | { 181 | "name": "office-printer.iot", 182 | "ipv4": "192.168.66.16", 183 | "ipv6": { 184 | "gua": "2600:6c4a:783f:7842:42b8:9aff:fe27:d4fd", 185 | "ula": "fd9e:1a04:f01d:66:42b8:9aff:fe27:d4fd", 186 | "lla": "fe80::42b8:9aff:fe27:d4fd" 187 | }, 188 | "mac": "40:b8:9a:27:d4:fd" 189 | } 190 | ] 191 | }, 192 | "interfaces": { 193 | "guest0": { 194 | "name": "guest0", 195 | "preference": "medium", 196 | "internal_dns": false, 197 | "ipv4": "192.168.9.1", 198 | "ipv6": { 199 | "gua": "2600:6c4a:783f:7809::1", 200 | "ula": "fd9e:1a04:f01d:9::1", 201 | "lla": "fe80::1" 202 | }, 203 | "hosts": [] 204 | }, 205 | "iot0": { 206 | "name": "iot0", 207 | "preference": "medium", 208 | "internal_dns": false, 209 | "ipv4": "192.168.66.1", 210 | "ipv6": { 211 | "gua": "2600:6c4a:783f:7842::1", 212 | "ula": "fd9e:1a04:f01d:66::1", 213 | "lla": "fe80::1" 214 | }, 215 | "hosts": [ 216 | { 217 | "name": "keylight", 218 | "ipv4": "192.168.66.10", 219 | "ipv6": { 220 | "gua": "2600:6c4a:783f:7842:3e6a:9dff:fe12:c4dc", 221 | "ula": "fd9e:1a04:f01d:66:3e6a:9dff:fe12:c4dc", 222 | "lla": "fe80::3e6a:9dff:fe12:c4dc" 223 | }, 224 | "mac": "3c:6a:9d:12:c4:dc" 225 | }, 226 | { 227 | "name": "living-room-hue-hub.iot", 228 | "ipv4": "192.168.66.14", 229 | "ipv6": { 230 | "gua": "2600:6c4a:783f:7842:eeb5:faff:fe1d:4fc2", 231 | "ula": "fd9e:1a04:f01d:66:eeb5:faff:fe1d:4fc2", 232 | "lla": "fe80::eeb5:faff:fe1d:4fc2" 233 | }, 234 | "mac": "ec:b5:fa:1d:4f:c2" 235 | }, 236 | { 237 | "name": "living-room-myq-hub.iot", 238 | "ipv4": "192.168.66.15", 239 | "ipv6": { 240 | "gua": "2600:6c4a:783f:7842:ce6a:10ff:fe0a:617f", 241 | "ula": "fd9e:1a04:f01d:66:ce6a:10ff:fe0a:617f", 242 | "lla": "fe80::ce6a:10ff:fe0a:617f" 243 | }, 244 | "mac": "cc:6a:10:0a:61:7f" 245 | }, 246 | { 247 | "name": "office-printer.iot", 248 | "ipv4": "192.168.66.16", 249 | "ipv6": { 250 | "gua": "2600:6c4a:783f:7842:42b8:9aff:fe27:d4fd", 251 | "ula": "fd9e:1a04:f01d:66:42b8:9aff:fe27:d4fd", 252 | "lla": "fe80::42b8:9aff:fe27:d4fd" 253 | }, 254 | "mac": "40:b8:9a:27:d4:fd" 255 | } 256 | ] 257 | }, 258 | "lab0": { 259 | "name": "lab0", 260 | "preference": "medium", 261 | "internal_dns": false, 262 | "ipv4": "192.168.2.1", 263 | "ipv6": { 264 | "gua": "2600:6c4a:783f:7802::1", 265 | "ula": "fd9e:1a04:f01d:2::1", 266 | "lla": "fe80::1" 267 | }, 268 | "hosts": [] 269 | }, 270 | "lan0": { 271 | "name": "lan0", 272 | "preference": "medium", 273 | "internal_dns": true, 274 | "ipv4": "192.168.10.1", 275 | "ipv6": { 276 | "gua": "2600:6c4a:783f:780a::1", 277 | "ula": "fd9e:1a04:f01d:10::1", 278 | "lla": "fe80::1" 279 | }, 280 | "hosts": [ 281 | { 282 | "name": "matt-3", 283 | "ipv4": "192.168.10.12", 284 | "ipv6": { 285 | "gua": "2600:6c4a:783f:780a:c6bd:e5ff:fe1b:8ae6", 286 | "ula": "fd9e:1a04:f01d:10:c6bd:e5ff:fe1b:8ae6", 287 | "lla": "fe80::c6bd:e5ff:fe1b:8ae6" 288 | }, 289 | "mac": "c4:bd:e5:1b:8a:e6" 290 | }, 291 | { 292 | "name": "matt-4", 293 | "ipv4": "192.168.10.13", 294 | "ipv6": { 295 | "gua": "2600:6c4a:783f:780a:16ac:60ff:fe46:8d91", 296 | "ula": "fd9e:1a04:f01d:10:16ac:60ff:fe46:8d91", 297 | "lla": "fe80::16ac:60ff:fe46:8d91" 298 | }, 299 | "mac": "14:ac:60:46:8d:91" 300 | }, 301 | { 302 | "name": "theatnerr-2", 303 | "ipv4": "192.168.10.14", 304 | "ipv6": { 305 | "gua": "2600:6c4a:783f:780a:1ac0:4dff:fe91:4d8", 306 | "ula": "fd9e:1a04:f01d:10:1ac0:4dff:fe91:4d8", 307 | "lla": "fe80::1ac0:4dff:fe91:4d8" 308 | }, 309 | "mac": "18:c0:4d:91:04:d8" 310 | } 311 | ] 312 | }, 313 | "mgmt0": { 314 | "name": "mgmt0", 315 | "preference": "medium", 316 | "internal_dns": true, 317 | "ipv4": "192.168.1.1", 318 | "ipv6": { 319 | "gua": "2600:6c4a:783f:7800::1", 320 | "ula": "fd9e:1a04:f01d::1", 321 | "lla": "fe80::1" 322 | }, 323 | "hosts": [ 324 | { 325 | "name": "servnerr-4", 326 | "ipv4": "192.168.1.10", 327 | "ipv6": { 328 | "gua": "2600:6c4a:783f:7800:6d9:f5ff:fe7e:1c47", 329 | "ula": "fd9e:1a04:f01d:0:6d9:f5ff:fe7e:1c47", 330 | "lla": "fe80::6d9:f5ff:fe7e:1c47" 331 | }, 332 | "mac": "04:d9:f5:7e:1c:47" 333 | }, 334 | { 335 | "name": "nerr-4", 336 | "ipv4": "192.168.1.7", 337 | "ipv6": { 338 | "gua": "2600:6c4a:783f:7800:7656:3cff:fe43:7337", 339 | "ula": "fd9e:1a04:f01d:0:7656:3cff:fe43:7337", 340 | "lla": "fe80::7656:3cff:fe43:7337" 341 | }, 342 | "mac": "74:56:3c:43:73:37" 343 | }, 344 | { 345 | "name": "monitnerr-1", 346 | "ipv4": "192.168.1.8", 347 | "ipv6": { 348 | "gua": "2600:6c4a:783f:7800:dea6:32ff:fe1e:6694", 349 | "ula": "fd9e:1a04:f01d:0:dea6:32ff:fe1e:6694", 350 | "lla": "fe80::dea6:32ff:fe1e:6694" 351 | }, 352 | "mac": "dc:a6:32:1e:66:94" 353 | }, 354 | { 355 | "name": "switch-core", 356 | "ipv4": "192.168.1.2", 357 | "ipv6": { 358 | "gua": "2600:6c4a:783f:7800:465b:edff:fef7:ceda", 359 | "ula": "fd9e:1a04:f01d:0:465b:edff:fef7:ceda", 360 | "lla": "fe80::465b:edff:fef7:ceda" 361 | }, 362 | "mac": "44:5b:ed:f7:ce:da" 363 | }, 364 | { 365 | "name": "switch-livingroom", 366 | "ipv4": "192.168.1.3", 367 | "ipv6": { 368 | "gua": "2600:6c4a:783f:7800:ee50:aaff:fe42:e83", 369 | "ula": "fd9e:1a04:f01d:0:ee50:aaff:fe42:e83", 370 | "lla": "fe80::ee50:aaff:fe42:e83" 371 | }, 372 | "mac": "ec:50:aa:42:0e:83" 373 | }, 374 | { 375 | "name": "switch-office", 376 | "ipv4": "192.168.1.4", 377 | "ipv6": { 378 | "gua": "2600:6c4a:783f:7800:76ac:b9ff:fee2:4ea5", 379 | "ula": "fd9e:1a04:f01d:0:76ac:b9ff:fee2:4ea5", 380 | "lla": "fe80::76ac:b9ff:fee2:4ea5" 381 | }, 382 | "mac": "74:ac:b9:e2:4e:a5" 383 | }, 384 | { 385 | "name": "pdu01", 386 | "ipv4": "192.168.1.5", 387 | "ipv6": { 388 | "gua": "2600:6c4a:783f:7800:20c:15ff:fe41:335e", 389 | "ula": "fd9e:1a04:f01d:0:20c:15ff:fe41:335e", 390 | "lla": "fe80::20c:15ff:fe41:335e" 391 | }, 392 | "mac": "00:0c:15:41:33:5e" 393 | }, 394 | { 395 | "name": "ap-livingroom", 396 | "ipv4": "192.168.1.6", 397 | "ipv6": { 398 | "gua": "2600:6c4a:783f:7800:363a:20ff:fec8:a9de", 399 | "ula": "fd9e:1a04:f01d:0:363a:20ff:fec8:a9de", 400 | "lla": "fe80::363a:20ff:fec8:a9de" 401 | }, 402 | "mac": "34:3a:20:c8:a9:de" 403 | }, 404 | { 405 | "name": "ap-basement", 406 | "ipv4": "192.168.1.9", 407 | "ipv6": { 408 | "gua": "2600:6c4a:783f:7800:d24d:c6ff:fec1:7296", 409 | "ula": "fd9e:1a04:f01d:0:d24d:c6ff:fec1:7296", 410 | "lla": "fe80::d24d:c6ff:fec1:7296" 411 | }, 412 | "mac": "d0:4d:c6:c1:72:96" 413 | }, 414 | { 415 | "name": "ups01", 416 | "ipv4": "192.168.1.11", 417 | "ipv6": { 418 | "gua": "2600:6c4a:783f:7800:20c:15ff:fe05:1ee6", 419 | "ula": "fd9e:1a04:f01d:0:20c:15ff:fe05:1ee6", 420 | "lla": "fe80::20c:15ff:fe05:1ee6" 421 | }, 422 | "mac": "00:0c:15:05:1e:e6" 423 | }, 424 | { 425 | "name": "hass", 426 | "ipv4": "192.168.1.12", 427 | "ipv6": { 428 | "gua": "2600:6c4a:783f:7800:5054:ff:fe22:db4d", 429 | "ula": "fd9e:1a04:f01d:0:5054:ff:fe22:db4d", 430 | "lla": "fe80::5054:ff:fe22:db4d" 431 | }, 432 | "mac": "52:54:00:22:db:4d" 433 | } 434 | ] 435 | }, 436 | "wg0": { 437 | "name": "wg0", 438 | "preference": "medium", 439 | "internal_dns": true, 440 | "ipv4": "192.168.20.1", 441 | "ipv6": { 442 | "gua": "2600:6c4a:783f:7814::1", 443 | "ula": "fd9e:1a04:f01d:20::1", 444 | "lla": "fe80::1" 445 | }, 446 | "hosts": [] 447 | } 448 | } 449 | } 450 | -------------------------------------------------------------------------------- /nixos/lib/vars.nix: -------------------------------------------------------------------------------- 1 | # Variables referenced two or more places in the configuration. 2 | let 3 | # Import computed host/interface data from vars.json. 4 | gen = builtins.fromJSON (builtins.readFile ./vars.json); 5 | hosts = gen.hosts; 6 | interfaces = gen.interfaces; 7 | wireguard = gen.wireguard; 8 | 9 | server_ipv4 = gen.server_ipv4; 10 | server_ipv6 = gen.server_ipv6; 11 | desktop_ipv4 = gen.desktop_ipv4; 12 | desktop_ipv6 = gen.desktop_ipv6; 13 | 14 | in 15 | { 16 | inherit hosts; 17 | inherit interfaces; 18 | inherit wireguard; 19 | 20 | inherit server_ipv4; 21 | inherit server_ipv6; 22 | inherit desktop_ipv4; 23 | inherit desktop_ipv6; 24 | 25 | domain = "lan.servnerr.com"; 26 | localhost = { 27 | ipv4 = "127.0.0.1"; 28 | ipv6 = "::1"; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /nixos/routnerr-3/README.md: -------------------------------------------------------------------------------- 1 | # routnerr-2 2 | 3 | This machine is my home router based on the [Deciso DEC 4 | 2750](https://shop.opnsense.com/product/dec2750-opnsense-rack-security-appliance/) 5 | OPNsense appliance, running NixOS. 6 | -------------------------------------------------------------------------------- /nixos/routnerr-3/caddy.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | let 4 | secrets = import ./lib/secrets.nix; 5 | vars = import ./lib/vars.nix; 6 | 7 | in 8 | { 9 | services.caddy = { 10 | enable = true; 11 | virtualHosts = { 12 | "alertmanager.servnerr.com".extraConfig = '' 13 | reverse_proxy http://servnerr-4.${vars.domain}:9093 14 | basicauth { 15 | ${secrets.caddy.alertmanager_auth} 16 | } 17 | ''; 18 | 19 | "grafana.servnerr.com".extraConfig = '' 20 | reverse_proxy http://servnerr-4.${vars.domain}:3000 21 | ''; 22 | 23 | "plex.servnerr.com".extraConfig = '' 24 | reverse_proxy http://servnerr-4.${vars.domain}:32400 25 | ''; 26 | 27 | "prometheus.servnerr.com".extraConfig = '' 28 | reverse_proxy http://servnerr-4.${vars.domain}:9090 29 | basicauth { 30 | ${secrets.caddy.prometheus_auth} 31 | } 32 | ''; 33 | }; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /nixos/routnerr-3/configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | 5 | { pkgs, ... }: 6 | 7 | let 8 | vars = import ./lib/vars.nix; 9 | 10 | in 11 | { 12 | imports = [ 13 | # Hardware and base system configuration. 14 | ./hardware-configuration.nix 15 | ./lib/system.nix 16 | 17 | # Base router networking. 18 | ./networking.nix 19 | ./nftables.nix 20 | 21 | # Networking daemons. 22 | ./coredns.nix 23 | ./corerad.nix 24 | ./caddy.nix 25 | ]; 26 | 27 | # TODO: https://github.com/NixOS/nixos-hardware/pull/673 28 | boot.kernelParams = [ "console=ttyS0,115200n8" ]; 29 | 30 | # Start getty over serial console. 31 | systemd.services."serial-getty@ttyS0" = { 32 | enable = true; 33 | wantedBy = [ "multi-user.target" ]; 34 | serviceConfig = { 35 | Restart = "always"; 36 | }; 37 | }; 38 | 39 | system.copySystemConfiguration = true; 40 | system.stateVersion = "23.05"; 41 | 42 | boot = { 43 | kernel = { 44 | sysctl = { 45 | # Forward on all interfaces. 46 | "net.ipv4.conf.all.forwarding" = true; 47 | "net.ipv6.conf.all.forwarding" = true; 48 | 49 | # By default, do not automatically configure any IPv6 addresses. 50 | "net.ipv6.conf.all.accept_ra" = 0; 51 | "net.ipv6.conf.all.autoconf" = 0; 52 | "net.ipv6.conf.all.use_tempaddr" = 0; 53 | 54 | # On wired WANs, allow IPv6 autoconfiguration and tempory address use. 55 | "net.ipv6.conf.wan0.accept_ra" = 2; 56 | "net.ipv6.conf.wan0.autoconf" = 1; 57 | "net.ipv6.conf.wan1.accept_ra" = 2; 58 | "net.ipv6.conf.wan1.autoconf" = 1; 59 | }; 60 | }; 61 | }; 62 | 63 | # Use the systemd-boot EFI boot loader. 64 | boot.loader.systemd-boot.enable = true; 65 | boot.loader.efi.canTouchEfiVariables = true; 66 | 67 | # Packages specific to this machine. The base package set is defined in 68 | # lib/system.nix. 69 | environment.systemPackages = with pkgs; [ 70 | # Stable packages. 71 | bind 72 | ]; 73 | 74 | services = { 75 | # Allow mDNS to reflect between VLANs where necessary for devices such as 76 | # Google Home and Chromecast. 77 | avahi = { 78 | enable = true; 79 | allowInterfaces = with vars.interfaces; [ 80 | "${mgmt0.name}" 81 | "${lan0.name}" 82 | "${iot0.name}" 83 | ]; 84 | ipv4 = true; 85 | ipv6 = true; 86 | reflector = true; 87 | }; 88 | 89 | lldpd.enable = true; 90 | 91 | # Enable the OpenSSH daemon. 92 | openssh = { 93 | enable = true; 94 | settings = { 95 | PasswordAuthentication = false; 96 | PermitRootLogin = "no"; 97 | }; 98 | }; 99 | 100 | atftpd = { 101 | enable = true; 102 | root = "/var/lib/tftp"; 103 | }; 104 | }; 105 | } 106 | -------------------------------------------------------------------------------- /nixos/routnerr-3/coredns.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | 3 | let 4 | vars = import ./lib/vars.nix; 5 | 6 | in 7 | { 8 | services.coredns = { 9 | enable = true; 10 | config = with vars; '' 11 | # Root zone. 12 | . { 13 | cache 3600 { 14 | success 8192 15 | denial 4096 16 | } 17 | prometheus :9153 18 | forward . tls://8.8.8.8 tls://8.8.4.4 tls://2001:4860:4860::8888 tls://2001:4860:4860::8844 { 19 | tls_servername dns.google 20 | health_check 5s 21 | } 22 | } 23 | 24 | # Internal zone. 25 | ${domain} { 26 | hosts { 27 | ${ 28 | # Write out internal DNS records for each of the configured hosts. 29 | # If the host does not have an IPv6 ULA address, omit it. 30 | lib.concatMapStrings 31 | (host: '' 32 | ${host.ipv4} ${host.name}.${domain} 33 | ${host.ipv4} ${host.name}.ipv4.${domain} 34 | 35 | ${ 36 | if host.ipv6.ula != "" then 37 | '' 38 | ${host.ipv6.ula} ${host.name}.${domain} 39 | ${host.ipv6.ula} ${host.name}.ipv6.${domain} 40 | '' 41 | else 42 | "" 43 | } 44 | '') 45 | ( 46 | hosts.servers 47 | ++ hosts.infra 48 | ++ [ 49 | { 50 | name = "routnerr-3"; 51 | ipv4 = interfaces.lan0.ipv4; 52 | ipv6.ula = interfaces.lan0.ipv6.ula; 53 | } 54 | ] 55 | ) 56 | } 57 | } 58 | } 59 | ''; 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /nixos/routnerr-3/corerad.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | 3 | let 4 | unstable = import { }; 5 | vars = import ./lib/vars.nix; 6 | 7 | in 8 | { 9 | services.corerad = { 10 | enable = true; 11 | 12 | # Enable as necessary to get development builds of CoreRAD. 13 | package = unstable.corerad; 14 | 15 | settings = with vars.interfaces; { 16 | # Base non-interface configuration. 17 | debug = { 18 | # No risk exposing these off-host because of the WAN firewall. 19 | address = ":9430"; 20 | prometheus = true; 21 | pprof = true; 22 | }; 23 | 24 | interfaces = 25 | # Upstream monitoring interfaces. 26 | [ 27 | { 28 | # Spectrum, Metronet does not provide IPv6 as of September 2023. 29 | names = [ "wan0" ]; 30 | monitor = true; 31 | } 32 | ] 33 | 34 | # Downstream advertising interfaces. 35 | ++ lib.forEach [ mgmt0 lab0 lan0 guest0 iot0 ] ( 36 | ifi: 37 | { 38 | name = ifi.name; 39 | advertise = true; 40 | 41 | # Configure a higher preference for interfaces with more bandwidth. 42 | preference = ifi.preference; 43 | 44 | # Advertise all /64 prefixes on the interface. 45 | prefix = [ 46 | # RFC8978: Reaction of IPv6 SLAAC to Flash-Renumbering Events 47 | { 48 | preferred_lifetime = "45m"; 49 | valid_lifetime = "90m"; 50 | } 51 | ]; 52 | 53 | # Automatically use the appropriate interface address as a DNS server. 54 | rdnss = [ { } ]; 55 | 56 | # Automatically propagate routes owned by loopback. 57 | route = [ 58 | # Tuning inspired by: 59 | # RFC8978: Reaction of IPv6 SLAAC to Flash-Renumbering Events 60 | { 61 | lifetime = "45m"; 62 | } 63 | ]; 64 | } 65 | // ( 66 | # Configure DNS search on some trusted LANs, or omit otherwise. 67 | # 68 | # TODO(mdlayher): probably rename to ifi.trusted. 69 | if ifi.internal_dns then 70 | { 71 | dnssl = [ { domain_names = [ vars.domain ]; } ]; 72 | } 73 | else 74 | { } 75 | ) 76 | ); 77 | }; 78 | }; 79 | } 80 | -------------------------------------------------------------------------------- /nixos/routnerr-3/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { 5 | config, 6 | lib, 7 | pkgs, 8 | modulesPath, 9 | ... 10 | }: 11 | 12 | { 13 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; 14 | 15 | boot.initrd.availableKernelModules = [ 16 | "nvme" 17 | "xhci_pci" 18 | ]; 19 | boot.initrd.kernelModules = [ ]; 20 | boot.kernelModules = [ "kvm-amd" ]; 21 | boot.extraModulePackages = [ ]; 22 | 23 | fileSystems."/" = { 24 | device = "/dev/disk/by-uuid/d720351b-787d-4cfd-bd95-a65bd29a18c1"; 25 | fsType = "ext4"; 26 | }; 27 | 28 | fileSystems."/boot" = { 29 | device = "/dev/disk/by-uuid/AC76-96D5"; 30 | fsType = "vfat"; 31 | }; 32 | 33 | swapDevices = [ { device = "/dev/disk/by-uuid/ea5ad06f-254f-42ee-92b4-84512016a0b6"; } ]; 34 | 35 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 36 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 37 | } 38 | -------------------------------------------------------------------------------- /nixos/routnerr-3/lib: -------------------------------------------------------------------------------- 1 | ../lib -------------------------------------------------------------------------------- /nixos/routnerr-3/networking.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | 3 | let 4 | unstable = import { }; 5 | vars = import ./lib/vars.nix; 6 | 7 | ethLink = ( 8 | name: 9 | (mac: { 10 | matchConfig = { 11 | Type = "ether"; 12 | MACAddress = mac; 13 | }; 14 | linkConfig = { 15 | Name = name; 16 | 17 | # Hardware tuning. Note that wan0/wan1/mgmt0 all happen to support a max 18 | # of 4096 since the NixOS option won't allow "max". 19 | RxBufferSize = 4096; 20 | TxBufferSize = 4096; 21 | }; 22 | }) 23 | ); 24 | 25 | vlanNetdev = ( 26 | name: 27 | (id: { 28 | netdevConfig = { 29 | Name = name; 30 | Kind = "vlan"; 31 | }; 32 | vlanConfig.Id = id; 33 | }) 34 | ); 35 | 36 | vlanNetwork = ( 37 | name: 38 | (id: { 39 | matchConfig.Name = name; 40 | # Embed ID directly in IPv4/6 addresses for clarity. 41 | address = [ 42 | "fd9e:1a04:f01d:${toString id}::1/64" 43 | "fe80::1/64" 44 | "192.168.${toString id}.1/24" 45 | ]; 46 | networkConfig = { 47 | DHCPPrefixDelegation = true; 48 | DHCPServer = true; 49 | IPv6AcceptRA = false; 50 | }; 51 | dhcpPrefixDelegationConfig = { 52 | # Router always lives at ::1. 53 | Token = "::1"; 54 | # Delegate the associated hex subnet ID from DHCPv6-PD. 55 | SubnetId = "${toString (decToHex id)}"; 56 | }; 57 | 58 | # DHCPServer on NixOS does not support Boot options yet. 59 | extraConfig = '' 60 | [DHCPServer] 61 | DefaultLeaseTimeSec = 86400 62 | MaxLeaseTimeSec = 86400 63 | PoolOffset = 50 64 | EmitDNS = true 65 | DNS = _server_address 66 | BootServerAddress = 192.168.${toString id}.1 67 | BootFilename = netboot.xyz.kpxe 68 | ''; 69 | 70 | # Write out fixed leases per subnet. 71 | dhcpServerStaticLeases = lib.forEach vars.interfaces."${name}".hosts (host: { 72 | Address = host.ipv4; 73 | MACAddress = host.mac; 74 | }); 75 | }) 76 | ); 77 | 78 | # Thanks, corpix! 79 | # https://gist.github.com/corpix/f761c82c9d6fdbc1b3846b37e1020e11 80 | decToHex = 81 | let 82 | intToHex = [ 83 | "0" 84 | "1" 85 | "2" 86 | "3" 87 | "4" 88 | "5" 89 | "6" 90 | "7" 91 | "8" 92 | "9" 93 | "a" 94 | "b" 95 | "c" 96 | "d" 97 | "e" 98 | "f" 99 | ]; 100 | toHex' = q: a: if q > 0 then (toHex' (q / 16) ((lib.elemAt intToHex (lib.mod q 16)) + a)) else a; 101 | in 102 | v: toHex' v ""; 103 | in 104 | { 105 | networking = { 106 | hostName = "routnerr-3"; 107 | 108 | # Use systemd-networkd for configuration. Forcibly disable legacy DHCP 109 | # client. 110 | useNetworkd = true; 111 | useDHCP = false; 112 | 113 | # Use nftables instead. 114 | nat.enable = false; 115 | firewall.enable = false; 116 | }; 117 | 118 | # Use resolved for local DNS lookups, querying through CoreDNS. 119 | services.resolved = { 120 | enable = true; 121 | domains = [ 122 | vars.domain 123 | "taild07ab.ts.net" 124 | ]; 125 | extraConfig = '' 126 | DNS=::1 127.0.0.1 127 | DNSStubListener=no 128 | ''; 129 | }; 130 | 131 | # Manage network configuration with networkd. 132 | systemd.network = { 133 | enable = true; 134 | 135 | config.networkConfig.SpeedMeter = "yes"; 136 | 137 | # Loopback. 138 | networks."5-lo" = { 139 | matchConfig.Name = "lo"; 140 | routes = [ 141 | { 142 | # We own the ULA /48, create a blanket unreachable route which will be 143 | # superseded by more specific /64s. 144 | Destination = "fd9e:1a04:f01d::/48"; 145 | Type = "unreachable"; 146 | } 147 | ]; 148 | }; 149 | 150 | # Wired WAN: Spectrum 1GbE. 151 | links."10-wan0" = ethLink "wan0" "f4:90:ea:00:c7:8d"; 152 | networks."10-wan0" = { 153 | matchConfig.Name = "wan0"; 154 | networkConfig.DHCP = "yes"; 155 | # Never accept ISP DNS or search domains for any DHCP/RA family. 156 | dhcpV4Config = { 157 | UseDNS = false; 158 | UseDomains = false; 159 | 160 | # Don't release IPv4 address on restart/reboots to avoid churn. 161 | SendRelease = false; 162 | 163 | # Deprioritize Spectrum IPv4. 164 | RouteMetric = 200; 165 | }; 166 | dhcpV6Config = { 167 | # Spectrum gives a /56. 168 | PrefixDelegationHint = "::/56"; 169 | 170 | UseDNS = false; 171 | }; 172 | ipv6AcceptRAConfig = { 173 | UseDNS = false; 174 | UseDomains = false; 175 | }; 176 | }; 177 | 178 | # Wired WAN: Metronet 10GbE. 179 | links."11-wan1" = ethLink "wan1" "f4:90:ea:00:c7:91"; 180 | networks."11-wan1" = { 181 | matchConfig.Name = "wan1"; 182 | networkConfig.Address = "216.82.20.71/26"; 183 | 184 | routes = [ 185 | { 186 | Gateway = "216.82.20.65"; 187 | 188 | # Prioritize Metronet IPv4. 189 | Metric = 100; 190 | } 191 | ]; 192 | }; 193 | 194 | # Physical management LAN. For physical LANs, we have to make sure to match 195 | # on both Type and MACAddress since VLANs would share the same MAC. 196 | links."15-mgmt0" = ethLink "mgmt0" "f4:90:ea:00:c7:8e"; 197 | networks."15-mgmt0" = { 198 | matchConfig.Name = "mgmt0"; 199 | 200 | # TODO(mdlayher): eventually it'd be nice to renumber this as 201 | # 192.168.0.1/24 but that would require a lot of device churn. 202 | address = [ 203 | "fd9e:1a04:f01d::1/64" 204 | "fe80::1/64" 205 | "192.168.1.1/24" 206 | ]; 207 | 208 | # VLANs associated with this physical interface. 209 | vlan = [ 210 | "lan0" 211 | "iot0" 212 | "guest0" 213 | "lab0" 214 | ]; 215 | 216 | networkConfig = { 217 | DHCPPrefixDelegation = true; 218 | DHCPServer = true; 219 | IPv6AcceptRA = false; 220 | }; 221 | dhcpPrefixDelegationConfig = { 222 | Token = "::1"; 223 | SubnetId = 0; 224 | }; 225 | 226 | # DHCPServer on NixOS does not support Boot options yet. 227 | extraConfig = '' 228 | [DHCPServer] 229 | DefaultLeaseTimeSec = 86400 230 | MaxLeaseTimeSec = 86400 231 | PoolOffset = 50 232 | EmitDNS = true 233 | DNS = _server_address 234 | BootServerAddress = 192.168.1.1 235 | BootFilename = netboot.xyz.kpxe 236 | ''; 237 | 238 | # Write out fixed leases per subnet. 239 | dhcpServerStaticLeases = lib.forEach vars.interfaces.mgmt0.hosts (host: { 240 | Address = host.ipv4; 241 | MACAddress = host.mac; 242 | }); 243 | }; 244 | 245 | # Unused Ethernet and SFP+ links. 246 | links."15-eth2" = ethLink "eth2" "f4:90:ea:00:c7:8f"; 247 | links."15-sfp0" = ethLink "sfp0" "f4:90:ea:00:c7:90"; 248 | 249 | # Home VLAN. 250 | netdevs."20-lan0" = vlanNetdev "lan0" 10; 251 | networks."20-lan0" = vlanNetwork "lan0" 10; 252 | 253 | # IoT VLAN. 254 | netdevs."25-iot0" = vlanNetdev "iot0" 66; 255 | networks."25-iot0" = vlanNetwork "iot0" 66; 256 | 257 | # Guest VLAN. 258 | netdevs."30-guest0" = vlanNetdev "guest0" 9; 259 | networks."30-guest0" = vlanNetwork "guest0" 9; 260 | 261 | # Lab VLAN. 262 | netdevs."35-lab0" = vlanNetdev "lab0" 2; 263 | networks."35-lab0" = vlanNetwork "lab0" 2; 264 | }; 265 | 266 | services.tailscale = { 267 | enable = true; 268 | package = unstable.tailscale; 269 | interfaceName = "ts0"; 270 | permitCertUid = "caddy"; 271 | useRoutingFeatures = "server"; 272 | }; 273 | 274 | # Tailscale readiness and DNS tweaks. 275 | systemd.network.wait-online.ignoredInterfaces = [ "ts0" ]; 276 | 277 | systemd.services.tailscaled = { 278 | after = [ 279 | "network-online.target" 280 | "systemd-resolved.service" 281 | ]; 282 | wants = [ "network-online.target" ]; 283 | }; 284 | } 285 | -------------------------------------------------------------------------------- /nixos/routnerr-3/nftables.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | 3 | let 4 | vars = import ./lib/vars.nix; 5 | 6 | # Port definitions. 7 | ports = { 8 | dns = "53"; 9 | dhcp4_server = "67"; 10 | dhcp4_client = "68"; 11 | dhcp6_client = "546"; 12 | dhcp6_server = "547"; 13 | http = "80"; 14 | https = "443"; 15 | mdns = "5353"; 16 | plex = "32400"; 17 | # Different tailscaled ports for different devices to avoid messing with 18 | # poking nftables firewall holes with miniupnpd or similar. 19 | tailscale = { 20 | router = "41461"; 21 | desktop = "41642"; 22 | }; 23 | }; 24 | 25 | # Produces a CSV list of interface names. 26 | mkCSV = lib.concatMapStrings (ifi: "${ifi.name}, "); 27 | 28 | # WAN interfaces. 29 | all_wans = "wan0, wan1"; 30 | 31 | # LAN interfaces, segmented into trusted, limited, and untrusted groups. 32 | trusted_lans = with vars.interfaces; [ 33 | mgmt0 34 | lan0 35 | lab0 36 | { name = "ts0"; } 37 | ]; 38 | limited_lans = with vars.interfaces; [ guest0 ]; 39 | untrusted_lans = with vars.interfaces; [ iot0 ]; 40 | 41 | # ICMP filtering. 42 | icmp_rules = '' 43 | ip6 nexthdr icmpv6 icmpv6 type { 44 | echo-request, 45 | echo-reply, 46 | destination-unreachable, 47 | packet-too-big, 48 | time-exceeded, 49 | parameter-problem, 50 | nd-neighbor-solicit, 51 | nd-neighbor-advert, 52 | } counter accept 53 | 54 | ip protocol icmp icmp type { 55 | echo-request, 56 | echo-reply, 57 | destination-unreachable, 58 | time-exceeded, 59 | parameter-problem, 60 | } counter accept 61 | ''; 62 | 63 | in 64 | { 65 | networking.nftables = { 66 | enable = true; 67 | ruleset = '' 68 | table inet filter { 69 | # Incoming connections to router itself. 70 | chain input { 71 | type filter hook input priority 0 72 | policy drop 73 | 74 | ct state {established, related} counter accept 75 | ct state invalid counter drop 76 | 77 | # Malicious subnets. 78 | ip saddr { 79 | 49.64.0.0/11, 80 | 218.92.0.0/16, 81 | 222.184.0.0/13, 82 | } counter drop comment "malicious subnets" 83 | 84 | # ICMPv4/6. 85 | ${icmp_rules} 86 | 87 | # Allow all WANs to selectively communicate with the router. 88 | iifname { 89 | ${all_wans} 90 | } jump input_wan 91 | 92 | # Always allow router solicitation from any LAN. 93 | ip6 nexthdr icmpv6 icmpv6 type nd-router-solicit counter accept 94 | 95 | # Allow localhost and trusted LANs to communicate with router. 96 | iifname { 97 | lo, 98 | ${mkCSV trusted_lans} 99 | } counter accept comment "localhost and trusted LANs to router" 100 | 101 | # Limit the communication abilities of limited and untrusted LANs. 102 | iifname { 103 | ${mkCSV limited_lans} 104 | ${mkCSV untrusted_lans} 105 | } jump input_limited_untrusted 106 | 107 | counter reject 108 | } 109 | 110 | chain input_wan { 111 | # Default route via NDP. 112 | ip6 nexthdr icmpv6 icmpv6 type nd-router-advert counter accept 113 | 114 | # router TCP 115 | tcp dport { 116 | ${ports.http}, 117 | ${ports.https}, 118 | } counter accept comment "router WAN TCP" 119 | 120 | # router UDP 121 | udp dport { 122 | ${ports.tailscale.router}, 123 | } counter accept comment "router WAN UDP" 124 | 125 | # router DHCPv6 client 126 | ip6 daddr fe80::/64 udp dport ${ports.dhcp6_client} udp sport ${ports.dhcp6_server} counter accept comment "router WAN DHCPv6" 127 | 128 | counter reject 129 | } 130 | 131 | chain input_limited_untrusted { 132 | # Handle some services early due to need for multicast/broadcast. 133 | udp dport ${ports.dhcp4_server} udp sport ${ports.dhcp4_client} counter accept comment "router untrusted DHCPv4" 134 | 135 | udp dport ${ports.mdns} udp sport ${ports.mdns} counter accept comment "router untrusted mDNS" 136 | 137 | # Drop traffic trying to cross VLANs or broadcast. 138 | ${lib.concatMapStrings (ifi: '' 139 | iifname ${ifi.name} ip daddr != ${ifi.ipv4} counter drop comment "${ifi.name} traffic leaving IPv4 VLAN" 140 | 141 | iifname ${ifi.name} ip6 daddr != { 142 | ${ifi.ipv6.lla}, 143 | ${ifi.ipv6.ula}, 144 | } counter drop comment "${ifi.name} traffic leaving IPv6 VLAN" 145 | '') (limited_lans ++ untrusted_lans)} 146 | 147 | # Allow only necessary router-provided services. 148 | tcp dport { 149 | ${ports.dns}, 150 | } counter accept comment "router untrusted TCP" 151 | 152 | udp dport { 153 | ${ports.dns}, 154 | } counter accept comment "router untrusted UDP" 155 | 156 | counter drop 157 | } 158 | 159 | chain output { 160 | type filter hook output priority 0 161 | policy accept 162 | counter accept 163 | } 164 | 165 | chain forward { 166 | type filter hook forward priority 0 167 | policy drop 168 | 169 | # Untrusted/limited LANs to trusted LANs. 170 | iifname { 171 | ${mkCSV limited_lans} 172 | ${mkCSV untrusted_lans} 173 | } oifname { 174 | ${mkCSV trusted_lans} 175 | } jump forward_limited_untrusted_lan_trusted_lan 176 | 177 | # We still want to allow limited/untrusted LANs to have working ICMP 178 | # to the internet as a whole, just not to any trusted LANs. 179 | ${icmp_rules} 180 | 181 | # Forwarding between different interface groups. 182 | 183 | # Trusted source LANs. 184 | iifname { 185 | ${mkCSV trusted_lans} 186 | } oifname { 187 | ${all_wans} 188 | } counter accept comment "Allow trusted LANs to all WANs"; 189 | 190 | iifname { 191 | ${mkCSV trusted_lans} 192 | } oifname { 193 | ${mkCSV trusted_lans}, 194 | ${mkCSV limited_lans}, 195 | ${mkCSV untrusted_lans}, 196 | } counter accept comment "Allow trusted LANs to reach all LANs"; 197 | 198 | # Limited/guest LANs to WAN. 199 | iifname { 200 | ${mkCSV limited_lans} 201 | ${mkCSV untrusted_lans} 202 | } oifname { 203 | ${all_wans} 204 | } counter accept comment "Allow limited LANs only to WANs"; 205 | 206 | # All WANs to trusted LANs. 207 | iifname { 208 | ${all_wans} 209 | } oifname { 210 | ${mkCSV trusted_lans} 211 | } jump forward_wan_trusted_lan 212 | 213 | # All WANs to limited/untrusted LANs. 214 | iifname { 215 | ${all_wans} 216 | } oifname { 217 | ${mkCSV limited_lans} 218 | ${mkCSV untrusted_lans} 219 | } jump forward_wan_limited_untrusted_lan 220 | 221 | counter reject 222 | } 223 | 224 | chain forward_limited_untrusted_lan_trusted_lan { 225 | # Only allow established connections from trusted LANs. 226 | ct state {established, related} counter accept 227 | ct state invalid counter drop 228 | 229 | counter drop 230 | } 231 | 232 | chain forward_wan_trusted_lan { 233 | ct state {established, related} counter accept 234 | ct state invalid counter drop 235 | 236 | # Plex running on server. 237 | ip daddr ${vars.server_ipv4} tcp dport ${ports.plex} counter accept comment "server IPv4 Plex" 238 | ip6 daddr ${vars.server_ipv6} tcp dport ${ports.plex} counter accept comment "server IPv6 Plex" 239 | 240 | # Tailscale running on desktop. 241 | ip daddr ${vars.desktop_ipv4} udp dport ${ports.tailscale.desktop} counter accept comment "desktop IPv4 Tailscale" 242 | ip6 daddr ${vars.desktop_ipv6} udp dport ${ports.tailscale.desktop} counter accept comment "desktop IPv6 Tailscale" 243 | 244 | counter reject 245 | } 246 | 247 | chain forward_wan_limited_untrusted_lan { 248 | ct state {established, related} counter accept 249 | ct state invalid counter drop 250 | 251 | counter reject 252 | } 253 | } 254 | 255 | table ip nat { 256 | chain prerouting { 257 | type nat hook prerouting priority 0 258 | 259 | # NAT IPv4 to all WANs. 260 | iifname { 261 | ${all_wans} 262 | } jump prerouting_wans 263 | accept 264 | } 265 | 266 | chain prerouting_wans { 267 | tcp dport { 268 | ${ports.plex}, 269 | } dnat ${vars.server_ipv4} comment "server TCPv4 DNAT" 270 | 271 | udp dport { 272 | ${ports.tailscale.desktop}, 273 | } dnat ${vars.desktop_ipv4} comment "desktop UDPv4 DNAT" 274 | 275 | accept 276 | } 277 | 278 | chain postrouting { 279 | type nat hook postrouting priority 0 280 | # Masquerade IPv4 to all WANs. 281 | oifname { 282 | ${all_wans} 283 | } masquerade 284 | } 285 | } 286 | ''; 287 | }; 288 | } 289 | -------------------------------------------------------------------------------- /nixos/servnerr-4/README.md: -------------------------------------------------------------------------------- 1 | # servnerr-4 2 | 3 | This machine is my home server which handles monitoring, hypervisor, and NAS 4 | duties. It's a custom built machine with an AMD Ryzen 9 3900x processor. 5 | -------------------------------------------------------------------------------- /nixos/servnerr-4/configuration.nix: -------------------------------------------------------------------------------- 1 | { lib, pkgs, ... }: 2 | 3 | let 4 | unstable = import { }; 5 | vars = import ./lib/vars.nix; 6 | 7 | in 8 | { 9 | imports = [ 10 | # Hardware and base system configuration. 11 | ./hardware-configuration.nix 12 | ./lib/system.nix 13 | ./networking.nix 14 | ./storage.nix 15 | 16 | # Service configuration. 17 | ./containers.nix 18 | ./prometheus.nix 19 | 20 | # Unstable or out-of-tree modules. 21 | # ./lib/modules/zedhook.nix 22 | ]; 23 | 24 | system.stateVersion = "22.11"; 25 | 26 | boot = { 27 | # Use the systemd-boot EFI boot loader. 28 | loader = { 29 | systemd-boot.enable = true; 30 | efi.canTouchEfiVariables = true; 31 | }; 32 | 33 | # Enable extra filesystems. 34 | supportedFilesystems = [ 35 | "ntfs" 36 | "zfs" 37 | ]; 38 | 39 | kernelParams = [ 40 | # Enable serial console. 41 | "console=ttyS1,115200n8" 42 | # 56GiB ZFS ARC. 43 | "zfs.zfs_arc_max=58720256" 44 | ]; 45 | }; 46 | 47 | # Start getty over serial console. 48 | systemd.services."serial-getty@ttyS1" = { 49 | enable = true; 50 | wantedBy = [ "multi-user.target" ]; 51 | serviceConfig = { 52 | Restart = "always"; 53 | }; 54 | }; 55 | 56 | # Scale down CPU frequency when load is low. 57 | powerManagement.cpuFreqGovernor = "ondemand"; 58 | 59 | # Packages specific to this machine. The base package set is defined in 60 | # lib/system.nix. 61 | environment.systemPackages = with pkgs; [ 62 | flac 63 | mkvtoolnix-cli 64 | sqlite 65 | zfs 66 | zrepl 67 | 68 | # Unstable and out-of-tree packages. 69 | ]; 70 | 71 | services = { 72 | apcupsd = { 73 | enable = true; 74 | configText = '' 75 | UPSCABLE usb 76 | UPSTYPE usb 77 | DEVICE 78 | UPSCLASS standalone 79 | UPSMODE disable 80 | ''; 81 | }; 82 | 83 | grafana = { 84 | enable = true; 85 | # Bind to all interfaces. 86 | settings.server.http_addr = ""; 87 | }; 88 | 89 | # Enable the OpenSSH daemon. 90 | openssh = { 91 | enable = true; 92 | settings.PasswordAuthentication = false; 93 | }; 94 | }; 95 | 96 | # root SSH key for remote builds. 97 | users.users.root.openssh.authorizedKeys.keys = [ 98 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP3+HUx05h15g95ID/lWbU5uvF6TLr2XESmthQjU7qvR NixOS distributed build" 99 | ]; 100 | } 101 | -------------------------------------------------------------------------------- /nixos/servnerr-4/containers.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | # These services are proprietary and run in systemd containers for confinement from 5 | # the rest of the system and on unstable for faster update cycles. 6 | containers = { 7 | plex = { 8 | autoStart = true; 9 | bindMounts = { 10 | # Mount Plex data directory as read-write. 11 | "/var/lib/plex" = { 12 | hostPath = "/var/lib/plex"; 13 | isReadOnly = false; 14 | }; 15 | # Mount the ZFS pool as read-only. 16 | "/primary/media" = { 17 | hostPath = "/primary/media"; 18 | isReadOnly = true; 19 | }; 20 | }; 21 | config = 22 | { ... }: 23 | let 24 | unstable = import { config.allowUnfree = true; }; 25 | in 26 | { 27 | system.stateVersion = "21.11"; 28 | services.plex = { 29 | enable = true; 30 | package = unstable.plex; 31 | }; 32 | }; 33 | }; 34 | }; 35 | 36 | # libvirtd hypervisor. 37 | virtualisation.libvirtd = { 38 | enable = true; 39 | onBoot = "start"; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /nixos/servnerr-4/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { 5 | config, 6 | lib, 7 | pkgs, 8 | modulesPath, 9 | ... 10 | }: 11 | 12 | { 13 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; 14 | 15 | boot.initrd.availableKernelModules = [ 16 | "nvme" 17 | "xhci_pci" 18 | "mpt3sas" 19 | "usbhid" 20 | "sd_mod" 21 | ]; 22 | boot.initrd.kernelModules = [ ]; 23 | boot.kernelModules = [ "kvm-amd" ]; 24 | boot.extraModulePackages = [ ]; 25 | 26 | fileSystems."/" = { 27 | device = "/dev/disk/by-uuid/39344788-52df-410c-97ae-027887e10e2f"; 28 | fsType = "ext4"; 29 | }; 30 | 31 | fileSystems."/boot" = { 32 | device = "/dev/disk/by-uuid/726C-3D2A"; 33 | fsType = "vfat"; 34 | }; 35 | 36 | swapDevices = [ { device = "/dev/disk/by-uuid/6e3f67c8-74e9-42f0-8925-d444ada3696d"; } ]; 37 | 38 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 39 | powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; 40 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 41 | } 42 | -------------------------------------------------------------------------------- /nixos/servnerr-4/lib: -------------------------------------------------------------------------------- 1 | ../lib/ -------------------------------------------------------------------------------- /nixos/servnerr-4/networking.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | 3 | let 4 | unstable = import { }; 5 | 6 | in 7 | { 8 | networking = { 9 | # Host name and ID. 10 | hostName = "servnerr-4"; 11 | hostId = "ed66dcdd"; 12 | 13 | # Use systemd-networkd for configuration. Forcibly disable legacy DHCP client. 14 | useNetworkd = true; 15 | useDHCP = false; 16 | 17 | # No local firewall. 18 | firewall.enable = false; 19 | }; 20 | 21 | services.tailscale = { 22 | enable = true; 23 | package = unstable.tailscale; 24 | interfaceName = "ts0"; 25 | }; 26 | 27 | # Tailscale readiness and DNS tweaks. 28 | systemd.network.wait-online.ignoredInterfaces = [ "ts0" ]; 29 | 30 | systemd.services.tailscaled = { 31 | after = [ 32 | "network-online.target" 33 | "systemd-resolved.service" 34 | ]; 35 | wants = [ "network-online.target" ]; 36 | }; 37 | 38 | systemd.network = { 39 | enable = true; 40 | 41 | # 1GbE management LAN. 42 | links."10-mgmt0" = { 43 | matchConfig.MACAddress = "04:d9:f5:7e:1c:47"; 44 | linkConfig.Name = "mgmt0"; 45 | }; 46 | networks."10-mgmt0" = { 47 | matchConfig.Name = "mgmt0"; 48 | networkConfig.DHCP = "ipv4"; 49 | dhcpV4Config.ClientIdentifier = "mac"; 50 | # Only accept DNS search on this interface. 51 | ipv6AcceptRAConfig.UseDomains = true; 52 | }; 53 | 54 | # 10GbE management LAN with bridge. 55 | netdevs."11-br0".netdevConfig = { 56 | Name = "br0"; 57 | Kind = "bridge"; 58 | }; 59 | networks."11-br0" = { 60 | matchConfig.Name = "br0"; 61 | networkConfig.DHCP = "ipv4"; 62 | dhcpV4Config.ClientIdentifier = "mac"; 63 | }; 64 | 65 | # 10GbE NIC tied to bridge. 66 | links."11-mgmt1" = { 67 | matchConfig.MACAddress = "8c:dc:d4:ac:96:24"; 68 | linkConfig.Name = "mgmt1"; 69 | }; 70 | networks."11-mgmt1" = { 71 | matchConfig.Name = "mgmt1"; 72 | bridge = [ "br0" ]; 73 | }; 74 | }; 75 | } 76 | -------------------------------------------------------------------------------- /nixos/servnerr-4/prometheus-alerts.nix: -------------------------------------------------------------------------------- 1 | { 2 | groups = [ 3 | { 4 | name = "default"; 5 | rules = [ 6 | # PCs which don't run 24/7 are excluded from alerts, and lab-* jobs are 7 | # excluded due to their experimental nature. 8 | { 9 | alert = "InstanceDown"; 10 | expr = ''up{instance!~"(nerr-.*|theatnerr-.*)",job!~"lab-.*|snmp-.*"} == 0''; 11 | for = "5m"; 12 | annotations.summary = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."; 13 | } 14 | { 15 | alert = "ServiceDown"; 16 | expr = ''probe_success{instance!~"nerr-.*",job!~"lab-.*|snmp-.*"} == 0''; 17 | for = "5m"; 18 | annotations.summary = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."; 19 | } 20 | { 21 | alert = "TLSCertificateNearExpiration"; 22 | expr = "probe_ssl_earliest_cert_expiry - time() < 60 * 60 * 24 * 2"; 23 | for = "1m"; 24 | annotations.summary = "TLS certificate for {{ $labels.instance }} will expire in less than 2 days."; 25 | } 26 | { 27 | alert = "DiskUsageHigh"; 28 | expr = ''(1 - node_filesystem_free_bytes{fstype=~"ext4|vfat"} / node_filesystem_size_bytes) > 0.75''; 29 | for = "1m"; 30 | annotations.summary = "Disk usage on {{ $labels.instance }}:{{ $labels.mountpoint }} ({{ $labels.device }}) exceeds 75%."; 31 | } 32 | { 33 | alert = "APCUPSOnBattery"; 34 | expr = "apcupsd_battery_time_on_seconds > 0"; 35 | annotations.summary = "UPS on {{ $labels.instance }} is running on battery power."; 36 | } 37 | { 38 | alert = "APCUPSBatteryTimeLeft"; 39 | expr = "apcupsd_battery_time_on_seconds > 0 and apcupsd_battery_time_left_seconds < 30*60"; 40 | annotations.summary = "UPS on {{ $labels.instance }} has less than 30 minutes of remaining battery runtime."; 41 | } 42 | # All advertising interfaces should be forwarding IPv6 traffic, and 43 | # have IPv6 autoconfiguration disabled. 44 | { 45 | alert = "CoreRADAdvertisingInterfaceMisconfigured"; 46 | expr = ''(corerad_interface_advertising{job="corerad"} == 1) and ((corerad_interface_forwarding == 0) or (corerad_interface_autoconfiguration == 1))''; 47 | for = "1m"; 48 | annotations.summary = "CoreRAD ({{ $labels.instance }}) interface {{ $labels.interface }} is misconfigured for sending IPv6 router advertisements."; 49 | } 50 | # All CoreRAD interfaces should multicast IPv6 RAs on a regular basis 51 | # so hosts don't drop their default route. 52 | { 53 | alert = "CoreRADAdvertiserNotMulticasting"; 54 | expr = ''rate(corerad_advertiser_router_advertisements_total{job="corerad",type="multicast"}[20m]) == 0''; 55 | for = "1m"; 56 | annotations.summary = "CoreRAD ({{ $labels.instance }}) interface {{ $labels.interface }} has not sent a multicast router advertisment in more than 20 minutes."; 57 | } 58 | # Monitor for inconsistent advertisements from hosts on the LAN. 59 | { 60 | alert = "CoreRADAdvertiserReceivedInconsistentRouterAdvertisement"; 61 | expr = ''rate(corerad_advertiser_router_advertisement_inconsistencies_total{job="corerad"}[5m]) > 0''; 62 | annotations.summary = "CoreRAD ({{ $labels.instance }}) interface {{ $labels.interface }} received an IPv6 router advertisement with inconsistent configuration compared to its own."; 63 | } 64 | # We are advertising 2 prefixes per interface out of GUA /56 (assume a 65 | # static /40) and ULA /48. 66 | { 67 | alert = "CoreRADAdvertiserMissingPrefix"; 68 | expr = ''(count by(instance, interface) (corerad_advertiser_prefix_autonomous{job="corerad",prefix=~"2600:6c4a:78.*|fd9e:1a04:f01d:.*"} == 1) != bool 2) == 1''; 69 | for = "1m"; 70 | annotations.summary = "CoreRAD ({{ $labels.instance }}) interface {{ $labels.interface }} is advertising an incorrect number of IPv6 prefixes for SLAAC."; 71 | } 72 | # All IPv6 prefixes are advertised with SLAAC. 73 | { 74 | alert = "CoreRADAdvertiserPrefixNotAutonomous"; 75 | expr = ''corerad_advertiser_prefix_autonomous{job="corerad"} == 0''; 76 | for = "1m"; 77 | annotations.summary = "CoreRAD ({{ $labels.instance }}) prefix {{ $labels.prefix }} on interface {{ $labels.interface }} is not configured for SLAAC."; 78 | } 79 | # Expect regular upstream router advertisements. 80 | { 81 | alert = "CoreRADMonitorNoUpstreamRouterAdvertisements"; 82 | expr = ''changes(corerad_monitor_messages_received_total{job="corerad",message="router advertisement"}[30m]) == 0''; 83 | annotations.summary = "CoreRAD ({{ $labels.instance }}) interface {{ $labels.interface }} has not received a router advertisement from {{ $labels.host }} in more than 30 minutes."; 84 | } 85 | # Ensure the default route does not expire. The LAN default route uses a 86 | # much lower threshold. 87 | { 88 | alert = "CoreRADMonitorDefaultRouteWANExpiring"; 89 | expr = ''corerad_monitor_default_route_expiration_timestamp_seconds{instance=~"routnerr-.*",job="corerad"} - time() < 2*60*60''; 90 | annotations.summary = "CoreRAD ({{ $labels.instance }}) interface {{ $labels.interface }} will drop its default route to WAN {{ $labels.router }} in less than 2 hours."; 91 | } 92 | { 93 | alert = "CoreRADMonitorDefaultRouteLANExpiring"; 94 | expr = ''corerad_monitor_default_route_expiration_timestamp_seconds{instance!~"routnerr-.*",job="corerad"} - time() < 1*60*10''; 95 | annotations.summary = "CoreRAD ({{ $labels.instance }}) interface {{ $labels.interface }} will drop its default route to LAN {{ $labels.router }} in less than 10 minutes."; 96 | } 97 | ]; 98 | } 99 | ]; 100 | } 101 | -------------------------------------------------------------------------------- /nixos/servnerr-4/prometheus.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, ... }: 2 | 3 | let 4 | secrets = import ./lib/secrets.nix; 5 | 6 | # Scrape a target with the specified module, interval, and list of targets. 7 | blackboxScrape = (module: blackboxScrapeJobName module module); 8 | 9 | # Same as blackboxScrape, but allow customizing the job name. 10 | blackboxScrapeJobName = ( 11 | job: module: interval: targets: { 12 | job_name = "blackbox_${job}"; 13 | scrape_interval = "${interval}"; 14 | metrics_path = "/probe"; 15 | params = { 16 | module = [ "${module}" ]; 17 | }; 18 | # blackbox_exporter location is hardcoded. 19 | relabel_configs = relabelTarget "servnerr-4:9115"; 20 | static_configs = [ { inherit targets; } ]; 21 | } 22 | ); 23 | 24 | # Scrape a list of static targets for a job. 25 | staticScrape = ( 26 | job_name: targets: { 27 | inherit job_name; 28 | static_configs = [ { inherit targets; } ]; 29 | } 30 | ); 31 | 32 | # Produces a relabeling configuration that replaces the instance label with 33 | # the HTTP target parameter. 34 | relabelTarget = ( 35 | target: [ 36 | { 37 | source_labels = [ "__address__" ]; 38 | target_label = "__param_target"; 39 | } 40 | { 41 | source_labels = [ "__param_target" ]; 42 | target_label = "instance"; 43 | } 44 | { 45 | target_label = "__address__"; 46 | replacement = "${target}"; 47 | } 48 | ] 49 | ); 50 | 51 | in 52 | { 53 | # Prometheus monitoring server and exporter configuration. 54 | services.prometheus = { 55 | enable = true; 56 | webExternalUrl = "https://prometheus.servnerr.com"; 57 | 58 | globalConfig.scrape_interval = "15s"; 59 | 60 | extraFlags = [ 61 | "--storage.tsdb.retention=1825d" 62 | "--web.enable-admin-api" 63 | ]; 64 | 65 | alertmanager = { 66 | enable = true; 67 | webExternalUrl = "https://alertmanager.servnerr.com"; 68 | 69 | configuration = { 70 | route = { 71 | group_by = [ "alertname" ]; 72 | group_wait = "10s"; 73 | group_interval = "10s"; 74 | repeat_interval = "1h"; 75 | receiver = "default"; 76 | }; 77 | receivers = [ 78 | { 79 | name = "default"; 80 | discord_configs = [ { webhook_url = secrets.alertmanager.discord.webhook_url; } ]; 81 | } 82 | ]; 83 | }; 84 | }; 85 | 86 | # Use alertmanager running on monitoring machine. 87 | alertmanagers = [ { static_configs = [ { targets = [ "servnerr-4:9093" ]; } ]; } ]; 88 | 89 | exporters = { 90 | # Node exporter already enabled on all machines. 91 | 92 | apcupsd.enable = true; 93 | 94 | blackbox = { 95 | enable = true; 96 | configFile = pkgs.writeText "blackbox.yml" ( 97 | builtins.toJSON ({ 98 | modules = { 99 | http_2xx.prober = "http"; 100 | http_401 = { 101 | prober = "http"; 102 | http.valid_status_codes = [ 401 ]; 103 | }; 104 | ssh_banner = { 105 | prober = "tcp"; 106 | tcp.query_response = [ { expect = "^SSH-2.0-"; } ]; 107 | }; 108 | }; 109 | }) 110 | ); 111 | }; 112 | 113 | # SNMP exporter with data file from release 0.26.0. 114 | snmp = { 115 | enable = true; 116 | configurationPath = builtins.fetchurl { 117 | url = "https://raw.githubusercontent.com/prometheus/snmp_exporter/44f8732988e726bad3f13d5779f1da7705178642/snmp.yml"; 118 | }; 119 | }; 120 | }; 121 | 122 | # TODO: template out hostnames or consider DNSSD. 123 | scrapeConfigs = [ 124 | # Simple, static scrape jobs. 125 | (staticScrape "apcupsd" [ 126 | "nerr-4:9162" 127 | "servnerr-4:9162" 128 | ]) 129 | (staticScrape "consrv" [ "monitnerr-1:9288" ]) 130 | (staticScrape "coredns" [ "routnerr-3:9153" ]) 131 | (staticScrape "corerad" [ "routnerr-3:9430" ]) 132 | (staticScrape "node" [ 133 | "monitnerr-1:9100" 134 | "nerr-4:9100" 135 | "routnerr-3:9100" 136 | "servnerr-4:9100" 137 | ]) 138 | (staticScrape "windows" [ "theatnerr-2.ipv4.lan.servnerr.com:9182" ]) 139 | (staticScrape "zrepl" [ "servnerr-4:9811" ]) 140 | 141 | # Home Assistant requires a more custom configuration. 142 | { 143 | job_name = "homeassistant"; 144 | metrics_path = "/api/prometheus"; 145 | bearer_token = "${secrets.prometheus.homeassistant_token}"; 146 | static_configs = [ { targets = [ "hass:8123" ]; } ]; 147 | } 148 | 149 | # Blackbox exporter and associated targets. 150 | (staticScrape "blackbox" [ "servnerr-4:9115" ]) 151 | (blackboxScrape "http_2xx" "15s" [ 152 | "http://living-room-myq-hub.iot.ipv4" 153 | "https://grafana.servnerr.com" 154 | ]) 155 | (blackboxScrape "http_401" "15s" [ 156 | "https://alertmanager.servnerr.com" 157 | "https://plex.servnerr.com" 158 | "https://prometheus.servnerr.com" 159 | ]) 160 | # The SSH banner check produces a fair amount of log spam, so only scrape 161 | # it once a minute. 162 | (blackboxScrape "ssh_banner" "1m" [ 163 | "nerr-4:22" 164 | "routnerr-3:22" 165 | "servnerr-4:22" 166 | ]) 167 | 168 | # SNMP relabeling configuration required to properly replace the instance 169 | # names and query the correct devices. 170 | (lib.mkMerge [ 171 | (staticScrape "snmp-cyberpower" [ 172 | "pdu01.ipv4" 173 | "ups01.ipv4" 174 | ]) 175 | { 176 | metrics_path = "/snmp"; 177 | params = { 178 | module = [ "cyberpower" ]; 179 | }; 180 | relabel_configs = relabelTarget "servnerr-4:9116"; 181 | } 182 | ]) 183 | ]; 184 | 185 | rules = [ (builtins.toJSON (import ./prometheus-alerts.nix)) ]; 186 | }; 187 | } 188 | -------------------------------------------------------------------------------- /nixos/servnerr-4/storage.nix: -------------------------------------------------------------------------------- 1 | { lib, pkgs, ... }: 2 | 3 | let 4 | secrets = import ./lib/secrets.nix; 5 | 6 | # Creates snapshots of zpool source using a zrepl snap job. 7 | snap = ( 8 | source: { 9 | name = "snap_${source}"; 10 | type = "snap"; 11 | 12 | # Snapshot the entire pool every 15 minutes. 13 | filesystems."${source}<" = true; 14 | snapshotting = { 15 | type = "periodic"; 16 | prefix = "zrepl_"; 17 | interval = "15m"; 18 | }; 19 | 20 | pruning.keep = keepSnaps; 21 | } 22 | ); 23 | 24 | # Advertises zpool source as a zrepl source job for target. 25 | sourceLocal = ( 26 | source: 27 | (target: { 28 | name = "source_${source}_${target}"; 29 | type = "source"; 30 | 31 | # Export everything, do not snapshot in this job. 32 | filesystems."${source}<" = true; 33 | snapshotting.type = "manual"; 34 | 35 | serve = { 36 | type = "local"; 37 | listener_name = "source_${source}_${target}"; 38 | }; 39 | }) 40 | ); 41 | 42 | # Templates out a zrepl pull job which replicates from zpool source into 43 | # target. 44 | _pullLocal = ( 45 | source: 46 | ( 47 | target: 48 | (root_fs: { 49 | name = "pull_${source}_${target}"; 50 | type = "pull"; 51 | 52 | # Replicate all of the source zpool into target. 53 | root_fs = root_fs; 54 | interval = "15m"; 55 | 56 | connect = { 57 | type = "local"; 58 | listener_name = "source_${source}_${target}"; 59 | # Assumes only a single client (localhost). 60 | client_identity = "local"; 61 | }; 62 | 63 | recv = { 64 | # Necessary for encrypted destination with unencrypted source. 65 | placeholder.encryption = "inherit"; 66 | 67 | properties = { 68 | # Inherit any encryption properties. 69 | "inherit" = [ 70 | "encryption" 71 | "keyformat" 72 | "keylocation" 73 | ]; 74 | 75 | override = { 76 | # Always enable compression. 77 | compression = "on"; 78 | 79 | # Do not mount sink pools. 80 | mountpoint = "none"; 81 | 82 | # Do not auto-snapshot sink pools. 83 | "com.sun:auto-snapshot" = false; 84 | "com.sun:auto-snapshot:frequent" = false; 85 | "com.sun:auto-snapshot:hourly" = false; 86 | "com.sun:auto-snapshot:daily" = false; 87 | "com.sun:auto-snapshot:weekly" = false; 88 | "com.sun:auto-snapshot:monthly" = false; 89 | }; 90 | }; 91 | }; 92 | 93 | # Allow replication concurrency. This should generally speed up blocking 94 | # zfs operations but may negatively impact file I/O. Tune as needed. 95 | replication.concurrency.steps = 4; 96 | 97 | pruning = { 98 | keep_sender = [ 99 | { 100 | # The source job handles pruning. 101 | type = "regex"; 102 | regex = ".*"; 103 | } 104 | ]; 105 | # Keep the same automatic snapshots as source. 106 | keep_receiver = keepSnaps; 107 | }; 108 | }) 109 | ) 110 | ); 111 | 112 | # Creates a zrepl pull job which replicates from zpool source into target 113 | # directly. 114 | pullLocal = (source: (target: (_pullLocal source target target))); 115 | 116 | # Creates a zrepl pull job which replicates from zpool source into an 117 | # encrypted top-level dataset in target. 118 | pullLocalEncrypted = (source: (target: (_pullLocal source target "${target}/encrypted"))); 119 | 120 | # Rules to keep zrepl snapshots. 121 | keepSnaps = [ 122 | # Keep manual snapshots. 123 | { 124 | type = "regex"; 125 | regex = "^manual_.*"; 126 | } 127 | # Keep time-based bucketed snapshots. 128 | { 129 | type = "grid"; 130 | # Keep: 131 | # - every snapshot from the last hour 132 | # - every hour from the last 24 hours 133 | # - every day from the last 2 weeks 134 | # - every week from the last 2 months 135 | # - every month from the last 2 years 136 | # 137 | # TODO(mdlayher): verify retention after a couple weeks! 138 | grid = "1x1h(keep=all) | 24x1h | 14x1d | 8x7d | 24x30d"; 139 | regex = "^zrepl_.*"; 140 | } 141 | ]; 142 | 143 | in 144 | { 145 | # primary zpool mounts. 146 | fileSystems = 147 | lib.genAttrs 148 | [ 149 | "/primary" 150 | "/primary/archive" 151 | "/primary/media" 152 | "/primary/misc" 153 | "/primary/text" 154 | "/primary/vm" 155 | ] 156 | (device: { 157 | # The device has the leading / removed. 158 | device = builtins.substring 1 255 device; 159 | fsType = "zfs"; 160 | }); 161 | 162 | # Don't mount secondary, just import it on boot. 163 | boot.zfs.extraPools = [ "secondary" ]; 164 | 165 | nixpkgs = { 166 | # Only allow certain unfree packages. 167 | config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "tarsnap" ]; 168 | }; 169 | 170 | services = { 171 | # Enable tarsnap backups. 172 | tarsnap = { 173 | enable = true; 174 | 175 | archives.archive = { 176 | directories = [ "/primary/archive" ]; 177 | verbose = true; 178 | }; 179 | }; 180 | 181 | # ZFS configuration. 182 | # 183 | # TODO(mdlayher): sharenfs integration? 184 | zfs = { 185 | # Scrub all pools regularly. 186 | autoScrub = { 187 | enable = true; 188 | interval = "monthly"; 189 | }; 190 | 191 | # ZED configuration. 192 | zed = { 193 | enableMail = false; 194 | settings = with secrets.zfs; { 195 | # Send event notifications via Pushbullet. 196 | ZED_PUSHBULLET_ACCESS_TOKEN = pushbullet.access_token; 197 | 198 | # Send event notifications via Pushover. 199 | # 200 | # TODO(mdlayher): it seems NixOS 21.11 ZFS does not support pushover 201 | # yet; we'll use pushbullet for now and reevaluate later. 202 | # ZED_PUSHOVER_TOKEN = pushover.token; 203 | # ZED_PUSHOVER_USER = pushover.user_key; 204 | 205 | # Verify integrity via scrub after resilver. 206 | ZED_SCRUB_AFTER_RESILVER = true; 207 | 208 | # More verbose reporting. 209 | ZED_NOTIFY_VERBOSE = true; 210 | ZED_DEBUG_LOG = "/var/log/zed.log"; 211 | }; 212 | }; 213 | }; 214 | 215 | # Replicate ZFS pools using zrepl. 216 | zrepl = { 217 | enable = true; 218 | settings = { 219 | global.monitoring = [ 220 | { 221 | type = "prometheus"; 222 | listen = ":9811"; 223 | } 224 | ]; 225 | jobs = [ 226 | # Take snapshots of primary and advertise it as a source for each 227 | # fan-out pull job. Notably a source per pull job is necessary to 228 | # maintain incremental replication, see: 229 | # https://zrepl.github.io/quickstart/fan_out_replication.html. 230 | (snap "primary") 231 | (sourceLocal "primary" "secondary") 232 | (sourceLocal "primary" "backup0") 233 | (sourceLocal "primary" "backup1") 234 | 235 | # Pull primary into backup pools: 236 | # - hot: pull into secondary 237 | # - cold: pull into backup{0,1} (if available) 238 | (pullLocal "primary" "secondary") 239 | (pullLocalEncrypted "primary" "backup0") 240 | (pullLocalEncrypted "primary" "backup1") 241 | ]; 242 | }; 243 | }; 244 | }; 245 | } 246 | -------------------------------------------------------------------------------- /obs/README.md: -------------------------------------------------------------------------------- 1 | # obs 2 | 3 | Matt's profiles and scenes for streaming using [Open Broadcaster Software (OBS)](https://obsproject.com/). 4 | -------------------------------------------------------------------------------- /obs/profiles/Programming/basic.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | Name=Programming 3 | OpenStatsOnStartup=false 4 | 5 | [Video] 6 | BaseCX=3840 7 | BaseCY=2160 8 | OutputCX=1920 9 | OutputCY=1080 10 | FPSType=0 11 | FPSCommon=30 12 | ColorSpace=709 13 | ColorRange=Partial 14 | ScaleType=bicubic 15 | 16 | [Panels] 17 | CookieId=80F26B86D4041C8A 18 | 19 | [SimpleOutput] 20 | VBitrate=12000 21 | StreamEncoder=x264 22 | RecQuality=HQ 23 | FilePath=/home/matt/stream/recordings 24 | FileNameWithoutSpace=true 25 | ABitrate=320 26 | UseAdvanced=false 27 | 28 | [Output] 29 | Mode=Advanced 30 | FilenameFormatting=%CCYY-%MM-%DD-%hh-%mm-%ss 31 | 32 | [AdvOut] 33 | TrackIndex=1 34 | RecType=Standard 35 | RecTracks=2 36 | FLVTrack=1 37 | FFOutputToFile=true 38 | FFFormat= 39 | FFFormatMimeType= 40 | FFVEncoderId=0 41 | FFVEncoder= 42 | FFAEncoderId=0 43 | FFAEncoder= 44 | FFAudioMixes=1 45 | RescaleRes=1080x1920 46 | RecRescaleRes=1080x1920 47 | FFRescaleRes=1080x1920 48 | RecFileNameWithoutSpace=true 49 | RecFilePath=/home/matt/stream/recordings 50 | RecEncoder=obs_x264 51 | Track2Bitrate=160 52 | Track1Name=Stream 53 | Track2Name= 54 | Track1Bitrate=160 55 | 56 | [Stats] 57 | geometry=AdnQywADAAAAAAUyAAAIYAAACG8AAAmcAAAFMgAACIUAAAhvAAAJnAAAAAIAAAAACHAAAAUyAAAIhQAACG8AAAmc 58 | 59 | [Audio] 60 | ChannelSetup=Mono 61 | MonitoringDeviceName=Monitor of Built-in Audio Analog Stereo 62 | MonitoringDeviceId=alsa_output.platform-snd_aloop.0.analog-stereo.monitor 63 | -------------------------------------------------------------------------------- /obs/profiles/Programming/recordEncoder.json: -------------------------------------------------------------------------------- 1 | { 2 | "bitrate": 12000, 3 | "preset": "veryfast", 4 | "rate_control": "CBR" 5 | } -------------------------------------------------------------------------------- /obs/profiles/Programming/streamEncoder.json: -------------------------------------------------------------------------------- 1 | { 2 | "bitrate": 6000 3 | } -------------------------------------------------------------------------------- /obs/stream/banner.txt: -------------------------------------------------------------------------------- 1 | @mdlayher | github.com/mdlayher | Go, networking, fun! 2 | -------------------------------------------------------------------------------- /obs/stream/terminal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdlayher/homelab/667d1eda27a1d3c6e7f08df403bda8c7dd1b63c9/obs/stream/terminal.gif --------------------------------------------------------------------------------