Skip to content

Certificates

SSL certificates should be used to secure web access and connections to virtual desktops with viewers.

IsardVDI will generate a default self signed generic certificate when installing from the first time if you don't configure letsencrypt parameters. That's why browsers will ask for certificate acceptance on first access to IsardVDI web...

If you configure letsencrypt domain parameters in isardvdi.cfg then it will generate one for you and autorenew it (remind that you should keep your server ports 80 and 443 open for external access through this domain). Also, if no certificate present it will generate a new self signed to make use of it by default.

You can also use your own certificate by replacing the auto-generated /opt/isard/certs/default/chain.pem with your concatenated certificate.

This works for all flavours (portal, video, all-in-one) as they all use the same certificate configuration.

Certificate Types and Setup

IsardVDI supports three types of SSL certificates:

1. Self-Signed Certificates (Default)

  • Generated automatically when no other certificate is configured
  • Good for: Testing, development, private networks
  • Location: /opt/isard/certs/default/chain.pem
  • Browser warning: Users will see security warnings and need to manually accept the certificate
  • Automatically generated and renewed when properly configured
  • Good for: Production deployments with public domain access
  • Requirements:
  • Public domain name pointing to your server
  • Ports 80 and 443 accessible from internet
  • Valid email address for Let's Encrypt notifications

Configuration in isardvdi.cfg:

DOMAIN=your-domain.com
LETSENCRYPT_EMAIL=admin@your-domain.com

# Optional: Separate domain for video hypervisor flavour
VIDEO_DOMAIN=video.your-domain.com

Renewal: Automatic daily renewal at 2:00 AM (Alpine Linux default schedule)

⚠️ Important: If you initially started with self-signed certificates and want to switch to Let's Encrypt, you must remove the existing certificates first:

docker-compose down
rm -rf /opt/isard/certs/default/*
# Update your isardvdi.cfg with DOMAIN and LETSENCRYPT_EMAIL
docker-compose up -d

3. Custom/Commercial Certificates

  • Manual installation of certificates from Certificate Authorities
  • Good for: Enterprise environments with existing PKI infrastructure
  • Supports: Commercial certificates, internal CA certificates, wildcard certificates

Spice certificates needs to be self-signed and are autogenerated and distributed automatically to auto-registered hypervisors. They are kept at /opt/isard/certs/viewers folder.

Manage certificates

Certificates are stored in path /opt/isard/certs/ where always will be the one self-signed or letsencrypt with name chain.pem.

If you are using self-signed or auto generated letsencrypt certificates you don't need to do anything else.

You can set your own certificate as said before. Follow this guide to generate your custom-xxxxx-chain.pem from your certificates.

Custom Certificate Installation

To install your own certificate, replace the auto-generated certificate:

# Stop IsardVDI
docker-compose down

# Remove existing certificates
rm -rf /opt/isard/certs/default/*

# Create your concatenated certificate as chain.pem
cat server-cert.pem server-key.pem > /opt/isard/certs/default/chain.pem

# Restart IsardVDI
docker-compose up -d

Commercial Certificate Example

For commercial certificates, include the intermediate chain:

# domain.crt:       domain certificate
# intermediate.pem: intermediate certificate
# domain.key:       private key

docker-compose down
rm -rf /opt/isard/certs/default/*
cat domain.crt intermediate.pem domain.key > /opt/isard/certs/default/chain.pem
docker-compose up -d

External Let's Encrypt Certificate

If you have a Let's Encrypt certificate obtained externally (not auto-generated by IsardVDI):

docker-compose down
rm -rf /opt/isard/certs/default/*
cat fullchain.pem privkey.pem > /opt/isard/certs/default/chain.pem
docker-compose up -d

Custom Certificate for All Flavours

All IsardVDI flavours (portal, video, all-in-one, hypervisor) use the same certificate configuration. There is no separate video certificate - all web traffic uses the same chain.pem file.

Examples with certificates from vendors

Commercial certificate

Put your concatenated certificate with correct name in /opt/isard/certs/default/ (replace everythig that it is already in that folder).

Then restart portal (or video) container.

docker restart isard-portal

Now you may connect to IsardVDI server using the qualified CN as provided with your certificate.

NOTE: Wilcard certificates have been also validated with this procedure to be working as expected. See example below:

Example wildcard SSL Certificate

For example you have a wildcard commercial certificate from a company (let's say you bought *.isardvdi.com). You will get this files from your certificate provider:

  • wildcard_isardvdi_com.crt.pem: Your wilcard certificate.
  • GandiStandardSSLCA2.pem: This is the intermediate certificate from certificate authority (in this example is gandi.net the provider). You can always get this certificate by copying or exporting from your browser certificate settings or download it from their webpage (i.e. wget -q -O - https://www.gandi.net/static/CAs/GandiStandardSSLCA2.pem)
  • wildcard_isardvdi_com.key.pem: Your certificate private key.

We will need to transform this files into the chain:

cat wildcard_isardvdi_com.crt.pem GandiStandardSSLCA2.pem wildcard_isardvdi_com.key.pem > /opt/isard/certs/default/chain.pem

Then restart portal (or video) container.

docker restart isard-portal

Reset certificates

If you replaced certificates and nothing worked it is recommended to start the proccess again by resetting certificates. If you manipulate certificates in the folder it could confuss IsardVDI certificate processing code.

You can always get your IsardVDI working again with self signed certificates by removing /opt/isard/certs/default folder. IsardVDI will generate and set up a new self signed certificate again. Procedure will be:

docker-compose down
rm -rf /opt/isard/certs/default/*
docker-compose up -d

You may have done a backup of your previously working self signed certificates and you could now also copy those ones in default certs folder instead of generating new ones.

Troubleshoot certificates

Common Issues and Solutions

Certificate Not Loading/Browser Still Shows Self-Signed

  1. Check certificate file exists and is valid:

    ls -la /opt/isard/certs/default/
    openssl x509 -in /opt/isard/certs/default/chain.pem -text -noout
    

  2. Restart portal container:

    docker restart isard-portal
    

  3. Check container logs:

    docker logs isard-portal
    

Let's Encrypt Certificate Generation Failed

  1. Verify domain points to your server:

    nslookup your-domain.com
    

  2. Check ports 80/443 are accessible:

    netstat -tulpn | grep :80
    netstat -tulpn | grep :443
    

  3. Check Let's Encrypt logs:

    docker exec isard-portal ls -la /var/log/letsencrypt/
    docker exec isard-portal cat /var/log/letsencrypt/letsencrypt.log
    

Continuous HAProxy Reloads (Fixed in Recent Versions)

If you experience frequent HAProxy reloads, ensure you're using the latest version which includes: - Single cron daemon for certificate renewals (no dual crond processes) - Single reload trigger per certificate operation (inotify-based reloads only)

Certificate Renewal Issues

  • Renewal time: Automatic renewal attempts occur daily at 2:00 AM
  • Manual renewal test:
    docker exec isard-portal certbot renew --dry-run
    

Emergency Certificate Reset

Reset to Self-Signed Certificates

If certificates become corrupted or unusable:

# Stop IsardVDI
docker-compose down

# Remove only default certificates (BACKUP FIRST if needed)
sudo rm -rf /opt/isard/certs/default/*

# Restart - will generate new self-signed certificates
docker-compose up -d

Reset Let's Encrypt Certificates

If Let's Encrypt certificates are expired or corrupted and you want to request fresh ones:

# Stop IsardVDI
docker-compose down

# Remove both default and letsencrypt certificates (BACKUP FIRST if needed)
sudo rm -rf /opt/isard/certs/default/*
sudo rm -rf /opt/isard/certs/letsencrypt/*

# Ensure DOMAIN and LETSENCRYPT_EMAIL are configured in isardvdi.cfg
# Restart - will request new Let's Encrypt certificates
docker-compose up -d

Internal Certificate Flow

Understanding how certificates work internally in IsardVDI:

Certificate Processing Pipeline

  1. Container Startup (haproxy-docker-entrypoint.sh):
  2. Checks if /certs/chain.pem exists and is non-empty
  3. If missing → triggers auto-generate-certs.sh (self-signed)
  4. If present → uses existing certificate

  5. Let's Encrypt Flow (letsencrypt.sh):

  6. Runs during container preparation if LETSENCRYPT_DOMAIN and LETSENCRYPT_EMAIL are set
  7. Uses certbot certonly --standalone on port 80 during startup
  8. Deploys certificate via letsencrypt-hook-deploy-concatenante.sh
  9. Creates /etc/environment.letsencrypt for cron environment variables

  10. Certificate Deployment (letsencrypt-hook-deploy-concatenante.sh):

  11. Concatenates fullchain.pem + privkey.pem/certs/chain.pem
  12. Uses atomic file operations (temporary file → move)
  13. Triggers HAProxy reload via inotify monitoring

  14. Automatic Renewal (letsencrypt-renew-cron.sh):

  15. Scheduled daily at 2:00 AM via Alpine Linux cron (/etc/periodic/daily/)
  16. Sources environment variables from /etc/environment.letsencrypt
  17. Uses certbot renew --http-01-port 8080
  18. Automatically calls deployment hook on successful renewal

  19. HAProxy Integration:

  20. SSL Termination: HAProxy binds to port 8443 with ssl crt /certs/chain.pem
  21. TCP Frontend: Port 443 routes to SSL terminator on 8443
  22. File Monitoring: inotifyd watches /certs/chain.pem:c for changes
  23. Automatic Reload: HAProxy reloads when certificate file changes

File Locations and Purposes

Path Purpose
/opt/isard/certs/default/chain.pem Primary certificate - auto-generated (self-signed), Let's Encrypt, or custom
/opt/isard/certs/letsencrypt/ Let's Encrypt working directory (volume mount)
/opt/isard/certs/viewers/ Spice certificates for hypervisors

Certificate Logic

IsardVDI certificate handling is simple:

  1. HAProxy always uses /opt/isard/certs/default/chain.pem
  2. chain.pem contains:
  3. Let's Encrypt certificate (if LETSENCRYPT_DOMAIN configured and obtained successfully)
  4. Custom certificate (if you replaced the auto-generated one)
  5. Self-signed certificate (auto-generated as fallback)

Please refer to the admin faq about certificates section for additional troubleshooting.