Add support for DNS names

- NEW: Add support for using DNS names (e.g. vpn.example.com) as
  the WireGuard VPN server's address. Users can now select this option
  during interactive install (sudo bash wireguard.sh).
- Example use case: With this new feature, when using a DNS name as
  the server address, users can take a snapshot of the server and
  restore it to a new server with a different IP, then update the
  DNS name to point to the new IP. After that, they can expect the
  VPN to continue to work.
This commit is contained in:
hwdsl2 2023-09-11 22:28:38 -05:00
parent 395bb0fdef
commit 6b11fa1630

View File

@ -69,6 +69,11 @@ check_nftables() {
fi fi
} }
check_dns_name() {
FQDN_REGEX='^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$'
printf '%s' "$1" | tr -d '\n' | grep -Eq "$FQDN_REGEX"
}
install_wget() { install_wget() {
# Detect some Debian minimal setups where neither wget nor curl are installed # Detect some Debian minimal setups where neither wget nor curl are installed
if ! hash wget 2>/dev/null && ! hash curl 2>/dev/null; then if ! hash wget 2>/dev/null && ! hash curl 2>/dev/null; then
@ -127,6 +132,33 @@ show_start_setup() {
fi fi
} }
enter_server_address() {
echo
echo "Do you want WireGuard VPN clients to connect to this server using a DNS name,"
printf "e.g. vpn.example.com, instead of its IP address? [y/N] "
read -r response
case $response in
[yY][eE][sS]|[yY])
use_dns_name=1
echo
;;
*)
use_dns_name=0
;;
esac
if [ "$use_dns_name" = 1 ]; then
read -rp "Enter the DNS name of this VPN server: " server_addr
until check_dns_name "$server_addr"; do
echo "Invalid DNS name. You must enter a fully qualified domain name (FQDN)."
read -rp "Enter the DNS name of this VPN server: " server_addr
done
ip="$server_addr"
else
detect_ip
check_nat_ip
fi
}
find_public_ip() { find_public_ip() {
ip_url1="http://ipv4.icanhazip.com" ip_url1="http://ipv4.icanhazip.com"
ip_url2="http://ip1.dynupdate.no-ip.com" ip_url2="http://ip1.dynupdate.no-ip.com"
@ -571,8 +603,13 @@ if [[ ! -e /etc/wireguard/wg0.conf ]]; then
install_wget install_wget
install_iproute install_iproute
show_start_setup show_start_setup
public_ip=""
if [ "$auto" = 0 ]; then
enter_server_address
else
detect_ip detect_ip
check_nat_ip check_nat_ip
fi
show_config show_config
detect_ipv6 detect_ipv6
select_port select_port
@ -689,13 +726,13 @@ EOF
firewall-cmd -q --permanent --add-port="$port"/udp firewall-cmd -q --permanent --add-port="$port"/udp
firewall-cmd -q --permanent --zone=trusted --add-source=10.7.0.0/24 firewall-cmd -q --permanent --zone=trusted --add-source=10.7.0.0/24
# Set NAT for the VPN subnet # Set NAT for the VPN subnet
firewall-cmd -q --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j SNAT --to "$ip" firewall-cmd -q --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j MASQUERADE
firewall-cmd -q --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j SNAT --to "$ip" firewall-cmd -q --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j MASQUERADE
if [[ -n "$ip6" ]]; then if [[ -n "$ip6" ]]; then
firewall-cmd -q --zone=trusted --add-source=fddd:2c4:2c4:2c4::/64 firewall-cmd -q --zone=trusted --add-source=fddd:2c4:2c4:2c4::/64
firewall-cmd -q --permanent --zone=trusted --add-source=fddd:2c4:2c4:2c4::/64 firewall-cmd -q --permanent --zone=trusted --add-source=fddd:2c4:2c4:2c4::/64
firewall-cmd -q --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j SNAT --to "$ip6" firewall-cmd -q --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j MASQUERADE
firewall-cmd -q --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j SNAT --to "$ip6" firewall-cmd -q --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j MASQUERADE
fi fi
else else
# Create a service to set up persistent iptables rules # Create a service to set up persistent iptables rules
@ -711,19 +748,19 @@ EOF
Before=network.target Before=network.target
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart=$iptables_path -t nat -A POSTROUTING -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j SNAT --to $ip ExecStart=$iptables_path -t nat -A POSTROUTING -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j MASQUERADE
ExecStart=$iptables_path -I INPUT -p udp --dport $port -j ACCEPT ExecStart=$iptables_path -I INPUT -p udp --dport $port -j ACCEPT
ExecStart=$iptables_path -I FORWARD -s 10.7.0.0/24 -j ACCEPT ExecStart=$iptables_path -I FORWARD -s 10.7.0.0/24 -j ACCEPT
ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ExecStop=$iptables_path -t nat -D POSTROUTING -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j SNAT --to $ip ExecStop=$iptables_path -t nat -D POSTROUTING -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j MASQUERADE
ExecStop=$iptables_path -D INPUT -p udp --dport $port -j ACCEPT ExecStop=$iptables_path -D INPUT -p udp --dport $port -j ACCEPT
ExecStop=$iptables_path -D FORWARD -s 10.7.0.0/24 -j ACCEPT ExecStop=$iptables_path -D FORWARD -s 10.7.0.0/24 -j ACCEPT
ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/wg-iptables.service ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/wg-iptables.service
if [[ -n "$ip6" ]]; then if [[ -n "$ip6" ]]; then
echo "ExecStart=$ip6tables_path -t nat -A POSTROUTING -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j SNAT --to $ip6 echo "ExecStart=$ip6tables_path -t nat -A POSTROUTING -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j MASQUERADE
ExecStart=$ip6tables_path -I FORWARD -s fddd:2c4:2c4:2c4::/64 -j ACCEPT ExecStart=$ip6tables_path -I FORWARD -s fddd:2c4:2c4:2c4::/64 -j ACCEPT
ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j SNAT --to $ip6 ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j MASQUERADE
ExecStop=$ip6tables_path -D FORWARD -s fddd:2c4:2c4:2c4::/64 -j ACCEPT ExecStop=$ip6tables_path -D FORWARD -s fddd:2c4:2c4:2c4::/64 -j ACCEPT
ExecStop=$ip6tables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/wg-iptables.service ExecStop=$ip6tables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/wg-iptables.service
fi fi
@ -888,14 +925,14 @@ else
firewall-cmd -q --zone=trusted --remove-source=10.7.0.0/24 firewall-cmd -q --zone=trusted --remove-source=10.7.0.0/24
firewall-cmd -q --permanent --remove-port="$port"/udp firewall-cmd -q --permanent --remove-port="$port"/udp
firewall-cmd -q --permanent --zone=trusted --remove-source=10.7.0.0/24 firewall-cmd -q --permanent --zone=trusted --remove-source=10.7.0.0/24
firewall-cmd -q --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j SNAT --to "$ip" firewall-cmd -q --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j MASQUERADE
firewall-cmd -q --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j SNAT --to "$ip" firewall-cmd -q --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j MASQUERADE
if grep -qs 'fddd:2c4:2c4:2c4::1/64' /etc/wireguard/wg0.conf; then if grep -qs 'fddd:2c4:2c4:2c4::1/64' /etc/wireguard/wg0.conf; then
ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:2c4:2c4:2c4::/64 '"'"'!'"'"' -d fddd:2c4:2c4:2c4::/64' | grep -oE '[^ ]+$') ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:2c4:2c4:2c4::/64 '"'"'!'"'"' -d fddd:2c4:2c4:2c4::/64' | grep -oE '[^ ]+$')
firewall-cmd -q --zone=trusted --remove-source=fddd:2c4:2c4:2c4::/64 firewall-cmd -q --zone=trusted --remove-source=fddd:2c4:2c4:2c4::/64
firewall-cmd -q --permanent --zone=trusted --remove-source=fddd:2c4:2c4:2c4::/64 firewall-cmd -q --permanent --zone=trusted --remove-source=fddd:2c4:2c4:2c4::/64
firewall-cmd -q --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j SNAT --to "$ip6" firewall-cmd -q --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j MASQUERADE
firewall-cmd -q --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j SNAT --to "$ip6" firewall-cmd -q --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:2c4:2c4:2c4::/64 ! -d fddd:2c4:2c4:2c4::/64 -j MASQUERADE
fi fi
else else
systemctl disable --now wg-iptables.service systemctl disable --now wg-iptables.service