SecureNT Intranet SSL

SSL/TLS Certificates for Internal Networks.

2026-09-18 16:00:00

Private SSL 203 - Securing Internal DevOps Dashboards (Grafana, Portainer, Jenkins)

DevOps teams rely heavily on internal dashboards like Grafana, Portainer, and Jenkins to observe telemetry, manage container runtimes, and deploy production code. Because these utilities reside behind VPNs, inside private VPCs, or within internal subnets, they are frequently accessed via internal hostnames or local IP addresses (such as grafana.internal, jenkins.infra.local, or 10.0.4.15).

Public Certificate Authorities cannot validate or issue certificates for non-public domains or RFC 1918 private IP addresses. As a result, engineering teams often fall back to accessing these mission-critical portals over cleartext HTTP or unmanaged self-signed certificates.

Leaving DevOps interfaces unencrypted or improperly secured presents substantial infrastructure risks. Deploying trusted internal SSL certificates from SecureNT provides seamless, automated HTTPS encryption across all developer operations dashboards.

The Risks of Insecure DevOps Portals

Grafana, Jenkins, and Portainer sit at the center of deployment automation and store elevated privilege tokens, cloud provider secrets, and source code access keys. Running these dashboards without trusted transport encryption introduces severe vulnerabilities:

  • Credential Sniffing on Internal Networks: Cleartext HTTP traffic exposes administrative session cookies, API tokens, and deployment secrets to anyone with packet-level access inside the internal network.
  • Webhook & API Integration Failures: Modern cloud webhooks (e.g., GitHub Enterprise, GitLab, or container registries) mandate valid SSL/TLS handshakes and outright reject self-signed certificates unless insecure skip-verify flags are applied.
  • Browser Security Fatigue & OAuth Friction: Integrating internal dashboards with enterprise Single Sign-On (SSO) providers via SAML or OAuth2 requires HTTPS callbacks. Untrusted certificates break redirect flows and cause recurring browser alerts.

Using SecureNT establishes a verified, enterprise-wide trust chain that secures developer workflows without disruption.

Architecture: Reverse Proxy vs. Native TLS

While services like Grafana and Jenkins can terminate TLS natively, deploying an Nginx or Traefik reverse proxy in front of containerized dashboards provides a cleaner architecture, centralized certificate management, and simpler renewal workflows:

[ Developer Workstation / Webhook ]
                 │
                 │ HTTPS (Port 443) - Trusted by SecureNT Root CA
                 ▼
[ Ingress Reverse Proxy (Nginx / Traefik) ]
                 │
                 ├── Proxy Pass to Grafana  (Port 3000)
                 ├── Proxy Pass to Jenkins  (Port 8080)
                 └── Proxy Pass to Portainer(Port 9443 / 9000)

Prerequisites

  • Administrative access (root or sudo shell) to your DevOps host server or Docker host.
  • An active internal DNS record pointing to your services (e.g., grafana.infra.internal or jenkins.infra.internal).
  • The SecureNT Root CA certificate installed across domain/developer workstations.

Step-by-Step Implementation Guide

Step 1: Generate the Private Key and CSR

Generate a 2048-bit RSA private key and Certificate Signing Request (CSR) on your management host. Replace the domain with your internal FQDN:

Bash
openssl req -new -newkey rsa:2048 -nodes \
 -keyout devops_private.key \
 -out devops_request.csr \
 -subj "/C=US/ST=State/L=City/O=Enterprise/OU=DevOps/CN=grafana.infra.internal"

If securing multiple dashboards under a single certificate, generate a CSR that includes Subject Alternative Names (SANs) covering all endpoints (e.g., DNS:grafana.infra.internal, DNS:jenkins.infra.internal, DNS:portainer.infra.internal).

Step 2: Submit the CSR to SecureNT

1. Visit the SecureNT Intranet SSL website.

2. Submit the new Server Certificate request (File: devops_request.csr).

3. Select your internal Web Server profile and choose the desired certificate validity period.

4. Approve and download the issued certificate (File: server.cer) along with the intermediate CA bundle (File: SecureNT CA-Bundle.cer).

Step 3: Assemble the Certificate Chain

Combine the server certificate and the SecureNT intermediate CA into a bundled PEM file for web servers and reverse proxies:

Bash
cat server.cer "SecureNT CA-Bundle.cer" > /etc/ssl/certs/devops_bundled.crt
mv devops_private.key /etc/ssl/private/devops_private.key
chmod 600 /etc/ssl/private/devops_private.key

Step 4: Configure Dashboard Ingress & Web Servers

Option A: Nginx Reverse Proxy Setup (Recommended for Unified Ingress)

Create an Nginx configuration file in /etc/nginx/conf.d/devops.conf:

Nginx
server {
    listen 80;
    server_name grafana.infra.internal jenkins.infra.internal portainer.infra.internal;
    return 301 https://$host$request_uri;
}

# Grafana Ingress
server {
    listen 443 ssl http2;
    server_name grafana.infra.internal;

    ssl_certificate /etc/ssl/certs/devops_bundled.crt;
    ssl_certificate_key /etc/ssl/private/devops_private.key;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

# Jenkins Ingress
server {
    listen 443 ssl http2;
    server_name jenkins.infra.internal;

    ssl_certificate /etc/ssl/certs/devops_bundled.crt;
    ssl_certificate_key /etc/ssl/private/devops_private.key;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_max_temp_file_size 0;
        proxy_read_timeout 90;
    }
}

Reload Nginx:

Bash
nginx -t && systemctl reload nginx

Option B: Direct Native Configuration in Grafana (grafana.ini)

If you run Grafana standalone without a reverse proxy, configure native TLS directly inside /etc/grafana/grafana.ini:

Ini
[server]
protocol = https
http_port = 3000
domain = grafana.infra.internal
cert_file = /etc/ssl/certs/devops_bundled.crt
cert_key = /etc/ssl/private/devops_private.key

Restart the Grafana service:

Bash

systemctl restart grafana-server

Option C: Portainer Container HTTPS Configuration

When launching Portainer via Docker, mount the certificates directly and bind port 9443:

Bash
docker run -d -p 9443:9443 --name portainer \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /etc/ssl/certs/devops_bundled.crt:/certs/portainer.crt:ro \
  -v /etc/ssl/private/devops_private.key:/certs/portainer.key:ro \
  -v portainer_data:/data \
  portainer/portainer-ce:latest \
  --sslcert /certs/portainer.crt \
  --sslkey /certs/portainer.key

Verification and Health Check

  1. Navigate to https://grafana.infra.internal in your browser.
  2. Confirm the presence of the lock icon and verify the certificate chain resolves cleanly to SecureNT without warnings.
  3. Test API and CLI access (such as curl or automated webhook invocations) from an internal server to verify zero SSL verification failures:
Bash

curl -Iv <https://jenkins.infra.internal>

The response should return HTTP 200 or 403/401 with complete TLS negotiation and no certificate validation errors.

Securing internal DevOps portals with SecureNT protects build environments and operational credentials from local network interception, while removing friction from CI/CD pipeline automation.

Copyright © 2026 Secure Network Traffic. All rights reserved. SecureNT is a registered trademark of Secure Network Traffic.