Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
Address = ${tpl_server_address}
ListenPort = 51820
PostUp = wg set wg0 private-key /etc/wireguard/privatekey
PostUp = iptables -A FORWARD -s ${tpl_server_address} -d ${tpl_destination_subnets} -j ACCEPT
PostUp = iptables -A FORWARD -i wg0 -s ${tpl_server_address} -j ACCEPT
PostUp = iptables -A FORWARD -s ${tpl_server_address} -j DROP
PostUp = iptables -t nat -A POSTROUTING -s ${tpl_server_address} -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -s ${tpl_server_address} -d ${tpl_destination_subnets} -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -s ${tpl_server_address} -j ACCEPT
PostDown = iptables -D FORWARD -s ${tpl_server_address} -j DROP
PostDown = iptables -t nat -D POSTROUTING -s ${tpl_server_address} -o eth0 -j MASQUERADE

Expand Down
52 changes: 37 additions & 15 deletions templates/scripts/add-vpn-user.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,77 @@ CLUSTER=$(kubectl config current-context | cut -d"/" -f2)

# this is a local script for a system user to generate VPN configuration for cluster ${CLUSTER}

NAMESPACE=<% .Name %>
REGION=<% index .Params `region` %>

# get pod id for execution
POD=$(kubectl -n vpn get pods | grep wireguard | cut -d' ' -f1)
EXTERNAL_DNS=$(kubectl -nvpn get svc wireguard -o jsonpath='{.metadata.annotations.external-dns\.alpha\.kubernetes\.io/hostname}')
POD=$(kubectl -n vpn get pods --selector=app=wireguard -o jsonpath='{.items[0].metadata.name}')

if [ -z "$POD" ]; then
echo "Warning: No VPN service running yet"
exit 1
fi
EXEC="kubectl -n vpn exec -it $POD -- /bin/bash -c"

function k8s_exec() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

kubectl -n vpn exec -it $POD -- /bin/bash -c "$1"
}

# get name
echo -n "Enter your name: "
read name
echo "Current cluster is '${CLUSTER}'"
echo -n "Enter your name: " && read name
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's print the name of the cluster before this so they know which context they are using. Otherwise they don't really know where they are adding the user to, and I don't think we explicitly tell them to change their kube context.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

echo
echo "Generating your client configuration file..."

# collect keys
server_public_key=$($EXEC "cat /etc/wireguard/privatekey | wg pubkey")
client_private_key=$($EXEC "wg genkey")
client_public_key=$($EXEC "echo -n $client_private_key | wg pubkey | tr -d \"\r\n\f\"")
server_public_key=$(k8s_exec "cat /etc/wireguard/privatekey | wg pubkey")
client_private_key=$(k8s_exec "wg genkey")
client_public_key=$(k8s_exec "echo -n $client_private_key | wg pubkey | tr -d \"\r\n\f\"")

# get next available IP
existing_ips=$($EXEC "cat /etc/wireguard/wg0.conf | grep AllowedIPs| cut -d\" \" -f3 | cut -d\"/\" -f1 | sort")
existing_ips=$(k8s_exec "cat /etc/wireguard/wg0.conf | grep AllowedIPs| cut -d\" \" -f3 | cut -d\"/\" -f1 | sort")
last_ip=$(echo "$existing_ips" | tr -cd "[:alnum:].\n" | tail -1)
next_ip=$last_ip
while [[ "$existing_ips" =~ "$next_ip" ]]; do
next_ip=${next_ip%.*}.$((${next_ip##*.}+1))
done

# get DNS server setting
dns_server=$(k8s_exec "cat /etc/resolv.conf | grep nameserver | tail -1 | cut -d\" \" -f2 | tr -d \"\r\n\f\"")

# get VPC CIDR for allowed IP subnet
VPCNAME=${CLUSTER%-$REGION}-vpc
vpc_cidr=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=${VPCNAME} | jq -r '.Vpcs[].CidrBlock')
[[ -z "$vpc_cidr" ]] && vpc_cidr = "10.10.0.0/16"

# get Endpoint DNS
EXTERNAL_DNS=$(kubectl -nvpn get svc wireguard -o jsonpath='{.metadata.annotations.external-dns\.alpha\.kubernetes\.io/hostname}')

# generate config file
CONFIG_DIR=~/.wireguard
mkdir -p $CONFIG_DIR
CONFIG_FILE=$CONFIG_DIR/wg-client-${CLUSTER}.conf

# Output TF line
echo "Configuration generated at $CONFIG_FILE with:"
echo
echo "Configuration for user '$name' generated at $CONFIG_FILE with:"
echo " - public key : $client_public_key"
echo " - private key: $client_private_key"
echo " - client IP : $next_ip/32"
echo
echo "Please modify kubernetes/terraform/environments/<env>/main.tf and append the following line to var.vpn_client_publickeys."
echo "Then apply the terraform, or ask an administrator to."
echo
printf ' ["%s", "%s", "%s"],' "$name" "$next_ip/32" "$client_public_key"
printf ' ["%s", "%s", "%s"],\n' "$name" "$next_ip/32" "$client_public_key"
echo
echo "After this is done you should be able to open the wireguard client and activate the tunnel."
echo "You can download the client at https://www.wireguard.com/install/"
echo "After this is done you should be able to open the wireguard client, import a tunnel file from ~/.wireguard/ and activate the tunnel."
echo
echo "When it is running you should be able to access internal resources, e.g. mysql -h 10.10.10.123"
echo "When it is running you should be able to access internal resources, eg. mysql -h <aws rds hostname>"
echo "You will be able to connect to resources within both the VPC and the Kubernetes cluster."
echo

# generate client conf
cat <<-EOF > ${CONFIG_FILE}

#
# This is a generated VPN(wireguard) client configuration
#
Expand All @@ -65,11 +86,12 @@ cat <<-EOF > ${CONFIG_FILE}
PrivateKey = $client_private_key
ListenPort = 34567
Address = $next_ip/32
DNS = $dns_server

[Peer]
# VPN server side
PublicKey = $server_public_key
AllowedIPs = 10.10.0.0/16
AllowedIPs = $vpc_cidr, $dns_server/32
Endpoint = $EXTERNAL_DNS:51820

EOF
Expand Down