Skip to content

Comments

Add DNS-01 challenge debugging guide, manual certificate installation, and NodePort external IP configuration to troubleshooting docs#102

Merged
bwalsh merged 3 commits intofeature/ingressfrom
copilot/sub-pr-92-another-one
Nov 26, 2025
Merged

Add DNS-01 challenge debugging guide, manual certificate installation, and NodePort external IP configuration to troubleshooting docs#102
bwalsh merged 3 commits intofeature/ingressfrom
copilot/sub-pr-92-another-one

Conversation

Copy link
Contributor

Copilot AI commented Nov 25, 2025

User asked how to configure external IP addresses for NodePort ingress in comment #3577836856, how to debug DNS-01 flow with "DNS record not yet propagated" errors in comment #3577905433, and how to install a manual certificate in comment #3578039890.

Changes

NodePort External IP Configuration

  • Added response clarifying NodePort vs LoadBalancer external IP behavior
  • Provided two configuration options:
    • MetalLB with LoadBalancer type (recommended) - automatic external IP assignment
    • Manual externalIPs field on NodePort service - requires manual routing setup
  • Referenced existing troubleshooting documentation (lines 1075-1213) for environment-specific details

DNS-01 Challenge Debugging

  • Added comprehensive 12-step debugging guide for DNS-01 challenges
  • Specific troubleshooting for "DNS record not yet propagated" error
  • CNAME verification steps for acme-dns integration
  • acme-dns TXT record validation commands
  • cert-manager DNS resolver configuration options
  • DNS propagation check period adjustment guidance
  • Real-time monitoring commands for cert-manager logs

Manual Certificate Installation

  • Step-by-step guide for creating TLS secrets from certificate files (local or remote)
  • Instructions to stop cert-manager from overwriting manual certificates
  • Certificate verification and testing steps
  • Multi-namespace deployment guidance
  • Certificate expiration warnings and manual renewal process
  • Re-enabling automated cert-manager management

Example Configuration

NodePort with MetalLB (assigns external IP automatically)

kubectl patch svc ingress-nginx-controller -n ingress-nginx -p '{"spec":{"type":"LoadBalancer"}}'

NodePort with Manual externalIPs

kubectl patch svc ingress-nginx-controller -n ingress-nginx -p '{
  "spec": {
    "type": "NodePort",
    "externalIPs": ["100.22.124.96"]
  }
}'

DNS-01 Quick Diagnostic

# Verify CNAME exists
dig _acme-challenge.calypr-demo.ddns.net CNAME +short

# Check acme-dns TXT record
FULLDOMAIN=$(kubectl get secret acme-dns-credentials -n cert-manager -o jsonpath='{.data.acmedns\.json}' | base64 -d | jq -r '."calypr-demo.ddns.net".fulldomain')
dig @auth.acme-dns.io $FULLDOMAIN TXT +short

Manual Certificate Installation

# Create TLS secret from certificate files
kubectl create secret tls calypr-demo-tls \
  -n argo-stack \
  --cert=/etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem \
  --key=/etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem

# Stop cert-manager from managing it
kubectl annotate ingress ingress-authz-workflows -n argo-stack cert-manager.io/cluster-issuer-
kubectl delete certificate calypr-demo-tls -n argo-stack

Documentation-only changes - no code modifications.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI mentioned this pull request Nov 25, 2025
Copilot AI changed the title [WIP] Add authz-aware ingress overlay for multi-tenant UIs and APIs Add NodePort external IP configuration guidance to troubleshooting docs Nov 25, 2025
Copilot AI requested a review from bwalsh November 25, 2025 22:26
@bwalsh
Copy link
Contributor

bwalsh commented Nov 25, 2025

@copilot

Read most up to date branch

How to debug dns01 flow? We still have self signed certificates!

…rror fixes

Co-authored-by: bwalsh <47808+bwalsh@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 25, 2025

@copilot

Read most up to date branch...

The error "DNS record for \"calypr-demo.ddns.net\" not yet propagated" means cert-manager can't find the TXT record via CNAME.

Quick diagnostic steps:

  1. Verify CNAME exists:
dig _acme-challenge.calypr-demo.ddns.net CNAME +short
# Should return: xxx.auth.acme-dns.io
  1. Check acme-dns TXT record:
FULLDOMAIN=$(kubectl get secret acme-dns-credentials -n cert-manager -o jsonpath='{.data.acmedns\.json}' | base64 -d | jq -r '."calypr-demo.ddns.net".fulldomain')
dig @auth.acme-dns.io $FULLDOMAIN TXT +short
  1. Monitor cert-manager:
kubectl logs -n cert-manager -l app=cert-manager -f | grep -i "dns\|propagation"

If CNAME is missing, add it in No-IP.com:

  • Subdomain: _acme-challenge
  • Type: CNAME
  • Target: <fulldomain>.auth.acme-dns.io

See comprehensive debugging guide in docs/troubleshooting.md (commit 4dd8a4d) - added 12-step DNS-01 debugging process with specific fixes for propagation errors.

Copilot AI changed the title Add NodePort external IP configuration guidance to troubleshooting docs Add DNS-01 challenge debugging guide and NodePort external IP configuration to troubleshooting docs Nov 25, 2025
@bwalsh
Copy link
Contributor

bwalsh commented Nov 25, 2025

@copilot

I've manually retrieved my certificate. It is stored at

"""
Certificate is saved at: /etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem
Key is saved at: /etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem
"""
how do I install it ?

Copy link
Contributor Author

Copilot AI commented Nov 25, 2025

@copilot

I've manually retrieved my certificate. It is stored at ...

To install your manually retrieved certificate:

# Create the TLS secret from your certificate files
kubectl create secret tls calypr-demo-tls \
  -n argo-stack \
  --cert=/etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem \
  --key=/etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem

# If the secret already exists, delete it first:
# kubectl delete secret calypr-demo-tls -n argo-stack

Stop cert-manager from managing this certificate:

# Remove cert-manager annotation from ingress
kubectl annotate ingress ingress-authz-workflows -n argo-stack \
  cert-manager.io/cluster-issuer-

# Delete the Certificate resource (prevents cert-manager from overwriting)
kubectl delete certificate calypr-demo-tls -n argo-stack

Your ingress will now use the manual certificate. Note: You'll need to manually renew it before expiration (Let's Encrypt certs are valid for 90 days).

To re-enable automated cert-manager management later:

  1. Delete the manual secret
  2. Re-add the cert-manager.io/cluster-issuer annotation
  3. Fix the DNS-01 configuration per the troubleshooting guide

@bwalsh
Copy link
Contributor

bwalsh commented Nov 25, 2025

@copilot update documentation with instructions how to install a manual certificate

Co-authored-by: bwalsh <47808+bwalsh@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 25, 2025

@copilot update documentation with instructions how to install a manual certificate

Added comprehensive manual certificate installation guide to docs/troubleshooting.md (commit d42721c).

The new section includes:

  • Creating TLS secrets from certificate files (local or remote)
  • Stopping cert-manager from overwriting manual certificates
  • Verification steps
  • Multi-namespace deployment
  • Certificate expiration warnings and renewal process
  • Re-enabling automated cert-manager management

See "Installing a Manual Certificate" section in the troubleshooting guide.

Copilot AI changed the title Add DNS-01 challenge debugging guide and NodePort external IP configuration to troubleshooting docs Add DNS-01 challenge debugging guide, manual certificate installation, and NodePort external IP configuration to troubleshooting docs Nov 25, 2025
@bwalsh
Copy link
Contributor

bwalsh commented Nov 25, 2025

@copilot What permission should be set on /etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem

  • /etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem

Copy link
Contributor Author

Copilot AI commented Nov 25, 2025

@copilot What permission should be set on /etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem

  • /etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem

For Let's Encrypt certificate files, use these permissions:

# Certificate files (public) - readable by all
chmod 644 /etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem

# Private key - readable only by owner
chmod 600 /etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem

# Ensure proper ownership (usually root)
chown root:root /etc/letsencrypt/live/calypr-demo.ddns.net/*.pem

Security Note: The private key (privkey.pem) should always be 600 (owner read/write only) to prevent unauthorized access. The fullchain certificate can be 644 since it's public information.

When copying to create the Kubernetes secret, ensure you have read permissions. If running kubectl create secret as a non-root user, you may need to temporarily copy the files or use sudo:

# Option 1: Use sudo
sudo kubectl create secret tls calypr-demo-tls -n argo-stack \
  --cert=/etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem \
  --key=/etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem

# Option 2: Copy to accessible location first
sudo cp /etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem /tmp/
sudo cp /etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem /tmp/
sudo chmod 644 /tmp/fullchain.pem /tmp/privkey.pem
kubectl create secret tls calypr-demo-tls -n argo-stack \
  --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem
rm /tmp/fullchain.pem /tmp/privkey.pem

@bwalsh
Copy link
Contributor

bwalsh commented Nov 26, 2025

@copilot The secret looks good

"""
$ kubectl get secret calypr-demo-tls -n argo-stack -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
06:0d:b2:4c:2f:8f:d2:c5:4a:10:13:92:b1:c3:72:6d:98:1e
Signature Algorithm: ecdsa-with-SHA384
Issuer: C=US, O=Let's Encrypt, CN=E7
Validity
Not Before: Nov 25 22:29:20 2025 GMT
Not After : Feb 23 22:29:19 2026 GMT
Subject: CN=calypr-demo.ddns.net
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:6f:d0:43:84:3b:56:75:cb:bd:a5:8a:e9:ca:54:
4f:6c:10:09:fe:28:43:42:b4:b7:e5:ca:db:80:4e:
14:54:c1:21:ff:9f:c2:38:9d:c8:da:79:c4:e0:2f:
f4:94:de:f6:f6:f7:08:5c:e5:cd:e9:51:d5:38:4e:
3a:31:3e:8d:66
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
AD:F2:29:86:32:13:39:5F:3D:C9:40:C3:E2:A7:62:49:77:3E:4B:73
X509v3 Authority Key Identifier:
AE:48:9E:DC:87:1D:44:A0:6F:DA:A2:E5:60:74:04:78:C2:9C:00:80
Authority Information Access:
CA Issuers - URI:http://e7.i.lencr.org/
X509v3 Subject Alternative Name:
DNS:calypr-demo.ddns.net
X509v3 Certificate Policies:
Policy: 2.23.140.1.2.1
X509v3 CRL Distribution Points:
Full Name:
URI:http://e7.c.lencr.org/31.crl
CT Precertificate SCTs:
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : 19:86:D4:C7:28:AA:6F:FE:BA:03:6F:78:2A:4D:01:91:
AA:CE:2D:72:31:0F:AE:CE:5D:70:41:2D:25:4C:C7:D4
Timestamp : Nov 25 23:27:50.433 2025 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:45:02:20:0F:14:18:A1:EF:D9:75:0B:66:86:26:1E:
5B:2F:B0:8B:30:B7:03:8E:38:77:1D:E1:D6:EF:34:88:
86:8D:47:D1:02:21:00:84:13:84:52:1F:FD:7B:C6:A5:
A1:A6:5B:32:E4:7D:A0:D3:D5:0B:70:1C:0A:CE:88:B7:
8E:5F:65:A5:45:E1:74
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : CB:38:F7:15:89:7C:84:A1:44:5F:5B:C1:DD:FB:C9:6E:
F2:9A:59:CD:47:0A:69:05:85:B0:CB:14:C3:14:58:E7
Timestamp : Nov 25 23:27:50.451 2025 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:45:02:21:00:B3:E7:C9:62:F7:F0:B0:52:D8:B8:79:
EA:DD:70:30:17:6E:D0:0D:BF:F9:58:74:35:63:A9:A1:
74:89:37:A2:BA:02:20:28:C7:FD:B2:4B:5B:90:4E:29:
94:C1:EA:02:04:E5:A3:91:AC:52:3F:6B:F2:F6:2A:50:
F2:65:0B:98:B5:56:2E
Signature Algorithm: ecdsa-with-SHA384
Signature Value:
30:66:02:31:00:a5:5d:f5:80:ce:0b:98:2e:bb:ac:ee:53:77:
dd:46:4c:be:44:5b:2d:5f:0f:a8:e9:a4:cf:ce:73:e9:75:c6:
6f:74:ba:6a:4b:5b:26:b8:08:98:cd:84:1a:ee:c8:f5:46:02:
31:00:de:5b:46:18:46:32:7c:f6:31:9e:f5:79:6c:1f:48:c7:
2f:2d:70:ba:a4:83:50:73:fa:0b:6a:32:0e:a8:1c:b3:70:7c:
40:16:d6:7b:36:9c:4d:9d:33:28:f8:9a:87:f1
"""

This last step is failing:

"""

Test HTTPS connection

$ curl -vI https://calypr-demo.ddns.net/workflows 2>&1

  • Host calypr-demo.ddns.net:443 was resolved.
  • IPv6: (none)
  • IPv4: 127.0.0.1
  • Trying 127.0.0.1:443...
  • ALPN: curl offers h2,http/1.1
  • TLSv1.3 (OUT), TLS handshake, Client hello (1):
  • CAfile: /etc/pki/tls/certs/ca-bundle.crt
  • CApath: none
  • TLSv1.3 (IN), TLS handshake, Server hello (2):
  • TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
  • TLSv1.3 (IN), TLS handshake, Certificate (11):
  • TLSv1.3 (OUT), TLS alert, unknown CA (560):
  • SSL certificate problem: self-signed certificate
  • closing connection #0
    curl: (60) SSL certificate problem: self-signed certificate
    More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the webpage mentioned above.

"""

"""
kubectl get ingress -n argo-stack -o yaml
apiVersion: v1
items:

  • apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    annotations:
    meta.helm.sh/release-name: ingress-authz-overlay
    meta.helm.sh/release-namespace: argo-stack
    nginx.ingress.kubernetes.io/auth-method: GET
    nginx.ingress.kubernetes.io/auth-response-headers: X-User,X-Email,X-Groups,X-Auth-Request-User,X-Auth-Request-Email,X-Auth-Request-Groups
    nginx.ingress.kubernetes.io/auth-signin: https://calypr-demo.ddns.net/tenants/login
    nginx.ingress.kubernetes.io/auth-snippet: |
    proxy_set_header Authorization $http_authorization;
    proxy_set_header X-Original-URI $request_uri;
    proxy_set_header X-Original-Method $request_method;
    proxy_set_header X-Forwarded-Host $host;
    nginx.ingress.kubernetes.io/auth-url: http://authz-adapter.security.svc.cluster.local:8080/check
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/upstream-vhost: argo-stack-argocd-server.argocd.svc.cluster.local
    nginx.ingress.kubernetes.io/use-regex: "true"
    creationTimestamp: "2025-11-26T00:01:34Z"
    generation: 1
    labels:
    app.kubernetes.io/component: ingress
    app.kubernetes.io/instance: ingress-authz-overlay
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-authz-overlay
    app.kubernetes.io/version: 1.0.0
    helm.sh/chart: ingress-authz-overlay-0.1.0
    ingress-authz-overlay.calypr.io/cross-namespace: "true"
    ingress-authz-overlay.calypr.io/route: applications
    ingress-authz-overlay.calypr.io/target-namespace: argocd
    name: ingress-authz-applications
    namespace: argo-stack
    resourceVersion: "1756"
    uid: 1ea5c9f6-8201-47ad-9860-1f44c3aacd61
    spec:
    ingressClassName: nginx
    rules:
    • host: calypr-demo.ddns.net
      http:
      paths:
      • backend:
        service:
        name: argo-stack-argocd-server-proxy
        port:
        number: 8080
        path: /applications(/|$)(.*)
        pathType: ImplementationSpecific
        tls:
    • hosts:
      • calypr-demo.ddns.net
        secretName: calypr-demo-tls
        status:
        loadBalancer: {}
  • apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    annotations:
    meta.helm.sh/release-name: ingress-authz-overlay
    meta.helm.sh/release-namespace: argo-stack
    nginx.ingress.kubernetes.io/auth-method: GET
    nginx.ingress.kubernetes.io/auth-response-headers: X-User,X-Email,X-Groups,X-Auth-Request-User,X-Auth-Request-Email,X-Auth-Request-Groups
    nginx.ingress.kubernetes.io/auth-signin: https://calypr-demo.ddns.net/tenants/login
    nginx.ingress.kubernetes.io/auth-snippet: |
    proxy_set_header Authorization $http_authorization;
    proxy_set_header X-Original-URI $request_uri;
    proxy_set_header X-Original-Method $request_method;
    proxy_set_header X-Forwarded-Host $host;
    nginx.ingress.kubernetes.io/auth-url: http://authz-adapter.security.svc.cluster.local:8080/check
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/upstream-vhost: github-repo-registrations-eventsource-svc.argo-events.svc.cluster.local
    nginx.ingress.kubernetes.io/use-regex: "true"
    creationTimestamp: "2025-11-26T00:01:34Z"
    generation: 1
    labels:
    app.kubernetes.io/component: ingress
    app.kubernetes.io/instance: ingress-authz-overlay
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-authz-overlay
    app.kubernetes.io/version: 1.0.0
    helm.sh/chart: ingress-authz-overlay-0.1.0
    ingress-authz-overlay.calypr.io/cross-namespace: "true"
    ingress-authz-overlay.calypr.io/route: registrations
    ingress-authz-overlay.calypr.io/target-namespace: argo-events
    name: ingress-authz-registrations
    namespace: argo-stack
    resourceVersion: "1758"
    uid: a296306e-925a-47d3-902b-34e4db9a6516
    spec:
    ingressClassName: nginx
    rules:
    • host: calypr-demo.ddns.net
      http:
      paths:
      • backend:
        service:
        name: github-repo-registrations-eventsource-svc-proxy
        port:
        number: 12000
        path: /registrations(/|$)(.*)
        pathType: ImplementationSpecific
        tls:
    • hosts:
      • calypr-demo.ddns.net
        secretName: calypr-demo-tls
        status:
        loadBalancer: {}
  • apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    annotations:
    meta.helm.sh/release-name: ingress-authz-overlay
    meta.helm.sh/release-namespace: argo-stack
    nginx.ingress.kubernetes.io/auth-method: GET
    nginx.ingress.kubernetes.io/auth-response-headers: X-User,X-Email,X-Groups,X-Auth-Request-User,X-Auth-Request-Email,X-Auth-Request-Groups
    nginx.ingress.kubernetes.io/auth-signin: https://calypr-demo.ddns.net/tenants/login
    nginx.ingress.kubernetes.io/auth-snippet: |
    proxy_set_header Authorization $http_authorization;
    proxy_set_header X-Original-URI $request_uri;
    proxy_set_header X-Original-Method $request_method;
    proxy_set_header X-Forwarded-Host $host;
    nginx.ingress.kubernetes.io/auth-url: http://authz-adapter.security.svc.cluster.local:8080/check
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/upstream-vhost: argo-stack-argo-workflows-server.argo-workflows.svc.cluster.local
    nginx.ingress.kubernetes.io/use-regex: "true"
    creationTimestamp: "2025-11-26T00:01:34Z"
    generation: 1
    labels:
    app.kubernetes.io/component: ingress
    app.kubernetes.io/instance: ingress-authz-overlay
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-authz-overlay
    app.kubernetes.io/version: 1.0.0
    helm.sh/chart: ingress-authz-overlay-0.1.0
    ingress-authz-overlay.calypr.io/cross-namespace: "true"
    ingress-authz-overlay.calypr.io/route: workflows
    ingress-authz-overlay.calypr.io/target-namespace: argo-workflows
    name: ingress-authz-workflows
    namespace: argo-stack
    resourceVersion: "1757"
    uid: 55cbbc69-0bdf-4e80-8d3c-86c4e00b7314
    spec:
    ingressClassName: nginx
    rules:
    • host: calypr-demo.ddns.net
      http:
      paths:
      • backend:
        service:
        name: argo-stack-argo-workflows-server-proxy
        port:
        number: 2746
        path: /workflows(/|$)(.*)
        pathType: ImplementationSpecific
        tls:
    • hosts:
      • calypr-demo.ddns.net
        secretName: calypr-demo-tls
        status:
        loadBalancer: {}
        kind: List
        metadata:
        resourceVersion: ""
        """

Copy link
Contributor Author

Copilot AI commented Nov 26, 2025

@copilot The secret looks good

"""...

The certificate is installed correctly (valid Let's Encrypt cert expires Feb 23, 2026). The issue is DNS resolution - calypr-demo.ddns.net is resolving to 127.0.0.1 (localhost) instead of your ingress IP.

Diagnose:

# Check what IP the domain resolves to
nslookup calypr-demo.ddns.net
dig calypr-demo.ddns.net +short

# Get your ingress controller's external IP
kubectl get svc -n ingress-nginx ingress-nginx-controller

The domain should resolve to your ingress IP, not 127.0.0.1.

Fix options:

  1. Check /etc/hosts override:
grep calypr-demo /etc/hosts
# If it shows 127.0.0.1, remove or update that line
  1. Update No-IP.com DNS to point to your ingress external IP (not localhost)

  2. Test with the actual IP to verify the certificate works:

# Get ingress IP
INGRESS_IP=$(kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

# Test directly (override DNS)
curl -vI --resolve calypr-demo.ddns.net:443:$INGRESS_IP https://calypr-demo.ddns.net/workflows

Once DNS points to the correct IP, the certificate will work. The "self-signed certificate" error is from a different service running on localhost, not your Kubernetes ingress.

@bwalsh
Copy link
Contributor

bwalsh commented Nov 26, 2025

@copilot Still getting self signed

"""
++ nslookup calypr-demo.ddns.net
Server: 172.31.0.2
Address: 172.31.0.2#53

Non-authoritative answer:
Name: calypr-demo.ddns.net
Address: 100.22.124.96

++ dig calypr-demo.ddns.net +short
100.22.124.96
++ kubectl get svc -n ingress-nginx ingress-nginx-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.96.55.55 100.22.124.96 80:30080/TCP,443:30443/TCP 10m
++ grep calypr-demo /etc/hosts
++ curl https://calypr-demo.ddns.net/tenants/login
curl: (60) SSL certificate problem: self-signed certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the webpage mentioned above.
"""

Copy link
Contributor Author

Copilot AI commented Nov 26, 2025

@copilot Still getting self signed

"""...

DNS is correct now. The issue is that ingress-nginx is type NodePort (port 443→30443), but traffic on port 443 may not be reaching the ingress controller properly.

Verify the certificate is loaded:

# Check if ingress-nginx sees the TLS secret
kubectl get secret calypr-demo-tls -n argo-stack -o yaml | grep -A1 "tls.crt\|tls.key"

# Check ingress-nginx logs for certificate loading
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller --tail=50 | grep -i "tls\|certificate\|calypr-demo"

# Force reload of ingress config
kubectl delete pod -n ingress-nginx -l app.kubernetes.io/component=controller

Test via NodePort directly:

# Access via the actual NodePort (bypasses any port forwarding issues)
curl -vI --resolve calypr-demo.ddns.net:30443:100.22.124.96 https://calypr-demo.ddns.net:30443/workflows

If NodePort works but port 443 doesn't:

You need to forward port 443 to NodePort 30443 on the node. Options:

# Option 1: Use iptables (on the node with IP 100.22.124.96)
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 30443
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 30080

# Option 2: Switch to LoadBalancer (recommended)
kubectl patch svc ingress-nginx-controller -n ingress-nginx -p '{"spec":{"type":"LoadBalancer"}}'

@bwalsh bwalsh marked this pull request as ready for review November 26, 2025 00:43
@bwalsh bwalsh merged commit 11234c2 into feature/ingress Nov 26, 2025
3 checks passed
@bwalsh bwalsh deleted the copilot/sub-pr-92-another-one branch November 26, 2025 00:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants