腾讯云COS监控 短时下载超过设定值关闭公有读

56 阅读3分钟

腾讯云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("", "")