Secure Remote Access Using Azure App Proxy + Apache Guacamole

A secure alternative to VPNs and Bastion for accessing RDP and SSH resources.


Introduction

Remote access is always a challenge for organizations. Traditional options like VPNs, RDS Gateways, and third-party remote access tools often introduce security risks, complex configurations, and ongoing maintenance overhead.

Microsoft Entra Application Proxy provides a different approach. Instead of exposing services through inbound firewall rules or DMZ infrastructure, the Application Proxy connector creates an outbound reverse tunnel to Microsoft Azure, eliminating the need to open ports to the internet.

Because authentication happens through Microsoft Entra ID first, organizations can enforce Conditional Access policies, MFA, and identity-based security controls before a user ever reaches the internal application being published.

This means internal web applications can be securely exposed using a Zero Trust Network Access (ZTNA) model. One particularly powerful use case is publishing Apache Guacamole, a browser-based remote access gateway.

Apache Guacamole provides a centralized portal for RDP, SSH, and VNC access to internal systems. By combining Guacamole with Azure Application Proxy, organizations can build a secure, scalable, identity-driven remote access solution without relying on traditional VPN infrastructure.


Architecture

The architecture for this solution is fairly lightweight and can be deployed using only a few components.

Required Components

  • Microsoft Entra ID P1 or P2 – Used for authentication, Conditional Access policies, and Azure Application Proxy.
  • Windows Server or Windows VM – Hosts the Azure Application Proxy Private Access Connector, which creates the outbound connection to Azure.
  • Linux or Windows Server – Hosts Apache Guacamole and the PostgreSQL database. In my experience, the easiest deployment method is running Guacamole with Docker, which works well on either Windows or Linux.

The ultimate architecture and workflow are visualized in the diagram below.

When a client or user initiates a web request to the Azure Application Proxy external URL, they are immediately redirected to Microsoft Entra ID for authentication (login.microsoftonline.com). If the user has already authenticated and selected the “remember me” option, the authentication process may occur silently using their existing session.

After successful authentication, Azure Application Proxy validates the request and forwards the traffic through the Application Proxy Connector installed on the internal Windows machine. The connector maintains a persistent outbound connection to Azure, meaning no inbound firewall ports need to be opened.

Once the request reaches the internal network, it is forwarded to the Apache Guacamole server, where the user can access configured RDP, SSH, or VNC connections through a browser-based interface.


Implementation

This implementation assumes you already have the following resources available:

  • A Windows Server or Windows client VM
  • An Ubuntu VM
  • Internal DNS management capable of creating A records (this will become important later)

Apache Guacamole Docker Setup

On your Ubuntu VM, run the following commands.

Install Docker

sudo apt update && sudo apt upgrade -y
sudo apt install ca-certificates curl gnupg -y
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

Setup Guacamole

Create a working directory:

mkdir ~/guacamole && cd ~/guacamole
mkdir init

Generate the Guacamole database initialization script:

docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgres > ./init/initdb.sql

Create the docker-compose.yml File:

services:
guacd:
image: guacamole/guacd
container_name: guacd
restart: always
postgres:
image: postgres:15-alpine
container_name: guac-postgres
restart: always
environment:
POSTGRES_DB: guacamole_db
POSTGRES_USER: guacamole_user
POSTGRES_PASSWORD: YourStrongPassword
volumes:
- ./init:/docker-entrypoint-initdb.d
- ./data:/var/lib/postgresql/data
guacamole:
image: guacamole/guacamole
container_name: guacamole
restart: always
ports:
- "8080:8080"
environment:
GUACD_HOSTNAME: guacd
POSTGRES_HOSTNAME: postgres
POSTGRES_DATABASE: guacamole_db
POSTGRES_USER: guacamole_user
POSTGRES_PASSWORD: YourStrongPassword
depends_on:
- guacd
- postgres

Start the Containers

Start the stack with:

docker compose up -d

Once complete, verify that the Guacamole web interface is accessible locally.

Example:

http://<GuacServerIP>:8080/guacamole

Azure App Proxy Setup

Navigate to Microsoft Entra ID using your preferred method.

Go to Manage > Application Proxy, select ‘Download connector service’…

Install the connector on a Windows machine that is always running and has network connectivity to your Apache Guacamole instance.

Before proceeding, verify connectivity by opening a browser on the connector machine and navigating to:

http://<GuacServerIP>:8080/guacamole

If the page loads successfully, the connector machine has proper connectivity.

IMPORTANT

Before Azure Application Proxy can publish the Guacamole instance, the connector server must be able to resolve the Guacamole hostname.

On the connector machine, run the following commands:

nslookup <guacServerHostname>
nslookup <guacServerIP>

Both queries must resolve correctly.

If they do not, review the troubleshooting section below for DNS resolution guidance.

Once complete, go back to Entra > Application Proxy, and hit ‘Configure an app’…

Enter the following…

Leave all other settings as default or configure as you desire.


Troubleshooting – Tips

DNS Issues

If you attempt to publish the Guacamole server using its internal IP address, Azure Application Proxy will not function properly. The connector must be able to resolve a hostname to an IP address.

For example, in my lab environment I use a domain such as:

contoso.net

I run OPNsense as my firewall, which allows forwarding DNS queries for specific domains to designated DNS servers.

Example workflow:

Client queries contoso.net
→ OPNsense forwards request
→ DNS server 10.0.0.20 resolves the record

If this type of DNS infrastructure is not available, you can deploy a Windows DNS server and configure the Application Proxy connector VM to use it as its primary DNS server.

Long story short: if you are not actively managing DNS in your network, you should be.

Azure App Proxy Url Quirks

Both the internal and external URLs must include /guacamole.

If this path is omitted, the application will not load properly.

For example:

Incorrect:

http://myGuacIP:8080/

Correct:

http://myGuacIP:8080/guacamole

The same rule applies to the external Azure App Proxy URL.

While this behavior can be modified with additional configuration, the default deployment expects the /guacamole path.

Recommendations

After completing the installation:

  • Immediately change the default guacadmin password
  • Configure user groups and access control lists
  • Enable Microsoft Entra Conditional Access policies
  • Require MFA for all remote access sessions

These steps ensure your remote access portal remains secure.


Conclusion

By combining Apache Guacamole with Microsoft Entra Application Proxy, you can build a lightweight Zero Trust remote access solution without exposing inbound firewall ports or maintaining traditional VPN infrastructure. Authentication happens through Microsoft Entra ID, allowing organizations to enforce MFA and Conditional Access policies before users reach internal resources. This makes it a flexible option for homelabs, consultants, and organizations looking for a secure remote access gateway.

Additional Notes & References:

If you’d like help designing secure remote access solutions using Microsoft Azure and Microsoft Entra ID, feel free to reach out to Algo IT Pro LLC for consulting and implementation services.

Leave a comment