GLAuth
Overview
GLAuth is a lightweight, open source LDAP authentication server. It is a single Go binary that serves an LDAP directory defined entirely by a flat configuration file. It gives downstream services such as dashboards, git forges, wikis, media servers and monitoring tools one shared set of user accounts to authenticate against. For small environments, it is an opinionated, simpler alternative to a full OpenLDAP or Active Directory deployment.
This guide covers deploying and configuring GLAuth on Ubuntu 24.04 on Azure with the SecureAnyCloud Azure Marketplace image. The image installs GLAuth 2.5.0 from the official prebuilt release binary and runs it under systemd as an unprivileged glauth user. The service holds only the CAP_NET_BIND_SERVICE capability, so it can bind the standard privileged ports.
Security by design: no default credentials and no demo users. GLAuth's upstream sample config ships several well-known demonstration accounts (serviceuser, johndoe, hackers) with published password hashes. None of those ship in this image. Each VM gets its own unique login, written to /root/glauth-credentials.txt, so no two instances share a credential.
What you get:
- GLAuth 2.5.0 from the official prebuilt release binary, run under systemd as the unprivileged
glauthuser (glauth.service) - A plain LDAP endpoint on
0.0.0.0:389and an LDAPS endpoint (LDAP over implicit TLS) on0.0.0.0:636, both bound on all interfaces for downstream services - No web interface and no database. The directory lives in the single config file
/etc/glauth/glauth.cfg - A single admin/service bind account,
cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com, with a per-instance password generated on the first boot of every VM. Its GLAuthpasssha256hash is written into a freshglauth.cfg, and the login is recorded in/root/glauth-credentials.txt(mode 0600, root only) - A per-instance self-signed TLS certificate for LDAPS, generated on first boot, which you replace with your own for production
- The config file backend, so you manage users and groups by editing one readable TOML file (
/etc/glauth/glauth.cfg) and restarting the service - The optional GLAuth REST API left disabled to keep the attack surface minimal
Prerequisites
- An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
- A subscription to the GLAuth listing on Azure Marketplace
- Network security group (NSG) rules that allow TCP 22 (admin), TCP 389 (LDAP) and TCP 636 (LDAPS) from the services that will authenticate against the server
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is ample for a small directory. GLAuth is extremely light, so you need a larger size only for very high bind volumes.
Deploy from the Azure Portal
In the Azure Marketplace, search for GLAuth, select the SecureAnyCloud publisher, and click Create.
Configure the network security group to allow TCP 389 (LDAP) and TCP 636 (LDAPS) from the application networks that will bind to the directory, and TCP 22 for administration. Restrict ports 389 and 636 to your internal application subnets rather than the whole internet.
Deploy from the Azure CLI
RG="ldap-prod"; LOCATION="eastus"; VM_NAME="glauth1" IMAGE_URN="sac1647283583153:glauth-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:glauth-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$IMAGE_URN" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 389 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 636 --priority 1002
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1003Review the first boot
On first boot, the image generates a unique admin bind password and renders /etc/glauth/glauth.cfg from the shipped template. It also generates a per-instance self-signed LDAPS certificate, starts glauth, and writes /root/glauth-credentials.txt. This completes within seconds.
SSH in as azureuser and read the credentials file:
sudo cat /root/glauth-credentials.txtThe file records the admin username (cimgadmin), the generated password, the base DN (dc=glauth,dc=com), the admin bind DN, and the LDAP and LDAPS URIs for this VM.
Confirm the service is running
Check that glauth.service is active and that glauth --version reports 2.5.0. Then confirm with ss that GLAuth is listening on :389 (LDAP) and :636 (LDAPS) on all interfaces.
systemctl is-active glauth.service /opt/glauth/glauth --version ss -tlnp | grep -E ':389 |:636 'Search the directory over LDAP
Read the admin password from the credentials file into a shell variable, then run an authenticated search against the loopback address. GLAuth returns the directory tree: the base DN, the ou=users and ou=groups containers, the svcaccts group, and the cimgadmin admin account.
PW=$(sudo grep '^GLAUTH_ADMIN_PASSWORD=' /root/glauth-credentials.txt | cut -d= -f2-) ldapsearch -x -LLL -H ldap://127.0.0.1:389 \
-D "cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com" -w "$PW" \
-b "dc=glauth,dc=com" "(objectClass=*)" dn cn uidNumber gidNumberThe admin binds with the short DN cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com. GLAuth reports the canonical entry under an ou=users level, as cn=cimgadmin,ou=svcaccts,ou=users,dc=glauth,dc=com. Either form authenticates, and downstream services can use the short bind DN.
Connect over LDAPS and confirm bad passwords are rejected
The same directory is served over LDAPS on port 636 with implicit TLS. The shipped certificate is per-instance and self-signed, so pass LDAPTLS_REQCERT=never for this test. In production, install your own certificate and validate it.
A bind with a wrong password is rejected with LDAP result 49 (Invalid credentials).
PW=$(sudo grep '^GLAUTH_ADMIN_PASSWORD=' /root/glauth-credentials.txt | cut -d= -f2-) LDAPTLS_REQCERT=never ldapsearch -x -LLL -H ldaps://127.0.0.1:636 \
-D "cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com" -w "$PW" \
-b "dc=glauth,dc=com" "(cn=cimgadmin)" dn cnOUT=$(ldapsearch -x -H ldap://127.0.0.1:389 \
-D "cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com" -w "wrong-password" \
-b "dc=glauth,dc=com" "(cn=cimgadmin)" 2>&1 || true)
echo "$OUT" | grep -i "invalid credentials (49)"Review the secure-by-default configuration
No default or shared credentials ship in the image. The credentials file is 0600 root:root, and the admin password is unique to this VM. The directory uses the config file backend, and none of the upstream demo users (serviceuser, johndoe, hackers) are present.
sudo stat -c '%n %a %U:%G' /root/glauth-credentials.txt grep -E 'datastore|baseDN|name = ' /etc/glauth/glauth.cfg echo -n 'demo users present: '; grep -cE 'serviceuser|johndoe|hackers|otpuser' /etc/glauth/glauth.cfg || trueAdd your own users and groups
You manage the directory by editing /etc/glauth/glauth.cfg. Each user is a [[users]] block, and each group is a [[groups]] block.
GLAuth passwords use passsha256, which is the SHA-256 hex digest of the password. Generate a hash for a new user, add the block, and restart the service. In the example, replace <new-password> with the real password you choose.
# 1) generate the GLAuth passsha256 for the new user's password printf '%s' '<new-password>' | sha256sum # 2) add a [[users]] block for the user to /etc/glauth/glauth.cfg (see the snippet below), # pasting the hash above into passsha256, then apply the change:
sudo systemctl restart glauthAdd a block like the following to /etc/glauth/glauth.cfg. The primarygroup value is the gidnumber of an existing [[groups]] block:
[[users]] name = "alice" givenname = "Alice" mail = "alice@example.com" uidnumber = 5010 primarygroup = 5501 passsha256 = "PASTE_THE_SHA256_HEX_HERE" [[users.capabilities]] action = "search" object = "dc=glauth,dc=com" [[groups]] name = "people" gidnumber = 5502After restarting, alice binds as cn=alice,ou=svcaccts,dc=glauth,dc=com (or cn=alice,ou=people,dc=glauth,dc=com if her primary group is people).
Point an application at GLAuth
Most self-hosted apps authenticate against GLAuth with a bind DN and password. The values below map directly onto the credentials file.
This example shows a Grafana [auth.ldap] server block. The same base DN, bind DN and search settings apply to Gitea, Nextcloud, Jenkins and similar tools.
[[servers]] host = "<glauth-vm-ip>" port = 389 bind_dn = "cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com" bind_password = "the-admin-password-from-the-credentials-file" search_filter = "(cn=%s)" search_base_dns = ["dc=glauth,dc=com"]For production, create a dedicated read-only service account in glauth.cfg for each application instead of reusing the admin bind account. Connect over LDAPS (port 636) with a certificate your clients trust.
Replace the LDAPS certificate for production
The image generates a per-instance self-signed certificate for LDAPS. For production, install a certificate issued for your server's hostname so that clients can validate it.
Generate or obtain the certificate, point glauth.cfg [ldaps] cert and key at it, and restart. In the example, replace <your-domain> with your hostname.
sudo openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes \
-keyout /etc/glauth/certs/glauth.key -out /etc/glauth/certs/glauth.crt \
-subj "/CN=ldap.<your-domain>"
sudo chown root:glauth /etc/glauth/certs/glauth.key
sudo systemctl restart glauthSecurity recommendations
Restrict the NSG. Allow TCP 389 and 636 only from the application subnets that authenticate against GLAuth, and TCP 22 for administration only. Do not expose the LDAP ports to the public internet.
Prefer LDAPS. Use port 636 (implicit TLS) for binds that carry credentials, and install a certificate your clients trust (Step 10).
Use dedicated service accounts. Create a read-only [[users]] account per application with a narrow search capability instead of reusing the admin bind account.
Protect the config file. /etc/glauth/glauth.cfg holds the password hashes and is 0640 root:glauth. Keep it root-owned and back it up, because it is the single source of truth for your directory.
Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
Support and Licensing
GLAuth is an open source project distributed under the MIT License. This SecureAnyCloud image bundles the unmodified official GLAuth release binary.
SecureAnyCloud provides the packaging, the systemd hardening, the per-instance credential and TLS automation, the paired deploy guide, and 24/7 support with a guaranteed 24-hour response SLA.
SecureAnyCloud is not affiliated with or endorsed by the GLAuth project. GLAuth is a mark of its respective owner and is used here only to identify the software.
Deploy on Azure
Find GLAuth on Ubuntu 24.04 LTS on the Azure Marketplace, published by SecureAnyCloud. Deploy from the Portal or the Azure CLI as shown above.
Need Help?
Email sales@secureanycloud.com for deployment help, configuration questions or licensing enquiries.
Deploy on Azure
Launch GLAuth 2.5.0 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
GLAuth is a lightweight, open source LDAP authentication server. It is a single Go binary that serves an LDAP directory defined entirely by a flat configuration file. It gives downstream services such as dashboards, git forges, wikis, media servers and monitoring tools one shared set of user accounts to authenticate against. For small environments, it is an opinionated, simpler alternative to a full OpenLDAP or Active Directory deployment.
This SecureAnyCloud image installs GLAuth 2.5.0 from the official prebuilt release binary and runs it under systemd as an unprivileged glauth user. The service holds only the CAP_NET_BIND_SERVICE capability, so it can bind the standard privileged ports.
Security by design: no default credentials and no demo users. GLAuth's upstream sample config ships several well-known demonstration accounts (serviceuser, johndoe, hackers) with published password hashes. None of those ship in this image. No two instances share a credential.
What you get:
- GLAuth 2.5.0, answering plain LDAP on port 389 and LDAPS (LDAP over implicit TLS) on port 636
- No web interface and no database. The directory lives in the single config file
/etc/glauth/glauth.cfg - A unique admin bind password generated on the very first boot of every instance. Its GLAuth
passsha256hash is written into a freshglauth.cfg, and the login is written to/root/glauth-credentials.txt(mode 0600, root only) - A per-instance self-signed TLS certificate generated for LDAPS
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network and inbound ports 389 (LDAP) and 636 (LDAPS) from the application subnets that will authenticate against the directory
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
Recommended instance type: m5.large (2 vCPU, 8 GB RAM) is ample for a small directory. GLAuth is extremely light, so you need a larger size only for very high bind volumes.
Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance.
Under Application and OS Images, choose AWS Marketplace AMIs and search for GLAuth. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick your instance type (m5.large recommended), your key pair, and a security group configured as described in Step 2. Then launch the instance.
Launch from the AWS CLI
Replace the values in the command with the AMI ID of the SecureAnyCloud GLAuth listing in your Region, and with your key pair name, subnet and security group.
AMI_ID="<ami-id>"
# the sac GLAuth AMI in your Region KEY_NAME="my-keypair" SUBNET_ID="<subnet-id>" SG_ID="<security-group-id>" aws ec2 run-instances \
--image-id "$AMI_ID" \
--instance-type m5.large \
--key-name "$KEY_NAME" \
--subnet-id "$SUBNET_ID" \
--security-group-ids "$SG_ID" \
--metadata-options "HttpTokens=required" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=glauth}]'Configure the security group to allow TCP 389 (LDAP) and TCP 636 (LDAPS) from the application subnets that will bind to the directory, and TCP 22 for administration. Restrict ports 389 and 636 to your internal application subnets rather than the whole internet.
Connect to your instance
Connect over SSH with your EC2 key pair. On Ubuntu 24.04 the login user is ubuntu, for example ssh -i my-keypair.pem ubuntu@<public-ip>.
After you connect, run all administration commands with sudo.
Review the first boot
On first boot, the image generates a unique admin bind password and renders /etc/glauth/glauth.cfg from the shipped template. It also generates a per-instance self-signed LDAPS certificate, starts glauth, and writes /root/glauth-credentials.txt. This completes within seconds.
SSH in and read the credentials file:
sudo cat /root/glauth-credentials.txtThe file records the admin username (cimgadmin), the generated password, the base DN (dc=glauth,dc=com), the admin bind DN, and the LDAP and LDAPS URIs for this instance.
Confirm the service is running
Check that glauth.service is active and that glauth --version reports 2.5.0. Then confirm with ss that GLAuth is listening on :389 (LDAP) and :636 (LDAPS) on all interfaces.
systemctl is-active glauth.service /opt/glauth/glauth --version ss -tlnp | grep -E ':389 |:636 'Search the directory over LDAP
Read the admin password from the credentials file into a shell variable, then run an authenticated search against the loopback address. GLAuth returns the directory tree: the base DN, the ou=users and ou=groups containers, the svcaccts group, and the cimgadmin admin account.
PW=$(sudo grep '^GLAUTH_ADMIN_PASSWORD=' /root/glauth-credentials.txt | cut -d= -f2-) ldapsearch -x -LLL -H ldap://127.0.0.1:389 \
-D "cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com" -w "$PW" \
-b "dc=glauth,dc=com" "(objectClass=*)" dn cn uidNumber gidNumberThe admin binds with the short DN cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com. GLAuth reports the canonical entry under an ou=users level, as cn=cimgadmin,ou=svcaccts,ou=users,dc=glauth,dc=com. Either form authenticates, and downstream services can use the short bind DN.
Connect over LDAPS and confirm bad passwords are rejected
The same directory is served over LDAPS on port 636 with implicit TLS. The shipped certificate is per-instance and self-signed, so pass LDAPTLS_REQCERT=never for this test. In production, install your own certificate and validate it.
A bind with a wrong password is rejected with LDAP result 49 (Invalid credentials).
PW=$(sudo grep '^GLAUTH_ADMIN_PASSWORD=' /root/glauth-credentials.txt | cut -d= -f2-) LDAPTLS_REQCERT=never ldapsearch -x -LLL -H ldaps://127.0.0.1:636 \
-D "cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com" -w "$PW" \
-b "dc=glauth,dc=com" "(cn=cimgadmin)" dn cnOUT=$(ldapsearch -x -H ldap://127.0.0.1:389 \
-D "cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com" -w "wrong-password" \
-b "dc=glauth,dc=com" "(cn=cimgadmin)" 2>&1 || true)
echo "$OUT" | grep -i "invalid credentials (49)"Review the secure-by-default configuration
No default or shared credentials ship in the image. The credentials file is 0600 root:root, and the admin password is unique to this instance. The directory uses the config file backend, and none of the upstream demo users (serviceuser, johndoe, hackers) are present.
sudo stat -c '%n %a %U:%G' /root/glauth-credentials.txt grep -E 'datastore|baseDN|name = ' /etc/glauth/glauth.cfg echo -n 'demo users present: '; grep -cE 'serviceuser|johndoe|hackers|otpuser' /etc/glauth/glauth.cfg || trueAdd your own users and groups
You manage the directory by editing /etc/glauth/glauth.cfg. Each user is a [[users]] block, and each group is a [[groups]] block.
GLAuth passwords use passsha256, which is the SHA-256 hex digest of the password. Generate a hash for a new user, add the block, and restart the service. In the example, replace <new-password> with the real password you choose.
# 1) generate the GLAuth passsha256 for the new user's password printf '%s' '<new-password>' | sha256sum # 2) add a [[users]] block for the user to /etc/glauth/glauth.cfg (see the snippet below), # pasting the hash above into passsha256, then apply the change:
sudo systemctl restart glauthAdd a block like the following to /etc/glauth/glauth.cfg. The primarygroup value is the gidnumber of an existing [[groups]] block:
[[users]] name = "alice" givenname = "Alice" mail = "alice@example.com" uidnumber = 5010 primarygroup = 5501 passsha256 = "PASTE_THE_SHA256_HEX_HERE" [[users.capabilities]] action = "search" object = "dc=glauth,dc=com" [[groups]] name = "people" gidnumber = 5502After restarting, alice binds as cn=alice,ou=svcaccts,dc=glauth,dc=com (or cn=alice,ou=people,dc=glauth,dc=com if her primary group is people).
Point an application at GLAuth
Most self-hosted apps authenticate against GLAuth with a bind DN and password. The values below map directly onto the credentials file.
This example shows a Grafana [auth.ldap] server block. The same base DN, bind DN and search settings apply to Gitea, Nextcloud, Jenkins and similar tools.
[[servers]] host = "<your-glauth-host>" port = 389 bind_dn = "cn=cimgadmin,ou=svcaccts,dc=glauth,dc=com" bind_password = "the-admin-password-from-the-credentials-file" search_filter = "(cn=%s)" search_base_dns = ["dc=glauth,dc=com"]For production, create a dedicated read-only service account in glauth.cfg for each application instead of reusing the admin bind account. Connect over LDAPS (port 636) with a certificate your clients trust.
Replace the LDAPS certificate for production
The image generates a per-instance self-signed certificate for LDAPS. For production, install a certificate issued for your server's hostname so that clients can validate it.
Generate or obtain the certificate, point glauth.cfg [ldaps] cert and key at it, and restart. In the example, replace <your-domain> with your hostname.
sudo openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes \
-keyout /etc/glauth/certs/glauth.key -out /etc/glauth/certs/glauth.crt \
-subj "/CN=ldap.<your-domain>"
sudo chown root:glauth /etc/glauth/certs/glauth.key
sudo systemctl restart glauthSecurity recommendations
Restrict the security group. Allow TCP 389 and 636 only from the application subnets that authenticate against GLAuth, and TCP 22 for administration only. Do not expose the LDAP ports to the public internet.
Prefer LDAPS. Use port 636 (implicit TLS) for binds that carry credentials, and install a certificate your clients trust (Step 11).
Use dedicated service accounts. Create a read-only [[users]] account per application with a narrow search capability instead of reusing the admin bind account.
Protect the config file. /etc/glauth/glauth.cfg holds the password hashes and is 0640 root:glauth. Keep it root-owned and back it up, because it is the single source of truth for your directory.
Keep the OS patched. Unattended security upgrades remain enabled on the running instance.
Support and Licensing
GLAuth is an open source project distributed under the MIT License. This SecureAnyCloud image bundles the unmodified official GLAuth release binary.
SecureAnyCloud provides the packaging, the systemd hardening, the per-instance credential and TLS automation, the paired deploy guide, and 24/7 support with a guaranteed 24-hour response SLA.
SecureAnyCloud is not affiliated with or endorsed by the GLAuth project. GLAuth is a mark of its respective owner and is used here only to identify the software.
Deploy on AWS
Find GLAuth on the AWS Marketplace, published by SecureAnyCloud. Launch from the console or the AWS CLI as shown above.
Need Help?
Email sales@secureanycloud.com for deployment help, configuration questions or licensing enquiries.
Deploy on AWS
Launch GLAuth on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com