<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Admin AINextSolutions</title>
    <description>The latest articles on Forem by Admin AINextSolutions (@ainext-solutions).</description>
    <link>https://forem.com/ainext-solutions</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3680792%2F72a8f32c-c529-479a-9da9-b5df80c0276f.png</url>
      <title>Forem: Admin AINextSolutions</title>
      <link>https://forem.com/ainext-solutions</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ainext-solutions"/>
    <language>en</language>
    <item>
      <title>I Lost $2,300 in One Night Because of Expired SSL CertificatesOr: How I learned to stop worrying and automate SSL monitoring</title>
      <dc:creator>Admin AINextSolutions</dc:creator>
      <pubDate>Sat, 27 Dec 2025 05:44:05 +0000</pubDate>
      <link>https://forem.com/ainext-solutions/i-lost-2300-in-one-night-because-of-expired-ssl-certificatesor-how-i-learned-to-stop-worrying-3911</link>
      <guid>https://forem.com/ainext-solutions/i-lost-2300-in-one-night-because-of-expired-ssl-certificatesor-how-i-learned-to-stop-worrying-3911</guid>
      <description>&lt;p&gt;&lt;strong&gt;2:47 AM. My phone won't stop screaming.&lt;/strong&gt;&lt;br&gt;
I grabbed it with one eye still closed, already knowing something was catastrophically wrong. The PagerDuty alerts were coming in waves. Then Slack. Then email. Then clients calling my emergency line.&lt;br&gt;
23 SSL certificates. All expired. All at once.&lt;br&gt;
Three e-commerce sites went down mid-checkout. A SaaS platform locked out 12,000 users. A banking portal showing security warnings to customers trying to check their accounts. The damage? $2,300 in SLA penalties that night. The real cost? Trust I'd spent years building, gone in 2 hours and 47 minutes.&lt;br&gt;
The worst part? I knew these certificates were expiring. I had a spreadsheet. I checked it weekly. I just... missed one week. One spreadsheet review. That's all it took.&lt;br&gt;
If you've ever managed SSL certificates across multiple domains, you know this nightmare. You might be living it right now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Silent Killer Nobody Talks About&lt;/strong&gt;&lt;br&gt;
Here's something that should terrify you: 847,000 websites are running with expired SSL &lt;strong&gt;certificates right now&lt;/strong&gt;. Today. As you read this.&lt;br&gt;
And these aren't random blog sites. GitHub went down in 2023 because of an expired certificate. Spotify had a 2-hour outage in 2022. LinkedIn's mobile app stopped working for millions in 2021. Same reason: SSL expiry.&lt;/p&gt;

&lt;p&gt;The problem isn't that engineers are incompetent. It's that manual SSL monitoring doesn't scale. Here's what I was doing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Excel spreadsheet with 47 domains&lt;/li&gt;
&lt;li&gt;Calendar reminders 30 days before expiry&lt;/li&gt;
&lt;li&gt;Manual checks via browser every Monday morning&lt;/li&gt;
&lt;li&gt;Prayer that renewal emails wouldn't hit spam&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It worked... until it didn't.&lt;br&gt;
The certificates that killed me that night were all Let's Encrypt 90-day certs. I had them auto-renewing via certbot, but three clients had changed their DNS configurations without telling me. Renewal failed silently. My spreadsheet showed "Auto-renewed ✓". Reality showed "Expired 💀".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution: 50 Lines of Python That Changed Everything&lt;/strong&gt;&lt;br&gt;
After that night, I rage-coded. Here's the exact script I built at 4 AM while on the phone with angry clients:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ssl
import socket
from datetime import datetime
from cryptography import x509
from cryptography.hazmat.backends import default_backend
import requests
import json

def check_ssl_expiry(hostname, port=443):
    """
    Connect to a domain and extract SSL certificate expiration date
    Returns days until expiry (negative if already expired)
    """
    try:
        # Create SSL context and connect
        context = ssl.create_default_context()
        with socket.create_connection((hostname, port), timeout=10) as sock:
            with context.wrap_socket(sock, server_hostname=hostname) as ssock:
                # Get certificate in DER format
                der_cert = ssock.getpeercert(binary_form=True)

        # Parse certificate using cryptography library
        cert = x509.load_der_x509_certificate(der_cert, default_backend())

        # Extract expiration date
        expiry_date = cert.not_valid_after
        days_remaining = (expiry_date - datetime.now()).days

        return {
            'hostname': hostname,
            'expiry_date': expiry_date.strftime('%Y-%m-%d %H:%M:%S'),
            'days_remaining': days_remaining,
            'issuer': cert.issuer.rfc4514_string(),
            'status': 'expired' if days_remaining &amp;lt; 0 else 'warning' if days_remaining &amp;lt; 30 else 'ok'
        }

    except Exception as e:
        return {
            'hostname': hostname,
            'error': str(e),
            'status': 'error'
        }

def send_slack_alert(webhook_url, cert_info):
    """
    Send formatted alert to Slack channel
    """
    if cert_info['status'] in ['expired', 'warning']:
        color = '#d00000' if cert_info['status'] == 'expired' else '#ff9500'
        emoji = '🚨' if cert_info['status'] == 'expired' else '⚠️'

        message = {
            'attachments': [{
                'color': color,
                'title': f'{emoji} SSL Certificate Alert: {cert_info["hostname"]}',
                'fields': [
                    {'title': 'Status', 'value': cert_info['status'].upper(), 'short': True},
                    {'title': 'Days Remaining', 'value': str(cert_info['days_remaining']), 'short': True},
                    {'title': 'Expiry Date', 'value': cert_info['expiry_date'], 'short': False},
                    {'title': 'Issuer', 'value': cert_info.get('issuer', 'Unknown'), 'short': False}
                ]
            }]
        }

        requests.post(webhook_url, json=message)

# Your domains to monitor
domains = [
    'example.com',
    'api.example.com',
    'app.example.com'
]

# Your Slack webhook URL
SLACK_WEBHOOK = 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'

# Run checks
print("🔐 Starting SSL Certificate Checks...\n")
for domain in domains:
    cert_info = check_ssl_expiry(domain)

    if 'error' in cert_info:
        print(f"❌ {domain}: ERROR - {cert_info['error']}")
    else:
        status_emoji = '✅' if cert_info['status'] == 'ok' else '⚠️' if cert_info['status'] == 'warning' else '🚨'
        print(f"{status_emoji} {domain}: {cert_info['days_remaining']} days remaining")

        # Send alert if needed
        send_slack_alert(SLACK_WEBHOOK, cert_info)

print("\n✅ Check complete!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script does four critical things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Actually connects to the domain&lt;/strong&gt; via SSL handshake (not just API checks that can lie)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parses the certificate&lt;/strong&gt; to get real expiration date and issuer info&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calculates days remaining&lt;/strong&gt; with negative numbers for expired certs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sends Slack alerts&lt;/strong&gt; for anything expiring in &amp;lt;30 days or already expired&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can run this as a cronjob every morning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Add to crontab (runs daily at 8 AM)
0 8 * * * /usr/bin/python3 /path/to/ssl_check.py &amp;gt;&amp;gt; /var/log/ssl_checks.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Results: Numbers Don't Lie&lt;/strong&gt;&lt;br&gt;
Six months after implementing this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;8 hours/week saved&lt;/strong&gt; from manual Excel checking (416 hours/year)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;47 certificates detected&lt;/strong&gt; at risk of expiry before they became incidents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 outages&lt;/strong&gt; from SSL expiry (compared to 3 in the previous year)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;15-minute setup time&lt;/strong&gt; vs the 3 weeks I spent evaluating Datadog and New Relic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ROI was instant. The peace of mind? Priceless.&lt;br&gt;
But running a Python script from cron got old fast. What about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitoring certs from multiple servers?&lt;/li&gt;
&lt;li&gt;Historical tracking of certificate changes?&lt;/li&gt;
&lt;li&gt;Team notifications (different people for different domains)?&lt;/li&gt;
&lt;li&gt;Mobile alerts when I'm not at my desk?&lt;/li&gt;
&lt;li&gt;Dashboard to see everything at a glance?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;From Script to Product&lt;/strong&gt;&lt;br&gt;
I spent the next two months turning this into something more robust. Built a proper SaaS around it. Called it &lt;strong&gt;NightWatch&lt;/strong&gt; because I was tired of 2 AM wake-up calls.&lt;br&gt;
The core monitoring logic is still that Python script – because it works. But now it runs distributed checks from multiple regions, stores history in PostgreSQL, sends alerts via Slack/email/SMS, and gives me a dashboard I can actually show clients.&lt;br&gt;
&lt;strong&gt;Full disclosure&lt;/strong&gt;: I'm not writing this article just to share knowledge. NightWatch is a real product I charge money for. But here's the thing – I built it because I needed it. Every feature exists because it solved a real problem I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-region checks&lt;/strong&gt;: Because that one time a certificate was valid in US-East but failed in EU-West due to CDN caching&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change detection&lt;/strong&gt;: Because GoDaddy once issued a different cert than we requested and I didn't notice for 3 weeks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team notifications&lt;/strong&gt;: Because my junior dev needed alerts for staging certs, not production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wildcard support&lt;/strong&gt;: Because monitoring *.example.com manually is impossible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Free tier covers 3 domains (perfect for side projects). Pro is $7/month for 25 domains with Slack integration. Enterprise tier for teams managing hundreds.&lt;br&gt;
You can keep using the Python script above – it's solid. Open source it, fork it, make it better. But if you want the headache of scaling it removed, that's what NightWatch does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Question That Haunts Me&lt;/strong&gt;&lt;br&gt;
I still think about that night sometimes. The panic. The phone calls. The realization that I'd failed clients who trusted me.&lt;br&gt;
But mostly I think about this: How many certificates are you monitoring right now? How many are in spreadsheets you "check regularly"? &lt;strong&gt;How many auto-renew&lt;/strong&gt;... until they don't?&lt;br&gt;
According to SSL Pulse, the average company has &lt;strong&gt;23 public-facing SSL certificates&lt;/strong&gt;. Most engineers I talk to can name maybe 10 of theirs off the top of their head.&lt;br&gt;
The ones you forget about? Those are the ones that expire at 2:47 AM.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try it out&lt;/strong&gt;: If you want to see what I built, check out &lt;a href="//nightwatch.ainextstudios.com"&gt;nightwatch.ainextstudios.com&lt;/a&gt;. Free tier, no credit card required. I built it to solve my problem – maybe it solves yours too.&lt;br&gt;
What's your SSL horror story? Drop it in the comments. Let's learn from each other's mistakes so we stop repeating them.&lt;br&gt;
🔐 Stay secure out there.&lt;/p&gt;




&lt;p&gt;P.S. – The Python script above is MIT licensed. Use it, modify it, sell it to your clients as value-add monitoring. Just maybe set that cronjob up before you have your own 2:47 AM moment.&lt;/p&gt;

</description>
      <category>security</category>
      <category>automation</category>
      <category>devops</category>
      <category>monitoring</category>
    </item>
  </channel>
</rss>
