---
title: 'Tutorial: Setting Up a Host-Checker Query File on Access Server'
canonical: https://openvpn.net/as-docs/tutorials/tutorial--host-checker-query-file/
product: Access Server Docs
description: Set up compliance checks through software version validation with Access Server and OpenVPN Connect using host-checker queries.
---

# Tutorial: Setting Up a Host-Checker Query File on Access Server

## Overview

OpenVPN Connect for Windows and macOS supports checking the presence of specific applications on a user's device and reporting their version numbers to Access Server. This host-checking feature allows administrators to enforce compliance checks based on specific software being present or updated on client devices. This tutorial will guide you through setting up a host-checker query file, loading it into your Access Server, and utilizing it in connection profiles to enhance security and compliance.

## Prerequisites

- An installed Access Server.
- OpenVPN Connect for Windows or macOS.
- Basic knowledge of regular expressions (regex) to construct application version checks.
- Console access and the ability to get root access.

> **Important**
>
> Ensure that all cluster nodes run the same Access Server version.

## Step 1: Understand the host-checker query file format

The host-checker query file defines which applications OpenVPN Connect will check for on the client device. The file consists of platform-specific or generic (all platforms) checks for specific applications, with each line specifying an application and a regex to match its name.

### File format

```
[PLATFORM1]
NAME1=REGEX1
NAME2=REGEX2
[PLATFORM2]
NAME1=REGEX1
NAME2=REGEX2
```

**PLATFORM** specifies the platform for the check. Use `'win'` for Windows, `'mac'` for macOS, or `'all'` for both.

**NAME** is a short, user-defined name for the application (alphanumeric and underscore only).

**REGEX** is a case-insensitive regular expression to match the full application name.

The version number of each matching application is reported back to Access Server and accessible in a post-authentication script through the `attributes['client_info']` dictionary.

A simple, one-line host-checker query file to check the version of Mozilla Firefox:

```
FIREFOX=^mozilla firefox
```

Additional examples:

- Check if Firefox and TeamViewer are installed on a Windows device:

  ```
  ['win']
  FIREFOX=^mozilla firefox
  TEAMVIEWER=^teamviewer
  ```
- Check if Firefox is installed on Windows devices and if TeamViewer is installed on macOS devices:

  ```
  ['win']
  FIREFOX=^mozilla firefox
  ['mac']
  TEAMVIEWER=^teamviewer
  ```

## Step 2: Create the host-checker query file

1. Create a file called `appver.txt` (or any other name of your choice).
2. Add the desired contents to the file. For our example, we're checking for Mozilla Firefox on both Windows and macOS:

   ```
   ['all']
   FIREFOX=^mozilla firefox
   ```

   > **Important**
   >
   > Using single quotes is required. E.g., `'mac'`.
3. Before adding applications to the file, you should collect the full application names to ensure accurate matching in the query file. You can do this using commands to gather application details for each platform:
   - **For Windows (via PowerShell):**

     ```
     Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
     ```

     This will provide you with the **DisplayName** of each application, which you can then use in your query file.
   - **For macOS:**

     ```
     system_profiler SPApplicationsDataType | grep -e "Location:" -e "Version:"
     ```

     This will list the installed applications along with their **Location** and **Version**, which can also be used for matching in the query file.
4. Add multiple checks for different applications and platforms in the file as needed. For example, you can check for Firefox on Windows and TeamViewer on both Windows and macOS:

   ```
   ['win']
   FIREFOX=^mozilla firefox
   TEAMVIEWER=^teamviewer

   ['mac']
   TEAMVIEWER=^teamviewer
   ```
5. Save and exit.

## Step 3: Load the host-checker query file into Access Server

1. If you didn't create the file directly on your Access Server console, upload it using an SCP or SFTP client.
2. Switch to the scripts directory:

   ```
   cd /usr/local/openvpn_as/scripts/
   ```
3. Load the host-checker file into Access Server:

   ```
   ./sacli --key "vpn.client.app_verify" --value_file="appver.txt" ConfigPut
   ```
4. Restart Access Server to apply the configuration:

   ```
   ./sacli start
   ```
5. Download a new connection profile (.ovpn) so the information in `appver.txt` will be embedded into this profile. This ensures the new connection profile contains the app verification checks defined in your query file.

## Step 4: Embed host-checker instructions into connection profiles

After you load the host-checker query file, the generated connection profiles from your Access Server will automatically include the host-checker instructions. These profiles will check the presence and versions of the specified applications during the VPN connection process.

When users connect to the VPN, OpenVPN Connect reports the version of the specified applications (such as Firefox) to Access Server. The reported version number can be accessed in the post-auth script using the following format:

```
attributes['client_info']['UV_APPVER_FIREFOX']
```

## Step 5: Handle application version in post-auth script

You can now use the reported application version in your post-auth script to determine whether to allow or deny the connection. For example, here’s a simple Python code snippet for checking Firefox's version:

```
from pyovpn.plugin import *

# this function is called by the Access Server after normal authentication
def post_auth(authcred, attributes, authret, info):

    # set this to error string, if auth fails
    error = ""

    if attributes.get('vpn_auth'): # only do this for VPN authentication
        firefox_version = attributes['client_info']['UV_APPVER_FIREFOX']

        # Deny access if Firefox is not installed or has no version
        if firefox_version in ['ERR_NOT_FOUND', 'ERR_NO_VERSION']:
            error = "Firefox is not installed or version not detected."
            print("***** POST_AUTH APP CHECK: connection attempt        : FAILED")
        else:
            print(f"Client Firefox version: {firefox_version}")
            print("***** POST_AUTH APP CHECK: connection attempt        : SUCCESS")

    # process error, if one occurred
    if error:
        authret['status'] = FAIL
        authret['reason'] = error # this error string is written to the server log file
        authret['client_reason'] = error # this error string is reported to the client user

    return authret
```

This script checks if Firefox is installed on the client device. If not, it fails the authentication and informs the user.

To add it to a post-auth script, use these tutorials for help writing your Python script:

- [Tutorial: How to Install a Post-Auth Script](https://openvpn.net/as-docs/tutorials/tutorial--install-post-auth-script.md)
- [Post-Authentication Python Script Guide](https://openvpn.net/as-docs/post-authentication-script-reference.md)

## Error handling

The host-checker can return the following error strings:

- **ERR\_NOT\_FOUND:** The application wasn't found on the client.
- **ERR\_NO\_VERSION:** The application doesn't have a detectable version number.
- **ERR\_MANY\_FOUND:** More than one application matched the regex.
- **ERR\_REGEX:** The regular expression couldn't be parsed.

You can handle these errors in the post-auth script as shown in the example above.

---

Prev: [Tutorial: How to Set Up SAML Group Mapping with a Post-Auth Script](https://openvpn.net/as-docs/tutorials/tutorial--post-auth-saml-group-mapping.md)
Next: [Tutorial: Implementing a Challenge/Response Authentication in Access Server](https://openvpn.net/as-docs/tutorials/tutorial--challenge-response-authentication.md)
Index: https://openvpn.net/as-docs/llms.txt
