Linux Management with Microsoft Intune

Exploring Linux Management with Microsoft Intune

With the October 2022 service release of Microsoft Intune, we saw Linux desktop management going GA. However, the current support is only for the Ubuntu desktop distribution, starting from version 22.04 or 20.04 LTS.

Other Linux distributions might be added later in, but in its current iteration, Linux management includes the following functionalities:

  • Conditional Access policy to protect access to company resources via Microsoft Edge.
  • Compliance policy. (There’s support for Bash script for custom compliance)

And as the Tech community announcement reads, a device configuration solution based on Bash scripts to configure and deploy Wi-Fi profiles and certificates to managed Linux endpoints is on the roadmap, to be delivered later this fall.

But for now, let’s go ahead and have our first Linux endpoint enrolled in Intune.

As already mentioned, Intune’s current Linux management capability is for Ubuntu only, with support starting from version 22.04 or 20.04 LTS.

So here I have Ubuntu Desktop version 22.04.1 LTS running in a VM.

NB: Note the codename for the release (jammy for the Ubuntu 22.04), as it will later be used during adding an external repository to the OS to get the corresponding Intune agent package and get it installed.

But before we get started with the actual content, that is to explore Linux management with Microsoft Intune, if you are someone who is completely new to Linux, then I have the below section written just for you to get you up to speed.

Why? Well, you can easily get your Ubuntu system managed with Microsoft Intune just by following the instructions as provided in the official Microsoft documentation, but if you are someone who is not very well versed in the Linux world, then you would not understand what the instructions are doing.

Now there’s nothing wrong with blindly following instructions as laid out by Microsoft, but knowing the process may actually help to improve your knowledge on the matter and might also come helpful in troubleshooting if required.

A quick run-through of some Linux basics

Linux is not an OS

Unlike Windows 10/11 and MacOS which we can call an Operating System (OS), Linux by itself cannot be called a functional OS.

Referring to Linux in the sense of an OS is technically incorrect as It’s actually only a kernel (the most important part of the OS), but pretty much useless by itself.

To understand, refer to the below picture.

Since Linux is open-source, it allows anyone (having the required knowledge) to get the underlying source code, modify it, add extra features and tools to it, to make it into a full-fledged OS that can then be installed and used by other people. And this is how we get a Linux distribution.

Where Linux is only the OS kernel, a Linux distribution (that we use as an OS) is an assortment of applications and utility softwares (various GNU tools and libraries, for example), packaged with the Linux kernel in such a way that its capabilities can meet the end-users needs.

Examples - Ubuntu, CentOS, RedHat Linux, Fedora, etc. are all examples of Linux OS distributions.

There are a thousand Linux distributions that exist out there in the world, some of which are created and commercially backed by companies, while some are entirely community driven.

Families of Linux distribution

Since there are so many variants of Linux distribution available in the market, we can roughly categorize the different Linux distributions into two unique families based on the package management system they use

  • Debian-based distributions which use the .deb package format (installed by the apt tool) like Ubuntu, Linux Mint, Kali Linux, etc.
  • RPM-based distributions which use the .rpm package format (installed by the yum tool) like Fedora, CentOS, RedHat Enterprise Linux, etc.

Since the current Linux management support of Microsoft Intune is limited to Ubuntu (from version 20.04 LTS or 22.04) which is a Debian-based distribution, as such, let’s get going through some basics of the same.

Some basics to get started working with Debian-based Linux distro

Get to know about sudo command

The sudo command allows you to run programs as another user, by default the Root user if you do not specify another account with the -u option, and is commonly used to install, start and stop applications that require root privileges.

In order to be able to use the sudo command, your account must either be added to the sudo group that is granted with sudo access to run all commands, or to the /etc/sudoers file to allow sudo usage for certain commands only.

For the purpose of rights elevation required to run a command, the usage of sudo is preferred over su command, as for sudo, you don’t need to know the Root credential. Instead, you are prompted to provide the credential for your own account.

The Root user account in Ubuntu is disabled by default for security reasons, and users are encouraged to perform system administrative tasks using sudo. The initial user created by the Ubuntu installer is already a member of the sudo group, as such, if you are logged in as the initial user that was created during the OS install process, the account is already granted sudo privileges.

The syntax for using the sudo command is as follows:
sudo [option]

Get to know about APT package management

APT (Advanced Package Tool) is the package management tool that is used to install, update, remove, and otherwise manage software packages on Debian-based Linux OS distributions like Ubuntu. It provides a powerful CLI-based program, apt, via which end-user can, in a simple and efficient way, handle software packages (install, update, upgrade, and manage) on their Debian-based Linux systems.

The syntax for using the apt command to install an app package is as follows: apt install [package_name]

If you want to install multiple packages with a single command, you need to specify the package names as a space-separated list like below

apt install [package_name_1] [package_name_2]
NB: Unless you have switched to the root prompt in the terminal, in most cases, you will be invoking the apt install command with a sudo command, like sudo apt install [package_name] for it to work.
Where does the apt tool install the program(s) from?

Working of apt is based on the apt package index which is like a database file that holds the records of all available packages from the repositories enabled in your system defined in the /etc/apt/sources.list file and files listed in /etc/apt/sources.list.d directory.

Repositories are the sources (network or local) from where apt can obtain the packages and install them onto your system.

Typically this is how standard repository information looks in Ubuntu.

With the default install of Ubuntu, you can get software packages coming from the below four main repositories.

  • Main – Canonical-supported free and open-source software.
  • Universe – Community-maintained free and open-source software.
  • Restricted – Proprietary drivers for devices.
  • Multiverse – Software restricted by copyright or legal issues.
The ISO image that we get to download already contains software packages from the "Main" and "Restricted" repositories, so even if are doing an offline installation with no internet connection available during the Install time, you can still install most of the required softwares of regular use.
What’s the significance of the sudo apt update and sudo apt upgrade commands?

When you run the sudo apt update command, it causes apt to download package information (metadata which helps to identify version and dependencies if any) for all the software packages that are available from all the configured sources and build a local cache in /var/lib/apt/lists directory.

This is the apt package index that was referenced above. Without having this local database of all available packages created, apt would then need to scan through all the sources just to check if a certain package is available or not, which can be time-consuming and not feasible.

This is the reason why it’s recommended to run the sudo apt update command as the first task when you are done with the OS installation.

But there’s one more use.

Say you need to install a software package that is available from a 3rd-party repository that you trust and as such you go ahead and add the repository as a source in Ubuntu’s configuration. Now after adding the repository as a source, without updating the local package index, if you try to run the apt command to install the package, you will get an error, because information of that app package is simply not there in the current local database.

So whenever you add new repositories to Ubuntu, you also need to run the sudo apt update command to rebuild the apt app index.

Now when you run sudo apt update command to update the local package index with the latest changes made in the repositories, while fetching the package information from the respective repositories, if apt finds that, for an installed software, there is an updated package version available, it will only report that but won’t go ahead and update the installed software package.

You need to run the apt list –upgradable command post running the sudo apt update command to see the list of application packages for which an updated version is available in the repositories.

Now if you want your installed software package to be upgraded to the updated package version that is available in the repository, all you need to do is run the sudo apt upgrade command.

When executed, the command matches the versions of installed packages with the local database, and then it will list those packages that have a newer version available. It’s an interactive command and requires end-user consent to continue with the update operation.

For sequence, you always need to run sudo apt update first to update the local database, before executing the sudo apt upgrade command.

You can do it in a one-liner as follows: sudo apt update && sudo apt upgrade -y
The && is a way to run multiple commands in Linux in a way such that the second command runs only when the previous command execution is completed succesfully. 

The -y option at the end provides the user consent that otherwise the sudo apt upgrade command would wait for to proceed with the actual update/upgrade.

Actions of the apt command, such as installation and removal of packages, are logged in the /var/log/dpkg.log log file.

What if you need to install a software package that is not available with the officially supported Ubuntu repositories?

If you want to install software, the package for which is available from a third-party repository, you must add it as a source to Ubuntu’s list of available repositories.

To do that, you can edit the /etc/apt/sources.list file (as root) to add a line in there that corresponds to the 3rd-party repository. However, it's not recommended to make direct edits in the /etc/apt/sources.list file. 

Instead, you can create separate files under /etc/apt/sources.list.d/ to add 3rd-party custom repositories for apt to get app packages from those locations.

However, you cannot just add any 3rd-party repository information to Ubuntu and expect to be able to install software packages available from that repository. You need to do some extra work which is explained below.

Debian repositories have this cryptographic security mechanism which is based on GPG-keys.

GnuPG, also known as GPG, is a complete and free implementation of the OpenPGP standard, that allows you to encrypt and sign your data and communications; it features a versatile key management system, along with access modules for all kinds of public key directories.

Every repository needs to have a unique GPG key associated with it. Packages coming from a particular repository are signed by the GPG key (private key) of the repository for the purpose of source verification.

Thus if you want to add a 3rd-party repository to Ubuntu and install software packages from that repository, you need to retrieve the public GPG-key of the repository and get it added to your system’s trusted keys, associate the key with the repository during adding it as a source for apt so that it trusts the packages coming from this repository.

This way, apt will be able to verify that the package is actually coming from the repository and is not spoofed.

This is all that you need to know before proceeding to follow the instructions of enrolling a device running a supported version of Ubuntu Linux to Microsoft Intune.

Enrolling Ubuntu Linux to Microsoft Intune

Get the app package for Intune agent

To enroll a device to Intune that is running the currently supported version of Ubuntu, first you will need to get the Microsoft Intune app from the Microsoft repository for Linux which is at https://packages.microsoft.com/.

If you happen to check this URL, you will find folders having names of different Linux distros in there. Maybe in the future, we will get to see support announcements for all of them or a few of them atleast. Can't really comment on this now.
If you happen to check this URL, you will find folders having names of different Linux distros in there. Maybe in the future, we will get to see support announcements for all of them or a few of them atleast. Can’t really comment on this now.

If you have understood the section related to APT above, you should be aware of the process that is required to get a package installed on Ubuntu from a 3rd-party repository.

  • First, we need to get the public key associated with the repository and have it added to the trusted keys so that the system can trust the packages coming from the repository.
  • Second, we need to make the repository entry and update the local database to enable installing software packages from the external 3rd-party repository.

Pretty simple that would be. So let’s open the terminal and follow the instructions as given in Microsoft’s documentation.

The first command that you get to run is sudo apt install curl gpg

Again, if you have understood the section related to APT above, you may have already guessed what the command is doing. Still, I will go ahead and break it down for your easy understanding.

  • sudo is used to execute the command with superuser privilege
  • apt install is to install a software package (can be multiple at one go), which in our case is,
    • curl – is a command-line utility for transferring data from or to a remote server. It helps you to download or upload data using one of the supported protocols, including HTTP, HTTPS, SCP, SFTP, and FTP.
    • gpg – is the OpenPGP (Pretty Good Privacy) part of the GNU Privacy Guard (GnuPG) and is again a CLI tool to provide digital encryption and signing services using the OpenPGP standard.

The next command that we run is curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg

The above snap shows me doing some extra work, but I will get to that later. For now, all you need to know is that the above command that you just ran is not a single command but two being piped together.

We use the pipe [|] operator in cases where we want the output of the first command to get routed as the input for the second command, to finally get the desired output. 

The first command in the pipe setup here is curl https://packages.microsoft.com/keys/microsoft.asc and all that it is doing is fetching the public key from the URL specified.

curl is a command-line tool to transfer data to or from a server, using any of the supported protocols (HTTP, FTP, IMAP, POP3, SCP, SFTP, SMTP, TFTP, TELNET, LDAP, or FILE). If not specified otherwise using options, curl writes the received data to stdout stream, meaning it will show the data as received from the URL specified on the terminal screen.

The above snap shows the raw output of running the above command.

Now if you look at the certificate file being retrieved, you can see that the key is not of type GPG, but PGP. (Notice the start and end blocks!)

But since apt only accepts the key files in GPG format, as such we need to convert the retrieved PGP key to its corresponding GPG format.

This is where the use of the pipe [|] operator comes in. Using the pipe operator, we are taking the stdout output of curl and feeding it to the next command which is gpg –dearmor > microsoft.gpg which does the

  • gpg command used with the –dearmor flag is doing the PGP to GPG key conversion, and then
  • >  microsoft.gpg is saving the resultant key file with the name microsoft.gpg to the current working directory.
This is important here. The key file is being saved to the current working directory and that is what I have shown in the snap above. You can use the ls command to see the contents of the current working directory and you can see the file in there. Further, you can use the ls command with the -l option to see the file permissions.

Now that we have retrieved the public key that’s associated with the repository that we want to add, the next step would be to get the key added to your system’s trusted keys.

On Ubuntu, the /usr/share/keyrings directory is the recommended location for your converted GPG files, as it is the default location where Ubuntu stores its keyrings.

And this is why we have our next command which is sudo install -o root -g root -m 644 microsoft.gpg /usr/share/keyrings/

The function of the command is to copy the microsoft.gpg key file from the current working directory to the destination location, which as recommended is, /usr/share/keyrings directory, and at the same time, also modify the file permissions.

The below terminal snapshot should help you understand better.

In here,

  • First I show you the content of the current working directory using the ls command which shows the microsoft.gpg key file that we created earlier.
  • Then I use the ls command with -l option to show the current file permissions set on the microsoft.gpg file.
  • Next, I run sudo install -o root -g root -m 644 microsoft.gpg /usr/share/keyrings/ which as I said is to copy the file to the specified destination and modify the file permissions.
  • So after running the above command, I check the content of the current working directory again to see the microsoft.gpg file in there. (we did a copy action and not move, so this was expected!`)
  • Next, I check the content of the /usr/share/keyrings directory to see the microsoft.gpg file in there as well, meaning the copy was successful.
  • Lastly, I check the permissions of the microsoft.gpg key file present in the location /usr/share/keyrings and you can see the permissions have changed as well from the microsoft.gpg key file that resides in the current working directory.
At this point, there is no further need of the microsoft.gpg key file that is there in the current working directory, and as such can be removed. (or deleted as we say!)

This is why you run the sudo rm microsoft.gpg command.

The rm command is used to remove file(s) (or directory(es) when specified with options -r or -d)

Now the below snap shows the rm command in action and I don’t think it needs any further explanation.

The rm command is used to remove file(s) (or directory(es) when specified with options -r or -d)

Now the below snap shows the rm command in action and I don’t think it needs any further explanation.

Note that at this point, we have retrieved the public key associated with the 3rd-party repository that we want to add and have the key file placed in the recommended location with the correct file permissions set.

The penultimate task that is now pending is to associate the key file with the repository while creating the source list file to make apt understand that packages from this repository need to be trusted if the signature can be verified with the specified key file.

And this is exactly what we are doing with the command sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/ubuntu/22.04/prod jammy main" > /etc/apt/sources.list.d/microsoft-ubuntu-jammy-prod.list'

Now if there is no typo in there, you won't get any output from running the above command.

As usual, let’s go ahead and break it down to see what every component of the command means.

  • deb specifies that the source uses a regular Debian architecture
  • arch=amd64 specifies that we are interested to get the amd64 architecture-compliant package from the source [the source may contain packages for multiple architectures like am64 or arm64]
  • signed-by=/usr/share/keyrings/microsoft.gpg specifies the gpg-key that will be used to verify the packages from this repository
  • https://packages.microsoft.com/ubuntu/22.04/prod jammy main is the URI representing the exact location within the repository from where the package can be found.
  • /etc/apt/sources.list.d/microsoft-ubuntu-jammy-prod.list is the location and name of the new file to be created.
Just as a note, instead of copying the key file to /usr/share/keyrings directory, if we have had the key file placed at the /etc/apt/trusted.gpg.d/ location, then we could have created the source list file without referencing the gpg key to the repository (meaning no value specified with the signed-by flag) and this way also works. 

But this method is not recommended, since placing a key file directly to /etc/apt/trusted.gpg.d/ location makes apt unconditionally trust all other repositories configured and enabled on the system that don't have the signed-by option set.
At this point, we have successfully configured our Ubuntu system with the 3rd-party repository information. 

But if we go ahead and try installing software from that repository straight away, the action will fail. This is because the local package manager database has not been updated with, post the new repository addition. So apt has no idea of the same.

Hence, our last task is to update the APT package index and we do that by running the sudo apt update command.

Post updating the local app package database, we can finally proceed with installing the Intune agent. And for that, you are running the sudo apt install intune-portal command.

Again the command is interactive so it will wait for user consent.

Once the install action completes, it is recommended that you restart your system. Post restart, you can get started with enrolling your device running Ubuntu Linux to Microsoft Intune.

Ubuntu Linux Enrolment to Microsoft Intune

From here, it’s a simple guided flow. You need to click on the Sign in button.

Provide your credentials and sign in.

Obviously, the account needs to have an Intune license assigned and the existing number of enrolled devices that the account has must be lesser than the device limit restriction as set by admin!)

Post successful auth, you will be asked to register your device. Clicking on the Register button triggers the AAD DRS process to create the corresponding Azure AD device object for this device.

Once the AAD DRS process completes, the flow from here is all about Intune enrolment. You click on Begin.

It shows you the “What can my organization see or do when I enroll my device?” screen as we have seen in the company portal flow for user enrolment of mobile devices. Click on Begin again.

This time, the device is registering to Intune doing the device enrolment.

And soon you get to see your device information in the company portal app (or agent). It may take some time for the compliance evaluation to complete.

If there is a compliance policy assigned that requires device encryption, it is recommended that you enable device encryption during OS install itself. 

If there is no compliance policy created yet for the Linux platform, compliance evaluation result depends on the global compliance settings of the tenant - whether "Mark devices with no compliance policy assigned as" is set to enabled or disabled.

Once the compliance evaluation completes, you can start accessing your work resources that are protected with Azure AD Conditional Access policy.

But for that, you will need to get Microsoft Edge as it is the only supported browser for work access from a Linux device.

Installing Microsoft Edge in Ubuntu for accessing Work resources protected with Azure AD Conditional Access

There are two ways that you can install Microsoft Edge on your Ubuntu system, either from the GUI or using the CLI method.

CLI method of Installing Microsoft Edge in Ubuntu

Since we already have the public key of the Microsoft repository for Linux available on the system, all we need to do is create the source list file referencing the same key to the repository.

You may have already guessed that we will be using the below command to do that.

sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/repos/edge stable main" > /etc/apt/sources.list.d/microsoft-edge-dev.list'

Next all we need to do is update the apt package index and we are good to go with the installation. That can be done with a one-liner as below

sudo apt update && sudo apt install microsoft-edge-stable

Once the installation process finishes, you will have Microsoft Edge available in the app launcher or you can simply run microsoft-edge from the terminal to start it.

But if you are a GUI person, then you can save yourself the trouble of installing Microsoft Edge the CLI way and instead follow the below.

GUI way of Installing Microsoft Edge in Ubuntu

Ubuntu comes with Firefox preinstalled, so you can use that to browse to the official Microsoft Edge download page and download Microsoft Edge for Ubuntu. There, you will find two package options for Linux,

  • one that has the .deb extension is for Debian-based Linux distros, and
  • the other with the .rpm extension is applicable for Fedora-based Linux distros.

You need to get the .deb version of the package for Ubuntu since it is a Debian-based distro.

You then need to agree to Microsoft Edge’s Terms of Service, post which the download will begin.

The download process should be saving the .deb package to the Downloads folder by default.

Once the download is complete, you can use the file manager to get to the package, right-click on the package and select the Open with Other Applications option.

Use the Software Install option.

In the new GUI window that opens, click on Install.

There will be a prompt for authentication at this stage. You need to provide administrational credentials for the same to continue with the installation.

As part of the install process, the official Microsoft Edge repository is added to your system’s list of software sources. This ensures that you will be able to upgrade to new versions of Edge as they’re released using Ubuntu’s Software Updater tool.

In the backend, this GUI method is also utlizing apt to get the installation done!

Post successful install, you should have Microsoft Edge ready for your use.

Configuration, Compliance, and Remote actions

At the time of writing this, device configuration policies are not yet available for the Linux platform.

So you do not get to configure Wi-Fi, VPN, Device restrictions, or Certificate profiles as of now. But they are all under work, so will be available soon.

And also, though the feature is in preview still, there is no enrolment restriction that is currently available in Intune to prevent users from enrolling their Linux device. (But how many of our regular users are Linux users to be honest?)

Now if you, as an IT admin, want to be in absolute control to not let your power users try and get their Linux devices enrolled into the tenant, there is a workaround which involves the use of an Azure AD Conditional Access policy set to Block access to the Intune Enrolment service from any Linux device. Timmy Anderson has it wonderfully explained in his blog here.

For compliance, you do get to create a compliance policy for Linux.

It's based on Settings catalog UI and you get to create a compliance policy based on 4 parameters.

You have

  • Allowed Distributions which lets you set the Max and Min OS version and Type which indicates the flavor of the Linux distribution.
For now, this may not be that useful since the current support is for only Ubuntu, that too from version 20.04 LTSC or 22.04 regular release. But later when the feature goes GA and support for other distros are added in, then this can be quite useful.
  • Custom compliance supports the use of a POSIX-compliant shell script that you can create. To know more about how you can configure custom compliance, check this Microsoft documentation.
  • Require device encryption checks the system for device-level encryption enabled on writable fixed disks.
There are several options for disk and partition encryption on Linux operating systems. Intune recognizes any encryption system that uses the underlying dm-crypt subsystem. 

Again, encrypting Linux system volumes after installation is possible but potentially time-consuming. As such it is recommended to set up disk encryption while installing the operating system.
  • Password Policy enables you to set password complexity requirements that must be met on the device.
Remember that user sign-in to Linux device is same as a user sign-in to an Azure AD registered Windows device - the sign-in involves a local account (or can be a Microsoft account as well for Windows) and not the users AD/AAD account.

And at the end, for remote actions, you can either only Retire or Delete the device from Intune.

The End

At the end, I can only say that it’s an impressive initiative by Microsoft to add Linux management capabilities into Microsoft Intune and this is just the beginning of it. I will be eagerly looking ahead to see how it shapes up when it goes GA in the future.

1 Trackback / Pingback

  1. Intune Newsletter - 18th November 2022 - Andrew Taylor

Comments are closed.