Serverless Screenshots

By Adrian | October 31, 2019

This is a project that I have wanted to get working for some time now, but everytime I tried it, it failed on me. There was always some dependency error or some random obscure error. I’ve used url2png.com in the past to capture screenshots of malicious and unknown websites, and while I have scripts that replicate this functionality via PowerShell, I’m not comfortable running that script on a production machine at work. An isoloted VM that is airgapped from the network yes, but for everyday usage, its a massive NO!

I am using the project from adieuadieu/serverless-chrome to do this, but had to make a few modifications along the way.

These were the installation steps I performed on my Linux box based off the README file in the serverless-chrome repo.

Prerqusites

You will need the following before you start. (My configuration in the parentheses):

  • Linux VM (Ubuntu 18.04LTS)
  • An AWS account
  • nodeJS (v12.10)
  • npm (v6.12.0)
  • aws credentials configured

Installation

Install serverless globally

npm install serverless -g

Get the example service

serverless create -u  https://github.com/adieuadieu/serverless-chrome/tree/master/examples/serverless-framework/aws

Update package.json

Change into the aws directory (cd aws) and update references of node 6.10 to node 8.10 in package.json file. There were 2 references.

Update serverless.yml file

  • Change the runtime from node 6.10 to node 8.10 (Lambda no longer supports new functions on node 6.10)
  • Remove the line under environment marked as DEBUG: "*" (it was causing the build to fail)

Install the dependencies

npm install

AWS Credentials

If you have an aws profile configured (via aws configured --profile <name>) then make that available for serverless with the following command:

export AWS_PROFILE=<profile-name>

Deploy the pacakge into AWS via serveless

Once you have completed the above you can push this configuration into AWS by running this command:

npm run deploy

# Summary Output

Serverless: Stack update finished...
Service Information
service: aws
stage: dev
region: us-east-2
stack: aws-dev
api keys:
  None
endpoints:
  GET - https://XXXXXXXXXX.execute-api.us-east-2.amazonaws.com/dev/version-info
  GET - https://XXXXXXXXXX.execute-api.us-east-2.amazonaws.com/dev/request-logger
  GET - https://XXXXXXXXXX.execute-api.us-east-2.amazonaws.com/dev/screenshot
  GET - https://XXXXXXXXXX.execute-api.us-east-2.amazonaws.com/dev/pdf
functions:
  version-info: aws-dev-version-info
  request-logger: aws-dev-request-logger
  screenshot: aws-dev-screenshot
  pdf: aws-dev-pdf

Stack Outputs
PdfLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-2:ACCOUNT_NUMBER:function:aws-dev-pdf:1
RequestDashloggerLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-2:ACCOUNT_NUMBER:function:aws-dev-request-logger:1
ScreenshotLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-2:ACCOUNT_NUMBER:function:aws-dev-screenshot:1
VersionDashinfoLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-2:ACCOUNT_NUMBER:function:aws-dev-version-info:1
ServiceEndpoint: https://XXXXXXXXXX.execute-api.us-east-2.amazonaws.com/dev
ServerlessDeploymentBucketName: aws-dev-serverlessdeploymentbucket-XXXXXXXXXXXXX

The deployment part took around 10 minutes to complete.

Testing

All going successful, 4 endpoints have been created and you will now be able to call on your screenshot service. Here is a sample of outputs using Postman.

endpoint: /version-info

Get in the internal version number of the function

postman-version-info

endpoint: /request-logger?url=

Returns all the requests that the page made while loading

postman-request-logger

endpoint: /screenshot?url=

Grab a screenshot of a page

postman-screenshot

endpoint: /pdf?url=

Grab the URL as a PDF. Now this function seems to be a little hit and miss either timing out, or not properly displaying the page as a PDF. Also Postman did’nt like displaying a PDF, so I used Chrome instead.

postman-pdf

Teardown

Should you wish to reverse all the changes you made in AWS you can run this command

serverless remove

# Output
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
.........................................
Serverless: Stack removal finished...

Closing thoughts

This is an excellent project from Marco Lüthy that has a tonne of potential uses, but there was one thing it’s missing for me, and that is locking down its use with API keys. While AWS does have a very generous free tier for Lambda, if your API gateway URL becomes known, you run the risk of someone running up excessive amounts of requests, and thats whats going to hit your bill. In its current state it is certainly in the “ease of use” category.

For now, I’ve gone about adding in API key authentication myself manaully, and am in the process of figuring out how to include this as part of the serverless.yml file, so it can be automatically included. Hopfully that will become a part 2 of this blog.