Skip to content

Instantly share code, notes, and snippets.

@AdrianVollmer
Created June 9, 2025 17:50
Show Gist options
  • Save AdrianVollmer/6c9fff5f195b8959b00c3c831185c009 to your computer and use it in GitHub Desktop.
Save AdrianVollmer/6c9fff5f195b8959b00c3c831185c009 to your computer and use it in GitHub Desktop.
Set up AdGuard Home as QEMU VM running OpenWRT using libvirt and virsh
#!/bin/bash
VM_NAME="adguard-home"
VM_RAM="512"
VM_VCPUS="1"
VM_DISK_SIZE="2G"
OPENWRT_VERSION="23.05.3"
OPENWRT_URL="https://downloads.openwrt.org/releases/${OPENWRT_VERSION}/targets/x86/64/openwrt-${OPENWRT_VERSION}-x86-64-generic-ext4-combined.img.gz"
BRIDGE_INTERFACE="enp1s0"
IP="192.168.178.2"
GATEWAY="192.168.178.1"
# Create images directory if it doesn't exist
mkdir -p /var/lib/libvirt/images
# Download OpenWrt image
echo "Downloading OpenWrt ${OPENWRT_VERSION}..."
wget -O /tmp/openwrt.img.gz "$OPENWRT_URL"
# Extract and convert to qcow2
echo "Converting image to qcow2..."
gunzip /tmp/openwrt.img.gz
qemu-img convert -f raw -O qcow2 /tmp/openwrt.img /var/lib/libvirt/images/${VM_NAME}.qcow2
# Resize the disk to give more space
qemu-img resize /var/lib/libvirt/images/${VM_NAME}.qcow2 $VM_DISK_SIZE
# Clean up temporary file
rm /tmp/openwrt.img
# Create VM with dual network interfaces
virt-install \
--name "$VM_NAME" \
--ram "$VM_RAM" \
--vcpus "$VM_VCPUS" \
--disk path=/var/lib/libvirt/images/${VM_NAME}.qcow2,format=qcow2,bus=virtio \
--network network=default \
--network type=direct,source=$BRIDGE_INTERFACE,source_mode=bridge \
--graphics none \
--console pty,target_type=serial \
--os-variant linux2022 \
--import \
--noautoconsole
cat <<EOF
VM created successfully!
Next steps:
1. Connect to VM: virsh console $VM_NAME
2. Resize root filesystem according to https://openwrt.org/docs/guide-user/advanced/expand_root
# Install packages
opkg update
opkg install parted losetup resize2fs blkid
# Download expand-root.sh
wget -U "" -O expand-root.sh "https://openwrt.org/_export/code/docs/guide-user/advanced/expand_root?codeblock=0"
# Source the script (creates /etc/uci-defaults/70-rootpt-resize and /etc/uci-defaults/80-rootpt-resize, and adds them to /etc/sysupgrade.conf so they will be re-run after a sysupgrade)
. ./expand-root.sh
# Resize root partition and filesystem (will resize partiton, reboot resize filesystem, and reboot again)
sh /etc/uci-defaults/70-rootpt-resize
3. Set root password: passwd
4. Configure WAN interface with static IP:
uci set network.wan.proto='static'
uci set network.wan.ipaddr='$IP'
uci set network.wan.netmask='255.255.255.0'
uci set network.wan.gateway='$GATEWAY'
uci set network.wan.dns='8.8.8.8 8.8.4.4'
uci set network.wan.metric='10'
uci delete network.lan.gateway 2>/dev/null
uci commit network
/etc/init.d/network restart
5. Configure LAN interface with DHCP:
uci set network.lan.proto='dhcp'
uci delete network.lan.ipaddr
uci delete network.lan.netmask
uci commit network
/etc/init.d/network restart
6. Configure dnsmasq to use different port:
uci set dhcp.@dnsmasq[0].port='5353'
uci commit dhcp
/etc/init.d/dnsmasq restart
7. Add firewall rule for DNS:
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-DNS-WAN'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest_port='53'
uci set firewall.@rule[-1].proto='tcp udp'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart
8. Install AdGuard Home: opkg update && opkg install adguardhome
9. Enable and start: /etc/init.d/adguardhome enable && /etc/init.d/adguardhome start
10. Configure AdGuard to bind to $IP:53 in the web GUI at <lan-ip>:3000
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment