In this guide, you’ll learn how to:
- Generate SSH keys using the Bitwarden SSH key vault
- Generate a YAML Butane file
- Convert the YAML Butane file into an Ignition file needed for CoreOS installation
- Locally share your Ignition file with the CoreOS install
- Install Fedora CoreOS
- Set up AdGuard Home for network-level ad blocking (via Podman)
Resources & Links:
- 🎬 Video Guide: Watch on YouTube
- 🔑 Free Bitwarden SSH Key Generator: bitwarden.com/linuxitguy
- 💿 Fedora CoreOS Bare Metal ISO: fedoraproject.org/coreos/download
Fedora CoreOS is great for turning a VM or an old laptop into an appliance dedicated to a single task. In this example, we’ll take a VM and turn it into an AdGuard Home DNS server running on top of CoreOS, but you could easily swap AdGuard for whatever use case you have in mind.
Prerequisites
- Host PC: Any Linux distro with a Flatpak-capable desktop (or adjust to your distro)
- Bitwarden Desktop App: Flatpak or native (free tier is fine)
- Target: A VM or old laptop
- Installer: Fedora CoreOS Bare Metal ISO
1. Generate an SSH Key with Bitwarden
Instead of generating your SSH key manually with ssh-keygen, we’re going to use Bitwarden’s built-in SSH key vault. This keeps your private key encrypted end-to-end inside your vault instead of sitting in plaintext under ~/.ssh.
- Open the Bitwarden desktop app.
- Click New → SSH Key.
- Name it something like
coreos. - Bitwarden generates a private/public key pair for you. Click Save.
- Click the copy button next to the public key (not the private key).
That’s it! No ssh-keygen needed. Keep this public key copied; you’ll paste it into your Butane file next.
2. Create the Butane YAML Config File
Now that we have our SSH key, let’s create our Butane YAML file. In this example, we’re keeping it simple: AdGuard Home as a Quadlet container unit and enough configuration to get SSH working once CoreOS is installed.
- Under your Downloads folder, create a
coreosfolder (~/Downloads/coreos). - Inside it, create a new empty file named
coreos.bu(the.buextension matters). - Check the Butane Specification for the latest variant version (this guide uses
1.7.0). - Paste in the following configuration, replacing
ssh-ed25519 XXXwith the public key you copied from Bitwarden:
variant: fcos
version: 1.7.0
passwd:
users:
- name: core
ssh_authorized_keys:
- ssh-ed25519 XXX
storage:
directories:
- path: /var/adguardhome/work
mode: 0755
- path: /var/adguardhome/conf
mode: 0755
files:
# 1. Disable systemd-resolved's local port 53 stub listener
- path: /etc/systemd/resolved.conf.d/adguard.conf
mode: 0644
contents:
inline: |
[Resolve]
DNSStubListener=no
# 2. Quadlet container unit
- path: /etc/containers/systemd/adguardhome.container
mode: 0644
contents:
inline: |
[Unit]
Description=AdGuard Home Container Service
After=network-online.target
Wants=network-online.target
[Container]
Image=docker.io/adguard/adguardhome:latest
ContainerName=adguardhome
Network=host
Volume=/var/adguardhome/conf:/opt/adguardhome/conf:Z
Volume=/var/adguardhome/work:/opt/adguardhome/work:Z
[Install]
WantedBy=multi-user.target
links:
# 3. Point resolv.conf away from stub resolver to the real upstream network DNS
- path: /etc/resolv.conf
target: /run/systemd/resolve/resolv.conf
overwrite: true
Save and close coreos.bu.
3. Convert Butane YAML to CoreOS Ignition
Now we’ll convert our human-readable YAML into the JSON-based Ignition file CoreOS actually reads. We’ll run Butane inside a Podman container.
Change directory into ~/Downloads/coreos, then run:
podman run -i --rm quay.io/coreos/butane:release --strict < coreos.bu > coreos.ign
Note: The
< coreos.bu > coreos.ignredirection syntax is required. Copy/paste this exact command if your file is namedcoreos.bu.
You now have your coreos.ign file ready.
4. Locally Share Your Ignition File
The CoreOS installer needs an HTTP URL pointing to your Ignition file during installation. We’ll host it temporarily over your local network using Python’s built-in web server.
-
Find your Host PC’s IP address:
ip addrMake note of your local IP (e.g.,
192.168.1.8). -
Temporarily disable your local firewall so the target machine can reach the file:
sudo systemctl stop firewalld -
Start a temporary web server inside
~/Downloads/coreos:python3 -m http.server
5. Install Fedora CoreOS
Now switch over to your VM or physical hardware:
-
Boot into the Fedora CoreOS Bare Metal ISO.
-
Identify your target disk:
lsblk(VMs typically show
/dev/vda; physical machines usually show/dev/sdaor/dev/nvme0n1). -
Execute the installer (adjust the drive path and Host PC IP address as needed):
sudo coreos-installer install /dev/sdX --ignition-url http://192.168.1.8:8000/coreos.ign --insecure-ignition -
Once installation completes, shut down the machine:
shutdown now
Post-Install Firewall Cleanup (Host PC)
Return to your Host PC:
- Stop the Python web server with
CTRL + C. - Re-enable the firewall:
sudo systemctl start firewalld sudo systemctl status firewalld
6. SSH into CoreOS via Bitwarden
Boot up your target machine/VM, then connect from your Host PC:
ssh core@<your-coreos-ip>
When prompted, accept the host fingerprint. Bitwarden will prompt you to authorize the connection using its encrypted SSH agent.
Troubleshooting Bitwarden Flatpak SSH Agent
If you run into a Permission denied (publickey) error while using the Bitwarden Flatpak, create a symlink to align the socket path:
mkdir -p ~/.bitwarden
ln -s ~/.var/app/com.bitwarden.desktop/data/.bitwarden/ssh-agent.sock ~/.bitwarden/ssh-agent.sock
export SSH_AUTH_SOCK=~/.bitwarden/ssh-agent.sock
Verify your SSH key is loaded into Bitwarden’s active agent:
ssh-add -L
Once logged in, confirm your OS release:
cat /etc/os-release
7. Set Up AdGuard Home
- Open your browser on the Host PC and visit:
http://<your-coreos-ip>:3000 - Follow the AdGuard Home wizard to set up your administrator login and upstream DNS servers.
Congrats! You now have Fedora CoreOS running as an automated, headless appliance with Bitwarden-backed SSH security and AdGuard Home managing your network DNS.