问题:我的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
答案 0 :(得分:4)
之所以会这样,是因为Firebase会自动为客户创建共享证书。这并不代表您的网站存在安全风险,因为Firebase保留了对证书私钥的完全控制。共享证书可以使我们为免费计划客户免费提供HTTPS +自定义域。
如果您的项目采用的是Blaze(即用即付)计划,则可以向Firebase support发送请求,我们可以将您迁移到专用证书。这仅适用于Blaze计划客户。
Firebase主机当前不支持上传自定义证书。如果这是对您很重要的用例,我建议您再次提出功能请求(再次通过Firebase support),以便我们对其进行评估以用于产品的未来改进。