【新增】【部署】阿里云WAF

pull/135/head
wantoper 2025-05-22 11:30:19 +08:00
parent 74c9d1e5c2
commit 3da1042187
8 changed files with 468 additions and 5 deletions

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@ package deploy
import (
"ALLinSSL/backend/internal/access"
"ALLinSSL/backend/internal/cert/deploy/client/aliyun"
"encoding/json"
"fmt"
aliyuncdn "github.com/alibabacloud-go/cdn-20180510/v6/client"
@ -11,6 +12,7 @@ import (
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"strconv"
"strings"
"time"
)
func ClientAliCdn(accessKey, accessSecret string) (_result *aliyuncdn.Client, err error) {
@ -223,3 +225,76 @@ func AliyunCdnAPITest(providerID string) error {
}
return nil
}
func DeployAliyunWaf(cfg map[string]any) error {
cert, ok := cfg["certificate"].(map[string]any)
if !ok {
return fmt.Errorf("证书不存在")
}
var providerID string
switch v := cfg["provider_id"].(type) {
case float64:
providerID = strconv.Itoa(int(v))
case string:
providerID = v
default:
return fmt.Errorf("参数错误provider_id")
}
providerData, err := access.GetAccess(providerID)
if err != nil {
return err
}
providerConfigStr, ok := providerData["config"].(string)
if !ok {
return fmt.Errorf("api配置错误")
}
var providerConfig map[string]string
err = json.Unmarshal([]byte(providerConfigStr), &providerConfig)
if err != nil {
return err
}
regionId, ok := cfg["region"].(string)
if !ok {
return fmt.Errorf("参数错误region")
}
wafclient, err := aliyun.ClientAliWaf(providerConfig["access_key_id"], providerConfig["access_key_secret"], regionId)
if err != nil {
return err
}
domain, ok := cfg["domain"].(string)
if !ok {
return fmt.Errorf("参数错误domain")
}
// 设置证书
keyPem, ok := cert["key"].(string)
if !ok {
return fmt.Errorf("证书错误key")
}
certPem, ok := cert["cert"].(string)
if !ok {
return fmt.Errorf("证书错误cert")
}
//根据地区获取实例ID 目前一个地区只能有一个waf实例
instanceId, err := wafclient.IGetInstanceId()
if err != nil {
return fmt.Errorf("获取地区实例ID失败: %v", err)
}
//查询接入详情
domainDesc, err := wafclient.IDescribeDomainDetail(*instanceId, domain)
if err != nil {
return fmt.Errorf("获取域名配置详情失败: %v", err)
}
//上传证书
certName := fmt.Sprintf("%s_allinssl_%d", domain, time.Now().UnixMilli())
certId, err := wafclient.ICreateCerts(certName, certPem, keyPem, *instanceId)
if err != nil {
return fmt.Errorf("创建证书失败: %v", err)
}
//更新接入
err = wafclient.IUpdateDomain(domainDesc, *instanceId, *certId)
if err != nil {
return fmt.Errorf("更新证书失败: %v", err)
}
return nil
}

View File

@ -0,0 +1,42 @@
package aliyun
import (
aliyuncas "github.com/alibabacloud-go/cas-20200407/v4/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea"
)
type ClientAliCas struct {
aliyuncas.Client
}
func NewClientAliCas(accessKey, accessSecret string) (_result *ClientAliCas, err error) {
config := &openapi.Config{
AccessKeyId: tea.String(accessKey),
AccessKeySecret: tea.String(accessSecret),
Endpoint: tea.String("cas.aliyuncs.com"),
}
casClient, err := aliyuncas.NewClient(config)
if err != nil {
return nil, err
}
client := &ClientAliCas{
Client: *casClient,
}
return client, nil
}
func (c *ClientAliCas) UploadCert(certName, certContent, certKey string) (*int64, error) {
certificateRequest := &aliyuncas.UploadUserCertificateRequest{
Cert: tea.String(certContent),
Key: tea.String(certKey),
Name: tea.String(certName),
}
uploadUserCertificateResp, err := c.UploadUserCertificate(certificateRequest)
if err != nil {
return nil, err
}
return uploadUserCertificateResp.Body.CertId, nil
}

View File

@ -0,0 +1,282 @@
package aliyun
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
openapiutil "github.com/alibabacloud-go/openapi-util/service"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
aliyunwaf "github.com/alibabacloud-go/waf-openapi-20211001/v5/client"
)
type AliyunWafClient struct {
aliyunwaf.Client
accessKey string
accessSecret string
region string
}
func ClientAliWaf(accessKey, accessSecret, region string) (_result *AliyunWafClient, err error) {
//region:[cn-hangzhou,ap-southeast-1]
config := &openapi.Config{
AccessKeyId: tea.String(accessKey),
AccessKeySecret: tea.String(accessSecret),
Endpoint: tea.String(fmt.Sprintf("wafopenapi.%s.aliyuncs.com", region)),
}
client, err := aliyunwaf.NewClient(config)
if err != nil {
return nil, err
}
aliyunwafClient := &AliyunWafClient{
Client: *client,
accessKey: accessKey,
accessSecret: accessSecret,
region: region,
}
return aliyunwafClient, nil
}
type CreateCertsResponseBody struct {
CertIdentifier *string `json:"CertIdentifier,omitempty" xml:"DomainInfo,omitempty"`
RequestId *string `json:"RequestId,omitempty" xml:"RequestId,omitempty"`
}
type CreateCertsResponse struct {
Headers map[string]*string `json:"headers,omitempty" xml:"headers,omitempty"`
StatusCode *int32 `json:"statusCode,omitempty" xml:"statusCode,omitempty"`
Body *CreateCertsResponseBody `json:"body,omitempty" xml:"body,omitempty"`
}
func (client *AliyunWafClient) ICreateCerts(certName, certContent, certKey, instanceId string) (certId *string, _err error) {
query := map[string]interface{}{
"CertName": certName,
"CertContent": certContent,
"CertKey": certKey,
"InstanceId": instanceId,
}
req := &openapi.OpenApiRequest{
Query: openapiutil.Query(query),
}
params := &openapi.Params{
Action: tea.String("CreateCerts"),
Version: tea.String("2021-10-01"),
Protocol: tea.String("HTTPS"),
Pathname: tea.String("/"),
Method: tea.String("POST"),
AuthType: tea.String("AK"),
Style: tea.String("RPC"),
ReqBodyType: tea.String("formData"),
BodyType: tea.String("json"),
}
createCertsResponse := &CreateCertsResponse{}
runtime := &util.RuntimeOptions{}
_body, _err := client.CallApi(params, req, runtime)
if _err != nil {
return nil, _err
}
_err = tea.Convert(_body, &createCertsResponse)
certId = createCertsResponse.Body.CertIdentifier
return certId, _err
}
func (client *AliyunWafClient) IGetInstanceId() (instanceId *string, _err error) {
req := &aliyunwaf.DescribeInstanceRequest{
RegionId: tea.String(client.region),
}
response, _err := client.DescribeInstance(req)
instanceId = response.Body.InstanceId
return instanceId, _err
}
func (client *AliyunWafClient) IDescribeDomainDetail(instanceId, domain string) (describeDomainDetailResponseBody *aliyunwaf.DescribeDomainDetailResponseBody, _err error) {
req := &aliyunwaf.DescribeDomainDetailRequest{
InstanceId: tea.String(instanceId),
RegionId: tea.String(client.region),
Domain: tea.String(domain),
}
response, _err := client.DescribeDomainDetail(req)
describeDomainDetailResponseBody = response.Body
return describeDomainDetailResponseBody, _err
}
func (client *AliyunWafClient) IUpdateDomain(domainDesc *aliyunwaf.DescribeDomainDetailResponseBody, instanceId, certId string) error {
modifyDomainReq := &aliyunwaf.ModifyDomainRequest{
InstanceId: tea.String(instanceId),
RegionId: tea.String(client.region),
Domain: domainDesc.Domain,
Listen: &aliyunwaf.ModifyDomainRequestListen{CertId: tea.String(certId)},
}
assignDomain(domainDesc, modifyDomainReq)
_, err := client.ModifyDomain(modifyDomainReq)
if err != nil {
return err
}
return nil
}
func assignDomain(from *aliyunwaf.DescribeDomainDetailResponseBody, to *aliyunwaf.ModifyDomainRequest) *aliyunwaf.ModifyDomainRequest {
if from == nil {
return to
}
if from.Listen != nil {
if to.Listen == nil {
to.Listen = &aliyunwaf.ModifyDomainRequestListen{}
}
if from.Listen.CipherSuite != nil {
to.Listen.CipherSuite = tea.Int32(int32(*from.Listen.CipherSuite))
}
if from.Listen.CustomCiphers != nil {
to.Listen.CustomCiphers = from.Listen.CustomCiphers
}
if from.Listen.EnableTLSv3 != nil {
to.Listen.EnableTLSv3 = from.Listen.EnableTLSv3
}
if from.Listen.ExclusiveIp != nil {
to.Listen.ExclusiveIp = from.Listen.ExclusiveIp
}
if from.Listen.FocusHttps != nil {
to.Listen.FocusHttps = from.Listen.FocusHttps
}
if from.Listen.Http2Enabled != nil {
to.Listen.Http2Enabled = from.Listen.Http2Enabled
}
if from.Listen.IPv6Enabled != nil {
to.Listen.IPv6Enabled = from.Listen.IPv6Enabled
}
if from.Listen.ProtectionResource != nil {
to.Listen.ProtectionResource = from.Listen.ProtectionResource
}
if from.Listen.TLSVersion != nil {
to.Listen.TLSVersion = from.Listen.TLSVersion
}
if from.Listen.XffHeaderMode != nil {
to.Listen.XffHeaderMode = tea.Int32(int32(*from.Listen.XffHeaderMode))
}
if from.Listen.XffHeaders != nil {
to.Listen.XffHeaders = from.Listen.XffHeaders
}
if from.Listen.HttpPorts != nil {
to.Listen.HttpPorts = make([]*int32, len(from.Listen.HttpPorts))
for i, port := range from.Listen.HttpPorts {
if port != nil {
to.Listen.HttpPorts[i] = tea.Int32(int32(*port))
}
}
}
if from.Listen.HttpsPorts != nil {
to.Listen.HttpsPorts = make([]*int32, len(from.Listen.HttpsPorts))
for i, port := range from.Listen.HttpsPorts {
if port != nil {
to.Listen.HttpsPorts[i] = tea.Int32(int32(*port))
}
}
}
}
if from.Redirect != nil {
if to.Redirect == nil {
to.Redirect = &aliyunwaf.ModifyDomainRequestRedirect{}
}
if from.Redirect.ConnectTimeout != nil {
to.Redirect.ConnectTimeout = from.Redirect.ConnectTimeout
}
if from.Redirect.FocusHttpBackend != nil {
to.Redirect.FocusHttpBackend = from.Redirect.FocusHttpBackend
}
if from.Redirect.Keepalive != nil {
to.Redirect.Keepalive = from.Redirect.Keepalive
}
if from.Redirect.KeepaliveRequests != nil {
to.Redirect.KeepaliveRequests = from.Redirect.KeepaliveRequests
}
if from.Redirect.KeepaliveTimeout != nil {
to.Redirect.KeepaliveTimeout = from.Redirect.KeepaliveTimeout
}
if from.Redirect.Loadbalance != nil {
to.Redirect.Loadbalance = from.Redirect.Loadbalance
}
if from.Redirect.ReadTimeout != nil {
to.Redirect.ReadTimeout = from.Redirect.ReadTimeout
}
if from.Redirect.Retry != nil {
to.Redirect.Retry = from.Redirect.Retry
}
if from.Redirect.SniEnabled != nil {
to.Redirect.SniEnabled = from.Redirect.SniEnabled
}
if from.Redirect.SniHost != nil {
to.Redirect.SniHost = from.Redirect.SniHost
}
if from.Redirect.WriteTimeout != nil {
to.Redirect.WriteTimeout = from.Redirect.WriteTimeout
}
if from.Redirect.XffProto != nil {
to.Redirect.XffProto = from.Redirect.XffProto
}
if from.Redirect.Backends != nil {
to.Redirect.Backends = make([]*string, len(from.Redirect.Backends))
for i, backend := range from.Redirect.Backends {
if backend != nil {
to.Redirect.Backends[i] = backend.Backend
}
}
}
if from.Redirect.BackupBackends != nil {
to.Redirect.BackupBackends = make([]*string, len(from.Redirect.BackupBackends))
for i, backend := range from.Redirect.BackupBackends {
if backend != nil {
to.Redirect.BackupBackends[i] = backend.Backend
}
}
}
if from.Redirect.RequestHeaders != nil {
to.Redirect.RequestHeaders = make([]*aliyunwaf.ModifyDomainRequestRedirectRequestHeaders, len(from.Redirect.RequestHeaders))
for i, header := range from.Redirect.RequestHeaders {
if header != nil {
to.Redirect.RequestHeaders[i] = &aliyunwaf.ModifyDomainRequestRedirectRequestHeaders{
Key: header.Key,
Value: header.Value,
}
}
}
}
}
return to
}

File diff suppressed because one or more lines are too long

View File

@ -46,6 +46,9 @@ func Deploy(cfg map[string]any, logger *public.Logger) error {
case "aliyun-oss":
logger.Debug("部署到阿里云OSS...")
return DeployOss(cfg)
case "aliyun-waf":
logger.Debug("部署到阿里云WAF...")
return DeployAliyunWaf(cfg)
case "safeline-site":
logger.Debug("部署雷池WAF网站...")
return DeploySafeLineWafSite(cfg, logger)

7
go.mod
View File

@ -3,10 +3,14 @@ module ALLinSSL
go 1.23.2
require (
github.com/alibabacloud-go/cas-20200407/v4 v4.0.0
github.com/alibabacloud-go/cdn-20180510/v6 v6.0.0
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7
github.com/alibabacloud-go/market-20151101/v4 v4.1.0
github.com/alibabacloud-go/openapi-util v0.1.1
github.com/alibabacloud-go/tea v1.3.9
github.com/alibabacloud-go/tea-utils/v2 v2.0.7
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.2
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/gin-contrib/gzip v1.2.3
github.com/gin-contrib/sessions v1.0.3
@ -29,10 +33,7 @@ require (
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
github.com/alibabacloud-go/debug v1.0.1 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.63.100 // indirect
github.com/aliyun/credentials-go v1.4.6 // indirect
github.com/baidubce/bce-sdk-go v0.9.223 // indirect
github.com/bytedance/sonic v1.13.2 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect

5
go.sum
View File

@ -60,6 +60,8 @@ github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do2
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 h1:zE8vH9C7JiZLNJJQ5OwjU9mSi4T9ef9u3BURT6LCLC8=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5/go.mod h1:tWnyE9AjF8J8qqLk645oUmVUnFybApTQWklQmi5tY6g=
github.com/alibabacloud-go/cas-20200407/v4 v4.0.0 h1:nCJ8Ih9IGTbcBrFUcUXQJ6IV/Mwm7jEYioVKOlTOgRI=
github.com/alibabacloud-go/cas-20200407/v4 v4.0.0/go.mod h1:OuMv6sG1bj4nhzySA/mMdBcSAOJxpi9okEHqM5l73qo=
github.com/alibabacloud-go/cdn-20180510/v6 v6.0.0 h1:mHVIQWtoGBRV7R7B8l2yoJha13rahY7eNYcKt5SLS/k=
github.com/alibabacloud-go/cdn-20180510/v6 v6.0.0/go.mod h1:ahEUlWkWWwrDvAruyPwIRfGkrzaMrCG0q6WKHU+BQgQ=
github.com/alibabacloud-go/darabonba-array v0.1.0 h1:vR8s7b1fWAQIjEjWnuF0JiKsCvclSRTfDzZHTYqfufY=
@ -69,6 +71,7 @@ github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F
github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc=
github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10/go.mod h1:26a14FGhZVELuz2cc2AolvW4RHmIO3/HRwsdHhaIPDE=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11/go.mod h1:wHxkgZT1ClZdcwEVP/pDgYK/9HucsnCfMipmJgCz4xY=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7 h1:ASXSBga98QrGMxbIThCD6jAti09gedLfvry6yJtsoBE=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7/go.mod h1:TBpgqm3XofZz2LCYjZhektGPU7ArEgascyzbm4SjFo4=
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg=
@ -102,6 +105,8 @@ github.com/alibabacloud-go/tea-utils/v2 v2.0.6/go.mod h1:qxn986l+q33J5VkialKMqT/
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 h1:WDx5qW3Xa5ZgJ1c8NfqJkF6w+AU5wB8835UdhPr6Ax0=
github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.2 h1:CmhJzCZ5RiSiWU6BV2XJUtIMD2LDo9FFfqlYGtx1aAw=
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.2/go.mod h1:9itYSTzipL3NlvhvNYfTjFaapoZzG68nlu/KUdh9SpA=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.100 h1:yUkCbrSM1cWtgBfRVKMQtdt22KhDvKY7g4V+92eG9wA=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.100/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=