Misthios/fedora intune os version defender #2
No files matched your search
@@ -2,6 +2,12 @@ name: Build containers
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
image:
|
||||||
|
description: Image to build
|
||||||
|
type: choice
|
||||||
|
options: [all, fedora-cosmic, fedora-remote, fedora-intune]
|
||||||
|
default: all
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
push:
|
push:
|
||||||
@@ -15,11 +21,17 @@ jobs:
|
|||||||
changes:
|
changes:
|
||||||
name: Compute changes
|
name: Compute changes
|
||||||
runs-on: job-v2
|
runs-on: job-v2
|
||||||
|
# The runner has no git: without it actions/checkout falls back to a
|
||||||
|
# tarball with no history, `git diff` fails and every image is rebuilt.
|
||||||
|
container:
|
||||||
|
image: "quay.io/fedora-ostree-desktops/buildroot:44"
|
||||||
outputs:
|
outputs:
|
||||||
cosmic: ${{ steps.changes.outputs.cosmic }}
|
cosmic: ${{ steps.changes.outputs.cosmic }}
|
||||||
remote: ${{ steps.changes.outputs.remote }}
|
remote: ${{ steps.changes.outputs.remote }}
|
||||||
intune: ${{ steps.changes.outputs.intune }}
|
intune: ${{ steps.changes.outputs.intune }}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Install tools
|
||||||
|
run: dnf install -y nodejs git
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -27,17 +39,53 @@ jobs:
|
|||||||
- name: Detect changed images
|
- name: Detect changed images
|
||||||
id: changes
|
id: changes
|
||||||
shell: bash
|
shell: bash
|
||||||
|
env:
|
||||||
|
EVENT: ${{ github.event_name }}
|
||||||
|
BEFORE: ${{ github.event.before }}
|
||||||
|
SHA: ${{ github.sha }}
|
||||||
|
BASE_REF: ${{ github.base_ref }}
|
||||||
|
DISPATCH_IMAGE: ${{ inputs.image }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
if [[ "${{ github.event_name }}" == "push" \
|
# Diff the event's commits; any failure rebuilds everything, but
|
||||||
&& -n "${{ github.event.before }}" \
|
# say so instead of hiding it.
|
||||||
&& "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]]; then
|
diff_or_all() {
|
||||||
changed="$(git diff --name-only "${{ github.event.before }}" "${{ github.sha }}" || true)"
|
if ! changed="$(git diff --name-only "$@")"; then
|
||||||
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
echo "::warning::git diff $* failed; rebuilding every image"
|
||||||
changed="$(git diff --name-only "origin/${{ github.base_ref }}...HEAD" || true)"
|
changed=""
|
||||||
else
|
elif [[ -z "${changed}" ]]; then
|
||||||
changed=""
|
# Nothing changed (e.g. an empty merge): build nothing rather
|
||||||
fi
|
# than everything.
|
||||||
|
changed="(none)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
case "${EVENT}" in
|
||||||
|
push)
|
||||||
|
if [[ -n "${BEFORE}" && "${BEFORE}" != 0000000000000000000000000000000000000000 ]]; then
|
||||||
|
diff_or_all "${BEFORE}" "${SHA}"
|
||||||
|
else
|
||||||
|
echo "::warning::push without a previous commit; rebuilding every image"
|
||||||
|
changed=""
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
pull_request)
|
||||||
|
diff_or_all "origin/${BASE_REF}...HEAD"
|
||||||
|
;;
|
||||||
|
workflow_dispatch)
|
||||||
|
# Pretend the chosen image's directory changed; "all" (or no
|
||||||
|
# input) rebuilds everything.
|
||||||
|
if [[ -n "${DISPATCH_IMAGE}" && "${DISPATCH_IMAGE}" != all ]]; then
|
||||||
|
changed="images/${DISPATCH_IMAGE}/"
|
||||||
|
else
|
||||||
|
changed=""
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# schedule: the weekly rebuild picks up package updates for all.
|
||||||
|
changed=""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
printf 'Changed paths:\n%s\n' "${changed:-(all)}"
|
||||||
eval "$(printf '%s\n' "${changed}" | ./ci-changes.sh)"
|
eval "$(printf '%s\n' "${changed}" | ./ci-changes.sh)"
|
||||||
echo "cosmic=${cosmic}" >> "$GITHUB_OUTPUT"
|
echo "cosmic=${cosmic}" >> "$GITHUB_OUTPUT"
|
||||||
echo "remote=${remote}" >> "$GITHUB_OUTPUT"
|
echo "remote=${remote}" >> "$GITHUB_OUTPUT"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ BUILD_MODE=upstream
|
|||||||
|
|
||||||
UPSTREAM_REPO="https://gitlab.com/fedora/ostree/ci-test.git"
|
UPSTREAM_REPO="https://gitlab.com/fedora/ostree/ci-test.git"
|
||||||
|
|
||||||
# Stable only; Defender comes from Microsoft's RHEL 10 repo, not rawhide.
|
# Stable only; Microsoft's Defender repo (fedora/44) has no rawhide build.
|
||||||
declare -A UPSTREAM_REFS=(
|
declare -A UPSTREAM_REFS=(
|
||||||
[44]=f44
|
[44]=f44
|
||||||
)
|
)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Microsoft Defender for Endpoint on Linux (mdatp), RHEL 10 build, from the
|
# Microsoft Defender for Endpoint on Linux (mdatp), Fedora 44 build, from the
|
||||||
# microsoft-rhel10 repo (repos/microsoft.repo).
|
# microsoft-fedora44 repo (repos/microsoft.repo).
|
||||||
#
|
#
|
||||||
# mdatp's %post does the real install: units, SELinux module, and per-machine
|
# mdatp's %post does the real install: units, SELinux module, and per-machine
|
||||||
# state under /var/opt/microsoft/mdatp (machine GUID, definitions database,
|
# state under /var/opt/microsoft/mdatp (machine GUID, definitions database,
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
# from the Defender portal on the device.
|
# from the Defender portal on the device.
|
||||||
|
|
||||||
repo-packages:
|
repo-packages:
|
||||||
- repo: microsoft-rhel10
|
- repo: microsoft-fedora44
|
||||||
packages:
|
packages:
|
||||||
- mdatp
|
- mdatp
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Report the full image version (VERSION_ID=44.20261019.0) to Entra ID and
|
||||||
|
# Intune instead of "44"; see /usr/libexec/himmelblau-os-release. Only this
|
||||||
|
# service's mount namespace sees the replacement os-release.
|
||||||
|
[Unit]
|
||||||
|
Requires=himmelblau-os-release.service
|
||||||
|
After=himmelblau-os-release.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
BindReadOnlyPaths=/run/himmelblau-os-release:/etc/os-release
|
||||||
@@ -2,3 +2,5 @@
|
|||||||
enable himmelblaud.service
|
enable himmelblaud.service
|
||||||
enable himmelblaud-tasks.service
|
enable himmelblaud-tasks.service
|
||||||
enable himmelblau-hsm-pin-init.service
|
enable himmelblau-hsm-pin-init.service
|
||||||
|
# Runs the Intune custom configuration scripts Himmelblau puts in /etc/cron.d.
|
||||||
|
enable crond.service
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Write the os-release that the Himmelblau daemons see (10-os-release.conf):
|
||||||
|
# the image's /usr/lib/os-release with VERSION_ID set to the full image version
|
||||||
|
# (OSTREE_VERSION, e.g. 44.20261019.0), so Intune shows the build and not just
|
||||||
|
# "44". Himmelblau reports VERSION_ID as the device's OS version and has no
|
||||||
|
# setting for it. The rest of the system keeps the stock VERSION_ID, which
|
||||||
|
# toolbox, flatpak and dnf expect to be the plain release.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SRC=/usr/lib/os-release
|
||||||
|
DEST=/run/himmelblau-os-release
|
||||||
|
|
||||||
|
version="$(. "${SRC}" && echo "${OSTREE_VERSION:-${IMAGE_VERSION:-}}")"
|
||||||
|
|
||||||
|
tmp="$(mktemp "${DEST}.XXXXXX")"
|
||||||
|
if [[ -n "${version}" ]]; then
|
||||||
|
sed "s/^VERSION_ID=.*/VERSION_ID=${version}/" "${SRC}" > "${tmp}"
|
||||||
|
else
|
||||||
|
# No image version (not an ostree/bootc deployment): pass it through as-is.
|
||||||
|
cat "${SRC}" > "${tmp}"
|
||||||
|
fi
|
||||||
|
chmod 0644 "${tmp}"
|
||||||
|
mv -f "${tmp}" "${DEST}"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Generate the os-release reported by Himmelblau to Intune
|
||||||
|
DefaultDependencies=no
|
||||||
|
After=local-fs.target
|
||||||
|
Before=himmelblaud.service himmelblaud-tasks.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/libexec/himmelblau-os-release
|
||||||
|
RemainAfterExit=yes
|
||||||
@@ -20,11 +20,18 @@ packages:
|
|||||||
# himmelblau-selinux compiles its policy module at install time.
|
# himmelblau-selinux compiles its policy module at install time.
|
||||||
- make
|
- make
|
||||||
- selinux-policy-devel
|
- selinux-policy-devel
|
||||||
|
# Intune custom configuration scripts are installed as /etc/cron.d jobs.
|
||||||
|
- cronie
|
||||||
|
|
||||||
add-files:
|
add-files:
|
||||||
- ["himmelblau.conf", "/etc/himmelblau/himmelblau.conf"]
|
- ["himmelblau.conf", "/etc/himmelblau/himmelblau.conf"]
|
||||||
- ["50-himmelblau.preset", "/usr/lib/systemd/system-preset/50-himmelblau.preset"]
|
- ["50-himmelblau.preset", "/usr/lib/systemd/system-preset/50-himmelblau.preset"]
|
||||||
- ["50-himmelblau-user.preset", "/usr/lib/systemd/user-preset/50-himmelblau-user.preset"]
|
- ["50-himmelblau-user.preset", "/usr/lib/systemd/user-preset/50-himmelblau-user.preset"]
|
||||||
|
# Report the full image version (44.20261019.0) as the OS version in Intune.
|
||||||
|
- ["himmelblau-os-release", "/usr/libexec/himmelblau-os-release"]
|
||||||
|
- ["himmelblau-os-release.service", "/usr/lib/systemd/system/himmelblau-os-release.service"]
|
||||||
|
- ["10-himmelblau-os-release.conf", "/usr/lib/systemd/system/himmelblaud.service.d/10-os-release.conf"]
|
||||||
|
- ["10-himmelblau-os-release.conf", "/usr/lib/systemd/system/himmelblaud-tasks.service.d/10-os-release.conf"]
|
||||||
|
|
||||||
postprocess:
|
postprocess:
|
||||||
# The package's %post selects its authselect vendor profile but drops
|
# The package's %post selects its authselect vendor profile but drops
|
||||||
@@ -38,6 +45,8 @@ postprocess:
|
|||||||
getent passwd "${user}" >/dev/null
|
getent passwd "${user}" >/dev/null
|
||||||
done
|
done
|
||||||
grep -q pam_himmelblau.so /etc/pam.d/system-auth
|
grep -q pam_himmelblau.so /etc/pam.d/system-auth
|
||||||
|
chmod 0755 /usr/libexec/himmelblau-os-release
|
||||||
|
test -d /etc/cron.d
|
||||||
|
|
||||||
# himmelblau-selinux builds and loads its module in %posttrans, which does
|
# himmelblau-selinux builds and loads its module in %posttrans, which does
|
||||||
# nothing in a compose; do it here.
|
# nothing in a compose; do it here.
|
||||||
|
|||||||
@@ -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
|
||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Intune custom configuration script for Linux: bring Microsoft Defender for
|
||||||
|
# Endpoint (mdatp) back to the state defender-compliance.sh checks for.
|
||||||
|
#
|
||||||
|
# Intune has no "run only when non-compliant" trigger for Linux, so this runs
|
||||||
|
# on the policy's schedule and only acts on what is wrong; on a healthy device
|
||||||
|
# it only reads `mdatp health`. Himmelblau installs it as an /etc/cron.d job.
|
||||||
|
#
|
||||||
|
# Intune > Devices > Configuration > Create > Linux > Settings catalog >
|
||||||
|
# Custom Configuration:
|
||||||
|
# Execution context: root
|
||||||
|
# Execution frequency: every 1 hour (or 15 minutes while rolling out)
|
||||||
|
# Execution retries: 1
|
||||||
|
# Script: this file, with ONBOARDING_JSON filled in
|
||||||
|
#
|
||||||
|
# Exit status is non-zero when Defender is still not healthy afterwards.
|
||||||
|
|
||||||
|
# Contents of mdatp_onboard.json from the Defender portal: Settings > Endpoints
|
||||||
|
# > Onboarding > Linux Server > "Local Script (Python)". The downloaded
|
||||||
|
# MicrosoftDefenderATPOnboardingLinuxServer.py writes this file to
|
||||||
|
# /etc/opt/microsoft/mdatp/ on the machine it runs on; paste that file's
|
||||||
|
# contents here. Leave the placeholder to skip onboarding.
|
||||||
|
ONBOARDING_JSON=$(cat <<'JSON'
|
||||||
|
REPLACE_WITH_MDATP_ONBOARD_JSON
|
||||||
|
JSON
|
||||||
|
)
|
||||||
|
|
||||||
|
MDATP=/usr/bin/mdatp
|
||||||
|
ONBOARD_FILE=/etc/opt/microsoft/mdatp/mdatp_onboard.json
|
||||||
|
|
||||||
|
log() {
|
||||||
|
logger -t defender-remediation -- "$*"
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print one `mdatp health` field without quotes, a trailing " [managed]" or
|
||||||
|
# the "ATTENTION: ..." lines mdatp prints while unlicensed.
|
||||||
|
field() {
|
||||||
|
"${MDATP}" health --field "$1" 2>/dev/null | grep -v '^ATTENTION' | tail -n1 \
|
||||||
|
| sed -e 's/ \[managed\]$//' -e 's/^"//' -e 's/"$//'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait up to 2 minutes for the daemon to answer.
|
||||||
|
wait_for_daemon() {
|
||||||
|
local i
|
||||||
|
for i in $(seq 1 24); do
|
||||||
|
[[ "$(field healthy)" =~ ^(true|false)$ ]] && return 0
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ! -x "${MDATP}" ]]; then
|
||||||
|
log "mdatp is not installed; it ships in the image, so update or rebase the device."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The image finishes the Defender install on first boot (mdatp-firstboot).
|
||||||
|
if [[ ! -f /var/lib/mdatp-firstboot.done ]]; then
|
||||||
|
log "Defender first-boot setup has not completed; starting it."
|
||||||
|
systemctl start mdatp-firstboot.service
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! systemctl is-active --quiet mdatp.service; then
|
||||||
|
log "mdatp.service is not running; restarting it."
|
||||||
|
systemctl restart mdatp.service
|
||||||
|
fi
|
||||||
|
if ! wait_for_daemon; then
|
||||||
|
log "The Defender daemon does not respond."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$(field org_id)" ]]; then
|
||||||
|
if [[ "${ONBOARDING_JSON}" == REPLACE_WITH_MDATP_ONBOARD_JSON ]]; then
|
||||||
|
log "Defender is not onboarded and this script has no onboarding JSON."
|
||||||
|
else
|
||||||
|
log "Defender is not onboarded; writing ${ONBOARD_FILE}."
|
||||||
|
install -d -m 0755 "$(dirname "${ONBOARD_FILE}")"
|
||||||
|
printf '%s\n' "${ONBOARDING_JSON}" > "${ONBOARD_FILE}.tmp"
|
||||||
|
chown root:mdatp "${ONBOARD_FILE}.tmp"
|
||||||
|
chmod 0600 "${ONBOARD_FILE}.tmp"
|
||||||
|
mv -f "${ONBOARD_FILE}.tmp" "${ONBOARD_FILE}"
|
||||||
|
systemctl restart mdatp.service
|
||||||
|
wait_for_daemon || { log "The Defender daemon does not respond after onboarding."; exit 1; }
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Settings Defender's own policy manages show " [managed]" and can't be
|
||||||
|
# changed locally; this only fixes a locally disabled real-time protection.
|
||||||
|
if [[ "$(field real_time_protection_enabled)" != true ]]; then
|
||||||
|
log "Real-time protection is off; enabling it."
|
||||||
|
"${MDATP}" config real-time-protection --value enabled
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$(field definitions_status)" != up_to_date ]]; then
|
||||||
|
log "Definitions are not up to date; updating them."
|
||||||
|
"${MDATP}" definitions update
|
||||||
|
fi
|
||||||
|
|
||||||
|
healthy="$(field healthy)"
|
||||||
|
log "healthy=${healthy} licensed=$(field licensed) org_id=$(field org_id) rtp=$(field real_time_protection_enabled) definitions=$(field definitions_status)"
|
||||||
|
[[ "${healthy}" == true ]]
|
||||||
@@ -27,7 +27,7 @@ opt-usrlocal: root
|
|||||||
|
|
||||||
repos:
|
repos:
|
||||||
- himmelblau
|
- himmelblau
|
||||||
- microsoft-rhel10
|
- microsoft-fedora44
|
||||||
- microsoft-edge
|
- microsoft-edge
|
||||||
|
|
||||||
include:
|
include:
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
# packages.microsoft.com, limited with includepkgs to the packages the image
|
# packages.microsoft.com, limited with includepkgs to the packages the image
|
||||||
# uses, so nothing else from the RHEL repo can replace a Fedora package.
|
# uses, so nothing else from the Microsoft repo can replace a Fedora package.
|
||||||
|
#
|
||||||
|
# Fedora 44 build of Defender (mdatp): Fedora is a supported Defender
|
||||||
|
# distribution, servers and desktops. Pinned to 44 rather than $releasever so a
|
||||||
|
# new Fedora release doesn't fail the build before Microsoft publishes its repo.
|
||||||
|
|
||||||
[microsoft-rhel10]
|
[microsoft-fedora44]
|
||||||
name=Microsoft Production (RHEL 10)
|
name=Microsoft Production (Fedora 44)
|
||||||
baseurl=https://packages.microsoft.com/rhel/10/prod/
|
baseurl=https://packages.microsoft.com/fedora/44/prod/
|
||||||
enabled=1
|
enabled=1
|
||||||
gpgcheck=1
|
gpgcheck=1
|
||||||
repo_gpgcheck=1
|
repo_gpgcheck=1
|
||||||
|
|||||||
Reference in new issue
Block a user