Skip to content
This repository has been archived by the owner on Jan 28, 2024. It is now read-only.

Commit

Permalink
update readme, randomize ipv6, add ability to change ipv6 subnet
Browse files Browse the repository at this point in the history
  • Loading branch information
finzzz committed Apr 26, 2021
1 parent efef960 commit 82167e0
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 66 deletions.
86 changes: 57 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,17 @@ If you need IPv6, please make sure you can access internet using ipv6 before pro

There are 2 types of connection:
### NAT
- Public IPv6 is being shared, and internal IPv6 uses ULA (Unique Local Address).
- Internal IPv6 communication uses ULA (Unique Local Address).
- Will prioritize on using public IPv6 (shared with all clients) and fallback to IPv4 when not available.
- You need to have IPv6 address similar to `2001::a:b:c:d/64`.
<img src="https://raw.githubusercontent.com/finzzz/wgzero/master/static/nat.jpg" width="500" height="300">

### Full Routing
- Assign public IPv6 to each clients.
- Personally, I got this feature works only on Linode and [Hetzner](#full-routing-ipv6-on-hetzner)(need ndppd).
- Vultr failed, not sure other about providers.
- Assign unique public IPv6 to each clients.
- I have tested this feature on Linode, [Hetzner, and Vultr (need ndppd)](#Full-IPv6-routing-on-Hetzner-and-Vultr).
- You need to have IPv6 address similar to `2001:a:b:c::/64`.
- notice the colons, it means that you can assign multiple addresses to clients.
- **Make sure you don't assign those IP addresses to any interfaces.**

<img src="https://raw.githubusercontent.com/finzzz/wgzero/master/static/fr.jpg" width="500" height="275">


Expand All @@ -40,9 +39,9 @@ There are 2 types of connection:
curl -sO https://raw.githubusercontent.com/finzzz/wgzero/master/wgzero
chmod +x wgzero && ./wgzero install
```

<img src="https://raw.githubusercontent.com/finzzz/wgzero/master/static/install.png" width="700" height="500">


# Other Commands
```
wgzero list
Expand All @@ -52,40 +51,69 @@ wgzero qr clientname
```

# FAQ, troubleshoot, etc.
- Initial steps on debian
## Initial steps on debian
```bash
echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
apt update && apt upgrade
apt install linux-headers-$(uname -r) wireguard curl qrencode iptables ipcalc jq
# replace linux-headers-$(uname -r) with linux-headers-amd64 if errors
```

- Running alongside Pihole
## Running alongside Pihole
Run `pihole restartdns` after setup

- Full routing IPv6 on Hetzner
## Full IPv6 routing on Hetzner and Vultr
***Install ndppd before proceeding***
By default, hetzner allocated a block of IPv6, such as `2a2a:fafa:caca:baba::/64`.
But address `2a2a:fafa:caca:baba::1/64` is attached to the default network.
So, in order for this to work, we need to split this block into smaller one.
In this example, I will arbitrarily use `2a2a:fafa:caca:baba:dada::/80`.

1. Create `/etc/ndppd.conf` with the following content
```
proxy eth0 {
timeout 500
ttl 16000
rule 2a2a:fafa:caca:baba:dada::/80 {
static
}
}
```
2. Enable and start ndppd
3. On installation, assign this IPv6 prefix
### Hetzner
By default, hetzner allocated a block of IPv6, such as `2a2a:fafa:caca:baba::/64`.
But address `2a2a:fafa:caca:baba::1/64` is attached to the default network.
So, in order for this to work, we need to split this block into smaller one.
In this example, I will arbitrarily use `2a2a:fafa:caca:baba:dada::/80`.

### Vultr
Similar to hetzner, if you enabled IPv6, you can go to `Settings -> IPv6` section.
The entry should be similar to this,
| Address | Network | Netmask | Default Gateway |
| ------------------------- | --------------------- | ------- | ---------------------- |
| 2a2a:fafa:caca:baba::abcd | 2a2a:fafa:caca:baba:: | 64 | (use router discovery) |


### Installation walkthrough
```
...
Initializing
Config folder .wgzero already exists, do you want to overwrite [y/N]: y
mode of '/etc/wireguard/wg0.conf' changed from 0644 (rw-r--r--) to 0600 (rw-------)
Writing configs
Available interfaces :
ens3
Interface [eth0]:
Server [1.2.3.4]:
Port [51820]:
Subnet [10.10.0.1/24]:
Enable IPv6 [y/N]: y
IPv6 Prefix [fd00::]: 2a2a:fafa:caca:baba:dada::
...
IPv6 Subnet [64]: 80
External routing:
[1] NAT
[2] Full Routing
Selection [1]: 2
Configure ndppd [y/N]: y
Enable IP forward
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.accept_ra = 2
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Generate server keys
Specify private key [none]:
Generate config file
Enable service
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.10.0.1/24 dev wg0
[#] ip -6 address add 2a2a:fafa:caca:baba:dada::2f04/80 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] /root/.wgzero/postup.sh FR
Done, make sure 51820/UDP is open
```
4. For now, you need to manually configure server configuration on `/etc/wireguard/wg0.conf` and client config.
Change `/64` to `/80` and reboot. This will be automated in the upcoming release.
2 changes: 1 addition & 1 deletion examples/fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Proceed only when `ping6 -I eth0 google.com` succeeds
valid_lft forever preferred_lft forever
```

/etc/ndppd.conf (may not be needed)
/etc/ndppd.conf
```
proxy eth0 {
timeout 500
Expand Down
78 changes: 42 additions & 36 deletions wgzero
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Run(){
"qr")
QR "$2" ;;
*)
Print "Unknown command\n" "red" ;;
Print "Unknown command\\n" "red" ;;
esac
}

Expand Down Expand Up @@ -56,14 +56,14 @@ WriteConfig(){

IsRoot(){
if [[ ! "$EUID" -eq 0 ]]; then
Print "Must be run as root\n" "red" && exit 1
Print "Must be run as root\\n" "red" && exit
fi
}

CheckPackages(){
for i in $1; do
if [[ ! $(command -v "$i") ]]; then
Print "$i: command not found, please check required packages.\n" "red" && exit 1
Print "$i: command not found, please check required packages.\\n" "red" && exit
fi
done
}
Expand All @@ -72,12 +72,12 @@ SetInterface(){
INTERFACES=$(ip -json l | jq -r '.[]|.ifname' | grep -v lo)
DEFAULT=$(echo "$INTERFACES" | head -1)

Print "Available interfaces :\n" "cyan" && echo "$INTERFACES"
Print "Available interfaces :\\n" "cyan" && echo "$INTERFACES"
WriteConfig "Interface" "$DEFAULT"
}

GetConf(){
grep -i "$1" "$CONFIGFOLDER/conf" | cut -d "=" -f 2
grep -i "^$1" "$CONFIGFOLDER/conf" | cut -d "=" -f 2
}

GeneratePrivateKey(){
Expand All @@ -97,7 +97,7 @@ Init(){
rm -rf "$CONFIGFOLDER" "$WG0"
ip link del wg0 2>/dev/null
else
exit 1
exit
fi
fi

Expand All @@ -124,9 +124,9 @@ EnableIPForward(){
}

Install(){
Print "Initializing\n" && Init
Print "Initializing\\n" && Init

Print "Writing configs\n"
Print "Writing configs\\n"
SetInterface && IFACE=$(GetConf interface)
sed -i "s/IFACE/$IFACE/g" "$CONFIGFOLDER"/post{up,down}.sh

Expand All @@ -139,51 +139,56 @@ Install(){
if [ "$VAL" == "y" ]; then
TYPE="NAT"
Read "IPv6 Prefix" "$IPv6Prefix" && echo "IPv6Prefix=$VAL" >> "$CONFIGFOLDER/conf"
Read "IPv6 Subnet" "64" && echo "IPv6Subnet=$VAL" >> "$CONFIGFOLDER/conf"

Print "External routing: \n" "orange"
Print "[1] NAT\n" "cyan"
Print "[2] Full Routing\n" "cyan"
Print "External routing: \\n" "orange"
Print "[1] NAT\\n" "cyan"
Print "[2] Full Routing\\n" "cyan"
Read "Selection" "1"

echo "ExternalRouting=$VAL" >> "$CONFIGFOLDER/conf"
if [ "$VAL" == "2" ]; then
TYPE="FR"

## Need more research
# curl -so /etc/ndppd.conf "$TEMPLATEURL/ndppd.conf"
# sed -i -e "s/IFACE/$IFACE/g" -e "s/PREFIX/$(GetConf IPv6Prefix)/g" /etc/ndppd.conf
# systemctl restart ndppd.service
Read "Configure ndppd" "y/N"
if [ "$VAL" == "y" ]; then
command -v ndppd > /dev/null || (Print "Please install ndppd\\n" "red" && exit)

curl -so /etc/ndppd.conf "$TEMPLATEURL/ndppd.conf"
sed -i -e "s/IFACE/$IFACE/g" -e "s/PREFIX/$(GetConf IPv6Prefix)/g" /etc/ndppd.conf
systemctl restart ndppd.service
fi
fi
fi

Print "Enable IP forward\n" && EnableIPForward
Print "Enable IP forward\\n" && EnableIPForward

Print "Generate server keys\n" && GeneratePrivateKey
Print "Generate server keys\\n" && GeneratePrivateKey

Read "Specify private key" "none"
[ "$VAL" != "none" ] && PRIVKEY="$VAL"
GeneratePublicKey "$CONFIGFOLDER" "$PRIVKEY"

Print "Generate config file\n"
Print "Generate config file\\n"
IPv4Addr=$(/usr/bin/ipcalc -b "$(GetConf subnet)" | grep -i hostmin | tr -s " " | cut -d " " -f 2)

sed -i -e "s/SERVER/$IPv4Addr/g" -e "s#PRIVKEY#$(cat "$CONFIGFOLDER"/priv.key)#g" \
-e "s/PORT/$(GetConf port)/g" -e "s#CONFDIR#$(pwd)/$CONFIGFOLDER#g" -e "s/TYPE/$TYPE/g" "$WG0"

if grep -q "IPv6Prefix" "$CONFIGFOLDER/conf"; then
4to6 "$IPv4Addr"
IPv6Addr="$(GetConf IPv6Prefix)$VAL/64"
SetClientIPv6
IPv6Addr="$(GetConf IPv6Prefix)$VAL/$(GetConf IPv6Subnet)"
sed -i "s#^Address.*#&, $IPv6Addr#g" "$WG0"
fi

Print "Enable service\n"
Print "Enable service\\n"
wg-quick up wg0
systemctl enable wg-quick@wg0

Print "Done, make sure $(GetConf port)/UDP is open\n" "red"
Print "Done, make sure $(GetConf port)/UDP is open\\n" "red"
}

SetClientIP(){
SetClientIPv4(){
PREFIX=$(GetConf subnet | cut -d "." -f 1,2,3)
MIN=$(/usr/bin/ipcalc -b "$(GetConf subnet)" | grep -i hostmin | cut -d "." -f 4 | tr -d " ")
MAX=$(/usr/bin/ipcalc -b "$(GetConf subnet)" | grep -i hostmax | cut -d "." -f 4 | tr -d " ")
Expand All @@ -193,18 +198,18 @@ SetClientIP(){
grep -q "$DEFAULT" $WG0 || break
done

Read "Choose client IP" "$DEFAULT"
Read "Choose client IPv4" "$DEFAULT"
}

4to6(){
VAL=$(echo "$1" | cut -d "." -f 4 | xargs printf "%x")
SetClientIPv6(){
VAL=$(head -c 2 /dev/random | od -A n -t x2 | tr -d " ") ## randomize IPv6
}

QR(){
CFG="$CONFIGFOLDER/$1/conf"
[ ! -f "$CFG" ] && Print "Client doesn't exist\n" "red" && exit 1
[ ! -f "$CFG" ] && Print "Client doesn't exist\\n" "red" && exit

Print "\n$CFG\n" "red"
Print "\\n$CFG\\n" "red"
/usr/bin/qrencode -t ansiutf8 < "$CFG"
}

Expand All @@ -213,21 +218,21 @@ List(){
for i in $PUBKEYS; do
CLIENT=$(grep -r "$i" "$CONFIGFOLDER" | cut -d "/" -f 2)
IP=$(grep -i address "$CONFIGFOLDER/$CLIENT/conf" | tr -d " " | cut -d "=" -f 2)
Print "$CLIENT $IP $i\n" "orange"
Print "$CLIENT $IP $i\\n" "orange"
done
}

Add(){
NAME="$2"

[[ ! "$NAME" ]] && exit 1
[[ -d "$CONFIGFOLDER/$NAME" ]] && Print "Client already exists\n" "red" && exit 1
[[ ! "$NAME" ]] && exit
[[ -d "$CONFIGFOLDER/$NAME" ]] && Print "Client already exists\\n" "red" && exit

mkdir "$CONFIGFOLDER/$NAME"
GeneratePrivateKey
GeneratePublicKey "$CONFIGFOLDER/$NAME" "$PRIVKEY"

SetClientIP && CLIENT_IP="$VAL"
SetClientIPv4 && CLIENT_IP="$VAL"

# appending server config
TMP=$(mktemp)
Expand Down Expand Up @@ -259,10 +264,11 @@ EOF

# handle IPv6
if grep -q "IPv6Prefix" "$CONFIGFOLDER/conf"; then
4to6 "$CLIENT_IP"
IPv6Addr="$(GetConf IPv6Prefix)$VAL"
SetClientIPv6 # set default

Read "Choose client IPv6" "$(GetConf IPv6Prefix)$VAL" && IPv6Addr="$VAL"

sed -i -e "s|^Address.*$|&, $IPv6Addr/64|g" \
sed -i -e "s|^Address.*$|&, $IPv6Addr/128|g" \
-e "s|^AllowedIPs.*$|&, ::/0|g" \
"$CONFIGFOLDER/$NAME/conf"

Expand Down Expand Up @@ -297,7 +303,7 @@ Del(){

rm -rf "$CFG"
else
Print "Client doesn't exist\n" "red"
Print "Client doesn't exist\\n" "red"
fi
}

Expand Down

0 comments on commit 82167e0

Please sign in to comment.