This repository has been archived by the owner on Mar 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Single endpoint that supports http/socks proxy (using gost library). This also supports many other types of tunnels/proxies. * Breakup setup and run logic and make subcommands (using viper/cobra libraries) * Add optional minimal IAM roles for setup and run commands * Update dependencies
- Loading branch information
Showing
22 changed files
with
733 additions
and
404 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,14 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/dan-v/awslambdaproxy" | ||
"flag" | ||
"fmt" | ||
"os" | ||
"strings" | ||
"time" | ||
"os/user" | ||
"log" | ||
"strconv" | ||
) | ||
|
||
const ( | ||
// Max execution time on lambda is 300 seconds currently | ||
lambdaMaxFrequencySeconds = 290 | ||
lambdaMinMemorySize = 128 | ||
lambdaMaxMemorySize = 1536 | ||
lambdaDefaultMemorySize = lambdaMinMemorySize | ||
"github.com/dan-v/awslambdaproxy/cmd/awslambdaproxy/cmd" | ||
) | ||
|
||
func main() { | ||
user, err := user.Current() | ||
if err != nil { | ||
log.Println("Failed to get current username") | ||
os.Exit(1) | ||
} | ||
|
||
lambdaRegionsPtr := flag.String("lambda-regions", "us-west-2", "Regions to run proxy " + | ||
"(e.g. us-west-2) (can be comma separated list)") | ||
lambdaFrequencyPtr := flag.Int("lambda-frequency", lambdaMaxFrequencySeconds, "Frequency in " + | ||
"seconds to execute Lambda function. Max=" + strconv.Itoa(lambdaMaxFrequencySeconds) + ". If multiple " + | ||
"lambda-regions are specified, this will cause traffic to rotate round robin at the interval " + | ||
"specified here") | ||
lambdaMemorySizePtr := flag.Int("lambda-memory", lambdaDefaultMemorySize, "Memory size in MB "+ | ||
"for Lambda function. Higher memory may allow for faster network throughput.") | ||
sshUserPtr := flag.String("ssh-user", user.Username, "SSH user for tunnel connections from Lambda") | ||
sshPortPtr := flag.String("ssh-port", "22", "SSH port for tunnel connections from Lambda") | ||
proxyPortPtr := flag.String("proxy-port", "8080", "Port to listen for client socks proxy "+ | ||
"connections") | ||
proxyUsernamePtr := flag.String("proxy-username", "admin", "Username for proxy authentication") | ||
proxyPasswordPtr := flag.String("proxy-password", "admin", "Password for proxy authentication") | ||
flag.Parse() | ||
|
||
if *proxyPortPtr == "" { | ||
flag.PrintDefaults() | ||
os.Exit(1) | ||
} | ||
if *lambdaRegionsPtr == "" { | ||
flag.PrintDefaults() | ||
os.Exit(1) | ||
} | ||
if *sshUserPtr == "" { | ||
flag.PrintDefaults() | ||
os.Exit(1) | ||
} | ||
if *sshPortPtr == "" { | ||
flag.PrintDefaults() | ||
os.Exit(1) | ||
} | ||
if *proxyUsernamePtr == "" { | ||
flag.PrintDefaults() | ||
os.Exit(1) | ||
} | ||
if *proxyPasswordPtr == "" { | ||
flag.PrintDefaults() | ||
os.Exit(1) | ||
if err := cmd.RootCmd.Execute(); err != nil { | ||
fmt.Println(err) | ||
os.Exit(-1) | ||
} | ||
|
||
// check memory | ||
if *lambdaMemorySizePtr > lambdaMaxMemorySize { | ||
log.Println("Maximum lambda memory size is " + strconv.Itoa(lambdaMaxMemorySize) + " MB") | ||
os.Exit(1) | ||
} | ||
if *lambdaMemorySizePtr < lambdaMinMemorySize { | ||
log.Println("Minimum lambda memory size is " + strconv.Itoa(lambdaMinMemorySize) + " MB") | ||
os.Exit(1) | ||
} | ||
lambdaMemorySize := int64(*lambdaMemorySizePtr) | ||
|
||
// check frequency | ||
if *lambdaFrequencyPtr > lambdaMaxFrequencySeconds { | ||
log.Println("Maximum lambda frequency is " + strconv.Itoa(lambdaMaxFrequencySeconds) + " seconds") | ||
os.Exit(1) | ||
} | ||
lambdaFrequencySeconds := time.Second * time.Duration(*lambdaFrequencyPtr) | ||
lambdaExecutionTimeout := int64(lambdaFrequencySeconds.Seconds()) + int64(10) | ||
|
||
// check for required aws keys | ||
access := os.Getenv("AWS_ACCESS_KEY_ID") | ||
if access == "" { | ||
log.Println("Must specify environment variable AWS_ACCESS_KEY_ID") | ||
os.Exit(1) | ||
} | ||
secret := os.Getenv("AWS_SECRET_ACCESS_KEY") | ||
if secret == "" { | ||
log.Println("Must specify environment variable AWS_SECRET_ACCESS_KEY") | ||
os.Exit(1) | ||
} | ||
|
||
// handle regions | ||
lambdaRegions := strings.Split(*lambdaRegionsPtr, ",") | ||
|
||
awslambdaproxy.ServerInit(*proxyPortPtr, *sshUserPtr, *sshPortPtr, *proxyUsernamePtr, *proxyPasswordPtr, | ||
lambdaRegions, lambdaMemorySize, lambdaFrequencySeconds, lambdaExecutionTimeout) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
var cfgFile string | ||
|
||
// RootCmd represents the base command when called without any subcommands | ||
var RootCmd = &cobra.Command{ | ||
Use: "awslambdaproxy", | ||
Short: "An AWS Lambda powered HTTP/SOCKS web proxy", | ||
Long: `awslambdaproxy is an AWS Lambda powered HTTP/SOCKS web proxy. | ||
It provides a constantly rotating IP address for your network traffic | ||
from all regions where AWS Lambda is available. The goal is to obfuscate | ||
your connections and make it harder to track you as a user.`, | ||
} | ||
|
||
// Execute adds all child commands to the root command sets flags appropriately. | ||
// This is called by main.main(). It only needs to happen once to the rootCmd. | ||
func Execute() { | ||
if err := RootCmd.Execute(); err != nil { | ||
fmt.Println(err) | ||
os.Exit(-1) | ||
} | ||
} | ||
|
||
func init() { | ||
cobra.OnInitialize(initConfig) | ||
} | ||
|
||
// initConfig reads in config file and ENV variables if set. | ||
func initConfig() { | ||
if cfgFile != "" { // enable ability to specify config file via flag | ||
viper.SetConfigFile(cfgFile) | ||
} | ||
|
||
viper.SetConfigName(".awslambdaproxy") // name of config file (without extension) | ||
viper.AddConfigPath("$HOME") // adding home directory as first search path | ||
viper.AutomaticEnv() // read in environment variables that match | ||
|
||
// If a config file is found, read it in. | ||
if err := viper.ReadInConfig(); err == nil { | ||
fmt.Println("Using config file:", viper.ConfigFileUsed()) | ||
} else { | ||
fmt.Println("Invalid config file", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
"os/user" | ||
"github.com/dan-v/awslambdaproxy" | ||
"time" | ||
"github.com/spf13/viper" | ||
"strings" | ||
"os" | ||
"fmt" | ||
"strconv" | ||
) | ||
|
||
var ( | ||
frequency time.Duration | ||
memory int64 | ||
sshUser, sshPort, regions, listeners string | ||
// Max execution time on lambda is 300 seconds currently | ||
lambdaMaxFrequency = time.Duration(290 * time.Second) // leave 10 seconds of leeway | ||
lambdaMinMemorySize = 128 | ||
lambdaMaxMemorySize = 1536 | ||
) | ||
|
||
// runCmd represents the run command | ||
var runCmd = &cobra.Command{ | ||
Use: "run", | ||
Short: "Run awslambdaproxy", | ||
Long: `This will execute awslambdaproxy in regions specified. Examples: | ||
# Make sure credentials are exported | ||
export AWS_ACCESS_KEY_ID=XXXXXXXXXX | ||
export AWS_SECRET_ACCESS_KEY=YYYYYYYYYYYYYYYYYYYYYY | ||
# Example 1 - Execute proxy in four different regions with rotation happening every 60 seconds | ||
./awslambdaproxy run -r us-west-2,us-west-1,us-east-1,us-east-2 -f 60s | ||
# Example 2 - Choose a different port and username/password for proxy and add another listener on localhost with no auth | ||
./awslambdaproxy run -r us-west-2 -l "admin:admin@:8888,localhost:9090" | ||
# Example 3 - Increase function memory size for better network performance | ||
./awslambdaproxy run -r us-west-2 -m 512 | ||
`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
aSshUser := viper.GetString("ssh-user") | ||
aSshPort := viper.GetString("ssh-port") | ||
aRegions := strings.Split(viper.GetString("regions"), ",") | ||
aMemory := viper.GetInt64("memory") | ||
aFrequency := viper.GetDuration("frequency") | ||
aListeners := strings.Split(viper.GetString("listeners"), ",") | ||
aTimeout := int64(viper.GetDuration("frequency").Seconds()) + int64(30) | ||
|
||
// check memory | ||
if aMemory > int64(lambdaMaxMemorySize) { | ||
fmt.Println("Maximum lambda memory size is " + strconv.Itoa(lambdaMaxMemorySize) + " MB") | ||
os.Exit(1) | ||
} | ||
if aMemory < int64(lambdaMinMemorySize) { | ||
fmt.Println("Minimum lambda memory size is " + strconv.Itoa(lambdaMinMemorySize) + " MB") | ||
os.Exit(1) | ||
} | ||
|
||
// check frequency | ||
if aFrequency > lambdaMaxFrequency { | ||
fmt.Println("Maximum lambda frequency is " + lambdaMaxFrequency.String() + " seconds") | ||
os.Exit(1) | ||
} | ||
|
||
// check for required aws keys | ||
access := os.Getenv("AWS_ACCESS_KEY_ID") | ||
if access == "" { | ||
fmt.Println("Must specify environment variable AWS_ACCESS_KEY_ID") | ||
os.Exit(1) | ||
} | ||
secret := os.Getenv("AWS_SECRET_ACCESS_KEY") | ||
if secret == "" { | ||
fmt.Println("Must specify environment variable AWS_SECRET_ACCESS_KEY") | ||
os.Exit(1) | ||
} | ||
|
||
awslambdaproxy.ServerInit(aSshUser, aSshPort, aRegions, aMemory, aFrequency, aListeners, aTimeout) | ||
}, | ||
} | ||
|
||
func getCurrentUserName() string { | ||
user, _ := user.Current() | ||
if user != nil { | ||
return user.Username | ||
} | ||
return "" | ||
} | ||
|
||
func init() { | ||
RootCmd.AddCommand(runCmd) | ||
|
||
runCmd.Flags().StringVarP(®ions, "regions", "r", "us-west-2","Regions to " + | ||
"run proxy.") | ||
runCmd.Flags().DurationVarP(&frequency, "frequency", "f", time.Duration(time.Second * 260), "Frequency " + | ||
"to execute Lambda function. Maximum is " + lambdaMaxFrequency.String() + ". If multiple " + | ||
"lambda-regions are specified, this will cause traffic to rotate round robin at the interval " + | ||
"specified here.") | ||
runCmd.Flags().Int64VarP(&memory, "memory", "m", 128, "Memory size in MB for Lambda function. " + | ||
"Higher memory may allow for faster network throughput.") | ||
runCmd.Flags().StringVarP(&listeners, "listeners", "l", "admin:awslambdaproxy@:8080","Add as many listeners" + | ||
"as you'd like.") | ||
runCmd.Flags().StringVarP(&sshUser, "ssh-user", "", getCurrentUserName(),"SSH user for tunnel " + | ||
"connections from Lambda.") | ||
runCmd.Flags().StringVarP(&sshPort, "ssh-port", "", "22","SSH port for tunnel " + | ||
"connections from Lambda.") | ||
|
||
viper.BindPFlag("regions", runCmd.Flags().Lookup("regions")) | ||
viper.BindPFlag("frequency", runCmd.Flags().Lookup("frequency")) | ||
viper.BindPFlag("memory", runCmd.Flags().Lookup("memory")) | ||
viper.BindPFlag("ssh-user", runCmd.Flags().Lookup("ssh-user")) | ||
viper.BindPFlag("ssh-port", runCmd.Flags().Lookup("ssh-port")) | ||
viper.BindPFlag("listeners", runCmd.Flags().Lookup("listeners")) | ||
} |
Oops, something went wrong.