Skip to content
This repository was archived by the owner on Mar 6, 2022. It is now read-only.

Commit d3a1182

Browse files
authored
Merge pull request #15 from yurymkomarov/master
[IaC] Terraform
2 parents e8cc220 + bdf0962 commit d3a1182

File tree

19 files changed

+1341
-61
lines changed

19 files changed

+1341
-61
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ jobs:
99
- run: go get -u github.com/go-bindata/go-bindata/...
1010
- run: make
1111
- store_artifacts:
12-
path: artifacts
12+
path: artifacts

.gitignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,39 @@ fabric.properties
8383
# .idea/misc.xml
8484
# *.ipr
8585

86+
### Terraform ###
87+
# Local .terraform directories
88+
**/.terraform/*
89+
90+
# .tfstate files
91+
*.tfstate
92+
*.tfstate.*
93+
94+
# Crash log files
95+
crash.log
96+
97+
# Ignore backend.tf files with Terraform backend configuration
98+
backend.tf
99+
100+
# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
101+
# .tfvars files are managed as part of configuration and so should be included in
102+
# version control.
103+
*.tfvars
104+
105+
# Ignore override files as they are usually used to override resources locally and so
106+
# are not checked in
107+
override.tf
108+
override.tf.json
109+
*_override.tf
110+
*_override.tf.json
111+
112+
# Include override files you do wish to add to version control using negated pattern
113+
# !example_override.tf
114+
115+
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
116+
*tfplan*
117+
118+
.awslambdaproxy
86119
bindata.go
87120
.DS_Store
88121
vendor/

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ COPY --from=build-env /src/artifacts/server/linux/awslambdaproxy /app/
1010

1111
ENV AWS_ACCESS_KEY_ID=
1212
ENV AWS_SECRET_ACCESS_KEY=
13+
ENV LAMBDA_NAME=
14+
ENV LAMBDA_IAM_ROLE_NAME=
1315
ENV REGIONS=
1416
ENV FREQUENCY=
1517
ENV MEMORY=
1618
ENV SSH_USER=
1719
ENV SSH_PORT=2222
1820
ENV LISTENERS=
21+
ENV DEBUG=
1922
ENV DEBUG_PROXY=
23+
ENV BYPASS=
2024

2125
WORKDIR /app
2226

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,4 @@ docker:
9090

9191
docker-release:
9292
docker push vdan/awslambdaproxy:$(VERSION)
93-
docker push vdan/awslambdaproxy:latest
93+
docker push vdan/awslambdaproxy:latest

README.md

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,54 +18,58 @@ At a high level, awslambdaproxy proxies TCP/UDP traffic through AWS Lambda regio
1818
![](/assets/images/how-it-works.png?raw=true)
1919

2020
## Installation
21+
- [Terraform](#terraform)
22+
- [Manual](#manual)
2123

22-
The easiest way is to download a pre-built binary from the [GitHub Releases](https://github.com/dan-v/awslambdaproxy/releases) page.
24+
## Terraform
2325

24-
## Usage
26+
1. Clone repository and go to Terraform component folder:
27+
```sh
28+
git clone git@github.com:dan-v/awslambdaproxy.git && cd awslambdaproxy/deployment/terraform
29+
```
30+
31+
2. Configure your Terrafom backend. Read more about Terraform backend [here](https://www.terraform.io/docs/backends/index.html).
32+
33+
3. Create and fill variable defenitions file ([read more here](https://www.terraform.io/docs/configuration/variables.html#variable-definitions-tfvars-files)) if you don't want to use default variables values.
34+
35+
4. Run those commands to init and apply configuration:
36+
```sh
37+
terraform init && terraform apply -auto-approve
38+
```
39+
40+
It will create all dependent resources and run awslambdaproxy inside Docker container. EC2 instance SSH key can be found in AWS Secret Manager in your [AWS Management Console](https://console.aws.amazon.com/).
2541

26-
1. Copy `awslambdaproxy` binary to a <b>publicly accessible</b> linux host (e.g. EC2 instance, VPS instance, etc). You will need to <b>open the following ports</b> on this host:
42+
NOTE: Some AWS regions have a big list of IP CIDR blocks and they can overhead default limits of security group ([read more](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups)). Need to make limit increase request through the AWS Support Center by choosing Create Case and then choosing Service Limit Increase to prevent deployment issues.
43+
44+
## Manual
45+
46+
1. Download a pre-built binary from the [GitHub Releases](https://github.com/dan-v/awslambdaproxy/releases) page.
47+
48+
2. Copy `awslambdaproxy` binary to a <b>publicly accessible</b> linux host (e.g. EC2 instance, VPS instance, etc). You will need to <b>open the following ports</b> on this host:
2749
* <b>Port 22</b> - functions executing in AWS Lambda will open SSH connections back to the host running `awslambdaproxy`, so this port needs to be open to the world. The SSH key used here is dynamically generated at startup and added to the running users authorized_keys file.
2850
* <b>Port 8080</b> - the default configuration will start a HTTP/SOCKS proxy listener on this port with default user/password authentication. If you don't want to publicly expose the proxy server, one option is to setup your own VPN server (e.g. [dosxvpn](https://github.com/dan-v/dosxvpn) or [algo](https://github.com/trailofbits/algo)), connect to it, and just run awslambdaproxy with the proxy listener only on localhost (-l localhost:8080).
2951

30-
2. Optional, but I'd highly recommend taking a look at the Minimal IAM Policies section below. This will allow you to setup minimal permissions required to setup and run the project. Otherwise, if you don't care about security you can always use an access key with full administrator privileges.
52+
3. Optional, but I'd highly recommend taking a look at the Minimal IAM Policies section below. This will allow you to setup minimal permissions required to setup and run the project. Otherwise, if you don't care about security you can always use an access key with full administrator privileges.
3153

32-
3. `awslambdaproxy` will need access to credentials for AWS in some form. This can be either through exporting environment variables (as shown below), shared credential file, or an IAM role if assigned to the instance you are running it on. See [this](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials) for more details.
54+
4. `awslambdaproxy` will need access to credentials for AWS in some form. This can be either through exporting environment variables (as shown below), shared credential file, or an IAM role if assigned to the instance you are running it on. See [this](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials) for more details.
3355

3456
```sh
3557
export AWS_ACCESS_KEY_ID=XXXXXXXXXX
3658
export AWS_SECRET_ACCESS_KEY=YYYYYYYYYYYYYYYYYYYYYY
3759
```
38-
4. Run `awslambdaproxy setup`.
60+
5. Run `awslambdaproxy setup`.
3961

4062
```sh
4163
./awslambdaproxy setup
4264
```
4365

44-
5. Run `awslambdaproxy run`.
66+
6. Run `awslambdaproxy run`.
4567

4668
```sh
4769
./awslambdaproxy run -r us-west-2,us-west-1,us-east-1,us-east-2
4870
```
4971

50-
6. Configure your web browser (or OS) to use the HTTP/SOCKS5 proxy on the publicly accessible host running `awslambdaproxy` on port 8080.
51-
52-
## Examples
53-
```
54-
# execute proxy in four different regions with rotation happening every 60 seconds
55-
./awslambdaproxy run -r us-west-2,us-west-1,us-east-1,us-east-2 -f 60s
56-
57-
# choose a different port and username/password for proxy and add another listener on localhost with no auth
58-
./awslambdaproxy run -l "admin:admin@:8888,localhost:9090"
59-
60-
# bypass certain domains from using lambda proxy
61-
./awslambdaproxy run -b "*.websocket.org,*.youtube.com"
62-
63-
# specify a dns server for the proxy server to use for dns lookups
64-
./awslambdaproxy run -l "admin:awslambdaproxy@:8080?dns=1.1.1.1"
65-
66-
# increase function memory size for better network performance
67-
./awslambdaproxy run -m 512
68-
```
72+
7. Configure your web browser (or OS) to use the HTTP/SOCKS5 proxy on the publicly accessible host running `awslambdaproxy` on port 8080.
6973

7074
## Minimal IAM Policies
7175
* This assumes you have the AWS CLI setup with an admin user
@@ -100,6 +104,24 @@ aws iam create-access-key --user-name awslambdaproxy-run
100104
}
101105
```
102106
107+
## Examples
108+
```
109+
# execute proxy in four different regions with rotation happening every 60 seconds
110+
./awslambdaproxy run -r us-west-2,us-west-1,us-east-1,us-east-2 -f 60s
111+
112+
# choose a different port and username/password for proxy and add another listener on localhost with no auth
113+
./awslambdaproxy run -l "admin:admin@:8888,localhost:9090"
114+
115+
# bypass certain domains from using lambda proxy
116+
./awslambdaproxy run -b "*.websocket.org,*.youtube.com"
117+
118+
# specify a dns server for the proxy server to use for dns lookups
119+
./awslambdaproxy run -l "admin:awslambdaproxy@:8080?dns=1.1.1.1"
120+
121+
# increase function memory size for better network performance
122+
./awslambdaproxy run -m 512
123+
```
124+
103125
## FAQ
104126
1. <b>Should I use awslambdaproxy?</b> That's up to you. Use at your own risk.
105127
2. <b>Why did you use AWS Lambda for this?</b> The primary reason for using AWS Lambda in this project is the vast pool of IP addresses available that automatically rotate.

cmd/awslambdaproxy/run.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import (
1313
)
1414

1515
var (
16-
frequency time.Duration
17-
memory int
18-
debug, debugProxy bool
19-
sshUser, sshPort, regions, listeners, bypass string
16+
frequency time.Duration
17+
memory int
18+
debug, debugProxy bool
19+
lambdaName, lambdaIamRole, sshUser, sshPort, regions, listeners, bypass string
2020
)
2121

2222
// runCmd represents the run command
@@ -50,12 +50,16 @@ var runCmd = &cobra.Command{
5050
aFrequency := viper.GetDuration("frequency")
5151
aListeners := strings.Split(viper.GetString("listeners"), ",")
5252
aBypass := viper.GetString("bypass")
53+
aLambdaName := viper.GetString("lambda-name")
54+
aLambdaIamRoleName := viper.GetString("lambda-iam-role-name")
5355

5456
if _, err := server.GetSessionAWS(); err != nil {
5557
log.Fatal("unable to find valid aws credentials")
5658
}
5759

5860
s, err := server.New(server.Config{
61+
LambdaName: aLambdaName,
62+
LambdaIamRoleName: aLambdaIamRoleName,
5963
LambdaRegions: aRegions,
6064
LambdaMemory: aMemory,
6165
LambdaExecutionFrequency: aFrequency,
@@ -84,6 +88,10 @@ func getCurrentUserName() string {
8488
func init() {
8589
RootCmd.AddCommand(runCmd)
8690

91+
runCmd.Flags().StringVarP(&lambdaName, "lambda-name", "n", "awslambdaproxy",
92+
fmt.Sprintf("name of lambda function"))
93+
runCmd.Flags().StringVarP(&lambdaIamRole, "lambda-iam-role-name", "i", "awslambdaproxy-role",
94+
fmt.Sprintf("name of lambda function"))
8795
runCmd.Flags().StringVarP(&regions, "regions", "r", "us-west-2",
8896
fmt.Sprintf("comma separted list of regions to run proxy (e.g. us-west-2,us-west-1,us-east-1). "+
8997
"valid regions include %v", server.GetValidLambdaRegions()))
@@ -111,6 +119,8 @@ func init() {
111119
"comma separated list of domains/ips to bypass lambda proxy (e.g. *.websocket.org,*.youtube.com). "+
112120
"note that when using sock5 proxy mode you'll need to be remotely resolving dns for this to work.")
113121

122+
viper.BindPFlag("lambda-name", runCmd.Flags().Lookup("lambda-name"))
123+
viper.BindPFlag("lambda-iam-role-name", runCmd.Flags().Lookup("lambda-iam-role-name"))
114124
viper.BindPFlag("regions", runCmd.Flags().Lookup("regions"))
115125
viper.BindPFlag("frequency", runCmd.Flags().Lookup("frequency"))
116126
viper.BindPFlag("memory", runCmd.Flags().Lookup("memory"))

cmd/awslambdaproxy/setup.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/dan-v/awslambdaproxy/pkg/server"
77
"github.com/spf13/cobra"
8+
"github.com/spf13/viper"
89
)
910

1011
// setupCmd represents the setup command
@@ -13,11 +14,14 @@ var setupCmd = &cobra.Command{
1314
Short: "setup awslambdaproxy aws infrastructure",
1415
Long: `this will setup all required aws infrastructure to run awslambdaproxy.`,
1516
Run: func(cmd *cobra.Command, args []string) {
17+
18+
aLambdaIamRoleName := viper.GetString("lambda-iam-role-name")
19+
1620
if _, err := server.GetSessionAWS(); err != nil {
1721
log.Fatal("unable to find valid aws credentials")
1822
}
1923

20-
err := server.SetupLambdaInfrastructure()
24+
err := server.SetupLambdaInfrastructure(aLambdaIamRoleName)
2125
if err != nil {
2226
log.Fatal("failed to run setup for awslambdaproxy: ", err)
2327
}

deployment/terraform/data.tf

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
data "aws_ami" "this" {
2+
most_recent = true
3+
owners = ["amazon"]
4+
5+
filter {
6+
name = "name"
7+
values = ["amzn2-ami-hvm*"]
8+
}
9+
}
10+
11+
data "aws_availability_zones" "this" {
12+
state = "available"
13+
}
14+
15+
data "aws_vpc" "default" {
16+
default = true
17+
}
18+
19+
data "aws_subnet_ids" "default" {
20+
vpc_id = data.aws_vpc.default.id
21+
}
22+
23+
data "aws_subnet" "default" {
24+
id = element(tolist(data.aws_subnet_ids.default.ids), 0)
25+
}
26+
27+
data "aws_security_group" "default" {
28+
vpc_id = data.aws_vpc.default.id
29+
30+
filter {
31+
name = "group-name"
32+
values = ["default"]
33+
}
34+
}
35+
36+
data "aws_iam_policy_document" "role" {
37+
statement {
38+
actions = ["sts:AssumeRole"]
39+
effect = "Allow"
40+
41+
principals {
42+
identifiers = ["vpc-flow-logs.amazonaws.com"]
43+
type = "Service"
44+
}
45+
}
46+
}
47+
48+
data "aws_iam_policy_document" "role_policy_cloudwatch" {
49+
statement {
50+
actions = [
51+
"logs:CreateLogGroup",
52+
"logs:CreateLogStream",
53+
"logs:PutLogEvents",
54+
"logs:DescribeLogGroups",
55+
"logs:DescribeLogStreams"
56+
]
57+
effect = "Allow"
58+
resources = ["*"]
59+
}
60+
}
61+
62+
data "aws_iam_policy_document" "profile_sts" {
63+
statement {
64+
effect = "Allow"
65+
actions = ["sts:AssumeRole"]
66+
67+
principals {
68+
identifiers = ["ec2.amazonaws.com"]
69+
type = "Service"
70+
}
71+
}
72+
}
73+
74+
data "aws_iam_policy_document" "lambda_sts" {
75+
statement {
76+
effect = "Allow"
77+
actions = ["sts:AssumeRole"]
78+
79+
principals {
80+
identifiers = ["lambda.amazonaws.com"]
81+
type = "Service"
82+
}
83+
}
84+
}
85+
86+
data "aws_iam_policy_document" "lambda" {
87+
statement {
88+
effect = "Allow"
89+
actions = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"]
90+
resources = ["arn:aws:logs:*:*:*"]
91+
}
92+
}
93+
94+
data "aws_iam_policy_document" "user" {
95+
statement {
96+
effect = "Allow"
97+
actions = ["lambda:*"]
98+
resources = ["arn:aws:lambda:*:*:function:${var.name}-*"]
99+
}
100+
101+
statement {
102+
effect = "Allow"
103+
actions = ["iam:GetRole", "iam:PassRole"]
104+
resources = ["arn:aws:iam::*:role/${var.name}-*"]
105+
}
106+
}
107+
108+
data "http" "current_ip" {
109+
url = "http://ipv4.icanhazip.com"
110+
}
111+
112+
data "aws_ip_ranges" "lambda" {
113+
for_each = toset(var.lambda_regions)
114+
115+
regions = [each.value]
116+
services = ["ec2"]
117+
}

deployment/terraform/dummy.zip

4.67 MB
Binary file not shown.

0 commit comments

Comments
 (0)