# Wireguard Setup on Azure

## Installation on server

```
$ sudo apt-get install wireguard-dkms wireguard-tools
```

```
$ sudo nano /etc/sysctl.conf
```

* uncomment the line

```
net.ipv4.ip_forward=1
```

## Generation of keys for server and client

```
$ sudo -i
$ cd /etc/wireguard
$ wg genkey | tee server_private_key | wg pubkey > server_public.key
```

## Configuration file for server

* create /etc/wireguard/wg0.conf as following
* for this example, the IP address of server used is 100.0.0.1
* make sure the ip address is not having same subnet as the internet source of the server for example eth0.
* DO NOT use IP 100.0.0.1 if you realize it is having same subnet as eth0 as shown below

```
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 100.0.0.4  netmask 255.255.255.0  broadcast 100.0.0.255
```

```
[Interface]
Address = 100.0.0.1/24
SaveConfig = true
PostUp = /etc/wireguard/iptable/rules.sh A
PostDown = /etc/wireguard/iptable/rules.sh D
ListenPort = 51820
PrivateKey = <server_private_key>

[Peer]
PublicKey = <client_public_key>
AllowedIPs = 100.0.0.2/32
```

* the ListenPort depends on the your UDP port allowed at firewall.
* example of firewall at Azure

![](/files/jvCINN3YfGWthl9Cwrll)

* create /etc/wireguard/iptable/rules.sh.

```
#!/bin/bash
IN_IFACE="eth0"                  # NIC connected to the internet
WG_IFACE="wg0"                   # WG NIC
SUB_NET="100.0.0.0/24"            # WG IPv4 sub/net aka CIDR
WG_PORT="51820"                  # WG udp port

# handle argument
ARG=$1
if [ "$ARG" = "A" ]
then
echo "Appending rules..."
elif [ "$ARG" = "D" ]
then
echo "Deleting rules..."
else
echo "Invalid operation!"
echo "Usage: ./rules.sh A or ./rules.sh D>"
exit 1
fi

# track VPN connection and allow related/established connections
/sbin/iptables -$ARG INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -$ARG FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# allow incoming VPN traffic on the listening port
/sbin/iptables -$ARG INPUT -p udp -m udp --dport $WG_PORT -m conntrack --ctstate NEW -j ACCEPT

# allow both TCP and UDP recursive DNS traffic
/sbin/iptables -$ARG INPUT -s $SUB_NET -p tcp -m tcp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
/sbin/iptables -$ARG INPUT -s $SUB_NET -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT

# allow forwarding of packets between interfaces
/sbin/iptables -$ARG FORWARD -i $WG_IFACE -o $WG_IFACE -m conntrack --ctstate NEW -j ACCEPT
/sbin/iptables -$ARG FORWARD -i $IN_IFACE -o $WG_IFACE -m conntrack --ctstate NEW -j ACCEPT
/sbin/iptables -$ARG FORWARD -i $WG_IFACE -o $IN_IFACE -m conntrack --ctstate NEW -j ACCEPT

######

# set up nat (if allowing clients to access Internet)
/sbin/iptables -t nat -$ARG POSTROUTING -s $SUB_NET -o $IN_IFACE -j MASQUERADE

######

# exit script
echo "Done"
exit 0
```

## Configuration for DNS

* Install unbound to provide DNS

```
$ apt-get install unbound unbound-host dnsutils
```

* check number of threads by running

```
lscpu | egrep 'Model name|Socket|Thread|NUMA|CPU\(s\)'
```

* You will need to fill in num-threads in the next configuration

```
$ curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.cache
$ chown -R unbound:unbound /var/lib/unbound
$ cd /etc/unbound/unbound.conf.d
$ nano unbound_srv.conf
```

```
server:

  num-threads: 1

  #Enable logs
  verbosity: 1

  #list of Root DNS Server
  root-hints: "/var/lib/unbound/root.hints"

  #Use the root servers key for DNSSEC
  #auto-trust-anchor-file: "/var/lib/unbound/root.key"

  #Respond to DNS requests on all interfaces
  interface: 0.0.0.0
  max-udp-size: 3072

  #Authorized IPs to access the DNS Server
  access-control: 0.0.0.0/0                 refuse
  access-control: 127.0.0.1                 allow
  access-control: 100.0.0.0/24               allow

  #not allowed to be returned for public internet  names
  private-address: 100.0.0.0/24

  # Hide DNS Server info
  hide-identity: yes
  hide-version: yes

  #Limit DNS Fraud and use DNSSEC
  harden-glue: yes
  harden-dnssec-stripped: yes
  harden-referral-path: yes

  #Add an unwanted reply threshold to clean the cache and avoid when possible a DNS Poisoning
  unwanted-reply-threshold: 10000000

  #Have the validator print validation failures to the log.
  val-log-level: 1

  #Minimum lifetime of cache entries in seconds
  cache-min-ttl: 1800

  #Maximum lifetime of cached entries
  cache-max-ttl: 14400
  prefetch: yes
  prefetch-key: yes
```

* Restart and enable unbound service

```
$ systemctl restart unbound
$ systemctl enable unbound
```

* You may need to disable the default DNS resolver if unbound fails to start with an error message saying port 53 has been binded to another process

```
% use netstat to check whether port 53 has been binded 
$ netstat -lutnp

% disable systemd-resolved
$ systemctl stop systemd-resolved.service
$ systemctl disable systemd-resolved.service

% fix hostname
% if you have seen error like "unable to resolve host <your_hostname>: Name or service not known"
$ nano /etc/hosts

% add your hostname
127.0.0.1 <your_hostname>
```

## Wireguard service on server

```
$ wg-quick up wg0
$ systemctl enable wg-quick@wg0.service
```

* You can test your DNS setup with the following commands and you should expect to see similar results returned

```
$ nslookup www.google.com 100.0.0.1

Server:		100.0.0.1
Address:	100.0.0.1#53

Non-authoritative answer:
Name:	www.google.com
Address: 74.125.24.103
```

## Setting up clients

### Server

```
$ wg genkey | tee client_private.key | wg pubkey > client_public.key
```

```
$ wg set wg0 peer <new_client_public_key> allowed-ips <new_client_vpn_IP>/32
```

```
$ wg addconf wg0 <(wg-quick strip wg0)
```

* Set wg0 down then up again in order to take effect

### Client

* Install dependencies

```
$ sudo apt install wireguard resolvconf
```

* Assuming the client vpn IP is 100.0.0.2
* Create configuration file as below

```
$ sudo -i
$ nano /etc/wireguard/wg0.conf
```

```
[Interface]
Address = 100.0.0.2/32
PrivateKey = <client_private_key>
DNS = 100.0.0.1

[Peer]
PublicKey = <server_public_key>
Endpoint = <server_public_IP>:<ListenPort>
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
```

* Bring up the connection

```
$ sudo wg-quick up wg0
$ sudo systemctl enable wg-quick@wg0.service
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://pinloon.gitbook.io/wiki/vpn/wireguard-setup-on-azure.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
