Merge pull request #1455 from DerDanilo/wg_ipv6_client_config

Basic wireguard IPv6 (NAT) support
This commit is contained in:
4s3ti 2022-03-10 11:00:39 +01:00 committed by GitHub
commit c03f1560ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 233 additions and 19 deletions

View file

@ -23,7 +23,9 @@ jobs:
include: include:
- stage: lint - stage: lint
name: "Shellcheck lint" name: "Shellcheck lint"
dist: linux dist: focal
virt: vm
arch: amd64
script: script:
- shellcheck auto_install/install.sh - shellcheck auto_install/install.sh
- find scripts/ -type f | xargs shellcheck - find scripts/ -type f | xargs shellcheck
@ -31,9 +33,12 @@ jobs:
- stage: test - stage: test
name: "OpenVPN Xenial & Commands" name: "OpenVPN Xenial & Commands"
dist: xenial dist: xenial
virt: vm
arch: amd64
before_script: before_script:
- cat /etc/os-release - cat /etc/os-release
- uname -a - uname -a
- ip a
- sudo chmod +x ciscripts/startup.sh - sudo chmod +x ciscripts/startup.sh
- ./ciscripts/startup.sh -o - ./ciscripts/startup.sh -o
script: script:
@ -54,9 +59,12 @@ jobs:
- stage: test - stage: test
name: "Wireguard Xenial & Commands" name: "Wireguard Xenial & Commands"
dist: xenial dist: xenial
virt: vm
arch: amd64
before_script: before_script:
- cat /etc/os-release - cat /etc/os-release
- uname -a - uname -a
- ip a
- sudo chmod +x ciscripts/startup.sh - sudo chmod +x ciscripts/startup.sh
- ./ciscripts/startup.sh -w - ./ciscripts/startup.sh -w
script: script:
@ -76,9 +84,12 @@ jobs:
- stage: test - stage: test
name: "OpenVPN Bionic & Commands" name: "OpenVPN Bionic & Commands"
dist: bionic dist: bionic
virt: vm
arch: amd64
before_script: before_script:
- cat /etc/os-release - cat /etc/os-release
- uname -a - uname -a
- ip a
- sudo chmod +x ciscripts/startup.sh - sudo chmod +x ciscripts/startup.sh
- ./ciscripts/startup.sh -o - ./ciscripts/startup.sh -o
script: script:
@ -98,9 +109,12 @@ jobs:
- stage: test - stage: test
name: "Wireguard Bionic & Commands" name: "Wireguard Bionic & Commands"
dist: bionic dist: bionic
virt: vm
arch: amd64
before_script: before_script:
- cat /etc/os-release - cat /etc/os-release
- uname -a - uname -a
- ip a
- sudo apt update -y - sudo apt update -y
- sudo chmod +x ciscripts/startup.sh - sudo chmod +x ciscripts/startup.sh
- ./ciscripts/startup.sh -w - ./ciscripts/startup.sh -w
@ -120,9 +134,12 @@ jobs:
- stage: test - stage: test
name: "OpenVPN Focal & Commands" name: "OpenVPN Focal & Commands"
dist: focal dist: focal
virt: vm
arch: amd64
before_script: before_script:
- cat /etc/os-release - cat /etc/os-release
- uname -a - uname -a
- ip a
- sudo chmod +x ciscripts/startup.sh - sudo chmod +x ciscripts/startup.sh
- ./ciscripts/startup.sh -o - ./ciscripts/startup.sh -o
script: script:
@ -142,9 +159,12 @@ jobs:
- stage: test - stage: test
name: "Wireguard Focal & Commands" name: "Wireguard Focal & Commands"
dist: focal dist: focal
virt: vm
arch: amd64
before_script: before_script:
- cat /etc/os-release - cat /etc/os-release
- uname -a - uname -a
- ip a
- sudo chmod +x ciscripts/startup.sh - sudo chmod +x ciscripts/startup.sh
- ./ciscripts/startup.sh -w - ./ciscripts/startup.sh -w
script: script:

View file

@ -51,6 +51,12 @@ skipSpaceCheck=false
reconfigure=false reconfigure=false
showUnsupportedNICs=false showUnsupportedNICs=false
######## Some vars that might be empty
# but need to be defined for checks
pivpnPERSISTENTKEEPALIVE=""
pivpnDNS2=""
pivpnenableipv6=""
######## SCRIPT ######## ######## SCRIPT ########
# Find the rows and columns. Will default to 80x24 if it can not be detected. # Find the rows and columns. Will default to 80x24 if it can not be detected.
@ -90,6 +96,9 @@ main(){
preconfigurePackages preconfigurePackages
installDependentPackages BASE_DEPS[@] installDependentPackages BASE_DEPS[@]
welcomeDialogs welcomeDialogs
if [ -z "$pivpnenableipv6" ] || [ "$pivpnenableipv6" == "1" ]; then
checkipv6uplink
fi
chooseInterface chooseInterface
if [ "$PLAT" != "Raspbian" ]; then if [ "$PLAT" != "Raspbian" ]; then
avoidStaticIPv4Ubuntu avoidStaticIPv4Ubuntu
@ -466,7 +475,9 @@ preconfigurePackages(){
# On Debian (and Ubuntu), we can only reliably assume the headers package for amd64: linux-image-amd64 # On Debian (and Ubuntu), we can only reliably assume the headers package for amd64: linux-image-amd64
[[ $PLAT == 'Debian' && $DPKG_ARCH == 'amd64' ]] || [[ $PLAT == 'Debian' && $DPKG_ARCH == 'amd64' ]] ||
# On Ubuntu, additionally the WireGuard package needs to be available, since we didn't test mixing Ubuntu repositories. # On Ubuntu, additionally the WireGuard package needs to be available, since we didn't test mixing Ubuntu repositories.
[[ $PLAT == 'Ubuntu' && $DPKG_ARCH == 'amd64' && -n $AVAILABLE_WIREGUARD ]] [[ $PLAT == 'Ubuntu' && $DPKG_ARCH == 'amd64' && -n $AVAILABLE_WIREGUARD ]] ||
# Ubuntu focal has wireguard support
[[ $PLAT == 'Ubuntu' && $DPKG_ARCH == 'arm64' && $OSCN == 'focal' && -n $AVAILABLE_WIREGUARD ]]
then then
WIREGUARD_SUPPORT=1 WIREGUARD_SUPPORT=1
fi fi
@ -580,11 +591,11 @@ local firstloop=1
if [[ "${showUnsupportedNICs}" == true ]]; then if [[ "${showUnsupportedNICs}" == true ]]; then
# Show every network interface, could be useful for those who install PiVPN inside virtual machines # Show every network interface, could be useful for those who install PiVPN inside virtual machines
# or on Raspberry Pis with USB adapters (the loopback interfaces is still skipped) # or on Raspberry Pis with USB adapters (the loopback and docker interfaces are still skipped)
availableInterfaces=$(ip -o link | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1 | grep -v -w 'lo') availableInterfaces=$(ip -o link | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1 | grep -v -w 'lo' | grep -v '^docker')
else else
# Find network interfaces whose state is UP, so as to skip virtual interfaces and the loopback interface # Find network interfaces whose state is UP, so as to skip virtual, loopback and docker interfaces.
availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1) availableInterfaces=$(ip -o link | awk '/state UP/ {print $2}' | cut -d':' -f1 | cut -d'@' -f1 | grep -v -w 'lo' | grep -v '^docker')
fi fi
if [ -z "$availableInterfaces" ]; then if [ -z "$availableInterfaces" ]; then
@ -606,30 +617,55 @@ if [ "${runUnattended}" = 'true' ]; then
if [ -z "$IPv4dev" ]; then if [ -z "$IPv4dev" ]; then
if [ "$interfaceCount" -eq 1 ]; then if [ "$interfaceCount" -eq 1 ]; then
IPv4dev="${availableInterfaces}" IPv4dev="${availableInterfaces}"
echo "::: No interface specified, but only ${IPv4dev} is available, using it" echo "::: No interface specified for IPv4, but only ${IPv4dev} is available, using it"
else else
echo "::: No interface specified and failed to determine one" echo "::: No interface specified for IPv4 and failed to determine one"
exit 1 exit 1
fi fi
else else
if ip -o link | grep -qw "${IPv4dev}"; then if ip -o link | grep -qw "${IPv4dev}"; then
echo "::: Using interface: ${IPv4dev}" echo "::: Using interface: ${IPv4dev} for IPv4"
else else
echo "::: Interface ${IPv4dev} does not exist" echo "::: Interface ${IPv4dev} for IPv4 does not exist"
exit 1 exit 1
fi fi
fi fi
echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile} echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile}
if [ "$pivpnenableipv6" == "1" ]; then
if [ -z "$IPv6dev" ]; then
if [ "$interfaceCount" -eq 1 ]; then
IPv6dev="${availableInterfaces}"
echo "::: No interface specified for IPv6, but only ${IPv6dev} is available, using it"
else
echo "::: No interface specified for IPv6 and failed to determine one"
exit 1
fi
else
if ip -o link | grep -qw "${IPv6dev}"; then
echo "::: Using interface: ${IPv6dev} for IPv6"
else
echo "::: Interface ${IPv6dev} for IPv6 does not exist"
exit 1
fi
fi
fi
if [ "$pivpnenableipv6" == "1" ] && [ -z "$IPv6dev" ]; then
echo "IPv6dev=${IPv6dev}" >> ${tempsetupVarsFile}
fi
return return
else else
if [ "$interfaceCount" -eq 1 ]; then if [ "$interfaceCount" -eq 1 ]; then
IPv4dev="${availableInterfaces}" IPv4dev="${availableInterfaces}"
echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile} echo "IPv4dev=${IPv4dev}" >> ${tempsetupVarsFile}
return if [ "$pivpnenableipv6" == "1" ]; then
IPv6dev="${availableInterfaces}"
echo "IPv6dev=${IPv6dev}" >> ${tempsetupVarsFile}
fi
return
fi fi
fi fi
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An interface (press space to select):" "${r}" "${c}" "${interfaceCount}") chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An interface for IPv4 (press space to select):" "${r}" "${c}" "${interfaceCount}")
if chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) ; then if chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) ; then
for desiredInterface in ${chooseInterfaceOptions}; do for desiredInterface in ${chooseInterfaceOptions}; do
IPv4dev=${desiredInterface} IPv4dev=${desiredInterface}
@ -640,6 +676,19 @@ else
echo "::: Cancel selected, exiting...." echo "::: Cancel selected, exiting...."
exit 1 exit 1
fi fi
if [ "$pivpnenableipv6" == "1" ]; then
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An interface for IPv6, usually the same as used by IPv4 (press space to select):" "${r}" "${c}" "${interfaceCount}")
if chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) ; then
for desiredInterface in ${chooseInterfaceOptions}; do
IPv6dev=${desiredInterface}
echo "::: Using interface: $IPv6dev"
echo "IPv6dev=${IPv6dev}" >> ${tempsetupVarsFile}
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
fi
} }
avoidStaticIPv4Ubuntu() { avoidStaticIPv4Ubuntu() {
@ -688,6 +737,19 @@ validIPAndNetmask(){
return $stat return $stat
} }
checkipv6uplink(){
curl --max-time 3 --connect-timeout 3 --silent --fail -6 http://google.com > /dev/null
curlv6testres=$?
if [ "$curlv6testres" != "0" ]; then
echo "::: IPv6 test connections to google.com have failed. Disabling IPv6 support. (The curl test failed with code: $curlv6testres)"
pivpnenableipv6="0"
else
echo "::: IPv6 test connections to google.com successful. Enabling IPv6 support."
pivpnenableipv6="1"
fi
return
}
getStaticIPv4Settings() { getStaticIPv4Settings() {
# Find the gateway IP used to route to outside world # Find the gateway IP used to route to outside world
CurrentIPv4gw="$(ip -o route get 192.0.2.1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk 'NR==2')" CurrentIPv4gw="$(ip -o route get 192.0.2.1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk 'NR==2')"
@ -1083,6 +1145,9 @@ setVPNDefaultVars(){
if [ -z "$subnetClass" ]; then if [ -z "$subnetClass" ]; then
subnetClass="24" subnetClass="24"
fi fi
if [ -z "$subnetClassv6" ]; then
subnetClassv6="64"
fi
} }
generateRandomSubnet() { generateRandomSubnet() {
@ -1128,12 +1193,22 @@ setWireguardDefaultVars(){
if [ -z "$pivpnNET" ]; then if [ -z "$pivpnNET" ]; then
pivpnNET="$(generateRandomSubnet)" pivpnNET="$(generateRandomSubnet)"
fi fi
if [ "$pivpnenableipv6" == "1" ] && [ -z "$pivpnNETv6" ]; then
pivpnNETv6="fd11:5ee:bad:c0de::"
fi
vpnGw="$(cut -d '.' -f 1-3 <<< "${pivpnNET}").1" vpnGw="$(cut -d '.' -f 1-3 <<< "${pivpnNET}").1"
if [ "$pivpnenableipv6" == "1" ]; then
vpnGwv6="${pivpnNETv6}1"
fi
# Allow custom allowed IPs via unattend setupVARs file. Use default if not provided. # Allow custom allowed IPs via unattend setupVARs file. Use default if not provided.
if [ -z "$ALLOWED_IPS" ]; then if [ -z "$ALLOWED_IPS" ]; then
# Forward all traffic through PiVPN (i.e. full-tunnel), may be modified by # Forward all traffic through PiVPN (i.e. full-tunnel), may be modified by
# the user after the installation. # the user after the installation.
ALLOWED_IPS="0.0.0.0/0, ::0/0" if [ "$pivpnenableipv6" == "1" ]; then
ALLOWED_IPS="0.0.0.0/0, ::0/0"
else
ALLOWED_IPS="0.0.0.0/0"
fi
fi fi
# The default MTU should be fine for most users but we allow to set a # The default MTU should be fine for most users but we allow to set a
# custom MTU via unattend setupVARs file. Use default if not provided. # custom MTU via unattend setupVARs file. Use default if not provided.
@ -1150,6 +1225,13 @@ writeVPNTempVarsFile(){
echo "pivpnDEV=${pivpnDEV}" echo "pivpnDEV=${pivpnDEV}"
echo "pivpnNET=${pivpnNET}" echo "pivpnNET=${pivpnNET}"
echo "subnetClass=${subnetClass}" echo "subnetClass=${subnetClass}"
if [ "$pivpnenableipv6" == "1" ]; then
echo "pivpnenableipv6=1"
echo "pivpnNETv6=\"${pivpnNETv6}\""
echo "subnetClassv6=${subnetClassv6}"
else
echo "pivpnenableipv6=0"
fi
echo "ALLOWED_IPS=\"${ALLOWED_IPS}\"" echo "ALLOWED_IPS=\"${ALLOWED_IPS}\""
} >> ${tempsetupVarsFile} } >> ${tempsetupVarsFile}
} }
@ -1161,7 +1243,7 @@ writeWireguardTempVarsFile(){
# Write PERSISTENTKEEPALIVE if provided via unattended file # Write PERSISTENTKEEPALIVE if provided via unattended file
# May also be added manually to /etc/pivpn/wireguard/setupVars.conf # May also be added manually to /etc/pivpn/wireguard/setupVars.conf
# post installation to be used for client profile generation # post installation to be used for client profile generation
if [ "$pivpnPERSISTENTKEEPALIVE" ]; then if [ -n "${pivpnPERSISTENTKEEPALIVE}" ]; then
echo "pivpnPERSISTENTKEEPALIVE=${pivpnPERSISTENTKEEPALIVE}" >> ${tempsetupVarsFile} echo "pivpnPERSISTENTKEEPALIVE=${pivpnPERSISTENTKEEPALIVE}" >> ${tempsetupVarsFile}
fi fi
} }
@ -2074,17 +2156,33 @@ confWireGuard(){
echo "::: Server Keys have been generated." echo "::: Server Keys have been generated."
if [ "$pivpnenableipv6" == "1" ]; then
echo "[Interface]
PrivateKey = $($SUDO cat /etc/wireguard/keys/server_priv)
Address = ${vpnGw}/${subnetClass},${vpnGwv6}/${subnetClassv6}
MTU = ${pivpnMTU}
ListenPort = ${pivpnPORT}" | $SUDO tee /etc/wireguard/wg0.conf &> /dev/null
else
echo "[Interface] echo "[Interface]
PrivateKey = $($SUDO cat /etc/wireguard/keys/server_priv) PrivateKey = $($SUDO cat /etc/wireguard/keys/server_priv)
Address = ${vpnGw}/${subnetClass} Address = ${vpnGw}/${subnetClass}
MTU = ${pivpnMTU} MTU = ${pivpnMTU}
ListenPort = ${pivpnPORT}" | $SUDO tee /etc/wireguard/wg0.conf &> /dev/null ListenPort = ${pivpnPORT}" | $SUDO tee /etc/wireguard/wg0.conf &> /dev/null
fi
echo "::: Server config generated." echo "::: Server config generated."
} }
confNetwork(){ confNetwork(){
# Enable forwarding of internet traffic # Enable forwarding of internet traffic
$SUDO sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf $SUDO sed -i '/net.ipv4.ip_forward=1/s/^#//g' /etc/sysctl.conf
if [ "$pivpnenableipv6" == "1" ]; then
$SUDO sed -i '/net.ipv6.conf.all.forwarding=1/s/^#//g' /etc/sysctl.conf
$SUDO echo "net.ipv6.conf.${IPv6dev}.accept_ra=2" > /etc/sysctl.d/99-pivpn.conf
fi
$SUDO sysctl -p > /dev/null $SUDO sysctl -p > /dev/null
if [ "$USING_UFW" -eq 1 ]; then if [ "$USING_UFW" -eq 1 ]; then
@ -2099,18 +2197,37 @@ confNetwork(){
echo "$0: ERR: Sorry, won't touch empty file \"/etc/ufw/before.rules\"."; echo "$0: ERR: Sorry, won't touch empty file \"/etc/ufw/before.rules\".";
exit 1; exit 1;
fi fi
if test -s /etc/ufw/before6.rules; then
$SUDO cp -f /etc/ufw/before6.rules /etc/ufw/before6.rules.pre-pivpn
else
echo "$0: ERR: Sorry, won't touch empty file \"/etc/ufw/before6.rules\".";
exit 1;
fi
### If there is already a "*nat" section just add our POSTROUTING MASQUERADE ### If there is already a "*nat" section just add our POSTROUTING MASQUERADE
if $SUDO grep -q "*nat" /etc/ufw/before.rules; then if $SUDO grep -q "*nat" /etc/ufw/before.rules; then
### Onyl add the NAT rule if it isn't already there ### Onyl add the IPv4 NAT rule if it isn't already there
if ! $SUDO grep -q "${VPN}-nat-rule" /etc/ufw/before.rules; then if ! $SUDO grep -q "${VPN}-nat-rule" /etc/ufw/before.rules; then
$SUDO sed "/^*nat/{n;s/\(:POSTROUTING ACCEPT .*\)/\1\n-I POSTROUTING -s ${pivpnNET}\/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule/}" -i /etc/ufw/before.rules $SUDO sed "/^*nat/{n;s/\(:POSTROUTING ACCEPT .*\)/\1\n-I POSTROUTING -s ${pivpnNET}\/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule/}" -i /etc/ufw/before.rules
fi fi
else else
$SUDO sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s ${pivpnNET}\/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before.rules $SUDO sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s ${pivpnNET}\/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before.rules
fi fi
if [ "$pivpnenableipv6" == "1" ]; then
if $SUDO grep -q "*nat" /etc/ufw/before6.rules; then
### Onyl add the IPv6 NAT rule if it isn't already there
if ! $SUDO grep -q "${VPN}-nat-rule" /etc/ufw/before6.rules; then
$SUDO sed "/^*nat/{n;s/\(:POSTROUTING ACCEPT .*\)/\1\n-I POSTROUTING -s ${pivpnNETv6}\/${subnetClassv6} -o ${IPv6dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule/}" -i /etc/ufw/before6.rules
fi
else
$SUDO sed "/delete these required/i *nat\n:POSTROUTING ACCEPT [0:0]\n-I POSTROUTING -s ${pivpnNETv6}\/${subnetClassv6} -o ${IPv6dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule\nCOMMIT\n" -i /etc/ufw/before6.rules
fi
fi
# Insert rules at the beginning of the chain (in case there are other rules that may drop the traffic) # Insert rules at the beginning of the chain (in case there are other rules that may drop the traffic)
$SUDO ufw insert 1 allow "${pivpnPORT}"/"${pivpnPROTO}" comment allow-${VPN} >/dev/null $SUDO ufw insert 1 allow "${pivpnPORT}"/"${pivpnPROTO}" comment allow-${VPN} >/dev/null
$SUDO ufw route insert 1 allow in on "${pivpnDEV}" from "${pivpnNET}/${subnetClass}" out on "${IPv4dev}" to any >/dev/null $SUDO ufw route insert 1 allow in on "${pivpnDEV}" from "${pivpnNET}/${subnetClass}" out on "${IPv4dev}" to any >/dev/null
if [ "$pivpnenableipv6" == "1" ]; then
$SUDO ufw route insert 1 allow in on "${pivpnDEV}" from "${pivpnNETv6}/${subnetClassv6}" out on "${IPv6dev}" to any >/dev/null
fi
$SUDO ufw reload >/dev/null $SUDO ufw reload >/dev/null
echo "::: UFW configuration completed." echo "::: UFW configuration completed."
@ -2123,7 +2240,11 @@ confNetwork(){
if ! $SUDO iptables -t nat -S | grep -q "${VPN}-nat-rule"; then if ! $SUDO iptables -t nat -S | grep -q "${VPN}-nat-rule"; then
$SUDO iptables -t nat -I POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule" $SUDO iptables -t nat -I POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule"
fi fi
if [ "$pivpnenableipv6" == "1" ]; then
if ! $SUDO ip6tables -t nat -S | grep -q "${VPN}-nat-rule"; then
$SUDO ip6tables -t nat -I POSTROUTING -s "${pivpnNETv6}/${subnetClassv6}" -o "${IPv6dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule"
fi
fi
# Count how many rules are in the INPUT and FORWARD chain. When parsing input from # Count how many rules are in the INPUT and FORWARD chain. When parsing input from
# iptables -S, '^-P' skips the policies and 'ufw-' skips ufw chains (in case ufw was found # iptables -S, '^-P' skips the policies and 'ufw-' skips ufw chains (in case ufw was found
# installed but not enabled). # installed but not enabled).
@ -2132,10 +2253,16 @@ confNetwork(){
# for this reasons we use '|| true' to force exit code 0 # for this reasons we use '|| true' to force exit code 0
INPUT_RULES_COUNT="$($SUDO iptables -S INPUT | grep -vcE '(^-P|ufw-)')" INPUT_RULES_COUNT="$($SUDO iptables -S INPUT | grep -vcE '(^-P|ufw-)')"
FORWARD_RULES_COUNT="$($SUDO iptables -S FORWARD | grep -vcE '(^-P|ufw-)')" FORWARD_RULES_COUNT="$($SUDO iptables -S FORWARD | grep -vcE '(^-P|ufw-)')"
INPUT_POLICY="$($SUDO iptables -S INPUT | grep '^-P' | awk '{print $3}')" INPUT_POLICY="$($SUDO iptables -S INPUT | grep '^-P' | awk '{print $3}')"
FORWARD_POLICY="$($SUDO iptables -S FORWARD | grep '^-P' | awk '{print $3}')" FORWARD_POLICY="$($SUDO iptables -S FORWARD | grep '^-P' | awk '{print $3}')"
if [ "$pivpnenableipv6" == "1" ]; then
INPUT_RULES_COUNTv6="$($SUDO ip6tables -S INPUT | grep -vcE '(^-P|ufw-)')"
FORWARD_RULES_COUNTv6="$($SUDO ip6tables -S FORWARD | grep -vcE '(^-P|ufw-)')"
INPUT_POLICYv6="$($SUDO ip6tables -S INPUT | grep '^-P' | awk '{print $3}')"
FORWARD_POLICYv6="$($SUDO ip6tables -S FORWARD | grep '^-P' | awk '{print $3}')"
fi
# If rules count is not zero, we assume we need to explicitly allow traffic. Same conclusion if # If rules count is not zero, we assume we need to explicitly allow traffic. Same conclusion if
# there are no rules and the policy is not ACCEPT. Note that rules are being added to the top of the # there are no rules and the policy is not ACCEPT. Note that rules are being added to the top of the
# chain (using -I). # chain (using -I).
@ -2151,6 +2278,19 @@ confNetwork(){
INPUT_CHAIN_EDITED=0 INPUT_CHAIN_EDITED=0
fi fi
if [ "$pivpnenableipv6" == "1" ]; then
if [ "$INPUT_RULES_COUNTv6" -ne 0 ] || [ "$INPUT_POLICYv6" != "ACCEPT" ]; then
if $SUDO ip6tables -S | grep -q "${VPN}-input-rule"; then
INPUT_CHAIN_EDITEDv6=0
else
$SUDO ip6tables -I INPUT 1 -i "${IPv6dev}" -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT -m comment --comment "${VPN}-input-rule"
fi
INPUT_CHAIN_EDITEDv6=1
else
INPUT_CHAIN_EDITEDv6=0
fi
fi
if [ "$FORWARD_RULES_COUNT" -ne 0 ] || [ "$FORWARD_POLICY" != "ACCEPT" ]; then if [ "$FORWARD_RULES_COUNT" -ne 0 ] || [ "$FORWARD_POLICY" != "ACCEPT" ]; then
if $SUDO iptables -S | grep -q "${VPN}-forward-rule"; then if $SUDO iptables -S | grep -q "${VPN}-forward-rule"; then
FORWARD_CHAIN_EDITED=0 FORWARD_CHAIN_EDITED=0
@ -2163,15 +2303,38 @@ confNetwork(){
FORWARD_CHAIN_EDITED=0 FORWARD_CHAIN_EDITED=0
fi fi
if [ "$pivpnenableipv6" == "1" ]; then
if [ "$FORWARD_RULES_COUNTv6" -ne 0 ] || [ "$FORWARD_POLICYv6" != "ACCEPT" ]; then
if $SUDO ip6tables -S | grep -q "${VPN}-forward-rule"; then
FORWARD_CHAIN_EDITEDv6=0
else
$SUDO ip6tables -I FORWARD 1 -d "${pivpnNETv6}/${subnetClassv6}" -i "${IPv6dev}" -o "${pivpnDEV}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule"
$SUDO ip6tables -I FORWARD 2 -s "${pivpnNETv6}/${subnetClassv6}" -i "${pivpnDEV}" -o "${IPv6dev}" -j ACCEPT -m comment --comment "${VPN}-forward-rule"
fi
FORWARD_CHAIN_EDITEDv6=1
else
FORWARD_CHAIN_EDITEDv6=0
fi
fi
case ${PLAT} in case ${PLAT} in
Debian|Raspbian|Ubuntu) Debian|Raspbian|Ubuntu)
$SUDO iptables-save | $SUDO tee /etc/iptables/rules.v4 > /dev/null $SUDO iptables-save | $SUDO tee /etc/iptables/rules.v4 > /dev/null
;; ;;
esac esac
echo "INPUT_CHAIN_EDITED=${INPUT_CHAIN_EDITED}" >> ${tempsetupVarsFile} case ${PLAT} in
echo "FORWARD_CHAIN_EDITED=${FORWARD_CHAIN_EDITED}" >> ${tempsetupVarsFile} Debian|Raspbian|Ubuntu)
$SUDO ip6tables-save | $SUDO tee /etc/iptables/rules.v6 > /dev/null
;;
esac
{
echo "INPUT_CHAIN_EDITED=${INPUT_CHAIN_EDITED}"
echo "FORWARD_CHAIN_EDITED=${FORWARD_CHAIN_EDITED}"
echo "INPUT_CHAIN_EDITEDv6=${INPUT_CHAIN_EDITEDv6}"
echo "FORWARD_CHAIN_EDITEDv6=${FORWARD_CHAIN_EDITEDv6}"
} >> ${tempsetupVarsFile}
fi fi
} }

View file

@ -2,6 +2,7 @@ IPv4dev=INTERFACE
IPv4addr=IPADDRESS IPv4addr=IPADDRESS
IPv4gw=GATEWAY IPv4gw=GATEWAY
dhcpReserv=0 dhcpReserv=0
pivpnenableipv6=0
install_user=pi install_user=pi
VPN=openvpn VPN=openvpn
pivpnPROTO=udp pivpnPROTO=udp

View file

@ -2,6 +2,7 @@ IPv4dev=INTERFACE
IPv4addr=IPADDRESS IPv4addr=IPADDRESS
IPv4gw=GATEWAY IPv4gw=GATEWAY
dhcpReserv=0 dhcpReserv=0
pivpnenableipv6=0
install_user=pi install_user=pi
VPN=wireguard VPN=wireguard
pivpnPORT=51820 pivpnPORT=51820

View file

@ -2,6 +2,7 @@ IPv4dev=eth0
IPv4addr=192.168.23.211/24 IPv4addr=192.168.23.211/24
IPv4gw=192.168.23.1 IPv4gw=192.168.23.1
dhcpReserv=0 dhcpReserv=0
pivpnenableipv6=0
install_user=pi install_user=pi
VPN=openvpn VPN=openvpn
pivpnNET=10.8.0.0 pivpnNET=10.8.0.0

View file

@ -1,8 +1,12 @@
IPv4dev=eth0 IPv4dev=eth0
IPv6dev=eth0
install_user=pi install_user=pi
VPN=wireguard VPN=wireguard
pivpnNET=10.6.0.0 pivpnNET=10.6.0.0
subnetClass=24 subnetClass=24
pivpnenableipv6=1
pivpnNETv6="fd11:5ee:bad:c0de::"
subnetClassv6=64
ALLOWED_IPS="0.0.0.0/0, ::0/0" ALLOWED_IPS="0.0.0.0/0, ::0/0"
pivpnMTU=1420 pivpnMTU=1420
pivpnPORT=51820 pivpnPORT=51820

View file

@ -1,5 +1,10 @@
#!/bin/bash #!/bin/bash
######## Some vars that might be empty
# but need to be defined for checks
pivpnPERSISTENTKEEPALIVE=""
pivpnDNS2=""
setupVars="/etc/pivpn/wireguard/setupVars.conf" setupVars="/etc/pivpn/wireguard/setupVars.conf"
if [ ! -f "${setupVars}" ]; then if [ ! -f "${setupVars}" ]; then
@ -105,9 +110,15 @@ done
NET_REDUCED="${pivpnNET::-2}" NET_REDUCED="${pivpnNET::-2}"
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [ "$pivpnenableipv6" == "1" ]; then
echo "[Interface]
PrivateKey = $(cat "keys/${CLIENT_NAME}_priv")
Address = ${NET_REDUCED}.${COUNT}/${subnetClass},${pivpnNETv6}${COUNT}/${subnetClassv6}" > "configs/${CLIENT_NAME}.conf"
else
echo "[Interface] echo "[Interface]
PrivateKey = $(cat "keys/${CLIENT_NAME}_priv") PrivateKey = $(cat "keys/${CLIENT_NAME}_priv")
Address = ${NET_REDUCED}.${COUNT}/${subnetClass}" > "configs/${CLIENT_NAME}.conf" Address = ${NET_REDUCED}.${COUNT}/${subnetClass}" > "configs/${CLIENT_NAME}.conf"
fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
echo -n "DNS = ${pivpnDNS1}" >> "configs/${CLIENT_NAME}.conf" echo -n "DNS = ${pivpnDNS1}" >> "configs/${CLIENT_NAME}.conf"
@ -130,16 +141,29 @@ if [ -n "${pivpnPERSISTENTKEEPALIVE}" ]; then
fi fi
echo "::: Client config generated" echo "::: Client config generated"
if [ "$pivpnenableipv6" == "1" ]; then
echo "### begin ${CLIENT_NAME} ###
[Peer]
PublicKey = $(cat "keys/${CLIENT_NAME}_pub")
PresharedKey = $(cat "keys/${CLIENT_NAME}_psk")
AllowedIPs = ${NET_REDUCED}.${COUNT}/32,${pivpnNETv6}${COUNT}/128
### end ${CLIENT_NAME} ###" >> wg0.conf
else
echo "### begin ${CLIENT_NAME} ### echo "### begin ${CLIENT_NAME} ###
[Peer] [Peer]
PublicKey = $(cat "keys/${CLIENT_NAME}_pub") PublicKey = $(cat "keys/${CLIENT_NAME}_pub")
PresharedKey = $(cat "keys/${CLIENT_NAME}_psk") PresharedKey = $(cat "keys/${CLIENT_NAME}_psk")
AllowedIPs = ${NET_REDUCED}.${COUNT}/32 AllowedIPs = ${NET_REDUCED}.${COUNT}/32
### end ${CLIENT_NAME} ###" >> wg0.conf ### end ${CLIENT_NAME} ###" >> wg0.conf
fi
echo "::: Updated server config" echo "::: Updated server config"
if [ -f /etc/pivpn/hosts.wireguard ]; then if [ -f /etc/pivpn/hosts.wireguard ]; then
echo "${NET_REDUCED}.${COUNT} ${CLIENT_NAME}.pivpn" >> /etc/pivpn/hosts.wireguard echo "${NET_REDUCED}.${COUNT} ${CLIENT_NAME}.pivpn" >> /etc/pivpn/hosts.wireguard
if [ "$pivpnenableipv6" == "1" ]; then
echo "${pivpnNETv6}${COUNT} ${CLIENT_NAME}.pivpn" >> /etc/pivpn/hosts.wireguard
fi
if killall -SIGHUP pihole-FTL; then if killall -SIGHUP pihole-FTL; then
echo "::: Updated hosts file for Pi-hole" echo "::: Updated hosts file for Pi-hole"
else else