Google Firebase SSL证书-我的证书列出了许多其他网站

时间:2018-11-26 01:28:53

标签: firebase ssl google-cloud-platform ssl-certificate

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

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

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

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

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

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证书。

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

""" 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

1 个答案:

答案 0 :(得分:4)

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

如果您的项目采用的是Blaze(即用即付)计划,则可以向Firebase support发送请求,我们可以将您迁移到专用证书。这仅适用于Blaze计划客户。

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