Say you have a script or something that gets run in cron/task scheduler and it needs a password… say to ssh to a raspberry pi elsewhere in your house.
How do you save that password in a way that automation can access it?
Some ideas:
- Plaintext file. Not a fan because its sitting unencrypted on the box somewhere.
- Environment variable. Not a fan because its still unencrypted somewhere to someone on the box (albeit likely the same user or an admin).
- A secrets manager. If I use something locally like hashicorp vault or infisical, I can get to a point where a cli/api call gets the password. Though in this case I still need a vault password/secret to get my password. So I fall back to needing one of the above to get this to work.
If the secrets manager is easily available, the secret to get into the secrets manager is available as well leading to a feeling of security by obscurity.
If someone breaks into my system via SSH/etc. then they can get the passwords either way.
… How do people normally do this? I’m not sure I actually get anything out of a secrets manager if its local and I have the disk itself encrypted before login.
What actually makes sense at a personal/home scale?
(Edit: I know using SSH key probably is better for getting to the raspberry pi, but still the question is the same idea).
Ansible vault. All my config files and scripts are deployed with Ansible. Usually they are pushing those into a file or environment variable but if you scope permissions narrowly and don’t run services/containers as root you should be somewhat safe. If someone has filesystem access you’re already in big trouble.
Instead I’d focus on keeping your attack surface as small as possible. Keep services behind a VPN or segment public facing services to a separate VLAN or docker network.
Is cert based auth an option?
- For kuberentes stuff, I use external-secrets-operator. It can be paired with selfhosted stuff, like Hashicorp Vault.
- For machines, disk encryption LUKS, and then files in plain text, with minimal permissions: mode 400.
- For my laptop, keepass.
In my opinion, for home selfhosted stuff you don’t have to go for complex solutions. In the industry, the problem is that secrets needs to be served to different systems, by different people, with some kind of audit logs. Unless you are working with lots of people, environment variables are OK. You github/gitlab may have all scripts with variables, and your disk may have a .env file with mode 400. If you make any machine or container with a single responsibility, there should be no secret leaks among them.
For example, let say your wordpress instance gets pwned. It should only have its needed secrets (like its db credentials), so your wikimedia instance is still fine.
On a completely unrelated side note: I like to see paralellisms of SOLID principles of OOP development and system administration.
A container may have one responsability. Or a service config (like nginx) may be closed to modifications but open to extensions, to avoid some automated client breaking elsewhere, etc, etc.
Sometimes I like to thing about system administration like some kind of very high level development.
spoiler
To mods: I have no problem to delete this comments if it doesn’t fit this community
Two more options you might consider:
- secret-tool - like a vault that unlocks when a user logs in to their session. This shifts the problem to keeping the user’s login credentials secure but depending on your setup that might be preferable. Just be aware the once unlocked any process could access the vault in theory (I wish they’d add access controls…)
- podman secrets - so you can securely provide secrets to containers. You can set these once securely then nothing except processes in the container can get them.
This is likely a too late, but reasonable moment to say this server happens to be Windows based.
… for backup reasons.
(The tool used for online backup only allows home versions of Windows and local drives)
One day if I build a new one, I might start with a Linux base, though that kind of requires this one to be on its last leg before I get to that point. It’s running a processor/mobo that are 14ish years old… so maybe I should think more about it.
In that case I’ll also mention that Powershell has a secure-string that allows you to load secrets from encrypted file/user input. I believe it’s secured by the user’s login/session like secret-tool. They are even remain encrypted in memory so they can’t be snooped on.
Environment variables. If they’re in my network, that has no open ports to the internet, I’ve got plenty more problems.
Even a dev machine, think about how many env vars a normal dev has, plenty to loose.
Secrets management tool for self hosting on my level would bring more complexity for little gain.
Bash scripts etc can be uploaded to open repo and not share secrets which is what I want.