Google Firebase SSL证书-我的证书中列出了大量其他网站 [英] Google Firebase SSL Certificate - My certificate has a large number of other websites listed

查看:41
本文介绍了Google Firebase SSL证书-我的证书中列出了大量其他网站的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:我的Google Firebase SSL证书中列出了其他域.

Problem: Other domains are listed in my Google Firebase SSL certificate.

我创建了一个firebase项目来测试来自Cloud Functions的firebase身份验证电子邮件. firebase.jhanley.com

I created a firebase project to test firebase authentication emails from Cloud Functions. firebase.jhanley.com

我在Cloud Functions中运行了单独的代码,该代码针对我拥有/管理的每个域验证SSL证书(以下代码).该代码的主要目的是在域的SSL证书即将到期时发送电子邮件.我们的某些SSL证书必须手动更新.

I have separate code that runs in Cloud Functions that validates SSL certificates for each domain that I own / manage (code below). The primary purpose of this code is to send an email when a domain's SSL certificate is about to expire. Some of our SSL certificates must be renewed manually.

问题是我检查SSL证书的代码正在为我的SSL证书返回大量其他域名.当我使用Chrome浏览器查看SSL证书时,还会看到其他域名.我确实希望我的网站与这些其他网站相关联.

The problem is that my code that checks the SSL certificate is returning a huge number of other domain names for my SSL certificate. When I look at the SSL certificate with Chrome, I also see these other domain names. I do want my site associated with these other sites.

在Firebase的SSL证书中看到的域的缩小列表:

A reduced list of the domains that I see in my SSL certificate for Firebase:

2r5consultoria.com.br
addlix.com
admin.migrationcover.ae
admin.thermoply.com
akut-med.zeitnachweise.de
...
firebase.jhanley.com
...

问)为什么Firebase SSL会发生这种情况,并且有解决方案吗?

问)Firebase是否支持安装您自己的SSL证书?

在Cloud Functions中运行的Python 3.x代码通过连接到列表中的每个域名来处理SSL证书.

Python 3.x code that runs in Cloud Functions that processes SSL certificates by connecting to each domain name from a list.

注意:此代码没有任何(已知)问题.我包含了源代码,以为社区中的其他人创造附加值.

Note: This code does not have any (known) problems. I am including the source code to create added value for others in the community.

""" Routines to process SSL certificates """

import  sys
import  datetime
import  socket
import  ssl
import  time
import  myhtml

g_email_required = False    # This is set during processing if a warning or error was detected

def get_email_requred():
    return g_email_required

def ssl_get_cert(hostname):
    """ This function returns an SSL certificate from a host """

    context = ssl.create_default_context()

    conn = context.wrap_socket(
        socket.socket(socket.AF_INET),
        server_hostname=hostname)

    # 3 second timeout because Google Cloud Functions has runtime limitations
    conn.settimeout(3.0)

    try:
        conn.connect((hostname, 443))
    except Exception as ex:
        print("{}: Exception: {}".format(hostname, ex), file=sys.stderr)
        return False, str(ex)

    host_ssl_info = conn.getpeercert()

    return host_ssl_info, ''

def get_ssl_info(host):
    """ This function retrieves the SSL certificate for host """
    # If we receive an error, retry up to three times waiting 10 seconds each time.

    retry = 0
    err = ''

    while retry < 3:
        ssl_info, err = ssl_get_cert(host)

        if ssl_info is not False:
            return ssl_info, ''

        retry += 1
        print('    retrying ...')
        time.sleep(10)

    return False, err

def get_ssl_issuer_name(ssl_info):
    """ Return the IssuerName from the SSL certificate """

    issuerName = ''

    issuer = ssl_info['issuer']

    # pylint: disable=line-too-long
    # issuer looks like this:
    # This is a set of a set of a set of key / value pairs.
    # ((('countryName', 'US'),), (('organizationName', "Let's Encrypt"),), (('commonName', "Let's Encrypt Authority X3"),))

    for item in issuer:
        # item will look like this as it goes thru the issuer set
        # Note that this is a set of a set
        #
        # (('countryName', 'US'),)
        # (('organizationName', "Let's Encrypt"),)
        # (('commonName', "Let's Encrypt Authority X3"),)

        s = item[0]

        # s will look like this as it goes thru the isser set
        # Note that this is now a set
        #
        # ('countryName', 'US')
        # ('organizationName', "Let's Encrypt")
        # ('commonName', "Let's Encrypt Authority X3")

        # break the set into "key" and "value" pairs
        k = s[0]
        v = s[1]

        if k == 'organizationName':
            if v != '':
                issuerName = v
                continue

        if k == 'commonName':
            if v != '':
                issuerName = v

    return issuerName

def get_ssl_subject_alt_names(ssl_info):
    """ Return the Subject Alt Names """

    altNames = ''

    subjectAltNames = ssl_info['subjectAltName']

    index = 0
    for item in subjectAltNames:
        altNames += item[1]
        index += 1

        if index < len(subjectAltNames):
            altNames += ', '

    return altNames

def process_hostnames(msg_body, hostnames, days_left):
    """ Process the SSL certificate for each hostname """

    # pylint: disable=global-statement
    global g_email_required

    ssl_date_fmt = r'%b %d %H:%M:%S %Y %Z'

    for host in hostnames:
        f_expired = False

        print('Processing host:', host)

        ssl_info, err = get_ssl_info(host)

        if ssl_info is False:
            msg_body = myhtml.add_row(msg_body, host, err, '', '', '', True)
            g_email_required = True
            continue

        #print(ssl_info)

        issuerName = get_ssl_issuer_name(ssl_info)

        altNames = get_ssl_subject_alt_names(ssl_info)

        l_expires = datetime.datetime.strptime(ssl_info['notAfter'], ssl_date_fmt)

        remaining = l_expires - datetime.datetime.utcnow()

        if remaining < datetime.timedelta(days=0):
            # cert has already expired - uhoh!
            cert_status = "Expired"
            f_expired = True
            g_email_required = True
        elif remaining < datetime.timedelta(days=days_left):
            # expires sooner than the buffer
            cert_status = "Time to Renew"
            f_expired = True
            g_email_required = True
        else:
            # everything is fine
            cert_status = "OK"
            f_expired = False

        msg_body = myhtml.add_row(msg_body, host, cert_status, str(l_expires), issuerName, altNames, f_expired)

    return msg_body

推荐答案

之所以发生这种情况,是因为Firebase会自动为客户创建共享证书.这并不代表您的网站存在安全风险,因为Firebase保留了对证书私钥的完全控制.共享证书可以使我们为免费计划客户免费提供HTTPS +自定义域.

This is happening because Firebase will automatically create shared certificates for customers. This does not represent a security risk for your site, as Firebase retains full control of the certificate private keys. Certificates are shared to allow us to offer HTTPS + custom domains without an additional fee for our free plan customers.

如果您的项目采用的是Blaze(即付即用)计划,则可以向

If you are on the Blaze (pay-as-you-go) plan for your project, you can send a request to Firebase support and we can migrate you to a dedicated certificate. This is only available for Blaze plan customers.

Firebase主机当前不支持上传自定义证书.如果这是对您很重要的用例,建议您提出功能请求(同样,通过 Firebase支持),以便我们对其进行评估,以用于产品的未来改进.

Firebase Hosting does not currently support uploading custom certificates. If this is a use case that's important to you, I'd recommend filing a feature request (again, through Firebase support) so that we can evaluate it for future improvements to the product.

这篇关于Google Firebase SSL证书-我的证书中列出了大量其他网站的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆