如何使用 AWS 经典负载均衡器 443 侦听器的对流层框架更新 SSL 协商策略

How to update the SSL negotiation policy in using the Troposhpere framework for an AWS classic load balancer 443 listener

我有一个可用的 Troposphere 模板,它为我的环境提供了 classic 负载平衡器。我正在修改它以使用 SSL 协商策略(密码)ELBSecurityPolicy-TLS-1-2-2017-01 启动负载平衡器端口 443 侦听器。

它会让我生成 cloudformation yaml,但是当我尝试使用生成的 yaml 创建堆栈时,我在尝试创建负载均衡器时收到错误“遇到不受支持的 属性 PolicyType”。

Troposphere 支持 PolicyType 但 AWS CF 不支持??

关于我做错了什么的任何线索? 有没有更好的方法?

我找不到任何使用对流层框架更新 SSL 协商的示例。

这是我的对流层 ELB 侦听器代码部分的片段,我认为它应该发挥作用 -

            LoadBalancerPort="443",
            InstancePort="443",
            Protocol="https",
            InstanceProtocol="https",
            PolicyNames=["StickyPolicy", "My-SSLNegotiation-Policy"],
            #todo - need valid cert
            SSLCertificateId=params.CA_SSL_CERT,
        ),
        elb.Policy(
            LoadBalancerPorts=["443"],
            InstancePorts=["443"],
            PolicyType="SSLNegotiationPolicyType",
            PolicyName="My-SSLNegotiation-Policy",
            Attributes=[{
            "Name": "Reference-Security-Policy",
            "Value": "ELBSecurityPolicy-TLS-1-2-2017-01"
            }]
        )`

这是对流层的政策 class elasticloadbalancing.py(https://github.com/cloudtools/troposphere/blob/master/troposphere/elasticloadbalancing.py)

class Policy(AWSProperty):
    props = {
        'Attributes': ([dict], False),
        'InstancePorts': (list, False),
        'LoadBalancerPorts': (list, False),
        'PolicyName': (basestring, True),
        'PolicyType': (basestring, True),
    }

这是我的整个对流层负载均衡器代码:

LoadBalancer = t.add_resource(LoadBalancer(
#https://github.com/cloudtools/troposphere/blob/master/examples/Autoscaling.py
    "LoadBalancer",
    ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy(
        Enabled=True,
        Timeout=120,
    ),
    ConnectionSettings=elb.ConnectionSettings(
        IdleTimeout=600
    ),
    Subnets=[DMZSubnet1a, DMZSubnet1b],
    LBCookieStickinessPolicy=[elb.LBCookieStickinessPolicy(
        PolicyName="StickyPolicy",
        CookieExpirationPeriod="28800"
        ),
    ],
    #AvailabilityZones=[Join("", [Ref("AWS::Region"), "a"]), Join("", [Ref("AWS::Region"), "b"])],
    HealthCheck=elb.HealthCheck(
        #Target="HTTPS:443/index.html",
        Target="TCP:80",
        HealthyThreshold="5",
        UnhealthyThreshold="5",
        Interval="30",
        Timeout="15",
    ),
    # Redirect http to https on classic load balancer   -  https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb/
    Listeners=[
        elb.Listener(
            LoadBalancerPort="80",
            InstancePort="80",
            Protocol="TCP",
            InstanceProtocol="TCP",
            #SSLCertificateId=Ref(SSLCertificateId)
            #SSLCertificateId=params.CA_SSL_CERT,
        ),
        elb.Listener(
            LoadBalancerPort="443",
            InstancePort="443",
            Protocol="https",
            InstanceProtocol="https",
            PolicyNames=["StickyPolicy", "My-SSLNegotiation-Policy"],
            #todo - need valid cert
            SSLCertificateId=params.CA_SSL_CERT,
        ),
        elb.Policy(
            LoadBalancerPorts=["443"],
            InstancePorts=["443"],
            PolicyType="SSLNegotiationPolicyType",
            PolicyName="My-SSLNegotiation-Policy",
            Attributes=[{
            "Name": "Reference-Security-Policy",
            "Value": "ELBSecurityPolicy-TLS-1-2-2017-01"
            }]
        )
    ],
    CrossZone=True,
    SecurityGroups=[LoadBalancerSG],
    LoadBalancerName=Join("-", [Ref("AWS::StackName"), "LdBlncr"]),
    Scheme="internet-facing",
))

这是它为负载均衡器创建的 AWS CloudFormation yaml:

  LoadBalancer:
    Properties:
      ConnectionDrainingPolicy:
        Enabled: true
        Timeout: 120
      ConnectionSettings:
        IdleTimeout: 600
      CrossZone: 'true'
      HealthCheck:
        HealthyThreshold: '5'
        Interval: '30'
        Target: TCP:80
        Timeout: '15'
        UnhealthyThreshold: '5'
      LBCookieStickinessPolicy:
        - CookieExpirationPeriod: '28800'
          PolicyName: StickyPolicy
      Listeners:
        - InstancePort: '80'
          InstanceProtocol: TCP
          LoadBalancerPort: '80'
          Protocol: TCP
        - InstancePort: '443'
          InstanceProtocol: https
          LoadBalancerPort: '443'
          PolicyNames:
            - StickyPolicy
            - My-SSLNegotiation-Policy
          Protocol: https
          SSLCertificateId: arn:aws:acm:us-east-1:000000000:certificate/d79e336-dd51-4cac-ba3
        - Attributes:
            - Name: Reference-Security-Policy
              Value: ELBSecurityPolicy-TLS-1-2-2017-01
          InstancePorts:
            - '443'
          LoadBalancerPorts:
            - '443'
          PolicyName: My-SSLNegotiation-Policy
          PolicyType: SSLNegotiationPolicyType
      LoadBalancerName: !Join
        - '-'
        - - !Ref 'AWS::StackName'
          - LdBlncr
      Scheme: internet-facing
      SecurityGroups:
        - !ImportValue
          Fn::Join:
            - '-'
            - - ernie
              - LoadBalancerSG
      Subnets:
        - !ImportValue
          Fn::Join:
            - '-'
            - - ernie
              - DMZSubnet1a
        - !ImportValue
          Fn::Join:
            - '-'
            - - ernie
              - DMZSubnet1b
    Type: AWS::ElasticLoadBalancing::LoadBalancer

Classic Load Balancer 策略应在策略 属性 下指定,而不是在侦听器 属性 下指定。 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb.html#cfn-ec2-elb-policies

Listerners=[ ...] 属性 中删除 elb.Policy( ... ) 并将 Policies = [ elb.Policy( ... ), ... ] 属性 添加到 LoadBalancer 资源/对象。

谢谢马林!

对于任何需要它的人,这里是工作对流层代码:

LoadBalancer = t.add_resource(LoadBalancer(
#https://github.com/cloudtools/troposphere/blob/master/examples/Autoscaling.py
    "LoadBalancer",
    ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy(
        Enabled=True,
        Timeout=120,
    ),
    ConnectionSettings=elb.ConnectionSettings(
        IdleTimeout=600
    ),
    Subnets=[DMZSubnet1a, DMZSubnet1b],
    LBCookieStickinessPolicy=[elb.LBCookieStickinessPolicy(
        PolicyName="StickyPolicy",
        CookieExpirationPeriod="28800"
        ),
    ],
    HealthCheck=elb.HealthCheck(
        Target="TCP:80",
        HealthyThreshold="5",
        UnhealthyThreshold="5",
        Interval="30",
        Timeout="15",
    ),
    # Redirect http to https on classic load balancer   -  https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb/
    Listeners=[
        elb.Listener(
            LoadBalancerPort="80",
            InstancePort="80",
            Protocol="TCP",
            InstanceProtocol="TCP",
        ),
        elb.Listener(
            LoadBalancerPort="443",
            InstancePort="443",
            Protocol="https",
            InstanceProtocol="https",
            PolicyNames=["StickyPolicy", "My-SSLNegotiation-Policy"],
            SSLCertificateId=params.CA_SSL_CERT,
        ),
    ],
    Policies=[
        elb.Policy(
            PolicyType="SSLNegotiationPolicyType",
            PolicyName="My-SSLNegotiation-Policy",
            Attributes=[{
                "Name": "Reference-Security-Policy",
                "Value": "ELBSecurityPolicy-TLS-1-1-2017-01"
            }]
        )
    ],