腾讯云COS监控 短时下载超过设定值关闭公有读
前言:
腾讯云白嫖COS每个月有10G的流量,现在作为我的博客图片的存储,为了防止被盗链,以及不想睡一觉起来就发现自己欠了一套房。使用腾讯云函数来监控,当瞬时流量超过设定值则关闭公有读,并发送邮件!
代码:
# -*- coding: utf8 -*-
import sys
import os
import logging
import json
import requests
import smtplib
import time
import datetime
import math
# import tencentcloud-sdk-python
from qcloud_cos_v5 import CosConfig
from qcloud_cos_v5 import CosS3Client
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.monitor.v20180724 import monitor_client, models
from datetime import timedelta
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formataddr
import smtplib
# SMTP 服务配置
host = "smtp.mxhichina.com" # SMTP服务器
user = "" # SMTP服务器登录用户名
passwd = "" # SMTP服务器密码
port = 465 # SMTP服务SSL端口号
receivers = ['', ''] # 收件人邮箱列表
def sendmail(mail_host, mail_user, mail_pass, mail_port, recipients, subject, content):
# 邮件内容设置
message = MIMEText(content, 'plain', 'utf-8')
message['From'] = formataddr((str(Header('消息', 'utf-8')), mail_user)) # 发件人信息
# 接收者信息,注意,这里需要将所有收件人的邮箱转换为一个字符串,每个邮箱地址用逗号分隔
message['To'] = ", ".join(recipients) # 调整为多个收件人
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP_SSL(mail_host, mail_port) # 使用SSL连接
smtpObj.login(mail_user, mail_pass)
# 发送邮件,这里需要传入收件人列表
smtpObj.sendmail(mail_user, recipients, message.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print(f"邮件发送失败: {e}")
finally:
smtpObj.quit() # 退出SMTP服务器
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
def checkQuota():
secret_id = '' # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
secret_key = '' # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
region = '' # 替换为bucket所属的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
# COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224
token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048
scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填
bucket = ''
localOffset = datetime.timedelta(hours=8) # 本地时差,当前以北京为例,UTC+8
S_delay = datetime.timedelta(minutes=15) # 开始时间差值,因云监控上报有时延,这里时间前置调整,时延单位为分钟
E_delay = datetime.timedelta(minutes=10) # 结束时间差值,因云监控上报有时延,这里时间前置调整,时延单位为分钟
time_start = datetime.datetime.now() + localOffset - S_delay # 查询云监控的开始时间,为当前时间前置15分钟。
time_end = datetime.datetime.now() + localOffset - E_delay # 查询云监控的结束时间,为当前时间前置10分钟。
cred = credential.Credential(secret_id, secret_key)
# 实例化一个http选项,可选的,没有特殊需求可以跳过
httpProfile = HttpProfile()
httpProfile.endpoint = "monitor.tencentcloudapi.com"
# 实例化一个client选项,可选的,没有特殊需求可以跳过
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
# 实例化要请求产品的client对象,clientProfile是可选的
client = monitor_client.MonitorClient(cred, region, clientProfile)
# 这里是获取云监控的分钟级数据
# MetricName 参数 InternetTraffic 指的是外网下行流量,CdnOriginTraffic指的是CDN回源流量,其他相关监控指标详见https://cloud.tencent.com/document/product/248/45140
req = models.GetMonitorDataRequest()
params = {
"Namespace": "QCE/COS",
"MetricName": "InternetTraffic",
"Period": 60,
"StartTime": time_start.strftime("%Y-%m-%d %H:%M:%S"),
"EndTime": time_end.strftime("%Y-%m-%d %H:%M:%S"),
"Instances": [
{
"Dimensions": [
{
"Name": "bucket",
"Value": bucket
}
]
}
]
}
req.from_json_string(json.dumps(params))
# 返回的resp是一个GetMonitorDataResponse的实例,与请求对象对应
resp = client.GetMonitorData(req)
# 输出json格式的字符串回包
_str = resp.to_json_string()
print(_str)
print("------------------------------------------------------")
jsObj = json.loads(_str)
for k, v in jsObj.items():
if k <span style="font-weight: bold;" class="mark"> "DataPoints":
for k, v in v[0].items():
if k </span> "Values":
_flow = sum(v)
if _flow > 50 * 1024 * 1024: # 超过5GB流量阈值
config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
cosclient = CosS3Client(config)
cosclient.put_bucket_acl(
Bucket=bucket,
ACL='private'
)
converted_to_mb = _flow / (1024**2)
mail_message = f'流量达到判断阈值:{converted_to_mb},已改为私有读写权限!'
sendmail(host, user, passwd, port, receivers, '腾讯云监控', mail_message)
# print("判断阈值",_flow)
# print("达到阈值,已改为私有读写权限")
else:
''' 如果需要在盗刷后自动恢复公共读权限,则去掉这段注释。
config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
cosclient = CosS3Client(config)
cosclient.put_bucket_acl(
Bucket=bucket,
ACL='public-read'
)
'''
print("判断阈值", _flow)
print("未达到阈值,不做权限修改操作")
def main_handler(event, context):
checkQuota()
if __name__ == '__main__':
main_handler("", "")