From 1df1bb492b73ee925ca7fee1a827e9f9824ecaae Mon Sep 17 00:00:00 2001 From: Adam0 Date: Wed, 30 Sep 2026 14:17:11 +0200 Subject: [PATCH] Add GNS3 GUI and OpenVPN profile --- modules/profiles/personal.nix | 3 ++ modules/programs/gui/gns3.nix | 77 +++++++++++++++++++++++++++++++++++ secrets.yaml | 8 +++- 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 modules/programs/gui/gns3.nix diff --git a/modules/profiles/personal.nix b/modules/profiles/personal.nix index 7639c7d..0430f1b 100644 --- a/modules/profiles/personal.nix +++ b/modules/profiles/personal.nix @@ -27,7 +27,10 @@ # keep-sorted end # GUI + # keep-sorted start + gns3 seahorse + # keep-sorted end # Services # keep-sorted start diff --git a/modules/programs/gui/gns3.nix b/modules/programs/gui/gns3.nix new file mode 100644 index 0000000..d987acf --- /dev/null +++ b/modules/programs/gui/gns3.nix @@ -0,0 +1,77 @@ +{ + flake.modules.nixos.gns3 = { + # keep-sorted start + config, + pkgs, + # keep-sorted end + ... + }: let + password = config.sops.secrets."educloud/password".path; + profile = config.sops.secrets."educloud/openvpn_profile".path; + username = config.sops.secrets."educloud/username".path; + in { + environment.systemPackages = [pkgs.gns3-gui]; + + sops.secrets = { + # keep-sorted start block=yes newline_separated=yes + "educloud/openvpn_profile" = { + # keep-sorted start + path = "/run/secrets/educloud.ovpn"; + restartUnits = ["gns3-openvpn-profile.service"]; + # keep-sorted end + }; + + "educloud/password" = {restartUnits = ["gns3-openvpn-profile.service"];}; + + "educloud/username" = {restartUnits = ["gns3-openvpn-profile.service"];}; + # keep-sorted end + }; + + systemd.services.gns3-openvpn-profile = { + description = "Import the Educloud OpenVPN profile into NetworkManager"; + + # keep-sorted start + after = ["NetworkManager.service" "sops-install-secrets.service"]; + requires = ["NetworkManager.service" "sops-install-secrets.service"]; + wantedBy = ["multi-user.target"]; + # keep-sorted end + + path = [pkgs.networkmanager]; + + serviceConfig = { + # keep-sorted start + StateDirectory = "gns3-openvpn-profile"; + Type = "oneshot"; + # keep-sorted end + }; + + script = '' + set -eu + if [ ! -s "${profile}" ]; then + exit 0 + fi + + result="$(nmcli connection import type openvpn file "${profile}")" + if [[ ! $result =~ \(([[:xdigit:]-]{36})\) ]]; then + echo "Cannot identify imported Educloud VPN connection: $result" >&2 + exit 1 + fi + uuid="''${BASH_REMATCH[1]}" + nmcli connection modify uuid "$uuid" connection.id Educloud connection.autoconnect no + if [ -s "${username}" ]; then + nmcli connection modify uuid "$uuid" vpn.user-name "$(< "${username}")" + fi + if [ -s "${password}" ]; then + nmcli connection modify uuid "$uuid" +vpn.data password-flags=0 vpn.secrets "password=$(< "${password}")" + fi + + uuid_file="$STATE_DIRECTORY/uuid" + if [ -f "$uuid_file" ]; then + read -r old_uuid < "$uuid_file" + nmcli connection delete uuid "$old_uuid" || true + fi + printf '%s\n' "$uuid" > "$uuid_file" + ''; + }; + }; +} diff --git a/secrets.yaml b/secrets.yaml index e00439e..9bd18a2 100644 --- a/secrets.yaml +++ b/secrets.yaml @@ -113,6 +113,10 @@ anubis: valkey_password: ENC[AES256_GCM,data:Z3vkFpbjSTeBpyZYPyvDAb3wH6hFDmeKUULCkoxqFLbNuNxc4jH/teghDuPR/KhyHGcmZjCBSQ84f1yjKuw8FA==,iv:f27IjYaK6weSS4f+qtQQAnGU+TWRShXHIHo62yS+Wxk=,tag:LB/Cs618F+zSI9OLBET3zQ==,type:str] atuin: ai_auth_token: ENC[AES256_GCM,data:0/pRC4POzBEncrml1OxSPstZ+HeS6PhAgUntEEowGQGQht2BCSABRa/nxjYUGnadve6/gHEseRzgzGUgmS2sbg==,iv:MFvLfywu68YgzGJoqUzz1SHpABqqUw2t2e0EFOEAQ3I=,tag:4hLLBFzZCTseR0Z9TXfbXw==,type:str] +educloud: + openvpn_profile: ENC[AES256_GCM,data:VPLME75WyVhWlS/YSJ9bZQtaNUZfxZmWa84b+OrLB8szIq+P29ls30YxMztmqxqIrmXVxZrOQWj6uF65d8AwCqG8XAZHPSJvkTBdpyXXptCY7yZyr0az2m5siPRIS0ZnPoUlel4tXFqm/5jh4rPmWnlLtyJ7jhFBP/2yjCbGP8/KX5SxcTwwvrx7RfUBGl9UCfH9/ZR4GXWa70VtsXSUl3XykUf+BV2kff7FCrqyG0twUHOpCa7ZdLp6e0Qg1GwGOuo0Sc/M3iTB/snIfvnZexqyfb1rYpQCdKW+pC5c14rbE5X/7hnTgJwkjsNI4k+MbCXPeSfdYNXVLre5OhK4rrgidrljkSWh+tKLzOlKJp0ODIP7QXKyPx6K4CTXXjTTlekYCDoVGbhm1azQxVNgb7+d8J/eg9sLz0dtDSSZaFxfoM1NdjJ/zmPKti+ejIMxDj0Y/QTwU52pqm7MDKf9u0Y06Lhp/JapredQGhb3YBXSKFhtGjVruolnwIQ7PTQ1uCxpSUbaH8GvJOQCyXqV2s0Ll5Ynj5Xm7H4Nn8U/6ETP7y44m235FTllGSH+iaO/dYz2RkR6P3uf2nCwuteA05l0Ro9axqst55+9uNSx6hJ+EkB6snyxebk6+bXEpaXygsLyU0uZjLccXiyeIvSoXUvbECW2RqL0O7zHxW4viqt1SUVX8ca7ZESJveun6BlgghE4Wlwfc0saaoaJINZfbVN+UUOHeDrjYauMD+TjO5mYEgvKlckJorDdPIY7QXhXJ2etID64MBIpiSd/FxHHjqx3NgpmBc2LW+NEIIl5O2U0gOpA7jwIDrtk1xpYZeohTCgiGxvmSGTX0kqBS/kyZ6ZE3zWAtvycPoj5OQ2G/zFB3lGqbZDhrLX1c8LGY8cLOkDySboiRqnI5jMhWv71sS1RNfgLiJlv91gND7pRKz5ntIQBS+yNGcgtQkh3S2sqvGRGEmX57U7lasRFce8pz4wQDtHmG0L3y/frCWpbSFpffpYiQ6Fd+I/11bstd7mozREz1ysCOvXijnx5AIo8es0rtvsTPHLCCl9aGOsvmThdxFg+NQOg9eeUE1PJp6oD3LMjk4wNWpJl0Ht/6WhpDask8DoQ4GjTxIjCMXUVQ2BhnQCwmQfG6pA6xN09DPBdgfXtKpYeLgl5AyRB9tMH754/HPZ5dWAritHWKywznLgKRAaK0kia0tgt6m/+w9NdlgAbz2JBa6JhUFRYVEzCaIM+Lsgowl0J5EyWrcNuU+Fw9wI9HPKUiQ0FJVMj+SnxZfiEpqbr1EEbFrfJuIw+ozoKLcXkwYNvwPjEduqAiDyJgfHD5uLshfJ02EkOKxN2w8sKEmkwC2BId042rFakfr1vDfWLx+wmNtIODi5JU/xA7EBtIR79krGQSujK4aUrsnfyzg0apu0bwumNjdDKyG1ziNnPVgHTATYy8M+bP5fyaEThVecAYi6VTQb61WmM2HJ56kGy08ij0kxaZ+IhnRMSfZgJBVTP58O1qvwqr97vSkHHCHR/RHD4UvB7C5QCk1+R33xwPP4oD66msVguk6osZ5nLtAB8OwHapd3kcw46ON3FzbSHbg7Edh7PxCWhlV9nIEOSWonscmwh5bIvtmW2//lLdwWCIB4+Ogah6WOrZ4FqMHzj2bPsORIkpjzkoI7PkQvWGzhq6w2+uxaxefm3ClvFMHlaGCaQQoWoD9Sv7NcRBxnR5Hc4d7vHTWGBYmssxn1mLEKhN9Vk7nWMrblTRls8O+4P1dtnngU2zUsUGGiHmWucgpghC/0hM59vATbbTHjUPPoDvIkno+iny+dZmi6FkB7Q7O1JXZnExE0NRgxTE7Oq6nxTfAWxox1umeUm7/v1v99NePXjTxjLxTVMb14hJBlwi27zw/lPRQVciL591VTto3AK3sKM/coyvHsuOKkXt60EAYwWqZoydZ4eJyA1yaGTp40wgI8+RRSQNZFfDp3wtvonzb3xzI1Ie99PMN2QwX7RdeD8agGpGy3JcFJPi/rRRS8NjtZjZMQF3jtcyabjrwAsikO4Iq/bE4Yqaktg+pfU5s5uRixtWSlqQkEnWFYFLpCbvEwkqdW2BlfU5gXWtr2mnvSgRX3DZFC8a0NK+xzjCFQo4SrJd0vxC9AgoT3CG8QNIBnCDs5e5bEIy8RzjzTcpW7e8iOEjR9U2hSOr+/CMxy0rDarY+mhN1+mm80HlEKMtCIFpOi/JPgobT4rKZbi3QynIl58kuSMefvyTP0EhdQIcfuCOnS15wiXGBfM9u8n3fmF2a01/Vmg+QrVFcaU8nopdfugnhqSZ0RahmSvXS8TQVmkx19DCS4U+yJOk+xyhLmyaiXs+XacQ+SFgVeSqO7v+dMmdoDzZftHy5Is433c3kulSerIT5rHd8CAMfe0G1pTAhw7Hy4ZPWzBDj04RvumM46CTvrqL05HK+chqaS1V1GWZ8SKBRwGOjtZ5UMSu35NO1qPrCwruLqbta5MSfCHXDE5NprAngEQy6kVS2HK3soDexlvbK2s4L3Zqyz9zQQ6YhRfM/Vinp80g4T7EO9J7DHa6ErUPxDV57HEhvWYTv7kfIjZDuJ/AFhwyVUNaTBEYv7cSbOQnOxK6hyC8B1gQ4i8SJp/TCP8mbgO8PzdbgASe1lNb8KJUEcfZIWo2mYP/nHwuEUP5sToczIEJVbNMQnGyA+C4c6bOvwjTDhALh1Z+bS9CxAsmltJxOkgkd62tIa77GA70T2H75nifwdtO0d8nXYHiOqicqBGMMg1SU0ZdpoiQUGfUZ5XmMYvWG0e+hoLSxlDTB7pE/HkyCYu/BNvhZvTRVtlc4vLm+MNx8Nvwyfor/+dkm+LHjppUGoD7jXsgGn8ATyTS0YHYKiliV5ltCD0WSzZzeBhgO4TrrZ2YxWJH81DRRwBwt350rMGp16fjWv2kH7jmfvkuO2PQnoKhPQwqnWUt7/Elv24kP1qbc5aadUUYn+O1J5QiuG/ht01dlqT0+JfJHOyGDfYITqjBOPahEIgAeDmO0cqTt/CM2Hfbr1FCOmNZ6Q8NB0da4iOTOwbSJv1v6LDKn/kTmknVwiW9FDtiY9xsHTZ8Ul0RQAoPJNurqy9cMgLZW4seOcwNSsFeWW4PFbJYLypK6RHnBuq5af3/c2OKOZEKSak4aZdHwjIZebcgLd5ytbljlpXe21obg0jSG3RFj8RqOGNCSg52C7+Rc2YvDDfmjRgx+7VBW0xAQVGa7nQKMX3/YZeegM2/90NmvSKDn8y26rQFG7CRm6UGeaeZJmTlKehrVdh8PVNz8+b8wLSMftnlX5avr4J2I16xlSbg9EGlBBAHXtuAaJp8yUgtAl9WxNKZn9WuwofKTrn3Lvx6a1tzrpVPAg54r16FWVZUnToqUhNiuaGADrBGHfon9do,iv:aMcu9vX102JVH/lIH0oKjCs3/if7/8xXP4YF3/GmirQ=,tag:SpoJ1vseoN9TcsLEjpN9yw==,type:str] + username: ENC[AES256_GCM,data:RQL7EHO9QQ==,iv:TOAF2Ix/W8Ij4ndKIT/rjukbRlEY4EJs1LWOhS/jGNk=,tag:UHHimYrXwgRXhJbtWT8V7g==,type:str] + password: ENC[AES256_GCM,data:CiM8wPhD2hMjLLpxm+u/FuETn+v9H4E5IFQ+K4NcUGkUkAGgdWC0EeD0JpFi/FcmCIKKXtP/zehD6fkfeAte1fBAhKxtghPS1l0BZaGSXAc2uCda6cmTTCglTmdB94JCJ79tyPCdTr18NCciW5WVNcp4m3GDQM8hz3fxG2QOMZA=,iv:fMFuAVhsTYjfQSKXtAvYT0jREmyogpINrQPyC+yfM0E=,tag:cYeJLXD47vq94yn12PyMgQ==,type:str] sops: age: - enc: | @@ -151,8 +155,8 @@ sops: w2ToACYVigKMSlqPNG9bKcK75XI/iAONG48DQm1Nse3yB9/q3jwd+Q== -----END AGE ENCRYPTED FILE----- recipient: age1yl52c6aemw9anmfuqayamvsnkvlu6fmy0kk3gzvrraexxd9pr90qvs8pe5 - lastmodified: "2026-09-06T07:34:36Z" - mac: ENC[AES256_GCM,data:QrHMGfTSqZDHPgu0Wo+eFsS37dXGyejTcWN23ldlMMcpIfIV2ogIcyvdAmcIPfzRkL+6oV1J+tnvzltMN5c5LS2gPEadpidk4BMp4G3ALb/V9HcNGdnLH6/gTGscSmwMFx03lzUCZYNjoqQb1vjUo6mZiHsaHfXVGE8jt2pB/kk=,iv:z9ZdQsl/JwdrHxuveHht1hzB0PGBEipjrgAyUMMKigY=,tag:Iu1aAgCmdP/W1gMzj0rJhA==,type:str] + lastmodified: "2026-09-30T13:23:56Z" + mac: ENC[AES256_GCM,data:TAQEizibaVv1dE7ZBNMxEYMYpHGJ0hT2agzCS3YIoWNMPnGXBnN0UJYdWVL38AcN6LUFIqp7Qa8twPnKxDoDGkcgFHioj5Y6JouzncYAgDMFCo4bGl5w73wJxG3CaOYBeFVgfN1IpFJqq/YiQ8vSAq6I0UYILKEEtLh5f+55uFg=,iv:ZpETqfbQvMAuN15AeM0L9o7IHfINHMwTr/x1yLd493U=,tag:2nVjAsqbIoX+2p7n03BYZg==,type:str] pgp: - created_at: "2026-06-02T01:50:38Z" enc: |- -- 2.51.2