Skip to content

Wireguard VPN Setup

Brandon Dombrowsky edited this page Mar 10, 2023 · 23 revisions

Quick Version

  1. How to set up a Point-to-Site VPN
  2. How to allow access to local devices
    • Just the PostUp and PostDown commands.

Step-by-Step

Pre-Setup

Set up EC2 Instance

  • Name: Home Assistant
  • Application and OS Image: Ubuntu
  • Key pair: Create new key pair
  • Network Settings:
    • Select an existing security group: homeassistant-sg.
  • Launch instance
    • Take note of public IP address.
    • Go to Security tab.
    • Click on security group.
    • Edit inbound rules.
    • Allow all traffic on your IP.
  1. SSH into EC2 instance.
    • Default user ubuntu (for now).
  2. sudo apt-get update
  3. sudo apt install -y docker.io
  4. sudo docker run hello-world
  • Test the installation.
Notes
  • Use docker info to find docker root directory.
  • Use docker ps to list docker images.
  • Use docker inspect <image [homeassistant]> to view information on an image.
    • This will show where the configuration files live.
    • This directory contains configuration.yaml, scripts.yaml, automations.yaml, scenes.yaml, etc.
  1. sudo docker run -d \ --name homeassistant \ --privileged \ --restart=unless-stopped \ -e TZ=America/Los_Angeles \ -v /homeassistantcontainer:/config \ --network=host \ ghcr.io/home-assistant/home-assistant:stable
    • This sets the time zone to Pacific.
    • This generates configuration files in ~/homeassistantcontainer/.
  2. Check successful installation: http://<ec2-instance-public-ip>:8123.
Notes
  • Use script: !include_dir_list scripts/ to include all scripts in the scripts/ directory.
  • Include script default: !include scripts.yaml to include the default script file.
    • Still figuring out how to change default configuration.

EC2 Instance: Endpoint A

Install Wireguard
  1. sudo apt install wireguard
    • Or view alternate installations here.
Generate Wireguard Keys
  1. mkdir wireguard-keys && cd wireguard-keys (optional)
  2. touch endpoint-a.key
  3. chmod 700 endpoint-a.key
  4. wg genkey > endpoint-a.key
  5. wg pubkey < endpoint-a.key > endpoint-a.pub
Configure Wireguard on Endpoint A
  1. Make a file /etc/wireguard/<wg-config-name>.conf.
    • I'm naming mine alexi.conf to differentiate if there are different connections.
    • sudo chmod 600 /etc/wireguard/<wg config name>.conf.
  2. Copy text into file:
  # /etc/wireguard/<wg-config-name>.conf

  # Local settings for Endpoint A
  [Interface]
  PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
  Address = 10.0.0.1/32
  ListenPort = 51821

  # Remote settings for Host B
  [Peer]
  PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
  Endpoint = <local-server-public-ip>:51822
  AllowedIPs = 192.168.0.0/24 # Whatever subnet devices are on
  • PrivateKey should be set to the contents of endpoint-a.key.
  • Peer PublicKey should be set to the contents of host-b.pub (below).
  • On a Raspberry Pi, the public IP can be found with curl icanhazip.com.
  • ListenPort and Endpoint port can be changed, so long as they are changed in the host config as well.

Start up Wireguard

  1. sudo systemctl enable wg-quick@<wg-config-name>.service
  2. sudo systemctl start wg-quick@<wg-config-name>.service

Local Server: Host B

Install Wireguard
  1. sudo apt install wireguard
    • Or view alternate installations here.
Generate Wireguard Keys
  1. mkdir wireguard-keys && cd wireguard-keys (optional)
  2. touch host-b.key
  3. chmod 700 host-b.key
  4. wg genkey > host-b.key
  5. wg pubkey < host-b.key > host-b.pub
Configure Wireguard on Host B
  1. Make a file /etc/wireguard/<wg-config-name>.conf.
    • I'm naming mine alexi.conf to differentiate if there are different connections.
    • sudo chmod 600 /etc/wireguard/<wg config name>.conf
  2. Copy text into file:
# /etc/wireguard/<wg-config-name>.conf

# local settings for Host β
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# Remote settings for Endpoint A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32
  • PrivateKey should be set to the contents of host-b.key.
  • Peer PublicKey should be set to the contents of endpoint-b.pub (above).
Configure Routing on Host B
  1. Add lines to configuration file:
# IP forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# IP masquerading
PreUp = iptables -t mangle -A PREROUTING -i wg0 -j MARK --set-mark 0x30
PreUp = iptables -t nat -A POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE
PostDown = iptables -t mangle -D PREROUTING -i wg0 -j MARK --set-mark 0x30
PostDown = iptables -t nat -D POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE
# Access other local devices
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o enp2s0 -j MASQUERADE

Start up Wireguard

  1. sudo systemctl enable wg-quick@<wg-config-name>.service
  2. sudo systemctl start wg-quick@<wg-config-name>.service

EC2 Settings

Inbound Rules

image

Outbound Rules

image

Example Configuration

EC2 Wireguard Configuration

# /etc/wireguard/wg0.conf
# EC2 instance config

# Local settings for Endpoint A
[Interface]
PrivateKey = <Host A Private Key>
Address = 10.0.0.1/32
ListenPort = 51821

# Remote settings for Host B
[Peer]
PublicKey = <Endpoint B Public Key>
Endpoint = <Local Server public IP>:51822
AllowedIPs = 192.168.0.0/24

Local Server (Raspberry Pi) Wireguard Configuration

# /etc/wireguard/wg0.conf
# Raspberry Pi config

# Local settings for Host B
[Interface]
PrivateKey = <Host B Private Key>
Address = 10.0.0.2/32
ListenPort = 51822

# IP forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# IP masquerading
PreUp = iptables -t mangle -A PREROUTING -i wg0 -j MARK --set-mark 0x30
PreUp = iptables -t nat -A POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE
PostDown = iptables -t mangle -D PREROUTING -i wg0 -j MARK --set-mark 0x30
PostDown = iptables -t nat -D POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE
# IP Address Forwarding (How to allow local device discovery from EC2)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o enp2s0 -j MASQUERADE

# Remote settings for Endpoint A
[Peer]
PublicKey = <Endpoint A Public Key>
AllowedIPs = 10.0.0.1/32

Notes

  • Need to add devices by IP in Home Assistant Dashboard.
  • Can ping RPi and local device IP from EC2.
  • Cannot ping EC2 private IP from RPi.
  • Cannot ping VPN addresses (10.0.0.1/2) from VPN devices.
    • But this seems to be as intended with NAT MASQUERADEing.
  • Seems that port forwarding needs to be enabled for the first connection when the service starts, but not after that.
  • See this note for file setup when making Wireguard keys.
  • In the local (Pi) configuration file, make sure the set all instances of wg0 to instead be the name of your config.
  • Be aware that some routers reserve IP addresses (for example Xfinity 10.0.0.1) and the tunnel configuration network may need to be changed.