Use Serverless Framework and AWS VPC to Protect Your Chatbot Resources
To show you how to protect your Chatbot we will be using the Glip chatbot as an example on how to do this. The examples you see below doesn’t just apply to Glip, but applies to other kinds of applications as well, which are deployed to AWS using serverless framework.
If you’re interested in learning more about the RingCentral Chatbot Framework for JavaScript follow the link. It shouldn’t take you more than 30 minutes to create and deploy a Glip chatbot to AWS. In this we will show you how to protect your Glip chatbot resources! In this article, I will share my experience about making my chatbots security compliance. I will be covering the following topics: firstly serverless framework, secondly AWS VPC and finally how to deploy your chatbot into AWS VPC in order to secure it.
Serverless Framework
Build web, mobile and IoT applications with serverless architectures using AWS Lambda, Azure Functions, Google CloudFunctions & more!
Simply put, serverless framework is a framework to help you to take advantage of serverless architectures. So serverless is a tool that helps us to provision, deploy and manage resources on AWS.
Serverless installation and usage are pretty straightforward. In theory you can create a project and deploy it to AWS with just four commands:
# install serverless framework
yarn install serverless# Create a new Serverless Service/Project
npx serverless create --template aws-nodejs --path my-service# Change into the newly created directory
cd my-service# deploy the service
npx sls deploy
This is so cool because you don’t need to manually touch AWS at all. Everything is taken care of by your serverless framework!
We are not going to go into great detail of serverless framework — if you want to go into greater depth read check out this article: https://serverless.com/framework/docs/providers/aws/.
AWS VPC
Amazon Virtual Private Cloud (Amazon VPC) lets you provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define. You have complete control over your virtual networking environment, including selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways. You can use both IPv4 and IPv6 in your VPC for secure and easy access to resources and applications.
VPC is not required to use AWS resources. But it is considered good practice, especially for enterprise applications.
Amazon VPC enables you to build a virtual network in the AWS cloud — no VPNs, hardware, or physical datacenters required. You can define your own network space, and control how your network and the Amazon EC2 resources inside your network are exposed to the Internet. You can also leverage the enhanced security options in Amazon VPC to provide more granular access to and from the Amazon EC2 instances in your virtual network.
VPC is like the traditional intranet, but in the cloud. Exposing your resource in the internet is not safe, it’s preferred to put them inside the intranet. Overall, VPC is considered good practice for security reasons.
How to deploy your chatbot into AWS VPC in order to secure it.
Let’s say you already have a Glip chatbot deployed to AWS, and you want to secure it. What should you do? Find out here with this step by step guide:
Step 1: create a VPC with subnets
resources:
Resources:
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16 PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: us-east-1a
CidrBlock: 10.0.1.0/24
VpcId:
Ref: Vpc
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: us-east-1b
CidrBlock: 10.0.2.0/24
VpcId:
Ref: Vpc
PrivateSubnet3:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: us-east-1c
CidrBlock: 10.0.3.0/24
VpcId:
Ref: Vpc PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: us-east-1d
CidrBlock: 10.0.21.0/24
VpcId:
Ref: Vpc
With the configuration above, we create a VPC with 3 private subnets and 1 public subnet. Private and public subnets are almost the same, the only difference is private subnets are associated with private route table while public subnets are associated with public route table. Private route table and public route table are also almost the same, the only difference is private route table points to NatGateway while public route table points to InternetGateway.
Step 2: Create route tables, NatGateway & InternetGateway
Eip:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
NatGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId:
Fn::GetAtt:
- Eip
- AllocationId
SubnetId:
Ref: PublicSubnet1
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: Vpc
PrivateRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId:
Ref: PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: NatGateway
SubnetRouteTableAssociationPrivate1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: PrivateSubnet1
RouteTableId:
Ref: PrivateRouteTable
SubnetRouteTableAssociationPrivate2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: PrivateSubnet2
RouteTableId:
Ref: PrivateRouteTable
SubnetRouteTableAssociationPrivate3:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: PrivateSubnet3
RouteTableId:
Ref: PrivateRouteTable InternetGateway:
Type: AWS::EC2::InternetGateway
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: Vpc
InternetGatewayId:
Ref: InternetGateway
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: Vpc
PublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId:
Ref: PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: InternetGateway
SubnetRouteTableAssociationPublic1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: PublicSubnet1
RouteTableId:
Ref: PublicRouteTable
Step 3: create database in VPC
A Public database could be dangerous, because it can be easily compromised, even if it is password protected. So let’s create it in VPC instead:
DbSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupName: ${self:service}-${self:provider.stage}-db
GroupDescription: Allow local inbound to port 5432, no outbound
SecurityGroupIngress:
- CidrIp: 10.0.0.0/16
IpProtocol: tcp
FromPort: 5432
ToPort: 5432
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 127.0.0.1/32
VpcId:
Ref: Vpc
DbSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupName: ${self:service}-${self:provider.stage}
DBSubnetGroupDescription: Private database subnet group
SubnetIds:
- Ref: PrivateSubnet1
- Ref: PrivateSubnet2
- Ref: PrivateSubnet3
Database:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: ${self:service}-${self:provider.stage}
Engine: postgres
DBName: dbname
AllocatedStorage: 20
EngineVersion: 11.2
DBInstanceClass: db.t3.micro
MasterUsername: ${self:provider.environment.RINGCENTRAL_CHATBOT_DATABASE_USERNAME}
MasterUserPassword: ${self:provider.environment.RINGCENTRAL_CHATBOT_DATABASE_PASSWORD}
DBSubnetGroupName:
Ref: DbSubnetGroup
VPCSecurityGroups:
- Ref: DbSecurityGroup
NOTE: Please pay attention to
DbSecurityGroup
, it’s how we control the accessibility of the database. We’ve made itAllow local inbound to port 5432, no outbound
.Also pay attention to
DbSubnetGroup
, in order to create a database in a VPC, you simply create it in DBSubnetGroup consisting of private subnets in that VPC.
Step 4: Create lambda function in VPC
LambdaSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupName: ${self:service}-${self:provider.stage}-lambda
GroupDescription: Allow all outbound traffic, no inbound
SecurityGroupIngress:
- IpProtocol: -1
CidrIp: 127.0.0.1/32
VpcId:
Ref: Vpc
First we created a security group. The rule is Allow all outbound traffic, no inbound
.
provider: ... vpc:
securityGroupIds:
- Ref: LambdaSecurityGroup
subnetIds:
- Ref: PrivateSubnet1
- Ref: PrivateSubnet2
- Ref: PrivateSubnet3
Then we defined the VPC settings in the provider level, so that all of our Lambda functions will inherit these settings.
Summary
We’ve put our chatbot resource in a VPC and now is safer than before because:
- The database can only be accessed inside the VPC. Your database is now safe even if its password is compromised.
- Lambda functions disallow inbound access, but is able to allow outbound traffic. Most importantly, it can access the database because they are in the same VPC.
For a sample project using the techniques discussed here, please refer to the Glip Announcement Chatbot.