问题:我的 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
最佳答案
发生这种情况是因为 Firebase 会自动为客户创建共享证书。这并不代表您的网站存在安全风险,因为 Firebase 保留对证书私钥的完全控制权。共享证书使我们能够为我们的免费计划客户免费提供 HTTPS + 自定义域。
如果您的项目采用 Blaze(现收现付)计划,您可以向 Firebase support 发送请求。我们可以将您迁移到专用证书。这仅适用于 Blaze 计划客户。
Firebase 托管目前不支持上传自定义证书。如果这是一个对您很重要的用例,我建议您提交功能请求(再次通过 Firebase support ),以便我们可以评估它以便将来改进产品。
关于firebase - Google Firebase SSL 证书 - 我的证书列出了大量其他网站,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53473695/