-
-
Save lukeplausin/4b412d83fb1246b0bed6507b5083b3a7 to your computer and use it in GitHub Desktop.
# This script will explain how to transfer a file to EC2 using SSM ONLY! | |
# You will need to have permission to run SSM commands on the target machine and have sudo access as well | |
# Infos | |
INSTANCE_ID=i-1234567890 | |
FILE_NAME=the_file.tar.gz | |
# Step 1: Run command on machine to install netcat and dump from port to filename | |
# < Start session | |
aws ssm start-session --target $INSTANCE_ID --document-name | |
# < (On target machine) : | |
cd && sudo yum install nc -y && sudo nc -l -p 1234 > the_file.tar.gz | |
# Step 2: On another shell, open a port-forwarding session from your machine to the target machine | |
aws ssm start-session --target $INSTANCE_ID --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["1234"],"localPortNumber":["1234"]}' | |
# Step 3: On yet another shell, cat the source file into the transfer port on localhost over the tunnel | |
nc -w 3 127.0.0.1 1234 < the_file.tar.gz | |
# Step 4: Once the command in step 3 finishes, close all of the other shell sessions. Your file should be on the target now. |
That's handy! I had to remove the --document-name
on the first start-session
call.
similarly, have you tried copying a file from ec2 to your local machine without using s3
Extremely helpful! Thank you for sharing.
Very helpful, thank you Luke ..
Thank helpful
Thanks for your script.
I wanted to download a file from the EC2 instance, so the commands are reversed somewhat.
Step 1: On EC2 instance dump from filename to port
nc -l 1234 < the_file.tar.gz
Step 2: On your machine open a shell, open a port-forwarding session from your machine to the target machine
aws ssm start-session --target $INSTANCE_ID --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["1234"],"localPortNumber":["1234"]}'
Step 3: On your machine open another shell, use nc to read the data over the tunnel and write to destination file
nc -w 3 localhost 1234 > the_file.tar.gz
Step 4: Once the command in step 3 finishes, close all of the other shell sessions. Your file should be on the destination now.
Same approach but in one script, save the below script into a file and call it like this:
./upload-file 1234 "/local/path/to/the_file" i-xxxxx "/remote/path/to/the_file"
Note, the script is also creating a folder on the remote if it doesn't exist
upload-file
#!/usr/bin/expect
# Set the script to not time out
set timeout -1
# Capture the script arguments
# Port for netcat
set port [lindex $argv 0]
# File to send via netcat
set file_to_send [lindex $argv 1]
# AWS SSM instance ID
set remote_instance_id [lindex $argv 2]
# Remove file name
set remote_file_name [lindex $argv 3]
# Start AWS SSM session on host A and run netcat to listen on a port
spawn aws ssm start-session --target $remote_instance_id
expect {
-re "sh-.*" {
send_user "\nAWS SSM session started.\n"
send "mkdir -p \"\$(dirname \"$remote_file_name\")\" && nc -l -p $port > \"$remote_file_name\"\r"
send_user "\nNetcat listener started on port $port > $remote_file_name.\n"
}
}
# Start a background AWS SSM session for port forwarding
spawn bash -c "aws ssm start-session --target $remote_instance_id --document-name AWS-StartPortForwardingSession --parameters '{\"portNumber\":\[\"$port\"\],\"localPortNumber\":\[\"$port\"\]}'"
expect {
-re "Waiting for connections" {
send_user "\nPort forwarding session established.\n"
}
}
# Use netcat to send the file to the port
spawn bash -c "nc localhost $port < \"$file_to_send\""
expect {
eof {
send_user "\nFile sent.\n"
}
}
# Terminate the netcat listener on the remote host
spawn aws ssm start-session --target $remote_instance_id
expect {
-re "sh-.*" {
send_user "\nTerminating netcat listener on remote host.\n"
send "pkill -f 'nc -l -p $port'\r"
}
}
# Terminate all AWS SSM sessions
send_user "\nClosing all sessions...\n"
exec pkill -f "aws ssm"
send_user "\nAll sessions terminated.\n"
exit
This was really useful. Thanks for publishing