From 42cb10cb5bdd66ff9404a7e16bc86d133ff1168f Mon Sep 17 00:00:00 2001 From: Bert Proesmans Date: Sun, 4 Aug 2024 12:54:45 +0000 Subject: [PATCH] Finished secret tooling iteration - Completed move backwards to yaml secrets REF; https://github.com/Mic92/sops-nix/issues/604 --- .sops.yaml | 16 ++--- nixosModules/hosts/buddy/keys.encrypted.json | 20 ------ nixosModules/hosts/buddy/keys.encrypted.yaml | 21 +++++++ .../hosts/buddy/secrets.encrypted.json | 26 -------- .../hosts/buddy/secrets.encrypted.yaml | 21 +++++++ nixosModules/hosts/development/default.nix | 8 +++ tasks.py | 62 +++++++++++++------ 7 files changed, 101 insertions(+), 73 deletions(-) delete mode 100644 nixosModules/hosts/buddy/keys.encrypted.json create mode 100644 nixosModules/hosts/buddy/keys.encrypted.yaml delete mode 100644 nixosModules/hosts/buddy/secrets.encrypted.json create mode 100644 nixosModules/hosts/buddy/secrets.encrypted.yaml diff --git a/.sops.yaml b/.sops.yaml index 1213552..168bb1f 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -15,10 +15,10 @@ keys: # ERROR; Age's extension for Yubikey derived age-keys is not yet merged into sops! # REF; https://github.com/getsops/sops/pull/1465 #- &yubikey_bert_proesmans age1yubikey1... - - &development age13s286le0puqz79e96zkpxw9pwuv9jqvgptd4k2j0n257jvgpp5qs75nejw + - &development_key age13s286le0puqz79e96zkpxw9pwuv9jqvgptd4k2j0n257jvgpp5qs75nejw # HOST KEYS - - &host_buddy age14an6m226h8vu06nv5q83s7vl59ytq8j9dkaujvrwgsdj98kr0ukq0a5k0g - - &decryptor_development age1rwl0helkcqtlx6fevquwzlw354tu87fg3tmv4gzlwsraz2ttpu0q0h2dqt + - &buddy_decryptor age1c27gckzuezcu4cqf7ksakksnxm4k694kjslysysas80jctjuwevsgd0ew3 + - &development_decryptor age1rwl0helkcqtlx6fevquwzlw354tu87fg3tmv4gzlwsraz2ttpu0q0h2dqt # NOTE; These rules are in effect when using the SOPS CLI. # Both creation of- and running the command updatekeys will modify the key material of files with sensitive content. @@ -29,14 +29,14 @@ creation_rules: - path_regex: hosts/buddy/[^/]+\.encrypted\.yaml$ key_groups: - age: - - *host_buddy - - *development + - *buddy_decryptor + - *development_key - path_regex: hosts/development/[^/]+\.encrypted\.yaml$ key_groups: - age: - - *decryptor_development - - *development + - *development_decryptor + - *development_key # NOTE; No path_regex as fallback option # @@ -44,4 +44,4 @@ creation_rules: - key_groups: - age: #- *yubikey_bert_proesmans - - *development \ No newline at end of file + - *development_key \ No newline at end of file diff --git a/nixosModules/hosts/buddy/keys.encrypted.json b/nixosModules/hosts/buddy/keys.encrypted.json deleted file mode 100644 index 254cfa9..0000000 --- a/nixosModules/hosts/buddy/keys.encrypted.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "ssh_host_ed25519_key": "ENC[AES256_GCM,data:UhPlhOsVCtIh1eqEaKPmWEOa3avmsMp/cGq6d26wVaGdAFsISWLQILfpizyw0+gU7S+n1sUdxFRjE+ONpR61DIbdleoRt3PSkJzNStGJck2upuJJdkMytUznzKiWkF2JECQEPqpjoL40E4VOqAa3Pr40MlJ1s2v7xl7zT/hzt0Vx36cHDJm28qx+yPIKUSGzONP1t4QdzV2s//zQ4aIajethYay3X6EWFvIv3I7Uwdbt2rWgJiZ2ga4CcMK+AWEeNOlwTuFx5N06AIkpStESKi9oCFc7CU84AoopmW52c/0RY3li6JTkLHp+E+i8kCrAJ8e6fOOGMQ1pt1asPX6bVAMwCcV+j2MEe+A+YKENIAObLZTQoQUTw4rAUqvVDFreoIRtKbkxO2TnQK1/cW7gj5ULwUzfU8hwFwTOm241WWdMCyWgJg2yo64ids/xMn2T4+Sv/1NHi/6H5XHzFMRVq81TKy6UvFW3LEfppLn11TsYfR9pE87LGGObS6VETWB8/deIc+DrWDUVMYCopyD5abo8mQHBZaNlhLf80l6KOL4OcAFBN3gry9O+5+ifUH+KqdkosPydCMbxIzc=,iv:WWt9ku9d7Qb3D/EkezOYSd8z+Pl2g/m9eXGfJm0GkZc=,tag:eCj6rz4B6WLFa7WFDGAlgA==,type:str]", - "sops": { - "kms": null, - "gcp_kms": null, - "azure_kv": null, - "hc_vault": null, - "age": [ - { - "recipient": "age13s286le0puqz79e96zkpxw9pwuv9jqvgptd4k2j0n257jvgpp5qs75nejw", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtVmFQNGdLME9scTFKaTlO\nSksvZXZlYXBNbFlCOTJEeDBsQmhWM1dheHlFCnk0UUxDVTJhbUV2ODcxVS9tQkVa\nWHJSUHQ1UFZzYlRzSVJ1dW15TGhhd1EKLS0tIEUxMnk4KzRsWWcvTTVQczBXcmpW\ndDVWdThEZE5wTzZkSWdCa2I2L3VsazgKXuiWiKap3OgHAziyEBd3mQtwM2Ash3r2\ngAoWMYCTZkzgfXKU7k63WNblqZNxXMJKoswTszYkDCC5kORVZcrCVA==\n-----END AGE ENCRYPTED FILE-----\n" - } - ], - "lastmodified": "2024-07-28T13:04:42Z", - "mac": "ENC[AES256_GCM,data:tmRSe3MaixBn0XvtiqDJaOf4pvmORhIAp2FG/Ijic/DtV+oSlU0/TIicOr0HkxPuf5b9uVTqRf2E3WfJtgMm4deBsiloQ7dySwCHxxBXcsElPyz+/k/3hl82MNuwllgeXm8FIhv8aROamg7TPRjf7423IcCA9FnEWL1HzvLf51g=,iv:YKpS5UrQfHT5ybhGR+X7otZopC+LeVvN5vra3jsvGmk=,tag:GNnhT8JJbE22GHCrILArxA==,type:str]", - "pgp": null, - "unencrypted_suffix": "_unencrypted", - "version": "3.9.0" - } -} \ No newline at end of file diff --git a/nixosModules/hosts/buddy/keys.encrypted.yaml b/nixosModules/hosts/buddy/keys.encrypted.yaml new file mode 100644 index 0000000..536ec77 --- /dev/null +++ b/nixosModules/hosts/buddy/keys.encrypted.yaml @@ -0,0 +1,21 @@ +buddy_decrypter: ENC[AES256_GCM,data:mrtScK491/dADqn2QE9pzh87Fw5Ck9BSjKQHpaWObZ9UNG00UviuqiRvAU88uekciN0rtb+SOMY7Iyp3e6Gu6GGwhzxVcA+igQHG5vUL7Jgkz9mDvUkmh869x+hoyH41GkZqjHBDu3d1P7HkMGGj/8uZx1MW8atZJopU8MnlYWQ6jNmeL5M7aH6FWKMXtXmAxdtEi8mrip2e/PtGDnIL9mM813Rw6e0dE44chpfSrMogy4nRW1jt,iv:zcPIrJeRTXooyaKceZzGUi7/NK93zxOs7x7ihEXksfY=,tag:i54ZhU0Of5L+5K0ha+ICTw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age13s286le0puqz79e96zkpxw9pwuv9jqvgptd4k2j0n257jvgpp5qs75nejw + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxSk9Cc3BQZXMyNkJVZ1lO + aUJhcSsvWkl0eGN5QWFpRlppS3RTWmlIeEFJCkxUNlhPTGFyQm0rRDdvdncxWlZx + WGIvcDc5K3NFOWEwNFNla3QvSVd6dTgKLS0tIGpKM3d1RnVXdjZQbFRtV2tyc2h4 + OUpOV0V6U2FtckNoS0JHSlNDTEYzTTgKu3CB3muX8XNefBzI+Ydn1Da5kERepERp + 1pJDoNwMqGyoilmlDtNEIu7W3gTnRCpPoddSqr/xhaueXqW89qj9cg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-08-04T12:32:10Z" + mac: ENC[AES256_GCM,data:zruU4w37DOsArIPpx5BOXH6pzRFEl07+UUe75GdEEXuE9b6qvcKaGzC0DOMCQvYzssK05Ikxj9LU34Sc/W96hhgw+772s9ZSe5XaSBlykN70Q64k7b5IVqKXa+/6qJp2nUgCQE1f9bxKqq0ITsHJMRkU35rZWojRlCFA6ao9eDE=,iv:eM5fdRxd6ZwejUzeft66C+Ln7bTvy28FhWLrm5VARYc=,tag:mDMOnzFwJrD9Eo242sjnbA==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.0 diff --git a/nixosModules/hosts/buddy/secrets.encrypted.json b/nixosModules/hosts/buddy/secrets.encrypted.json deleted file mode 100644 index 0beab51..0000000 --- a/nixosModules/hosts/buddy/secrets.encrypted.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "auth_container": { - "kanidm_ssh_ed25519_key": "" - }, - "sops": { - "kms": null, - "gcp_kms": null, - "azure_kv": null, - "hc_vault": null, - "age": [ - { - "recipient": "age14an6m226h8vu06nv5q83s7vl59ytq8j9dkaujvrwgsdj98kr0ukq0a5k0g", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5elVBYjdLT1QvWkVsQWp5\nUitlWlZTdElwaWpmWVhDRCtHTG1FYnNqSlNBClRzaFU0QnVCcDhiSHZGVmV3bXBB\ndFloTFI5QjFPbWM4R08vaWoxeWNjd28KLS0tIHdzdkg0UXFBTG5RQ1BxZHF3L3E5\neUJ3anlqMXp2NHQwdnN4Sk5PUXdFZFUKYmI4RdjE8r/hhgQQsDbwtxFxxJ+kLO1F\nEP/w1wEqx0fqrfnfgKceU8bZj6uC60+wM8Gn+/dGcPn1uKdUfaEdAg==\n-----END AGE ENCRYPTED FILE-----\n" - }, - { - "recipient": "age13s286le0puqz79e96zkpxw9pwuv9jqvgptd4k2j0n257jvgpp5qs75nejw", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBad0hYM0NCOEJBNFlWdS9F\nb1NFaFJ4WmxoSzZmck1tK3pZZnpGbitRNkFFCjhNWTU0WmFSemRIczl2TjJDT1hI\nK3RjOU1xa3BqSnBYeWlPUlc1M0hUN0EKLS0tIDFZbGRCYjNUaWhGNC9ZNFJ1Rmsz\nWWQ0bGV0V3kzRzhqbHZmN1VackxzOTQKVK6ohHLlelz/Db7PzalhVTrpKz8UUgZo\nG2UpiHiQ5MzXx/mQR/AHXmLQtsEiO5MnU6Wpqf1iSKhYpNdddyPFEQ==\n-----END AGE ENCRYPTED FILE-----\n" - } - ], - "lastmodified": "2024-07-28T13:06:01Z", - "mac": "ENC[AES256_GCM,data:Hb4nlZArazGr8lw4g6JkOnI9o7U7AGCh+96zYrj6q0RZf+OvVPB/7r7sU7DzUfBkProLPruBi8+DHgjY03YBJe54/mu8vYMI7dR9iuvStp6X0HPDfZHIyth00venJ54kSAzYP4knIaNePCOu7pYZ2DeAf6I1ndf8IVbv1kSjPaI=,iv:w1ttTEsr5Ikic0NUAQBx7DlCvDvl2XOQF2dfMJlNA6Q=,tag:l3rL/UZniKXtsFUlfJje3g==,type:str]", - "pgp": null, - "unencrypted_suffix": "_unencrypted", - "version": "3.9.0" - } -} \ No newline at end of file diff --git a/nixosModules/hosts/buddy/secrets.encrypted.yaml b/nixosModules/hosts/buddy/secrets.encrypted.yaml new file mode 100644 index 0000000..4ba9aa7 --- /dev/null +++ b/nixosModules/hosts/buddy/secrets.encrypted.yaml @@ -0,0 +1,21 @@ +ssh_host_ed25519_key: ENC[AES256_GCM,data:0S1p/xEAJeUgrbpmVF1VC08TlRI+qlTJdZYf4jkvK63gov8+DFqs92mh1WTsyuZWu04PQw2Nz8SLXEg2VvJooXwFlblqc6vuBl/UwVZuDCwMgAl6BIP3Ja1ljCBzCdP5IOjpPsHrpH2cVxZ4HmznZNEkJkhdX2AnSnd2NV/kiCopmmUdRlLrmSL1uP1xEUmkMUWhKO0W4NbMHGl6njmQLhQNPodzhQwrTcEK5JZFQCn1DkPQAyKPA28TuaI+XM7gAX8Wer4IIcW3fWc0uxMZB1snzD+HH1/kEI32xHZmIbKprsV0tXJhkxPtk/P5ZN8X331PB2ycivULOTnMMoVZ04dmPip0yFhvV2lO+oJjDJIc0zp0CwOwgNRipwkT24Lwx/5XnNBo/QolIFFWA2Xe7ue8VG296PGDamUfcsDBMDwN5UknF77wfg/AXQBxZtU5IhhK/UzaoB/kniec8xOh5urmb4ISTqsOTyvKkjF6NE73llXIuy1K77zCMar1/YvunnK+ZzoczAFRK211uRutEhIO6ruUMBiTTcTwlie7PWJKMBo=,iv:bjqm6HIohTysvLYJQofHkQ/yRHwkc0qucAbH7wheO6c=,tag:2/pGxwUKGIsq8pixurY3Sw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age13s286le0puqz79e96zkpxw9pwuv9jqvgptd4k2j0n257jvgpp5qs75nejw + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxM2tDRjM5eldtVmYzYnl0 + ZytkemxDZmw5Tkl6QXN1OEVvRFVvcXdsdlNNCmRkb0QxcVpYS2RPOThrRmZha21R + cklpTStndlpOSWdjQ2JRbjNjWWVrZlEKLS0tIDVYOHJ6ckI1aDI4aWsxSWNLMDFO + aktOMVBTVDlrU3VEZk1hY0ZxcVl6ekEKU3Qax3MPVGyzFF0hJNTpl0YIw8XJmhai + R33YySG56117l+x8bT63IlcJAx76bPRiVXWAGB4a2RPug1RQ5USxUw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-08-04T12:37:45Z" + mac: ENC[AES256_GCM,data:fi/5VJPlzRP7FFPWbio/SC97yYSMypats9a/Ko+WBYfgl0Az/zAQFDu+Q9zaAp7C2izog6N77cCy27GTL9VUQeMNYbRaUyPywfcR16w/fn2MzTn32QAIaLS/mfxoBELs6cDLPos767N7ebi7OlqT+qBigAdSk3zNKYAjPnVEQOg=,iv:+tSjMMeGGlc5cvF2j15CC63oCrWJKghVU0FAlEcJ1Uo=,tag:XOlSyy2edtM1e//3EBf9cw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.0 diff --git a/nixosModules/hosts/development/default.nix b/nixosModules/hosts/development/default.nix index cce8717..731e49d 100644 --- a/nixosModules/hosts/development/default.nix +++ b/nixosModules/hosts/development/default.nix @@ -201,8 +201,16 @@ owner = config.users.users.root.name; group = config.users.users.root.group; mode = "0400"; + restartUnits = [ systemd.services.sshd.name ]; }; + services.openssh.hostKeys = [ + { + path = "/etc/ssh/ssh_host_ed25519_key"; + type = "ed25519"; + } + ]; + microvm.host.enable = lib.mkForce true; microvm.vms = { test = { diff --git a/tasks.py b/tasks.py index be5bc62..2dd53da 100644 --- a/tasks.py +++ b/tasks.py @@ -32,6 +32,21 @@ def default_decryptor_name(hostname: str) -> str: return f"{hostname}_decrypter" +def find_string_in_file(file_path, needle): + try: + with open(file_path, "r") as file: + for line in file: + if needle in line: + return True + return False + except FileNotFoundError: + print(f"find_string_in_file: The file at {file_path} was not found.") + raise + except Exception as e: + print(f"find_string_in_file: An error occurred: {e}") + raise + + @task # USAGE: invoke check def check(c: Any) -> None: @@ -43,22 +58,13 @@ def check(c: Any) -> None: @task -# USAGE: invoke check -def format(c: Any) -> None: - """ - Format the source code of this repository. - """ - c.run("nix fmt") - - -@task -def update_sops_files(c: Any) -> None: +def sops_files_update(c: Any) -> None: """ Update all sops files according to .sops.yaml rules """ environment = os.environ.copy() environment.pop("SOPS_AGE_KEY_FILE", None) - environment["SOPS_AGE_KEY"] = decrypt_dev_key() + environment["SOPS_AGE_KEY"] = dev_key_decrypt() subprocess.run( """ @@ -75,7 +81,7 @@ def private_opener(path: str, flags: int) -> Union[str, int]: return os.open(path, flags, 0o400) -def decrypt_dev_key() -> str: +def dev_key_decrypt() -> str: assert DEV_KEY.exists(), """ The encrypted development key is not found next to the tasks.py file! """ @@ -134,7 +140,7 @@ def deploy( environment = os.environ.copy() environment.pop("SOPS_AGE_KEY_FILE", None) - environment["SOPS_AGE_KEY"] = decrypt_dev_key() + environment["SOPS_AGE_KEY"] = dev_key_decrypt() print(f"Decrypting AGE identity from {encrypted_file}:{secret_name}..") age_key = subprocess.run( @@ -219,7 +225,7 @@ def secret_edit( environment = os.environ.copy() environment.pop("SOPS_AGE_KEY_FILE", None) - environment["SOPS_AGE_KEY"] = decrypt_dev_key() + environment["SOPS_AGE_KEY"] = dev_key_decrypt() result = subprocess.run( ["sops", encrypted_file.as_posix()], @@ -237,7 +243,7 @@ def secret_edit( @task # USAGE; invoke create-ssh-key development ["secrets.encrypted.yaml"] ["ssh_host_ed25519_key"] -def create_ssh_key( +def ssh_key_create( c: Any, hostname: str, secrets_file: str = "secrets.encrypted.yaml", @@ -320,9 +326,18 @@ def create_ssh_key( check=True, ) else: + if find_string_in_file(encrypted_file, f"{secret_name}:"): + warnings.warn( + "The secret name is found in the encrypted file, it's very likely we're gonna overwrite existing data" + ) + if not ask_user_input( + "Do you want to keep going and possibly overwrite your encrypted data?" + ): + raise ValueError("Process canceled as to not overwrite data") + environment = os.environ.copy() environment.pop("SOPS_AGE_KEY_FILE", None) - environment["SOPS_AGE_KEY"] = decrypt_dev_key() + environment["SOPS_AGE_KEY"] = dev_key_decrypt() subprocess.run( [ @@ -342,7 +357,7 @@ def create_ssh_key( @task -def create_development_key(c: Any, name: str = "development") -> None: +def development_key_create(c: Any, name: str = "development") -> None: """ Creates a new development key, password protect it, and store it at path {FLAKE}/.age @@ -354,7 +369,7 @@ def create_development_key(c: Any, name: str = "development") -> None: @task # USAGE; invoke create-decrypter-key development -def create_decrypter_key(c: Any, hostname: str, secret_name: str = None) -> None: +def decrypter_key_create(c: Any, hostname: str, secret_name: str = None) -> None: """ Create a new AGE key for encrypting/decrypting all secrets provided to a host. """ @@ -412,9 +427,18 @@ def create_decrypter_key(c: Any, hostname: str, secret_name: str = None) -> None ) return + if find_string_in_file(encrypted_file, f"{secret_name}:"): + warnings.warn( + "The secret name is found in the encrypted file, it's very likely we're gonna overwrite existing data" + ) + if not ask_user_input( + "Do you want to keep going and possibly overwrite your encrypted data?" + ): + raise ValueError("Process canceled as to not overwrite data") + environment = os.environ.copy() environment.pop("SOPS_AGE_KEY_FILE", None) - environment["SOPS_AGE_KEY"] = decrypt_dev_key() + environment["SOPS_AGE_KEY"] = dev_key_decrypt() subprocess.run( [