亚马逊AWS官方博客

使用 AWS IoT 按钮实现按需 VPN 访问

本博文由 AWS 社区精英 Teri Radichel 特约发表。Teri Radichel 通过她的公司 2nd Sight Lab 提供网络安全评估、渗透测试和研究服务。她还是 AWS 架构师西雅图聚会 (AWS Architects Seattle Meetup) 的发起人。

在出差提供云安全培训期间,我会在酒店客房以及课堂上使用 VPN 连接 Wi-Fi 网络。大多数公司都将一个远程 VPN 终端节点暴露于整个互联网。有一次我设想可以使用 AWS IoT 按钮将网络访问权限仅限于要求的位置。如果 VPN 用户可以单击获取访问权限,触发打开某个网络规则,然后再次双击禁止网络流量,结果会如何? 我对此想法进行了测试,下面是我的测试结果。

您可能会想为什么需要使用 VPN 来进行远程云管理。为什么要使用 AWS IoT 按钮而不是笔记本电脑或移动应用程序? 更多信息请参阅我的云安全博客

最初,我计划使用 AWS IoT Enterprise 按钮,因为它允许组织控制设备上使用的证书。此外它还要使用 Wi-Fi,并且我希望获取按钮的 IP 地址以授予网络访问权限。为此,我必须能够证明按钮通过 Wi-Fi 网络收到的 IP 地址与我的笔记本电脑的地址相同。很不幸,由于一些无线网络使用自有门户的原因,我在一些地点连接按钮时遇到问题。

然后我尝试了 AT&T LTE-M 按钮。此按钮对于我的使用按钮工作正常,但存在一些对用户不太友好的要求。由于在酒店客房中此按钮采用蜂窝式移动网络而非 Wi-Fi 来连接我的 VPN,我无法自动确定 IP 地址。我必须使用 AWS IoT 移动应用程序来手动设置。

我遇到的另一个问题是一些网络会更改 Wi-Fi 客户端在 VPN 连接之后的公有 IP 地址。之前和之后的 IP 地址始终在同一网络块中,但不一致。与使用单一 IP 地址相反,用户必须了解如何确定哪个 IP 范围经过了按钮。这种概念验证式的实现效果很好,但对于非网络高手用户而言并非理想的解决方案。

好消息是我不需要使用管理员权限登录我的 AWS 账户即可更改网络设置,允许从我的位置访问 VPN 终端节点。AWS IoT 按钮用户拥有受限的权限,授予访问权限的 AWS Lambda 函数角色也是如此。AWS IoT 按钮采用多重身份验证方式。

使用 Lambda 函数来配置按钮

注意:这并非对生产就绪解决方案的完整测试,只是以此为起点,为您演示为管理终端节点赋予按需网络访问权限的一些概念。按钮和 Lambda 函数的角色可以比我在概念验证实现中使用的角色拥有更多限制。

1.设置 VPN 终端节点(指令不属于本博文的范围)。您可以使用类似于 OpenVPN 或任何可让您创建远程访问 VPN 的 AWS Marketplace 解决方案的指令。

2.Jeff Barr 已经就如何使用 Lambda 函数设置 AWS IoT 按钮撰写了一篇优秀的博文。过程非常简单直接。

3.为您的 Lambda 角色添加替换网络 ACL 条目的能力,从而让您的按钮可以更改网络。此角色可让分配的资源更新账户中的规则 — 但不建议这样操作! 将此权限进一步限制为特定的网络 ACL。此外,确保用户仅可以编辑分配给自己的按钮的置放属性。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ec2:ReplaceNetworkAclEntry",
            "Resource": "*"
        }
    ]
}

4.编写代码。

对于我的测试,我编辑了按钮提供的默认代码,以证明我要进行的操作将会奏效。我编写了将在网络更改后发送文本消息的代码行。这样,如果没有错误,用户不会收到 SNS 消息。

此外,您始终、始终、始终需要验证从客户端发送到任何应用程序的任何输入。我增加了日志行来显示您可以在哪里添加。根据您的环境更改这些变量:vpcid、nacl、规则。规则参数是网络 ACL 中的规则,将更新以使用按钮应用程序提供的 IP 地址。

from __future__ import print_function

import boto3
import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

sns = boto3.client('sns')

def lambda_handler(event, context):

    logger.info('Received event: ' + json.dumps(event))

    attributes = event['placementInfo']['attributes']

    phone_number = attributes['phoneNumber']
    message = attributes['message']
    ip = attributes['ip']

    logger.info("Need code here to validate this is a valid IP address")
    logger.info("Need code here to validate the message")
    logger.info("Need code here to validate the phone number")

    for key in attributes.keys():
        message = message.replace('{{%s}}' % (key), attributes[key])
    message = message.replace('{{*}}', json.dumps(attributes))

    dsn = event['deviceInfo']['deviceId']
    click_type = event['deviceEvent']['buttonClicked']['clickType']
  
    vpcid = 'vpc-xxxxxxxxxxxxxxxx'
    nacl = 'acl-xxxxxxxxxxxxxxx'
    rule = 200
    
    cidr =  ip + '/32'
    
    message = message + " " + cidr
    
    client = boto3.client('ec2')

    response = client.replace_network_acl_entry(
        NetworkAclId=nacl,
        CidrBlock=cidr,
        DryRun=False,
        Egress=False,
        PortRange={
            'From': 500,
            'To': 500
        },
        Protocol="17",
        RuleAction="allow",
        RuleNumber=rule
    )
    
    sns.publish(PhoneNumber=phone_number, Message=message)

    logger.info('SMS has been sent to ' + phone_number)

 

5.编写删除网络访问权限的双击代码。我将此代码留给读者来练习。如果您熟悉如何在上一步中编辑网络 ACL,您应该能够通过将行 RuleAction=”allow” 修改为 RuleAction=”deny”,编写禁止流量的双击函数。您现在已经阻止了允许远程用户连接 VPN 的网络端口的访问权限。

按钮测试

1.通过 https://whatismyip.com 等网站获取您当前网络的公有 IP 地址。

对于此博文,假设您只需要单个 IP 地址。但您可以轻松修改上述代码以允许某个 IP 地址范围(亦即 CIDR 块)。

2.登录按钮的手机应用程序。

3.选择 Projects,然后选择您的按钮项目。我的项目名称为 vpn2。

4.与您分配给按钮的 Lambda 函数关联的项目需要下列置放属性:
message:网络已更新!
phoneNumber:接收文本消息的电话号码。
ip:从 whatismyip.com 获取的 IP 地址。

5.选择修改某个现有的属性或选择 + Add Placement Attribute 来添加新属性。

6.按下 AWS IoT 按钮以触发 Lambda 函数。如果运行正常无误,您将收到一条显示您输入的 IP 地址的文本消息。

7.检查您的 VPC 网络 ACL 规则以验证对 IP 地址的更改正确。

8.验证您可以连接到 VPN。

9.假设您实施了双击函数来禁用访问权限,双击按钮以将网络 ACL 规则从“allow”更改为“deny”。

现在您已经了解如何使用 AWS IoT 按钮来按需更改网络规则。希望本文能够为您带来启发,为您的 AWS VPN 和管理终端节点增加额外的安全层!