Replacing passwordless root with a dom0 prompt

@taradiddles

Step 2. Configuring Fedora template to prompt Dom0 for any authorization request” no longer works in Fedora Core 39 template, because RedHat now has user authentication managed by authselect utility - so now /etc/pam.d/system-auth is a symlink to /etc/authselect/system-auth, automatically generated by authselect.

Ways to deal with it:

  • Either create a custom authselect profile with our auth policy:

    [root@fedora-39-x64]# authselect create-profile sudo-dom0-prompt --base-on=sssd --symlink-meta --symlink-pam
    [root@fedora-39-x64]# mv /etc/authselect/custom/sudo-dom0-prompt/system-auth /etc/authselect/custom/sudo-dom0-prompt/system-auth.original_aside
    [root@fedora-39-x64]# cp /etc/authselect/system-auth /etc/authselect/custom/sudo-dom0-prompt
    

    Now edit /etc/authselect/custom/sudo-dom0-prompt/system-auth, replace all lines beginning with “auth” with these lines:

    auth  [success=1 default=ignore]  pam_exec.so seteuid /usr/lib/qubes/qrexec-client-vm dom0 qubes.VMAuth /bin/grep -q ^1$
    auth  requisite  pam_deny.so
    auth  required   pam_permit.so
    

    Then select new profile:

    [root@fedora-39-x64]# authselect select custom/sudo-dom0-prompt
    

    (Optional) Check that /etc/pam.d/system-auth has correct contents:

    [root@fedora-39-x64]# cat /etc/pam.d/system-auth
    
  • Or alternately opt out from authselect-managed configuration and then edit the static file /etc/pam.d/system-auth as before:

    [root@fedora-39-x64]# authselect opt-out
    

    I haven’t tried opting out - thought that if RedHat is moving ahead with authselect, it’s better to work with it, rather than disable it.

3 Likes

This works, thank you so much!

Also, for other users:

Require authentication for sudo. Replace the first line of /etc/sudoers.d/qubes with:

This is not necessarily the first line anymore. Replace the like that has NOPASSWD: all in it.

rm /etc/polkit-1/localauthority/50-local.d/qubes-allow-all.pkla

This file does not exist in Fedora templates anymore, at least not in the Fedora 40 GNOME one

1 Like

With the Whonix templates (I haven’t checked on Debian as I don’t use it)

These files no longer exist

  • /etc/polkit-1/localauthority/50-local.d/qubes-allow-all.pkla
  • /etc/pam.d/su.qubes

Is this guide still relevant? Some users mentioned that certain parts of this guide should be updated. Please, could someone rewrite it for Qubes R4.2?

I didn’t use this guide, but apart from the last update in 2023, the dom0 RPC policies are clearly outdated.

This is actually meaningless because the command executed by sudo (or any actions taken by a program) is not displayed to Dom0. A user will not know if they are authenticating a valid program or a harmful one.

Imagine this case: A malicious program can edit your home folder without direct access to root. This program can modify .bashrc to create a function named sudo, which is a wrapper for the real /usr/bin/sudo, in order to append its malicious command after the user’s input.

Feel free to correct me if I’m wrong. :smiley:

4 Likes

My solution is this script in dom0:

read -p "Enter VM name: " vm
qvm-run -u root "$vm" "/usr/bin/xfce4-terminal"

You could also combine this with the ‘qvm-terminal-open.sh’ script so you just need to press Super_Shift + Return to open a root shell in the currently focused VM without typing the vm name manually

1 Like

@Mirai
Thanks for your solution, but this topic is about a window that pops up in dom0 and allows the user to run sudo in a VM. Your solution applies when users remove the qubes-core-agent-passwordless-root package and then run commands as root in the VM via dom0.
I’ve written a script for this purpose — run it in dom0 :

#!/bin/bash

# === Function: Run root terminal in selected Qube ===
run_root_terminal_in_qube() {
    local qube_name=$1
    echo "Opening root terminal in Qube '$qube_name'..."
    qvm-run -u root "$qube_name" qubes-run-terminal &
    sleep 1
}

# === Function: Display VM selection menu ===
choose_vm() {
    local vm_list="$1"
    declare -A vm_options
    local counter=1

    echo
    echo "Choose a VM from the list below:"
    for vm in $vm_list; do
        echo "$counter) $vm"
        vm_options[$counter]=$vm
        ((counter++))
    done

    read -rp "Enter the number of your choice: " choice
    if [[ -n "${vm_options[$choice]}" ]]; then
        selected_vm="${vm_options[$choice]}"
        echo "You selected: $selected_vm"
        return 0
    else
        echo "Invalid choice. Please try again."
        return 1
    fi
}

# === Main Script Loop ===
while true; do
    echo
    echo "=========================="
    echo " Qube Root Terminal Tool "
    echo "=========================="
    echo "1) Show all VMs"
    echo "2) Show halted VMs"
    echo "3) Show running VMs"
    echo "4) Exit"
    echo

    read -rp "Choose an option: " list_option

    case $list_option in
        1)
            VM_LIST=$(qvm-ls --all | awk 'NR>1 {print $1}')
            ;;
        2)
            VM_LIST=$(qvm-ls --halt | awk 'NR>1 {print $1}')
            ;;
        3)
            VM_LIST=$(qvm-ls --running | awk 'NR>1 {print $1}')
            ;;
        4)
            echo "Goodbye!"
            exit 0
            ;;
        *)
            echo "Invalid option, try again."
            continue
            ;;
    esac

    # VM selection and action menu
    while true; do
        if ! choose_vm "$VM_LIST"; then
            continue
        fi

        while true; do
            echo
            echo "Options for Qube '$selected_vm':"
            echo "1) Run root terminal"
            echo "2) Choose another VM"
            echo "3) Return to VM list menu"
            echo "4) Exit"
            read -rp "Select an action: " action

            case $action in
                1)
                    run_root_terminal_in_qube "$selected_vm"
                    ;;
                2)
                    break  # Back to VM selection within same list
                    ;;
                3)
                    continue 3  # Jump back to VM list selection
                    ;;
                4)
                    echo "Goodbye!"
                    exit 0
                    ;;
                *)
                    echo "Invalid option, try again."
                    ;;
            esac
        done
    done
done