Last active
December 30, 2023 10:25
-
-
Save bruceoutdoors/1194470fed8b00d71eeeed0e2e476c61 to your computer and use it in GitHub Desktop.
Quick Wireguard VPN setup for AWS. Just run the CloudFormation stack, access the VM via SSM, and execute `wg-addclient` to add a client. See https://bruceoutdoors.wordpress.com/2023/02/01/how-to-build-a-wireguard-vpn/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Note: Must run as root! | |
cd /etc/wireguard/ | |
# Get next available internal IP address | |
IP=$((`tac wg0.conf | grep -m1 -oP "[0-9]+(?=/32)" || echo 1` + 1)) | |
# Generate client key | |
CLIENT_PRIVATE=`wg genkey` | |
CLIENT_PUBLIC=`wg pubkey <<< $CLIENT_PRIVATE` | |
# Append to server config | |
cat <<EOF >> wg0.conf | |
[Peer] | |
PublicKey = $CLIENT_PUBLIC | |
AllowedIPs = 10.10.0.$IP/32, fd86:ea04:1111::$IP/128 | |
EOF | |
# Output client config and render QR | |
CONF=`mktemp` | |
trap "rm $CONF" EXIT | |
cat <<EOF | tee $CONF | |
[Interface] | |
PrivateKey = $CLIENT_PRIVATE | |
Address = 10.10.0.$IP/32 | |
DNS = 8.8.8.8 | |
[Peer] | |
PublicKey = `cat public.key` | |
AllowedIPs = 0.0.0.0/0, ::/0 | |
Endpoint = `curl -s ifconfig.me`:51820 | |
EOF | |
cat $CONF | qrencode -t ansiutf8 | |
# Reload the Wireguard service | |
systemctl reload wg-quick@wg0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
apt update | |
apt install -y wireguard qrencode | |
cd /etc/wireguard/ | |
# Generate server keys | |
wg genkey | tee private.key | wg pubkey > public.key | |
# Write config | |
NET=`lshw -C network | grep -oP '(?<=logical name: )\w+'` | |
cat <<EOF > wg0.conf | |
[Interface] | |
Address = 10.10.0.1/24 | |
Address = fd86:ea04:1111::1/64 | |
ListenPort = 51820 | |
PostUp = sysctl -q -w net.ipv4.ip_forward=1 | |
PostUp = sysctl -q -w net.ipv6.conf.all.forwarding=1 | |
PostDown = sysctl -q -w net.ipv4.ip_forward=0 | |
PostDown = sysctl -q -w net.ipv6.conf.all.forwarding=0 | |
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o $NET -j MASQUERADE | |
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o $NET -j MASQUERADE | |
PrivateKey = `cat private.key` | |
EOF | |
# Start Wireguard service on boot | |
systemctl enable wg-quick@wg0 | |
systemctl start wg-quick@wg0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: '2010-09-09' | |
Description: Set up a wireguard VPN | |
Parameters: | |
LatestAmiId: | |
Description: Grab the latest Ubuntu AMI (see https://ubuntu.com/tutorials/build-your-cloudformation-templates-with-the-latest-ubuntu-ami#2-lets-start) | |
Default: /aws/service/canonical/ubuntu/server/jammy/stable/current/amd64/hvm/ebs-gp2/ami-id | |
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> | |
InstanceType: | |
Default: t2.micro | |
Description: Instance type | |
Type: String | |
Resources: | |
VpnSecurityGroup: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: VPN security group created by cloudformation | |
SecurityGroupIngress: | |
- IpProtocol: udp | |
FromPort: 51820 | |
ToPort: 51820 | |
CidrIp: '0.0.0.0/0' | |
VpnInstance: | |
Type: AWS::EC2::Instance | |
Properties: | |
ImageId: !Ref 'LatestAmiId' | |
InstanceType: !Ref 'InstanceType' | |
IamInstanceProfile: !Ref 'WgEc2IamProfile' | |
UserData: !Base64 | | |
#!/bin/bash | |
apt update | |
apt install -y wireguard qrencode | |
cd /etc/wireguard/ | |
# Generate server keys | |
wg genkey | tee private.key | wg pubkey > public.key | |
# Write config | |
NET=`lshw -C network | grep -oP '(?<=logical name: )\w+'` | |
cat <<EOF > wg0.conf | |
[Interface] | |
Address = 10.10.0.1/24 | |
Address = fd86:ea04:1111::1/64 | |
ListenPort = 51820 | |
PostUp = sysctl -q -w net.ipv4.ip_forward=1 | |
PostUp = sysctl -q -w net.ipv6.conf.all.forwarding=1 | |
PostDown = sysctl -q -w net.ipv4.ip_forward=0 | |
PostDown = sysctl -q -w net.ipv6.conf.all.forwarding=0 | |
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o $NET -j MASQUERADE | |
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o $NET -j MASQUERADE | |
PrivateKey = `cat private.key` | |
EOF | |
# Start Wireguard service on boot | |
systemctl enable wg-quick@wg0 | |
systemctl start wg-quick@wg0 | |
# Write wg-addclient executable | |
cat <<'WGADD' > /usr/bin/wg-addclient | |
#!/bin/bash | |
# Note: Must run as root! | |
cd /etc/wireguard/ | |
# Get next available internal IP address | |
IP=$((`tac wg0.conf | grep -m1 -oP "[0-9]+(?=/32)" || echo 1` + 1)) | |
# Generate client key | |
CLIENT_PRIVATE=`wg genkey` | |
CLIENT_PUBLIC=`wg pubkey <<< $CLIENT_PRIVATE` | |
# Append to server config | |
cat <<EOF >> wg0.conf | |
[Peer] | |
PublicKey = $CLIENT_PUBLIC | |
AllowedIPs = 10.10.0.$IP/32, fd86:ea04:1111::$IP/128 | |
EOF | |
# Output client config and render QR | |
CONF=`mktemp` | |
trap "rm $CONF" EXIT | |
cat <<EOF | tee $CONF | |
[Interface] | |
PrivateKey = $CLIENT_PRIVATE | |
Address = 10.10.0.$IP/32 | |
DNS = 8.8.8.8 | |
[Peer] | |
PublicKey = `cat public.key` | |
AllowedIPs = 0.0.0.0/0, ::/0 | |
Endpoint = `curl -s ifconfig.me`:51820 | |
EOF | |
cat $CONF | qrencode -t ansiutf8 | |
# Reload the Wireguard service | |
systemctl reload wg-quick@wg0 | |
WGADD | |
chmod 755 /usr/bin/wg-addclient | |
SecurityGroups: | |
- !Ref 'VpnSecurityGroup' | |
WireguardEIP: | |
Type: AWS::EC2::EIP | |
Properties: | |
Domain: vpc | |
WireguardVpnEipAsso: | |
Type: AWS::EC2::EIPAssociation | |
Properties: | |
EIP: !Ref 'WireguardEIP' | |
InstanceId: !Ref 'VpnInstance' | |
WgEc2IamRole: | |
Type: AWS::IAM::Role | |
Properties: | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ec2.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
WgEc2IamProfile: | |
Type: AWS::IAM::InstanceProfile | |
Properties: | |
Roles: | |
- !Ref 'WgEc2IamRole' | |
Outputs: | |
SSMURL: | |
Description: Session manager URL. Inside instance, execute `wg-addclient` as root to add client | |
Value: !Join | |
- '' | |
- - https:// | |
- !Ref 'AWS::Region' | |
- .console.aws.amazon.com/systems-manager/session-manager/ | |
- !Ref 'VpnInstance' | |
- '?region=' | |
- !Ref 'AWS::Region' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment