Skip to content

Add instance-portforward() for SSM portforwarding #327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions aliases
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ alias instance-dns='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma instance-dns'
alias instance-health-set-unhealthy='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma instance-health-set-unhealthy'
alias instance-iam-profile='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma instance-iam-profile'
alias instance-ip='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma instance-ip'
alias instance-portforward='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma instance-portforward'
alias instance-ssh='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma instance-ssh'
alias instance-ssh-details='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma instance-ssh-details'
alias instance-ssm='${BMA_HOME:-$HOME/.bash-my-aws}/bin/bma instance-ssm'
Expand Down
1 change: 1 addition & 0 deletions bash_completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ complete -F _bma_instances_completion instance-dns
complete -F _bma_instances_completion instance-health-set-unhealthy
complete -F _bma_instances_completion instance-iam-profile
complete -F _bma_instances_completion instance-ip
complete -F _bma_instances_completion instance-portforward
complete -F _bma_instances_completion instance-ssh
complete -F _bma_instances_completion instance-ssh-details
complete -F _bma_instances_completion instance-ssm
Expand Down
58 changes: 58 additions & 0 deletions docs/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,64 @@ List ip address of EC2 Instance(s)
i-89cefa9403373d7a5 10.155.35.61 54.214.206.114
i-806d8f1592e2a2efd 10.178.243.63 54.214.244.90

### instance-portforward

Setup a SSM portforward between a port on a remote EC2 Instance and a local port.

Remote port may be given as a number, or as a keyword from the following list:

- aurora (i.e. port 3306)
- dns (i.e. port 53)
- elasticgfx (i.e. port 2007)
- http (i.e. port 80)
- https (i.e. port 443)
- imap (i.e. port 143)
- imaps (i.e. port 993)
- ldap (i.e. port 398)
- mssql (i.e. port 1433)
- mysql (i.e. port 3306)
- oracle (i.e. port 1521)
- pop3 (i.e. port 110)
- pop3s (i.e. port 995)
- postgres (i.e. port 5432)
- redshift (i.e. port 5439)
- rdp (i.e. port 3389)
- smb (i.e. port 445)
- smtp (i.e. port 25)
- smtps (i.e. port 465)
- ssh (i.e. port 22)
- winrm (i.e. port 5985)
- winrms (i.e. port 5986)

Local port is optional and must be a number. If unspecified, the same port number as the remote port will be attempted.

USAGE: instance-portforward [remote port] [local port (optional)] [instance-id]

# Example: Remote RDP portforwarded to localhost port 9000
# ec2-instance:3389 <-- portforward --> localhost:9000
$ instances example-windows-host | instance-portforward rdp 9000

Portforwarding between EC2 instance i-008db2027225a0a40 port 3389 and localhost port 9000

Starting session with SessionId: jo.bloggs@contoso.com-0e84c8293af47aad6.
Port 9000 opened for sessionId jo.bloggs@contoso.com-0e84c8293af47aad6.
Waiting for connections...

# At this point, we open an RDP client and connect to localhost:9000
Connection accepted for session [jo.bloggs@contoso.com-0e84c8293af47aad6]

# When you're finished, enter Ctrl+C to close the portforward and exit
^CTerminate signal received, exiting.

Exiting session with sessionId: jo.bloggs@contoso.com-0e84c8293af47aad6.

Further examples without example output:

# ec2-instance:1433 <-- portforward --> localhost:5600
$ instances mssql01 | instance-portforward 1433 5600

# ec2-instance:443 <-- portforward --> localhost:8080
$ instance-portforward https 8080 i-806d8f1592e2a2efd

### instance-ssh

Expand Down
1 change: 1 addition & 0 deletions functions
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ instance-dns
instance-health-set-unhealthy
instance-iam-profile
instance-ip
instance-portforward
instance-ssh
instance-ssh-details
instance-ssm
Expand Down
77 changes: 77 additions & 0 deletions lib/instance-functions
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,83 @@ instance-ip() {
column -s$'\t' -t
}

instance-portforward() {

# Establish SSM-based portforwards from EC2 Instance(s)
#
# USAGE: instance-portforward [remote port] [local port (optional)] [instance-id]
#
# Remote port may be given as a number, or as a keyword from the list below
# e.g. 'instance-portforwarding rdp' is equivalent to 'instance-portforwarding 3389'
#
# Local port is optional and must be a number
# If unspecified, the same port number as the remote port will be attempted.
local instance_id remote_port local_port

# We want this to word split
# shellcheck disable=SC2046,SC2068
set -- $(skim-stdin ${@})

# Map our remote port
case "${1}" in
(aurora) remote_port=3306 ;;
(dns) remote_port=53 ;;
(elasticgfx) remote_port=2007 ;;
(http) remote_port=80 ;;
(https) remote_port=443 ;;
(imap) remote_port=143 ;;
(imaps) remote_port=993 ;;
(ldap) remote_port=398 ;;
(mssql) remote_port=1433 ;;
(mysql) remote_port=3306 ;;
(oracle) remote_port=1521 ;;
(pop3) remote_port=110 ;;
(pop3s) remote_port=995 ;;
(postgres) remote_port=5432 ;;
(redshift) remote_port=5439 ;;
(rdp) remote_port=3389 ;;
(smb) remote_port=445 ;;
(smtp) remote_port=25 ;;
(smtps) remote_port=465 ;;
(ssh) remote_port=22 ;;
(winrm) remote_port=5985 ;;
(winrms) remote_port=5986 ;;
(*) remote_port="${1}" ;;
esac

# Validate that the remote port is a number.
printf -- '%d\n' "${remote_port}" >/dev/null 2>&1 || {
__bma_error "Remote Port must be a number or a recognised keyword"
return 1
}

# Map the rest of our vars based on how many params are given
case "${#}" in
(2) local_port="${remote_port}"; instance_id="${2}" ;;
(3) local_port="${2}"; instance_id="${3}" ;;
(*)
__bma_usage "[remote port] [local port (optional)] [instance-id]"
return 1
;;
esac

# Validate that the local port is a number
printf -- '%d\n' "${local_port}" >/dev/null 2>&1 || {
__bma_error "Local Port must be a number"
return 1
}

printf -- '\nPortforwarding between EC2 instance %s port %d and localhost port %d\n' \
"${instance_id}" "${remote_port}" "${local_port}"

# Ignore shellcheck alert on parameters directive
# shellcheck disable=SC2140
aws ssm start-session \
--target "${instance_id}" \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"=["${remote_port}"],"localPortNumber"=["${local_port}"]

}

instance-ssh() {

Expand Down