Fedora

Install Microsoft Defender for Endpoint on Linux (Ubuntu, Fedora)

Until October 2026, Microsoft supported Defender for Endpoint on Linux on servers only. That left the Ubuntu and Fedora laptops in most Microsoft shops outside the security team’s view. The public preview for Linux desktops uses the same mdatp agent, the same packages and the same deployment methods as servers. There is no desktop build to wait for, so if your SOC already watches Linux servers, your developers’ workstations can report to the same console today.

Original content from computingforgeeks.com - post 174398

The install has two traps before you ever reach the portal. Microsoft’s documented key command leaves Ubuntu 26.04 with an unsigned repository error, and the Fedora 45 tree on packages.microsoft.com does not contain mdatp yet. This guide installs the agent on an Ubuntu 26.04 GNOME desktop, an Ubuntu 24.04 server and Fedora 45. It records what the agent does before it is licensed, proves detection with EICAR and lays out onboarding and the audit after it.

Tested October 2026 on Ubuntu 26.04 (GNOME) and 24.04, and on Fedora 45 and 44 with SELinux enforcing.

What the machine and the tenant need

Two things gate this install, and only one of them lives on the Linux box. The machine side is light, but the licence decides whether a desktop is allowed into the preview at all, and a device that cannot reach Microsoft’s endpoints installs fine and then never reports. Check each of these before you start:

  • The tenant holds Defender for Endpoint Plan 2, Microsoft 365 E5 or Microsoft 365 E7 for desktops. Servers need Defender for Servers Plan 1 or 2, Defender for Endpoint for servers or Defender for Business servers.
  • The distro is on Microsoft’s list: Ubuntu LTS 16.04 to 26.04 and Fedora 33 to 44 on x86_64. Fedora 45 is not listed yet, although it runs the Fedora 44 build cleanly (tested below).
  • systemd runs as init, and the machine has at least 1 CPU core, 1 GB of RAM and 2 GB of free disk.
  • Outbound HTTPS reaches packages.microsoft.com and the Defender endpoints, with no PAC, WPAD, authenticated or intercepting proxy and no SSL inspection in the path.
  • No other fanotify-based scanner runs on the host. On RHEL and Fedora, fapolicyd is the one exception Microsoft allows.

Those come from Microsoft’s Defender for Endpoint on Linux prerequisites. The disk floor is generous: the package used 465 MB on Ubuntu and about 417 MB on Fedora, and the first definitions set added 111 MB under /var/opt/microsoft. If you don’t have a tenant to test with, Microsoft’s sign-up page offers a “Microsoft Defender for Endpoint P2 Web Trial”. On October 16, 2026 that page read “Start your free 1-month trial today”, even though the Learn trial guide still describes a 90-day evaluation, so plan your test window around the shorter number.

Desktop or server: how Defender classifies a Linux device

You do not tell Defender that a Linux machine is a workstation. The service decides from what the agent reports, and when the evidence is thin it files the device as a server. The prerequisites page lists the signals it weighs: operating system metadata, distribution product information, subscription and licensing details, system purpose declarations, cloud and vendor metadata, image SKUs, Ubuntu Pro contracts, VMware guest properties, virtual desktop indicators and installation records. It then states the default plainly: “When the available signals do not conclusively identify a device as a Workstation, Microsoft Defender for Endpoint classifies the device as a Server by default.”

That default is the part to test before you roll out to laptops. Our desktop VM shows why: it started as an Ubuntu 26.04 cloud image and had ubuntu-desktop-minimal added afterwards, so its image SKU and installation records point at a server. The signal list does not mention a desktop environment at all, and the blog says support does not depend on which one you run, so having GNOME installed may count for nothing. Microsoft’s blog is clear that there is no separate desktop agent, which means the classification is the only thing that makes a laptop a laptop in the portal.

That makes the first onboarded laptop a pilot, not a formality. Build it the same way as the rest of the fleet, open its page in the device inventory and read the device type before you enrol anything else. A machine that grew from a server image, like ours, carries more server signals than one installed from the desktop ISO, so it is the likeliest to land on the wrong side of that default.

Install mdatp on Ubuntu 26.04 and 24.04

Add the repository with Microsoft’s packages-microsoft-prod.deb, because each Ubuntu release gets its own copy with the signing key that release actually needs. The 26.04 repository is signed only by Microsoft’s 2025 key (EE4D7792F748182B), while the 24.04 one is still signed by the older EB3E94ADBE1229CF key, and the package installs whichever one matches. Make sure curl is present first:

sudo apt update
sudo apt install -y curl

Download the repository package for the release you are running. lsb_release -rs prints 26.04 or 24.04, so the same two lines work on both:

curl -sSLO https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb

It writes /etc/apt/sources.list.d/microsoft-prod.list and /usr/share/keyrings/microsoft-prod.gpg. Refresh the index and install the agent:

sudo apt update
sudo apt install -y mdatp

The download is 154 MB on both releases. This is the 26.04 desktop, which took 53 seconds from start to a running service:

Need to get 154 MB of archives.
After this operation, 465 MB of additional disk space will be used.
Fetched 154 MB in 9s (16.7 MB/s)
Setting up mdatp (101.26081.0010) ...

The package enables and starts mdatp.service on its own, so there’s nothing to enable. Confirm it is up:

systemctl status mdatp --no-pager

Look for active (running) with wdavdaemon as the main process:

● mdatp.service - Microsoft Defender
     Loaded: loaded (/usr/lib/systemd/system/mdatp.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-10-16 10:51:19 UTC; 28s ago
 Invocation: 99d3f939c6c540b9ad976bfd04714505
   Main PID: 9374 (wdavdaemon)
      Tasks: 0 (limit: 6420)
     Memory: 129.7M (peak: 297M)
        CPU: 3.177s
     CGroup: /system.slice/mdatp.service

The service sat at about 130 MB once the first definitions had loaded, with a 297 MB peak during that load. On the 24.04 server the same numbers were 148 MB and 306 MB, so size small VMs for the peak rather than the steady state, especially on a 1 GB machine that is already running workloads.

Error: NO_PUBKEY EE4D7792F748182B on Ubuntu 26.04

Microsoft’s manual install page tells you to pipe microsoft.asc into the keyring for “Debian 12, Ubuntu 24.04 and later”. That works on 24.04 and breaks on 26.04, because microsoft.asc doesn’t contain the key that signs the resolute repository. apt then refuses the whole source:

apt update failing with NO_PUBKEY EE4D7792F748182B after adding microsoft.asc for the mdatp repository on Ubuntu 26.04

If you followed the manual steps, overwrite the keyring with the 2025 key and refresh. The chmod is Microsoft’s own step and makes sure apt can read the file whatever root’s umask is:

curl -sSL https://packages.microsoft.com/keys/microsoft-2025.asc | gpg --dearmor | sudo tee /usr/share/keyrings/microsoft-prod.gpg > /dev/null
sudo chmod o+r /usr/share/keyrings/microsoft-prod.gpg
sudo apt update

After the swap, apt fetched resolute InRelease and offered mdatp as the install candidate. Only the manual instructions are behind here. Microsoft’s own installer script already picks microsoft-2025.asc for Ubuntu 26.04, and the repository package above ships the right key, so you will not hit this on the recommended path.

Install mdatp on Fedora 45 and 44

Microsoft publishes a Fedora tree per release on packages.microsoft.com. From Fedora 43 onward those trees are signed with the same 2025 key, and Microsoft’s installer script only switches to the native Fedora tree from 43, so use your release’s own tree. Fedora’s dnf5 also dropped config-manager --add-repo, so the command shape changes too. Our dnf5 repository guide covers the new addrepo syntax in more depth. Add the repository for your release and install:

sudo dnf config-manager addrepo --from-repofile=https://packages.microsoft.com/config/fedora/$(rpm -E %fedora)/prod.repo --save-filename=microsoft-prod.repo
sudo dnf install -y mdatp

The --save-filename option matters more than it looks. Without it, dnf5 saves the file as /etc/yum.repos.d/prod.repo, a name any other vendor’s repo file can collide with. On Fedora 44 that installs mdatp straight away, after dnf imports Microsoft’s key. Check the fingerprint before you accept it anywhere you install interactively:

Importing OpenPGP key 0xF748182B:
 UserID     : "Microsoft Corporation - General GPG Signer <[email protected]>"
 Fingerprint: AA86F75E427A19DD33346403EE4D7792F748182B
 From       : https://packages.microsoft.com/keys/microsoft-2025.asc
The key was successfully imported.

Both Fedora releases ran the install with SELinux enforcing, and ausearch -m avc -ts recent returned no denials afterwards. On Fedora 45 it stayed clean after real-time protection came on and through the EICAR test further down, so you do not need a policy module for it. For the rest of the host, our Fedora hardening guide covers what Defender doesn’t touch.

Error: No match for argument: mdatp on Fedora 45

On Fedora 45 the same commands load a valid, signed repository that holds one package, packages-microsoft-prod, and nothing else. dnf has nothing called mdatp to install, so it fails with a message that reads like a typo. Before you go hunting for one, ask the repository what it actually carries:

sudo dnf repoquery -q --repo=packages-microsoft-com-prod mdatp

Empty output means Microsoft has not published mdatp for your release yet. Point the same repo file at the Fedora 44 tree, which installs and runs on Fedora 45 without complaint. The whole sequence, failure included, looked like this on our Fedora 45 host:

dnf install mdatp failing with No match for argument on Fedora 45 and succeeding from the Fedora 44 Microsoft repository

These are the two commands that fixed it. --overwrite replaces the existing microsoft-prod.repo instead of refusing because the file exists:

sudo dnf config-manager addrepo --from-repofile=https://packages.microsoft.com/config/fedora/44/prod.repo --save-filename=microsoft-prod.repo --overwrite
sudo dnf install -y mdatp

Once Microsoft publishes mdatp in the Fedora 45 tree, rerun the first addrepo command with --overwrite added to move back to your release’s own repository. Microsoft also says a major OS upgrade after installation needs the product reinstalled, which on Fedora means every release upgrade and on Ubuntu the move from 24.04 to 26.04. Microsoft’s mde_installer.sh does not help here either. It detects Fedora 45, writes the 45 repository and stops:

--- mde_installer.sh v1.2.9 ---
[v] detected: x86_64 architecture
[v] detected: fedora 45  (fedora)
[v] scaled: 45
[v] set package manager: dnf
[v] no conflicting applications found
[>] installing  dnf-plugins-core
[>] configuring the repository
[>] installing MDE
[x] unable to install MDE (exit code: 1)
[*] exiting (21)

Exit code 21 there is the same empty repository, not a problem with your machine, so the manual Fedora 44 fallback above is the way through.

Error: Unknown argument “–add-repo” for command “config-manager”

This one comes from copying the RHEL instructions onto Fedora. dnf config-manager --add-repo <url> was dnf4 syntax, and dnf5 rejects it before it touches the network:

Unknown argument "--add-repo" for command "config-manager". Add "--help" for more information about the arguments.

Use addrepo --from-repofile= as shown earlier and point it at the Fedora tree, not the RHEL one.

mdatp health before onboarding

Between the install and onboarding, the agent runs, pulls definitions and reports itself unhealthy, which is correct. Every mdatp command prints ATTENTION: No license found first, licensed is false and the antivirus sits in passive mode. This is the full health report from the 26.04 desktop a few seconds after install:

mdatp health on Ubuntu 26.04 desktop before onboarding showing licensed false and missing license

We pushed the unlicensed agent further to see where it stops, because the gap between install and onboarding is where people assume a machine is already protected. Real-time protection can be switched on without a licence, and it works. On-demand scans don’t, and nothing reports anywhere:

CheckFresh installAfter sudo mdatp config real-time-protection --value enabled
licensed / health_issuesfalse / [“missing license”]unchanged
passive_mode_enabledtruefalse
antivirus_enforcement_level“passive”“real_time”
engine_load_status“Engine not loaded”“Engine load succeeded” within 16 seconds
definitions_status“up_to_date”“up_to_date”
mdatp scan quick / scan custom“No scan is running”, exit 2“No scan is running”, exit 2
EICAR downloadedleft on disk, mdatp threat list says “No threats.”quarantined within seconds
EICAR written while the engine was still loadingnot scannedstill on disk, never rescanned

The last row is the one to remember. A file that lands in the seconds before the engine finishes loading is never looked at again, and the scan that would normally sweep it up refuses to run without a licence. Treat this state as staging, not protection, and onboard the device the same day you install it.

The banner also breaks scripts. It goes to stdout, not stderr, so mdatp health --field licensed 2>/dev/null | wc -l returned 2 on the unlicensed 24.04 server, and a check like [ "$(mdatp health --field healthy)" = "true" ] compares against two lines. Take the last line with tail -n 1 in any health check you write.

mdatp connectivity test fails with TRANSPORT_ERROR

Run the connectivity test before you onboard, because it is the quickest way to find a proxy or firewall that will keep the device out of the portal:

mdatp connectivity test

Before onboarding, the test probed about 20 gateway hosts across seven geographies, from Australia and India to the UK and the US. From our lab, four UAE endpoints failed TLS verification and one UAE events host didn’t resolve, and that was enough to make the command exit 1 even though every other region printed [OK]:

Testing connection with https://edr-aen0a.uae.endpoint.security.microsoft.com/edr/commands/test ... [ERROR] [Command and control] TRANSPORT_ERROR (transport-level failure - DNS, TLS, or TCP)
	SSL peer certificate or SSH remote key was not OK
Testing connection with https://aea-v20.events.endpoint.security.microsoft.com/ping ... [ERROR] [Command and control] TRANSPORT_ERROR (transport-level failure - DNS, TLS, or TCP)
	Could not resolve hostname

Read the hostnames before you open a ticket with your network team. Failures confined to a region your tenant does not use are noise. Failures on every winatp-gw-* host, or a Proxy detected: YES line you didn’t expect, are the real problem.

Onboard the Linux device to Microsoft Defender

We had no Defender tenant for this lab, so the onboarding, deployment tool, device type and portal alert steps follow Microsoft’s documentation and were not run here. Every command before this section was. Onboarding ties the agent to your tenant and is the step that turns licensed true. The package is tenant-specific and comes from the Microsoft Defender portal: open System, Settings, Endpoints, Device management and Onboarding, pick Linux Server as the operating system and Local Script as the deployment method, then download the onboarding package. Treat the zip like a credential. Anyone who has it can enrol a machine into your tenant.

Copy WindowsDefenderATPOnboardingPackage.zip to the machine, unpack it and run the script with Python 3. Install unzip first if the box does not have it (sudo apt install -y unzip or sudo dnf install -y unzip):

unzip WindowsDefenderATPOnboardingPackage.zip
sudo python3 MicrosoftDefenderATPOnboardingLinuxServer.py

Then confirm the device took the tenant. org_id should now hold your organisation ID instead of an empty string:

mdatp health --field org_id
mdatp health --field licensed
mdatp health --field healthy

Microsoft’s manual deployment guide notes that a machine onboarded for the first time can take up to 20 minutes to show up in the portal. A device missing from the inventory five minutes in is not yet a fault. The health fields do not wait for the portal: org_id and licensed are local and should change within minutes of the script finishing, which also ends the ATTENTION banner. Microsoft notes that healthy can stay false while the first definitions download.

For new machines, Microsoft also ships a Defender deployment tool, still labelled preview, that installs the latest production agent and onboards it in one run. It comes from the same Onboarding page with Linux picked as the operating system, as GatewayLinuxDefenderDeploymentTool.zip, and it is tied to one tenant in the same way. It also needs outbound 443 to msdefender.download.prss.microsoft.com on top of the usual Defender endpoints:

unzip GatewayLinuxDefenderDeploymentTool.zip
chmod +x defender_deployment_tool.sh
sudo bash defender_deployment_tool.sh

It logs to /tmp/defender_deployment_tool.log, with the events it sends to the portal in /tmp/defender_deployment_tool_telemetry.log. Microsoft’s deployment tool guide suggests a dry run with --pre-req first to surface problems before it installs anything. It also refuses to run with 1 GB of RAM or less or with 2 GB of free disk or less, so the minimums in the list at the top are not enough for it. Fedora 45 isn’t on Microsoft’s supported list yet, so on that release use the repository steps above and the local onboarding script instead.

Detection proof with the EICAR test file

A health report that says true proves the agent is licensed, not that it stops anything. The EICAR file is a harmless 68-byte string every antivirus engine flags on purpose, so it is the safe way to prove real-time protection. Our runs used agents that were never onboarded, with real-time protection switched on by hand, which tests the local engine on its own. Passive is the agent’s default enforcement level whether it is onboarded or not, until a command or managed policy changes it, so turn real-time protection on first and watch the engine load:

sudo mdatp config real-time-protection --value enabled
mdatp health --field engine_load_status

Repeat the second command until it reads "Engine load succeeded", which took up to 16 seconds here. On Fedora 45 it printed "["Engine client exited"]" three times first, which is normal while the engine starts. A file written before then is never rescanned, as the table above showed. Then download EICAR into a user directory and list it with the threat history. The mkdir covers servers and cloud images that have no ~/Downloads:

mkdir -p ~/Downloads
curl -so ~/Downloads/eicar.com.txt https://secure.eicar.org/eicar.com.txt
sleep 5
ls -l ~/Downloads
mdatp threat list

On the 26.04 desktop the file was gone within 3 seconds and mdatp threat list showed it as Virus:DOS/EICAR_Test_File with status quarantined. The earlier entry in this capture is the first test from a few minutes before:

EICAR test file quarantined by Microsoft Defender real-time protection on Ubuntu 26.04 with mdatp threat list

Fedora 45 behaved the same way: the engine loaded seconds after real-time protection came on, and a copy downloaded to /tmp was quarantined before the first ls. Quarantined files stay in Defender’s quarantine store, and mdatp threat quarantine list shows what is being held.

EICAR proves the antivirus half. For the portal half, Microsoft’s manual deployment guide points to a separate EDR detection test script to run on an onboarded machine. Its alert is the one to open, along with the machine timeline, to confirm the device reports end to end. We did not run it here. It tries to upload a zip of dummy files to file.io, and the alert comes from that collect-and-exfiltrate behaviour. If zip or curl is missing it installs them with sudo and removes them afterwards, which is worth knowing on a locked-down production box.

Two on-access scanners on one host

Microsoft lists running mdatp next to another fanotify-based security tool as unsupported, and its conflicting_applications health field only lists apps that use fanotify in blocking mode. We ran ClamAV’s on-access scanner, clamonacc, in notify mode (OnAccessPrevention no) watching /home on the 24.04 server, using the same setup as our ClamAV on-access guide, with mdatp’s real-time protection on. Then we downloaded EICAR into /home:

  • Both wdavdaemon and clamonacc held a fanotify file descriptor.
  • clamd logged Eicar-Test-Signature FOUND six times for the one file, three of them after Defender had already deleted it.
  • Defender quarantined the same file.
  • mdatp health --field conflicting_applications still returned [] two and a half minutes after clamonacc started, as Microsoft’s blocking-mode wording predicts.

Nothing broke in a 68-byte test, but every file write was now inspected twice by two daemons racing each other, which is exactly the unsupported state Microsoft warns about, and nothing in mdatp flagged it. We did not test ClamAV in prevention mode. On any host you onboard, stop clamonacc with sudo pkill clamonacc (our ClamAV guide starts it by hand, so remove it from any unit or boot script you added) and remove the OnAccessIncludePath lines from /etc/clamav/clamd.conf. Scheduled clamscan runs don’t use fanotify and can stay as a second opinion. The same goes for other open source scanners from our Linux malware scanner roundup that you run on demand.

If you are weighing Defender against an open source stack rather than running both, Wazuh on Ubuntu covers file integrity and host monitoring without a per-device licence, at the cost of running and patching the manager yourself.

Post-onboarding audit checklist

Run this on every Linux machine you onboard, desktop or server. Each line closes a gap this lab ran into or one the health report can hide, from an agent left in passive mode to a laptop filed as a server:

  1. mdatp health --field licensed returns true and the ATTENTION banner is gone.
  2. mdatp health --field org_id returns your tenant’s ID, not an empty string.
  3. mdatp health --field healthy returns true and health_issues is [].
  4. antivirus_enforcement_level reads "real_time", not "passive". Passive is Microsoft’s default even after onboarding, so expect this to fail unless a policy says otherwise. Fix it with sudo mdatp config real-time-protection --value enabled or set the enforcement level to real-time in your managed policy, then check again. A managed policy wins over the local command, so if it pins passive, change the policy.
  5. definitions_status reads "up_to_date".
  6. conflicting_applications is [] and pgrep clamonacc returns nothing.
  7. mdatp connectivity test shows [OK] for your tenant’s region.
  8. The device appears in the portal’s device inventory with the device type you expect.
  9. An EICAR download is quarantined locally, and Microsoft’s EDR detection test raises an alert in the portal.

Item 4 catches the agent left in passive mode, the same state that let EICAR sit on disk untouched in the table earlier. When a machine leaves the fleet, download the offboarding script from the portal’s Offboarding page (its file name carries an expiry date), run it on the machine as Microsoft’s offboarding guide describes, and only then remove the package with sudo apt purge mdatp or sudo dnf remove mdatp. On the 24.04 server the purge left /etc/opt/microsoft/mdatp/tmp/temp_telemetry behind, so delete /etc/opt/microsoft by hand if the machine is being reimaged for someone else. Defender covers malware and EDR, not configuration, so pair it with the basics in our Ubuntu server hardening guide.

Keep reading

Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) Ubuntu Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 Security UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Php PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Upgrade Kali Linux to the Latest Version Kali Linux Upgrade Kali Linux to the Latest Version Best Cybersecurity and Penetration Testing Books for 2026 Books Best Cybersecurity and Penetration Testing Books for 2026 Best Practices for Developers On How to Secure Cloud-Based Applications Cloud Best Practices for Developers On How to Secure Cloud-Based Applications

Leave a Comment

Press ESC to close