Necessity of sudo while installing with dnf

I’m using Fedora 33. I’m confused by probably a simple fact.

If I try to run a program which isn’t installed, dnf will search repos and suggest to install it. If I answer yes, it will be installed and I’m able to use it normally.

If I were to try and install that software (dnf install <package>), I would be asked for superuser password.

For my example I tried installing "ranger" both ways and I can’t seem to find a difference. Both are located in the same bin directory and both are running under user in processes.

My question is following: If it is possible to simply install software without password anyway, why does dnf ask for it?

Asked By: sabak


When you type a non-installed program name, it’s not dnf installing it but PackageKit and it’s command not found plugin (package PackageKit-command-not-found). PackageKit uses PolicyKit to decide whether to ask for password when doing privileged tasks or not and local active admin users don’t need to give password for package installation (it’s not Fedora specific feature, it came from usptream, see this FESCO discussion). This is the same reason why you don’t need to provide password when installing or updating packages from the GUI tools like GNOME Software which also uses PackageKit as backend.

You can also use PackageKit from command line, the command is pkcon and pkcon install <package> also won’t ask for password.

And why dnf needs sudo? It simply doesn’t use PolicyKit.

Answered By: Vojtech Trefny

In the scenario you describe, "you" are not installing the package that is installed – the PackageKit service (which is already running as root) is doing the installation on your behalf. The PackageKit uses PolicyKit to determine who is or is not allowed to install packages – if you don’t want unprivileged users to be able to install software, you can change the PolicyKit policy to disallow it. One of the reasons PackageKit exists is so the user doesn’t have to know the details of the package management system on whatever distro the are using (whether it’s dnf, or yum, or apt, or pacman, or whatever) – they just have to ask PackageKit to install the package, and PackageKit deals with the details of package management and installation on that particular distro. When you manually use dnf to install a package on Fedora, you are directly interacting with the package management system – PackageKit is not doing this operation on your behalf – which is why you need to be running as root (or provide the root password) in order to install packages at that level. But, as an ordinary user, you can use pkcon install <packagename> to ask PackageKit to do the installation on your behalf (as long as system policy as configured in PolicyKit allows you to do so), without ever having to be running as root (via su or sudo etc.), or providing the root password.

The behavior you’re talking about, where you’re prompted to install a package if you try to run something on the command line that’s provided by a package you do not already have installed, is driven by a package called "PackageKit-command-not-found". I absolutely detest this behavior, and one of the very first things I do on any newly installed Linux system is to remove the PackageKit-command-not-found package so this is not done….

Answered By: patbarron

Restrict DNF to install only packages that are currently managed by existing repos. Implement both explicit allow and explicit deny if you’re paranoid, but at least do explicit allow because explicit deny by itself isn’t so great:

  • Explicit allow:
    • Cache a list of available packages somewhere in cron
    • ie, dnf list available
    • Only allow the installation packages that are in that list
    • Only allow packages named [0-9A-Za-z][0-9A-Za-z._-]+ (can’t start with a -)
    • deny everything else
  • Explicit deny:
    • Deny any option that starts with a ‘-‘
    • Deny any option that contains "/" so local and remote packages can’t be installed.
  • Testing:
    • provide sudo access to the wrapper
    • verify that sudo fails if trying to run /usr/bin/dnf
    • verify that your script is command-injection safe

Did I miss anything? I can’t think of a way to leverage this to get root unless there is a package that can be installed which does (ie, an exploitable package has a root escalation or defaults are poorly configured).

If you don’t want binaries being built by users (which could be used to leverage a kernel vulnerability), then exclude these with your script, too:

  • gcc
  • c++
  • clang
  • go
  • rust
  • fortran
  • others?
Answered By: KJ7LNW
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.