fedora-intune: report full image version to Intune, Defender compliance script
Himmelblau reports VERSION_ID from /etc/os-release as the device OS version, so Intune showed "44". Give himmelblaud and himmelblaud-tasks their own os-release (bind-mounted in their mount namespace only) with VERSION_ID set to OSTREE_VERSION, e.g. 44.20261019.0. The rest of the system keeps the stock VERSION_ID that toolbox, flatpak and dnf expect. Add an Intune custom compliance discovery script and rules for Microsoft Defender for Endpoint (installed, running, onboarded, licensed, healthy, real-time protection, definitions up to date). These are uploaded to Intune, not shipped in the image. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
350b381200
commit
75c3b502d7
6 files changed
+214
No files matched your search
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"Rules": [
|
||||
{
|
||||
"SettingName": "DefenderInstalled",
|
||||
"Operator": "IsEquals",
|
||||
"DataType": "Boolean",
|
||||
"Operand": true,
|
||||
"MoreInfoUrl": "https://learn.microsoft.com/en-us/defender-endpoint/linux-install-manually",
|
||||
"RemediationStrings": [
|
||||
{
|
||||
"Language": "en_US",
|
||||
"Title": "Microsoft Defender is not installed.",
|
||||
"Description": "Microsoft Defender for Endpoint (mdatp) must be installed on this device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"SettingName": "DefenderRunning",
|
||||
"Operator": "IsEquals",
|
||||
"DataType": "Boolean",
|
||||
"Operand": true,
|
||||
"MoreInfoUrl": "https://learn.microsoft.com/en-us/defender-endpoint/linux-install-manually",
|
||||
"RemediationStrings": [
|
||||
{
|
||||
"Language": "en_US",
|
||||
"Title": "Microsoft Defender is not running.",
|
||||
"Description": "The Microsoft Defender service (mdatp.service) is not responding. Restart the device or contact IT."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"SettingName": "DefenderOnboarded",
|
||||
"Operator": "IsEquals",
|
||||
"DataType": "Boolean",
|
||||
"Operand": true,
|
||||
"MoreInfoUrl": "https://learn.microsoft.com/en-us/defender-endpoint/linux-install-manually",
|
||||
"RemediationStrings": [
|
||||
{
|
||||
"Language": "en_US",
|
||||
"Title": "Microsoft Defender is not onboarded.",
|
||||
"Description": "This device is not onboarded to your organization's Microsoft Defender tenant. Contact IT."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"SettingName": "DefenderLicensed",
|
||||
"Operator": "IsEquals",
|
||||
"DataType": "Boolean",
|
||||
"Operand": true,
|
||||
"MoreInfoUrl": "https://learn.microsoft.com/en-us/defender-endpoint/linux-install-manually",
|
||||
"RemediationStrings": [
|
||||
{
|
||||
"Language": "en_US",
|
||||
"Title": "Microsoft Defender is not licensed.",
|
||||
"Description": "Microsoft Defender has no valid license on this device. Contact IT."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"SettingName": "DefenderHealthy",
|
||||
"Operator": "IsEquals",
|
||||
"DataType": "Boolean",
|
||||
"Operand": true,
|
||||
"MoreInfoUrl": "https://learn.microsoft.com/en-us/defender-endpoint/linux-install-manually",
|
||||
"RemediationStrings": [
|
||||
{
|
||||
"Language": "en_US",
|
||||
"Title": "Microsoft Defender reports a problem.",
|
||||
"Description": "Run 'mdatp health' to see the reported issues, or contact IT."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"SettingName": "DefenderRealTimeProtection",
|
||||
"Operator": "IsEquals",
|
||||
"DataType": "Boolean",
|
||||
"Operand": true,
|
||||
"MoreInfoUrl": "https://learn.microsoft.com/en-us/defender-endpoint/linux-install-manually",
|
||||
"RemediationStrings": [
|
||||
{
|
||||
"Language": "en_US",
|
||||
"Title": "Real-time protection is off.",
|
||||
"Description": "Microsoft Defender real-time protection must be enabled."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"SettingName": "DefenderDefinitionsUpToDate",
|
||||
"Operator": "IsEquals",
|
||||
"DataType": "Boolean",
|
||||
"Operand": true,
|
||||
"MoreInfoUrl": "https://learn.microsoft.com/en-us/defender-endpoint/linux-install-manually",
|
||||
"RemediationStrings": [
|
||||
{
|
||||
"Language": "en_US",
|
||||
"Title": "Microsoft Defender definitions are out of date.",
|
||||
"Description": "Connect the device to the network so Microsoft Defender can update its security intelligence."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
# Intune custom compliance discovery script for Linux: is Microsoft Defender
|
||||
# for Endpoint (mdatp) installed, onboarded, licensed and protecting?
|
||||
#
|
||||
# Upload in Intune > Devices > Compliance > Scripts (Linux), and pair it with
|
||||
# defender-compliance.json in a Linux compliance policy (Custom compliance).
|
||||
# Himmelblau runs it as root inside himmelblaud-tasks.service and sends the
|
||||
# JSON on stdout to Intune, which evaluates it against the rules. Every setting
|
||||
# is always emitted, so a missing or stopped Defender reads as non-compliant
|
||||
# instead of as a script error.
|
||||
|
||||
MDATP=/usr/bin/mdatp
|
||||
|
||||
# Print one `mdatp health` field without quotes or a trailing " [managed]".
|
||||
# Unlicensed or unonboarded, mdatp prints "ATTENTION: ..." lines first.
|
||||
field() {
|
||||
"${MDATP}" health --field "$1" 2>/dev/null | grep -v '^ATTENTION' | tail -n1 \
|
||||
| sed -e 's/ \[managed\]$//' -e 's/^"//' -e 's/"$//'
|
||||
}
|
||||
|
||||
bool() {
|
||||
[[ "$1" == true ]] && echo true || echo false
|
||||
}
|
||||
|
||||
installed=false
|
||||
running=false
|
||||
healthy=false
|
||||
licensed=false
|
||||
onboarded=false
|
||||
rtp=false
|
||||
definitions_ok=false
|
||||
definitions_age=-1
|
||||
version=""
|
||||
|
||||
if [[ -x "${MDATP}" ]]; then
|
||||
installed=true
|
||||
if [[ "$(field healthy)" =~ ^(true|false)$ ]]; then
|
||||
# The daemon answered.
|
||||
running=true
|
||||
healthy="$(bool "$(field healthy)")"
|
||||
licensed="$(bool "$(field licensed)")"
|
||||
rtp="$(bool "$(field real_time_protection_enabled)")"
|
||||
[[ -n "$(field org_id)" ]] && onboarded=true
|
||||
[[ "$(field definitions_status)" == up_to_date ]] && definitions_ok=true
|
||||
age="$(field definitions_updated_minutes_ago)"
|
||||
[[ "${age}" =~ ^[0-9]+$ ]] && definitions_age=$(( age / 1440 ))
|
||||
version="$(field app_version)"
|
||||
version="${version//[^0-9A-Za-z._-]/}"
|
||||
fi
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
{
|
||||
"DefenderInstalled": ${installed},
|
||||
"DefenderRunning": ${running},
|
||||
"DefenderHealthy": ${healthy},
|
||||
"DefenderLicensed": ${licensed},
|
||||
"DefenderOnboarded": ${onboarded},
|
||||
"DefenderRealTimeProtection": ${rtp},
|
||||
"DefenderDefinitionsUpToDate": ${definitions_ok},
|
||||
"DefenderDefinitionsAgeDays": ${definitions_age},
|
||||
"DefenderVersion": "${version}"
|
||||
}
|
||||
EOF
|
||||
Reference in new issue
Block a user