Skip to content

Instantly share code, notes, and snippets.

@goruck
Last active September 21, 2022 14:47
Show Gist options
  • Save goruck/89231f9d8a73f84245a713216c9b765a to your computer and use it in GitHub Desktop.
Save goruck/89231f9d8a73f84245a713216c9b765a to your computer and use it in GitHub Desktop.
Script to create a ssh tunnel from an AWS Lambda function to a remote host via an AWS EC2 instance.
#!/bin/sh
# Script to start a ssh tunnel via an AWS EC2 instance.
# Copyright (C) 2017 Lindo St. Angel.
# Must be called after the instance is setup by ssh-tunnel.sh
# Include global variables:
# EC2_MACH - EC2 machine type
# EC2_TYPE - EC2 instance type
# EC2_KEY_LOC - EC2 keypair location
# EC2_KPAR - EC2 keypair name
# EC2_PORT - EC2 tunnel port number
# EC2_SUB - vpc subnet ID that instance will run in
# EC2_SG - security group ID that controls EC2 ingress
# LAMBDA - lambda function arn that will use tunnel to PFC
# LCL_PORT - local port number that will use tunnel
. /home/pi/bin/ssh-tunnel/vars.sh
# Get external ip address of remote host (this machine).
IP_ADDR=`dig +short myip.opendns.com @resolver1.opendns.com`
if [ -z "$IP_ADDR" ]
then
echo "***Error - Can't get external IP address, terminating."
exit 1
else
echo "***Info - External IP address is $IP_ADDR."
fi
# Get public IP addr for instance.
EC2_HOST=`/home/pi/.local/bin/aws ec2 describe-instances --filters Name=tag:foodcomputer,Values=tunnel \
Name=instance-state-name,Values=running --query "Reservations[*].Instances[*].[PublicIpAddress]"`
echo "***Info - EC2 proxy IP is $EC2_HOST."
# Start tunnel through ec2 instance.
/usr/bin/ssh -f -N -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
-i $EC2_KEY_LOC/amznkey.pem -R 0.0.0.0:$EC2_PORT:localhost:$LCL_PORT root@$EC2_HOST > /dev/null
err=$?
if [ $err -ne 0 ]
then
echo "***Error - SSH to start tunnel failed with error code ${err}."
exit 1
else
echo "***Info - Started tunnel between localhost at $IP_ADDR:$LCL_PORT and EC2 proxy at $EC2_HOST:$EC2_PORT."
fi
exit 0
#!/bin/sh
# Script to create a ssh tunnel from an AWS Lambda function to a remote host via an AWS EC2 instance.
# Copyright (C) 2017 Lindo St. Angel.
echo "**************************************************************"
echo "Starting ssh tunnel on `uname -n` on `date +%y/%m/%d_%H:%M:%S`"
echo "**************************************************************"
# Include global variables:
# EC2_MACH - EC2 machine type
# EC2_TYPE - EC2 instance type
# EC2_KEY_LOC - EC2 keypair location
# EC2_KPAR - EC2 keypair name
# EC2_PORT - EC2 tunnel port number
# EC2_SUB - vpc subnet ID that instance will run in
# EC2_SG - security group ID that controls EC2 ingress
# LAMBDA - lambda function arn that will use tunnel to PFC
# LCL_PORT - local port number that will use tunnel
source ./vars.sh
# Get external ip address of remote host (this machine).
IP_ADDR=`dig +short myip.opendns.com @resolver1.opendns.com`
if [ -z "$IP_ADDR" ]
then
echo "***Error - Can't get external IP address, terminating."
exit 1
else
echo "***Info - External IP address is $IP_ADDR."
fi
# Update security group to allow this machine to ssh into ec2 instance.
CIDR=/32
aws ec2 authorize-security-group-ingress --group-id $EC2_SG --protocol tcp --port 22 --cidr $IP_ADDR$CIDR > /dev/null
#aws ec2 authorize-security-group-ingress --group-id $EC2_SG --protocol tcp --port 0-65535 --cidr 0.0.0.0/0 > /dev/null
echo "***Info - Updated security group $EC2_SG."
# Create an aws ec2 instance in the defined vpc subnet with the defined security group.
EC2_INSTANCE=`aws ec2 run-instances --image-id $EC2_MACH --instance-type $EC2_TYPE --key-name $EC2_KPAR \
--security-group-ids $EC2_SG --subnet-id $EC2_SUB | tr '\t' '\n' | grep '^i-'`
if [ -z "$EC2_INSTANCE" ]
then
echo "***Error - Can't create EC2 instance, terminating tunnel."
aws ec2 revoke-security-group-ingress --group-id $EC2_SG --protocol tcp --port 22 --cidr $IP_ADDR$CIDR > /dev/null
exit 1
else
echo "***Info - Created ec2 instance $EC2_INSTANCE."
fi
# Tag instance so that it can identified and used later.
aws ec2 create-tags --resources $EC2_INSTANCE --tags Key=foodcomputer,Value=tunnel
# Get public IP addr for the instance.
EC2_HOST=`/home/pi/.local/bin/aws ec2 describe-instances --instance-ids $EC2_INSTANCE\
--query "Reservations[*].Instances[*].[PublicIpAddress]"`
echo "***Info - Host public IP $EC2_HOST."
# Prepare ec2 instance for tunneling.
# Note that we don't need to check known host file since fingerprint of host has already been verified.
#
# "ClientAliveInterval" and "ClientAliveCountMax" makes sure the SSH tunnel will stay up by sending a NULL TCP packet every 120 seconds
# and do not disconnect the client until it became inactive for more than 24 hours (120 secs * 720).
#
# By default, the SSH tunnel will listen on the loopback (127.0.0.1) interface only. To enable access from other sources, need to
# configure tunnel to listen on the wildcard interface (0.0.0.0) by updating GatewayPorts to "clientspecified".
#
# Adding "PermitRootLogin" equal to yes only and removing error message from authorized_keys file allows for ssh root login.
#
# Note: a client ssh config file needs to be added with ServerAliveInterval = 30 and ServerAliveCountMax = 6
# This will ensure the client keeps the connection alive at its end.
# See https://unix.stackexchange.com/questions/3026/what-options-serveraliveinterval-and-clientaliveinterval-in-sshd-config-exac
/usr/bin/ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
-i $EC2_KEY_LOC/amznkey.pem ec2-user@$EC2_HOST \
"echo -e 'ClientAliveInterval 120\n''ClientAliveCountMax 720\n''GatewayPorts clientspecified\n''PermitRootLogin yes'\
| sudo tee -a /etc/ssh/sshd_config > /dev/null &&\
sudo sed -i '/PermitRootLogin forced-commands-only/s/.*/#PermitRootLogin forced-commands-only/' /etc/ssh/sshd_config > /dev/null &&\
sudo /etc/init.d/sshd reload > /dev/null &&\
sudo sed -i 's/^.*ssh-rsa/ssh-rsa/' /root/.ssh/authorized_keys > /dev/null"
err=$?
if [ $err -ne 0 ]
then
echo "***Error - SSH to remote server to prep for tunnel failed with error code ${err}."
echo "***Error - Terminating tunnel."
aws ec2 terminate-instances --instance-ids $EC2_INSTANCE > /dev/null
sleep 60
aws ec2 revoke-security-group-ingress --group-id $EC2_SG --protocol tcp --port 22 --cidr $IP_ADDR$CIDR > /dev/null
exit 1
else
echo "***Info - Instance prepared for tunnel."
fi
# Update lambda function with tunnel private IP addr and port.
# This will allow lambda to connect to ec2 in the vpc.
EC2_HOST_PRI=`/home/pi/.local/bin/aws ec2 describe-instances --instance-ids $EC2_INSTANCE\
--query "Reservations[*].Instances[*].[PrivateIpAddress]"`
echo "***Info - Private IP of host is $EC2_HOST_PRI."
aws lambda update-function-configuration --function-name $LAMBDA --environment '{"Variables":{"host":"'$EC2_HOST_PRI'","port":"'$EC2_PORT'"}}'
echo "***Info - Updated lambda function with tunnel IP $EC2_HOST_PRI:$EC2_PORT."
# Start tunnel through ec2 instance using ssh.
# The start-tunnel script needs to be in the same directory as this script.
source ./ssh-tunnel-start.sh
echo "***Info - ssh tunnel started."
echo "You can start it again if needed by executing the following:"
echo "/usr/bin/ssh -f -N -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ec2/amznkey.pem -R 0.0.0.0:$EC2_PORT:localhost:$LCL_PORT root@$EC2_HOST"
echo "Or by running the start script manually:"
echo "./ssh-tunnel-start"
# Start tunnel through ec2 instance.
#/usr/bin/ssh -f -N -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
# -i ~/.ec2/amznkey.pem -R 0.0.0.0:$EC2_PORT:localhost:$LCL_PORT root@$EC2_HOST
#echo "***Info - Started tunnel between localhost at $IP_ADDR:$LCL_PORT and EC2 proxy at $EC2_HOST:$EC2_PORT."
echo "***************************************************************"
echo "Completed ssh tunnel on `uname -n` on `date +%y/%m/%d_%H:%M:%S`"
echo "***************************************************************"
exit 0
@rehmanazhar922
Copy link

hey i need this bro how can i load it on lambda make a video
Do you have any youtube channel?

@rehmanazhar922
Copy link

i need a lambda function to make a reverse ssh tunnel for my pc that have elastic ip

@rehmanazhar922
Copy link

u can contact me on skype live:rehmanazhar922 or messenger https://www.facebook.com/abdulrehman.azhar.773

@rehmanazhar922
Copy link

plzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment