Skip to content

Instantly share code, notes, and snippets.

@martinvirtel
Last active July 20, 2017 18:22
Show Gist options
  • Save martinvirtel/14708a3e06382a1ea3983af3350c5d5d to your computer and use it in GitHub Desktop.
Save martinvirtel/14708a3e06382a1ea3983af3350c5d5d to your computer and use it in GitHub Desktop.
Fabulous VPN Makefile

VPN helper

This is a short makefile that enables you to get a VPN if you have both SSH and AWS cli access to the infrastructure.

Start by testing your access

make test-aws -> tests if you have AWS cli access (If not, set the aws-config variable in the Makefile accordingly)

make list-nat -> lists all publicly available hosts with 'nat' in their name. Select the IP address the one you want to connect to. This is the point you will be connecting to. Let's say it's 1.2.3.4. You will use it as bastion variable.

bastion=1.2.3.4 make test-ssh -> tests if you have SSH access

bastion=1.2.3.4 make vpn -> Conntects to the VPN, creating and downloading a client certificate in the process. It will stay in the foreground by default, soyou can monitor progress.

After the VPN is active, you can switch to another terminal and list private IPs that you might be able to connect to using make list-vpn-hosts. If you found something interesting, use host=interesting.ip.1.2.3 make ssh to connect.

#! /bin/bash
TARGET=$1
SOURCE=$2
STARTMARKER="##vpc-start"
ENDMARKER="##vpc-end"
sed -i "/##${STARTMARKER}/,/##${ENDMARKER}/d;
\${;a##${STARTMARKER}
r ${TARGET}
a##${ENDMARKER}
a
}" ${SOURCE}
me := $(shell whoami)
aws-config := --profile=odc
ssh-config := -i /home/martin/.ssh/id_martinvirtel_server_2016
SHELL := /bin/bash
DB := feedback
# Look for variables in fish universal environment
#ifndef bastion
# bastion := $(shell fish -c "echo \$$bastion")
#endif
#ifndef vpc
# vpc := $(shell fish -c "echo \$$vpc")
#endif
# improvements: test if already set, loop over arguments
#define read_fish_var
#$(eval $(1) := $(shell fish -c "echo \$$$(1)") )
#endef
#$(call read_fish_var,vpc)
#$(call read_fish_var,bastion)
ssh-bastion = ubuntu@$(bastion) $(ssh-config)
vpn-name = $(me)-$(bastion).ovpn
.PHONY: test-ssh test-aws list-nat list-vpn-hosts create-client vpn ssh
test-ssh :
ifndef bastion
$(error Please define bastion IP address in $$bastion variable. Use make list-nat to get a list of candidates)
else
ssh $(ssh-bastion) echo "Connection OK"
endif
test-aws:
@aws $(aws-config) ec2 describe-instances --query 'length(Reservations[].Instances[])' | sed '1iRunning ec2 instances:'
list-nat: test-aws
@aws $(aws-config) ec2 describe-instances --output=text --query "Reservations[].Instances[?type(PublicIpAddress)=='string'].{ip:PublicIpAddress,name: Tags[?Key=='Name'].Value,launched: LaunchTime,vpc:VpcId} | [] | [?contains(name[0],'nat')][ip,vpc,name[0],launched]" | sort -t\# -k1 | awk '{print("set -Ux bastion " $$1 "; set -Ux vpc " $$2 " # " $$3 " " $$4)}'
list-vpn-hosts: test-aws
aws $(aws-config) ec2 describe-instances --output=text --query "Reservations[].Instances[?type(PublicIpAddress)!='string'].{ip:PrivateIpAddress,name: Tags[?Key=='Name'].Value} | [][ip,name[0]]" | sort -k2
list-endpoints: test-aws
aws $(aws-config) ec2 describe-instances --filters "Name=vpc-id,Values=$(vpc)" --output=text --query "Reservations[].Instances[].{ip:PrivateIpAddress,name: Tags[?Key=='Name'].Value} | [][ip,name[0]]" | sort -k2 | sed -n \
-e '/couchdb/s_\([^\t]*\)\t\(.*\)_http://\1:5984/\_utils/ \2_p' \
-e '/neo4j/s_\([^\t]*\)\t\(.*\)_http://\1:7474/ \2_p' \
-e '/consul/s_\([^\t]*\)\t\(.*\)_http://\1:8500/ \2_p'
list-vpc-hosts: test-aws
aws $(aws-config) ec2 describe-instances --output=text --filters "Name=vpc-id,Values=$(vpc)" --query "Reservations[].Instances[].{ipi:PublicIpAddress,ipp:PrivateIpAddress,name: Tags[?Key=='Name'].Value} | [][ipi,ipp,name[0]]"
list-vpcs: test-aws
aws --profile=odc ec2 describe-vpcs --output=text --query "Vpcs[?State=='available'].{id:VpcId name: Tags[?Key=='Name'].Value} | [].[id,name[0]]"
$(vpn-name):
ifndef bastion
$(error please set bastion host IP address in bastion= variable.)
else
-ssh $(ssh-bastion) sudo docker run --volumes-from ovpn-data --rm gosuri/openvpn easyrsa build-client-full "$(me)" nopass 1>&2 2>/dev/null
ssh $(ssh-bastion) sudo docker run --volumes-from ovpn-data --rm gosuri/openvpn /usr/local/bin/ovpn_getclient "$(me)" >$(vpn-name)
endif
vpn : $(vpn-name) /etc/hosts
test $$(ps ax | grep -c "openvpn $(vpn-name)") -gt 3 || sudo openvpn $(vpn-name)
rsync-template:
echo 'rsync -Pav -e "ssh -i ~/.ssh/id_martinvirtel_server_2016" [src] [dest]'
vars :
echo $(SHELL)
ssh :
ifndef host
$(error Please set host= variable to IP in order to connect)
else
ssh ubuntu@$(host) $(ssh-config)
endif
define lookup_ip
aws $(aws-config) ec2 describe-instances --filters "Name=vpc-id, Values=$(vpc)" --output=text \
--query "Reservations[].Instances[] | [?Tags[?Key=='Name' && contains(Value,'$(1)')]].PrivateIpAddress"
endef
VPCHOSTS=$(vpc).hosts
$(VPCHOSTS) :
{ \
aws $(aws-config) ec2 describe-instances --output=text --filters "Name=vpc-id,Values=$(vpc)" \
--query "Reservations[].Instances[].{ipp:PrivateIpAddress,name: Tags[?Key=='Group'].Value} | [][ipp,name[0]]" | \
sed '/consul/{;s/consul/consul.service.consul/;n;};s/$$/.vpc/' >$@ ;\
}
/etc/hosts : $(VPCHOSTS)
{ \
sudo ./include.sh $^ $@; \
}
postgres-shell:
{ \
postgres_host=`$(call lookup_ip,postgres)` ;\
consul_host=`$(call lookup_ip,consul)` ;\
export PGPASSWORD=`curl -s http://$$consul_host:8500/v1/kv/postgres_password | jp '[0].Value' | sed 's/"//g' | base64 --decode `;\
echo connecting to $$postgres_host ... ;\
psql --user=postgres --no-password --host=$$postgres_host $(DB);\
echo alias pg \"env PGPASSWORD=$$PGPASSWORD psql --user=postgres --no-password --host=$$postgres_host $(DB)\" ;\
}
consul-ui:
{ \
consul_host=`$(call lookup_ip,consul)` ;\
xdg-open http://$$consul_host:8500/ ;\
}
couchdb-ui:
{ \
host=`$(call lookup_ip,couchdb)` ;\
xdg-open http://$$host:5984/_utils/ ;\
}
view-endpoints: endpoints.html
xdg-open endpoints.html
%.html : %.md
pandoc --from markdown_github --to html --standalone <$< >$@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment