Free multiOTP MFA cloud hosting with Azure App Service

Title image of multiOTP logo, Azure App Service logo, and Windows multiOTP login screen

All product names, logos, and brands used in this post are property of their respective owners.

As you may know from one of my previous posts, I am a big fan of the multiOTP project (specifically, the multiOTP credential provider for Windows). It is one of the few (only?) free and open-source options for applying robust, scalable multifactor authentication (MFA) to Windows console and RDP logins. Do not be deceived by the “free” and “open source” aspects of multiOTP. It matches the capabilities of expensive (paid) 2-factor authentication solutions stride for stride.

I want to reiterate my thanks, kudos, and admiration to SysCo systèmes de communication sa for the countless, ongoing hours of development behind the project, and for making it available as open source.

Depending on your needs, you can deploy and run the multiOTP server (to centrally generate, manage, and validate MFA OTP credentials) to the Microsoft Azure App Service COMPLETELY FREE OF CHARGE! And because Azure App Service is a platform as a service (PaaS) offering, there are no servers or runtime environments to install or maintain - pretty sweet!

In this post, I will describe the process to install and configure the multiOTP server 5.8.x.x (with file-backed configuration, no database) as an Azure App using the free (F1) App Service Plan with PHP 7 on Linux.

Obtain the required multiOTP server files

Download the latest version of multiOTP from the multiOTP download site. At the time of writing, the latest was 5.8.2.9. The required file is multiotp_w.x.y.z.zip (where w.x.y.z is the version number - i.e. 5.8.2.9).

Screenshot of multiOTP download page with the required download circled - multiotp_w.x.y.z.zip (where w.x.y.z is the version number)

Unzip the file, and retrieve only the following files and folders (set them aside in another folder - you will need them later):

multiotp_w.x.y.z\linux\multiotp.server.php
multiotp_w.x.y.z\linux\templates
multiotp_w.x.y.z\linux\templates\template.html

Finally, rename multiotp.server.php to index.php.

Update the multiotp_etc_dir value in the multiOTP server code

As of multiOTP 5.0.4.6 (June 2017), the configuration file path (where multiOTP generates and stores its configuration, users, etc.) is hardcoded to be /etc/multiotp. That is fine on a full Linux server, but with the Azure App Service, the path does not exist (and cannot be created).

That being the case, I made a minor tweak to the multiOTP server code to point the configuration directory to /home/etc/multiotp instead. The /home path exists in Azure Apps, and the child path etc/multiotp can be created via FTPS.

In version 5.8.2.9, I made the following change to line 73,538 of multiotp.server.php (which is renamed to index.php if you are following along):

REPLACE: $multiotp_etc_dir = '/etc/multiotp';

WITH: $multiotp_etc_dir = '/home/etc/multiotp';

The line number may differ in different versions of multiOTP, but ultimately, you need to point the $multiotp_etc_dir variable to /home/etc/multiotp instead of /etc/multiotp.

Create the Azure App (and App Service Plan)

The next step is creating an Azure App and associated App Service Plan to run the multiOTP server in Azure. As noted, if you use the free plan (F1), there is no cost (but there are limitations - see App Service pricing). You will also need an Azure free account (or a funded Azure subscription if you have one).

Login to Azure, navigate to App Services, and click “Create”. Select a Subscription and Resource Group for the Web App, creating new ones if required.

Give the application a unique (preferably randomized) Name; for security (really obfuscation), I used “multiotp-” followed by a random GUID. The Name becomes your multiOTP server URL - in my example:

https://multiotp-6bfa298c-885d-4176-a393-055cabbc9df6.azurewebsites.net

Next, set the Code option for Publish, select PHP 7.4 as the Runtime stack, select Linux for Operating System, and choose an appropriate Region.

Screenshot of Azure App Service configuration screen with appropriate options described above set

For the App Service Plan, create or select a “Free F1” plan. Depending on your requirements, you can seamlessly scale up the App Service Plan later.

Screenshot of Azure App Service Plan selection, highlighting the F1 or “free” plan

Once done, click Review + create and then Create to deploy the Azure resources.

Deploy multiOTP server to the Azure App

Deploying the multiOTP server is very easy, provided you completed the prework in the previous steps. Create a few folders and copy the required multiOTP files (previously extracted/renamed) into their respective locations in the App Service folder tree, and you are off to the races.

Manipulating files and folders in Azure App Service can be handled in multiple ways, but I selected FTPS (using WinSCP of course) for the sake of familiarity. The FTPS username and password for the App Service are found under App Services -> (select the name of your new multiOTP App Service) -> Deployment Center -> FTPS credentials.

Screenshot of Azure App Service Deployment Center blade, with FTPS credentials tab selected. Annotations show copy/paste of hostname, username, and password into WinSCP connection screen, with FTP protocol and explicit encryption via port 21 selected

Once connected, the default folder structure of the App Service appears in WinSCP as follows:

/
├─ ASP.NET/
│  ├─ DataProtection-Keys/
├─ Data/
│  ├─ DaaS/
│    ├─ Sessions/
│      ├─ Active/
│      ├─ Complete/
├─ LogFiles/
│  ├─ kudu/
│    ├─ deployment/
│    ├─ trace/
│  ├─ webssh/
├─ site/
│  ├─ deployments/
│    ├─ tools/
│  ├─ locks/
│  ├─ repository/
│  ├─ wwwroot/

Note that the FTP root points to /home on the Azure App Service filesystem. In other words, the root folder (/) you see in WinSCP is actually /home on the underlying filesystem.

Perform the following operations to deploy multiOTP server to the App Service:

  1. Create a new folder in the FTP root (/) called etc
  2. Create a new subfolder under /etc called multiotp
  3. Create a new subfolder under /site/wwwroot called templates
  4. Delete the default page hostingstart.html from /site/wwwroot
  5. Upload your copy of index.php (modified in the previous steps) to /site/wwwroot
  6. Upload template.html to /site/wwwroot/templates

Once done, the structure of your App Service file system should resemble the following:

/
├─ ASP.NET/
│  ├─ DataProtection-Keys/
├─ Data/
│  ├─ DaaS/
│    ├─ Sessions/
│      ├─ Active/
│      ├─ Complete/
├─ etc/
  ├─ multiotp/
├─ LogFiles/
│  ├─ kudu/
│    ├─ deployment/
│    ├─ trace/
│  ├─ webssh/
├─ site/
│  ├─ deployments/
│    ├─ tools/
│  ├─ locks/
│  ├─ repository/
│  ├─ wwwroot/
│    ├─ hostingstart.html
│    ├─ index.php
│    ├─ templates/
│      ├─ template.html

After the required files and folders are in place, the multiOTP server is ready to run in the Azure App Service! It is worth noting that the first time you access multiOTP server in a browser (more below), it will automatically create additional, required files and folders under /etc/multiotp.

Reset the multiOTP server admin password and create a user

At this point, the multiOTP server should be up and running in the App Service. Browse to the App Service URL (from the App Service blade -> Overview in Azure):

Screenshot of Azure AD App Service Overview screen with two methods to launch or browse the application URL

The multiOTP web interface should appear:

Screenshot of multiOTP server web interface login page

Login with the default username (admin) and password (1234), and immediately reset the admin password.

Screenshot of multiOTP server web interface password reset page

Once reset, you must log in again using the new admin password.

Next, add a user to multiOTP. For the limited scope of this post, the only requirement is that the multiOTP username matches the local or domain username of a user on the Windows device you want to secure with MFA.

Screenshot of multiOTP server web interface and adding a test user “amoss” with default options selected

Then, print the new user’s MFA (OATH-TOTP) enrollment information. Of particular interest is the QR code from step 3 (Token provisioning) - that TOTP credential must be scanned into an authenticator app (like Google Authenticator, Microsoft Authenticator, Duo Mobile, Authy, etc.).

Screenshot of multiOTP server web interface and printing the OATH-TOTP enrollment information for the “amoss” user, created previously

Install the multiOTP credential provider and test

As the last step, install the multiOTP credential provider on the Windows device(s) you want to protect with multi-factor authentication. The credential provider installer is available in a standalone archive on the multiOTP credential provider page (near the bottom), but it is also bundled in the multiotp_w.x.y.z.zip file (credential-provider/multiOTPCredentialProvider-w.x.y.x.exe) downloaded previously.

Ensure your Windows device(s) have the latest x86 and x64 versions of Microsoft Visual C++ Redistributable for Visual Studio installed (see “PREREQUISITES” here).

Run the installer multiOTPCredentialProvider-w.x.y.x.exe, and when prompted, configure the credential provider as follows:

Screenshot of multiOTP credential provider configuration: specifically, ensuring the credential provider points to the Azure App Service URL, setting a relatively high timeout value, like 60 seconds, to accommodate the Azure App Service “wake up” time, especially on the free/F1 plan, and specifying the default shared secret of ClientServerSecret

Screenshot of multiOTP credential provider configuration: specifically, setting the authentication mode according to your needs, I used mandatory MFA for both RDP and console login, and disabling local caching if desired

In brief:

  • Ensure the credential provider points to your Azure App Service URL
  • Set a relatively high timeout value (I used 60 seconds) to accommodate the Azure App Service “wake up” time (especially on the free/F1 plan)
  • Specify the default shared secret of ClientServerSecret
  • Set the authentication mode according to your needs (I used mandatory MFA for both RDP and console login)
  • Disable local caching (if desired)

After installation, log out of Windows and log back in as the test user (with a username matching the one you created in multiOTP previously). After entering the username and password, the multiOTP TOTP passcode screen should appear:

Screenshot of multiOTP credential provider for Windows login screen, with one-time passcode entered from authenticator app

Enter the OTP for the user (displayed in your authenticator app), and you are logged into Windows.

Closing thoughts

I cut some corners and omitted details in this post, so a multiOTP server implementation on the free (F1) Azure App Service Plan is far from production-ready. But, with some additional hardening, configuration, and a paid App Service Plan, you can scale up your Azure-hosted multiOTP server to handle virtually any MFA workload. I hope this helps, and feel free to comment if you have thoughts, questions, or your own multiOTP/Azure App Service experiences to share.