如何实现一个可以动态配置腾讯云安全组的接口?

腾讯云相关文档:https://cloud.tencent.com.cn/document/product/1207/48254

本文以腾讯云轻量云服务器为例

使用场景

为了保证服务器安全,正常情况下我们都会把22(ssh)、3306(mysql)、6379(redis)等常用端口在安全组内禁用。

但是有些时候,我们确实也需要在外网连接SSH操作一些东西或者连接Mysql操作数据库。所以每次在操作之前,都要去配置一下安全组开放这些端口,等使用完了再禁用。

整个过程都比较麻烦,所以为了偷懒也想了好些方法。

1.指定IP放行

且不说大部分人都没有固定IP,有了固定IP也是在固定的场所,这样也不是很方便。

2.代理IP

放行一个自己常用的代理IP,每次通过连接这个代理IP来操作。

这种还行,但是估计代理IP就得让不少人放弃。

3.动态接口

腾讯云官方提供了操作服务器安全组相关的API,通过这些API接口,我们可以实现一个自己的接口,比如:

具体需要操作哪台服务器,配置哪些端口都可以在API内自己定义。

提示
以上例子均为不存在的接口,仅用于演示

简单实现

以下是基于PHP简单实现的一个接口,使用方法跟上面的例子是一样的。

通过Composer安装腾讯的sdk:

composer require tencentcloud/lighthouse

创建一个php文件,将下面的代码复制进去,按照自己的需求进行修改,保存到你的某个站点下面:

<?php
require_once 'vendor/autoload.php';

use TencentCloudCommonCredential;
use TencentCloudCommonExceptionTencentCloudSDKException;
use TencentCloudCommonProfileClientProfile;
use TencentCloudCommonProfileHttpProfile;
use TencentCloudLighthouseV20200324LighthouseClient;
use TencentCloudLighthouseV20200324ModelsModifyFirewallRulesRequest;

/* 配置 */
$enable_ssh = $_GET['ssh'] ?? null;
$enable_mysql = $_GET['mysql'] ?? null;
$enable_ip = $_GET['ip'] ?? "127.0.0.1";

/* 无操作 */
if ($enable_ssh === null && $enable_mysql === null) {
    exit('null');
}

/* 非数字 */
if (!is_numeric($enable_ssh) || !is_numeric($enable_mysql)) {
    exit('number');
} else {
    $enable_mysql = intval($enable_mysql);
    $enable_ssh = intval($enable_ssh);
}

try {

    // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
    // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
    // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
    $cred = new Credential("腾讯云SecretId ", "腾讯云SecretKey ");

    // 实例化一个http选项,可选的,没有特殊需求可以跳过
    $httpProfile = new HttpProfile();
    $httpProfile->setEndpoint("lighthouse.tencentcloudapi.com");

    // 实例化一个client选项,可选的,没有特殊需求可以跳过
    $clientProfile = new ClientProfile();
    $clientProfile->setHttpProfile($httpProfile);

    // 这个填服务器所在地区,比如:ap-shanghai
    $client = new LighthouseClient($cred, "ap-shanghai", $clientProfile);

    // 实例化一个请求对象,每个接口都会对应一个request对象
    $req = new ModifyFirewallRulesRequest();

    $params = [
        "InstanceId" => "sever-name", //这里填服务器名称
        "FirewallRules" => [
	        [
		        "Action" => "ACCEPT",
		        "AppType" => "HTTP (80)",
		        "CidrBlock" => "0.0.0.0/0",
		        "FirewallRuleDescription" => "Web服务HTTP (80),如 Apache、Nginx",
		        "Port" => "80",
		        "Protocol" => "TCP"
	        ],
	        [
		        "Action" => "ACCEPT",
		        "AppType" => "Ping",
		        "CidrBlock" => "0.0.0.0/0",
		        "FirewallRuleDescription" => "通过Ping测试网络连通性 (放通ALL ICMP)",
		        "Port" => "ALL",
		        "Protocol" => "ICMP"
	        ],
            [
                "Action" => "ACCEPT",
                "AppType" => "Linux login (22)",
                "CidrBlock" => $enable_ssh ? "0.0.0.0/0" : $enable_ip,
                "FirewallRuleDescription" => "Linux SSH登录",
                "Port" => "22",
                "Protocol" => "TCP"
            ],
            [
                "Action" => "ACCEPT",
                "AppType" => "HTTPS (443)",
                "CidrBlock" => "0.0.0.0/0",
                "FirewallRuleDescription" => "Web服务HTTPS (443),如 Apache、Nginx",
                "Port" => "443",
                "Protocol" => "TCP"
            ],
            [
                "Action" => "ACCEPT",
                "AppType" => "MySQL (3306)",
                "CidrBlock" => $enable_mysql ? "0.0.0.0/0" : $enable_ip,
                "FirewallRuleDescription" => "数据库",
                "Port" => "3306",
                "Protocol" => "TCP"
            ]
        ]
    ];

    $req->fromJsonString(json_encode($params));
    $resp = $client->ModifyFirewallRules($req);
    print_r($resp->toJsonString());

} catch (TencentCloudSDKException $e) {
    echo $e;
}