mirror of
https://github.com/hwdsl2/openvpn-install.git
synced 2026-01-11 19:06:18 +00:00
Improve VPN script
- Refactor the script into Bash functions for improved organization and readability.
This commit is contained in:
@@ -21,6 +21,26 @@ check_ip() {
|
|||||||
printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX"
|
printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_root() {
|
||||||
|
if [ "$(id -u)" != 0 ]; then
|
||||||
|
exiterr "This installer must be run as root. Try 'sudo bash $0'"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_shell() {
|
||||||
|
# Detect Debian users running the script with "sh" instead of bash
|
||||||
|
if readlink /proc/$$/exe | grep -q "dash"; then
|
||||||
|
exiterr 'This installer needs to be run with "bash", not "sh".'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_kernel() {
|
||||||
|
# Detect OpenVZ 6
|
||||||
|
if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then
|
||||||
|
exiterr "The system is running an old kernel, which is incompatible with this installer."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
check_os() {
|
check_os() {
|
||||||
if grep -qs "ubuntu" /etc/os-release; then
|
if grep -qs "ubuntu" /etc/os-release; then
|
||||||
os="ubuntu"
|
os="ubuntu"
|
||||||
@@ -71,6 +91,30 @@ This version of CentOS is too old and unsupported."
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_tun() {
|
||||||
|
if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then
|
||||||
|
exiterr "The system does not have the TUN device available.
|
||||||
|
TUN needs to be enabled before running this installer."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
--auto)
|
||||||
|
auto=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
show_usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
show_usage "Unknown parameter: $1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
check_nftables() {
|
check_nftables() {
|
||||||
if [ "$os" = "centos" ]; then
|
if [ "$os" = "centos" ]; then
|
||||||
if grep -qs "hwdsl2 VPN script" /etc/sysconfig/nftables.conf \
|
if grep -qs "hwdsl2 VPN script" /etc/sysconfig/nftables.conf \
|
||||||
@@ -403,6 +447,305 @@ confirm_setup() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disable_limitnproc() {
|
||||||
|
# If running inside a container, disable LimitNPROC to prevent conflicts
|
||||||
|
if systemd-detect-virt -cq; then
|
||||||
|
mkdir /etc/systemd/system/openvpn-server@server.service.d/ 2>/dev/null
|
||||||
|
echo "[Service]
|
||||||
|
LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_pkgs() {
|
||||||
|
if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
apt-get -yqq update || apt-get -yqq update
|
||||||
|
apt-get -yqq --no-install-recommends install openvpn >/dev/null
|
||||||
|
) || exiterr2
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
apt-get -yqq install openssl ca-certificates $firewall >/dev/null
|
||||||
|
) || exiterr2
|
||||||
|
elif [[ "$os" = "centos" ]]; then
|
||||||
|
if grep -qs "Amazon Linux release 2 " /etc/system-release; then
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
amazon-linux-extras install epel -y >/dev/null
|
||||||
|
) || exit 1
|
||||||
|
else
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
yum -y -q install epel-release >/dev/null
|
||||||
|
) || exiterr3
|
||||||
|
fi
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
yum -y -q install openvpn openssl ca-certificates tar $firewall >/dev/null 2>&1
|
||||||
|
) || exiterr3
|
||||||
|
elif [[ "$os" = "fedora" ]]; then
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
dnf install -y openvpn openssl ca-certificates tar $firewall >/dev/null
|
||||||
|
) || exiterr "'dnf install' failed."
|
||||||
|
else
|
||||||
|
# Else, OS must be openSUSE
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
zypper install -y openvpn openssl ca-certificates tar $firewall >/dev/null
|
||||||
|
) || exiterr4
|
||||||
|
fi
|
||||||
|
# If firewalld was just installed, enable it
|
||||||
|
if [[ "$firewall" == "firewalld" ]]; then
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
systemctl enable --now firewalld.service >/dev/null 2>&1
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_pkgs() {
|
||||||
|
if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
rm -rf /etc/openvpn/server
|
||||||
|
apt-get remove --purge -y openvpn >/dev/null
|
||||||
|
)
|
||||||
|
elif [[ "$os" = "openSUSE" ]]; then
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
zypper remove -y openvpn >/dev/null
|
||||||
|
rm -rf /etc/openvpn/server
|
||||||
|
)
|
||||||
|
rm -f /etc/openvpn/ipp.txt
|
||||||
|
else
|
||||||
|
# Else, OS must be CentOS or Fedora
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
yum -y -q remove openvpn >/dev/null
|
||||||
|
rm -rf /etc/openvpn/server
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
create_firewall_rules() {
|
||||||
|
if systemctl is-active --quiet firewalld.service; then
|
||||||
|
# Using both permanent and not permanent rules to avoid a firewalld
|
||||||
|
# reload.
|
||||||
|
# We don't use --add-service=openvpn because that would only work with
|
||||||
|
# the default port and protocol.
|
||||||
|
firewall-cmd -q --add-port="$port"/"$protocol"
|
||||||
|
firewall-cmd -q --zone=trusted --add-source=10.8.0.0/24
|
||||||
|
firewall-cmd -q --permanent --add-port="$port"/"$protocol"
|
||||||
|
firewall-cmd -q --permanent --zone=trusted --add-source=10.8.0.0/24
|
||||||
|
# Set NAT for the VPN subnet
|
||||||
|
firewall-cmd -q --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
||||||
|
firewall-cmd -q --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
||||||
|
if [[ -n "$ip6" ]]; then
|
||||||
|
firewall-cmd -q --zone=trusted --add-source=fddd:1194:1194:1194::/64
|
||||||
|
firewall-cmd -q --permanent --zone=trusted --add-source=fddd:1194:1194:1194::/64
|
||||||
|
firewall-cmd -q --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
||||||
|
firewall-cmd -q --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Create a service to set up persistent iptables rules
|
||||||
|
iptables_path=$(command -v iptables)
|
||||||
|
ip6tables_path=$(command -v ip6tables)
|
||||||
|
# nf_tables is not available as standard in OVZ kernels. So use iptables-legacy
|
||||||
|
# if we are in OVZ, with a nf_tables backend and iptables-legacy is available.
|
||||||
|
if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f "$(command -v iptables)" | grep -q "nft" && hash iptables-legacy 2>/dev/null; then
|
||||||
|
iptables_path=$(command -v iptables-legacy)
|
||||||
|
ip6tables_path=$(command -v ip6tables-legacy)
|
||||||
|
fi
|
||||||
|
echo "[Unit]
|
||||||
|
Before=network.target
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=$iptables_path -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
||||||
|
ExecStart=$iptables_path -I INPUT -p $protocol --dport $port -j ACCEPT
|
||||||
|
ExecStart=$iptables_path -I FORWARD -s 10.8.0.0/24 -j ACCEPT
|
||||||
|
ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
ExecStop=$iptables_path -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
||||||
|
ExecStop=$iptables_path -D INPUT -p $protocol --dport $port -j ACCEPT
|
||||||
|
ExecStop=$iptables_path -D FORWARD -s 10.8.0.0/24 -j ACCEPT
|
||||||
|
ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service
|
||||||
|
if [[ -n "$ip6" ]]; then
|
||||||
|
echo "ExecStart=$ip6tables_path -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
||||||
|
ExecStart=$ip6tables_path -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
|
||||||
|
ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
||||||
|
ExecStop=$ip6tables_path -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
|
||||||
|
ExecStop=$ip6tables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/openvpn-iptables.service
|
||||||
|
fi
|
||||||
|
echo "RemainAfterExit=yes
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
systemctl enable --now openvpn-iptables.service >/dev/null 2>&1
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_firewall_rules() {
|
||||||
|
port=$(grep '^port ' "$OVPN_CONF" | cut -d " " -f 2)
|
||||||
|
protocol=$(grep '^proto ' "$OVPN_CONF" | cut -d " " -f 2)
|
||||||
|
if systemctl is-active --quiet firewalld.service; then
|
||||||
|
ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$')
|
||||||
|
# Using both permanent and not permanent rules to avoid a firewalld reload.
|
||||||
|
firewall-cmd -q --remove-port="$port"/"$protocol"
|
||||||
|
firewall-cmd -q --zone=trusted --remove-source=10.8.0.0/24
|
||||||
|
firewall-cmd -q --permanent --remove-port="$port"/"$protocol"
|
||||||
|
firewall-cmd -q --permanent --zone=trusted --remove-source=10.8.0.0/24
|
||||||
|
firewall-cmd -q --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
||||||
|
firewall-cmd -q --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
||||||
|
if grep -qs "server-ipv6" "$OVPN_CONF"; then
|
||||||
|
ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$')
|
||||||
|
firewall-cmd -q --zone=trusted --remove-source=fddd:1194:1194:1194::/64
|
||||||
|
firewall-cmd -q --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64
|
||||||
|
firewall-cmd -q --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
||||||
|
firewall-cmd -q --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
systemctl disable --now openvpn-iptables.service
|
||||||
|
rm -f /etc/systemd/system/openvpn-iptables.service
|
||||||
|
fi
|
||||||
|
if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
|
||||||
|
semanage port -d -t openvpn_port_t -p "$protocol" "$port"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_easyrsa() {
|
||||||
|
# Get easy-rsa
|
||||||
|
easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.2.0/EasyRSA-3.2.0.tgz'
|
||||||
|
mkdir -p /etc/openvpn/server/easy-rsa/
|
||||||
|
{ wget -t 3 -T 30 -qO- "$easy_rsa_url" 2>/dev/null || curl -m 30 -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1
|
||||||
|
if [ ! -f /etc/openvpn/server/easy-rsa/easyrsa ]; then
|
||||||
|
exiterr "Failed to download EasyRSA from $easy_rsa_url."
|
||||||
|
fi
|
||||||
|
chown -R root:root /etc/openvpn/server/easy-rsa/
|
||||||
|
}
|
||||||
|
|
||||||
|
create_pki_and_certs() {
|
||||||
|
cd /etc/openvpn/server/easy-rsa/ || exit 1
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
# Create the PKI, set up the CA and the server and client certificates
|
||||||
|
./easyrsa --batch init-pki >/dev/null
|
||||||
|
./easyrsa --batch build-ca nopass >/dev/null 2>&1
|
||||||
|
./easyrsa --batch --days=3650 build-server-full server nopass >/dev/null 2>&1
|
||||||
|
./easyrsa --batch --days=3650 build-client-full "$client" nopass >/dev/null 2>&1
|
||||||
|
./easyrsa --batch --days=3650 gen-crl >/dev/null 2>&1
|
||||||
|
)
|
||||||
|
# Move the stuff we need
|
||||||
|
cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/server
|
||||||
|
# CRL is read with each client connection, while OpenVPN is dropped to nobody
|
||||||
|
chown nobody:"$group_name" /etc/openvpn/server/crl.pem
|
||||||
|
# Without +x in the directory, OpenVPN can't run a stat() on the CRL file
|
||||||
|
chmod o+x /etc/openvpn/server/
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
# Generate key for tls-crypt
|
||||||
|
openvpn --genkey --secret /etc/openvpn/server/tc.key >/dev/null
|
||||||
|
)
|
||||||
|
# Create the DH parameters file using the predefined ffdhe2048 group
|
||||||
|
echo '-----BEGIN DH PARAMETERS-----
|
||||||
|
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||||
|
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||||
|
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||||
|
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||||
|
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||||
|
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||||
|
-----END DH PARAMETERS-----' > /etc/openvpn/server/dh.pem
|
||||||
|
}
|
||||||
|
|
||||||
|
create_dns_config() {
|
||||||
|
case "$dns" in
|
||||||
|
1)
|
||||||
|
# Locate the proper resolv.conf
|
||||||
|
# Needed for systems running systemd-resolved
|
||||||
|
if grep '^nameserver' "/etc/resolv.conf" | grep -qv '127.0.0.53' ; then
|
||||||
|
resolv_conf="/etc/resolv.conf"
|
||||||
|
else
|
||||||
|
resolv_conf="/run/systemd/resolve/resolv.conf"
|
||||||
|
fi
|
||||||
|
# Obtain the resolvers from resolv.conf and use them for OpenVPN
|
||||||
|
grep -v '^#\|^;' "$resolv_conf" | grep '^nameserver' | grep -v '127.0.0.53' | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do
|
||||||
|
echo "push \"dhcp-option DNS $line\"" >> "$OVPN_CONF"
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
2|"")
|
||||||
|
echo 'push "dhcp-option DNS 8.8.8.8"' >> "$OVPN_CONF"
|
||||||
|
echo 'push "dhcp-option DNS 8.8.4.4"' >> "$OVPN_CONF"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
echo 'push "dhcp-option DNS 1.1.1.1"' >> "$OVPN_CONF"
|
||||||
|
echo 'push "dhcp-option DNS 1.0.0.1"' >> "$OVPN_CONF"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
echo 'push "dhcp-option DNS 208.67.222.222"' >> "$OVPN_CONF"
|
||||||
|
echo 'push "dhcp-option DNS 208.67.220.220"' >> "$OVPN_CONF"
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
echo 'push "dhcp-option DNS 9.9.9.9"' >> "$OVPN_CONF"
|
||||||
|
echo 'push "dhcp-option DNS 149.112.112.112"' >> "$OVPN_CONF"
|
||||||
|
;;
|
||||||
|
6)
|
||||||
|
echo 'push "dhcp-option DNS 94.140.14.14"' >> "$OVPN_CONF"
|
||||||
|
echo 'push "dhcp-option DNS 94.140.15.15"' >> "$OVPN_CONF"
|
||||||
|
;;
|
||||||
|
7)
|
||||||
|
echo "push \"dhcp-option DNS $dns1\"" >> "$OVPN_CONF"
|
||||||
|
if [ -n "$dns2" ]; then
|
||||||
|
echo "push \"dhcp-option DNS $dns2\"" >> "$OVPN_CONF"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
create_server_config() {
|
||||||
|
# Generate server.conf
|
||||||
|
echo "local $ip
|
||||||
|
port $port
|
||||||
|
proto $protocol
|
||||||
|
dev tun
|
||||||
|
ca ca.crt
|
||||||
|
cert server.crt
|
||||||
|
key server.key
|
||||||
|
dh dh.pem
|
||||||
|
auth SHA256
|
||||||
|
tls-crypt tc.key
|
||||||
|
topology subnet
|
||||||
|
server 10.8.0.0 255.255.255.0" > "$OVPN_CONF"
|
||||||
|
# IPv6
|
||||||
|
if [[ -z "$ip6" ]]; then
|
||||||
|
echo 'push "block-ipv6"' >> "$OVPN_CONF"
|
||||||
|
echo 'push "ifconfig-ipv6 fddd:1194:1194:1194::2/64 fddd:1194:1194:1194::1"' >> "$OVPN_CONF"
|
||||||
|
else
|
||||||
|
echo 'server-ipv6 fddd:1194:1194:1194::/64' >> "$OVPN_CONF"
|
||||||
|
fi
|
||||||
|
echo 'push "redirect-gateway def1 ipv6 bypass-dhcp"' >> "$OVPN_CONF"
|
||||||
|
echo 'ifconfig-pool-persist ipp.txt' >> "$OVPN_CONF"
|
||||||
|
create_dns_config
|
||||||
|
echo 'push "block-outside-dns"' >> "$OVPN_CONF"
|
||||||
|
echo "keepalive 10 120
|
||||||
|
cipher AES-128-GCM
|
||||||
|
user nobody
|
||||||
|
group $group_name
|
||||||
|
persist-key
|
||||||
|
persist-tun
|
||||||
|
verb 3
|
||||||
|
crl-verify crl.pem" >> "$OVPN_CONF"
|
||||||
|
if [[ "$protocol" = "udp" ]]; then
|
||||||
|
echo "explicit-exit-notify" >> "$OVPN_CONF"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
show_clients() {
|
||||||
|
tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
|
||||||
|
}
|
||||||
|
|
||||||
get_export_dir() {
|
get_export_dir() {
|
||||||
export_to_home_dir=0
|
export_to_home_dir=0
|
||||||
export_dir=~/
|
export_dir=~/
|
||||||
@@ -491,6 +834,70 @@ EOF
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_selinux() {
|
||||||
|
# If SELinux is enabled and a custom port was selected, we need this
|
||||||
|
if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
|
||||||
|
# Install semanage if not already present
|
||||||
|
if ! hash semanage 2>/dev/null; then
|
||||||
|
if [[ "$os_version" -eq 7 ]]; then
|
||||||
|
# Centos 7
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
yum -y -q install policycoreutils-python >/dev/null
|
||||||
|
) || exiterr3
|
||||||
|
else
|
||||||
|
# CentOS 8/9 or Fedora
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
dnf install -y policycoreutils-python-utils >/dev/null
|
||||||
|
) || exiterr "'dnf install' failed."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
semanage port -a -t openvpn_port_t -p "$protocol" "$port"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
create_client_common() {
|
||||||
|
# client-common.txt is created so we have a template to add further users later
|
||||||
|
echo "client
|
||||||
|
dev tun
|
||||||
|
proto $protocol
|
||||||
|
remote $ip $port
|
||||||
|
resolv-retry infinite
|
||||||
|
nobind
|
||||||
|
persist-key
|
||||||
|
persist-tun
|
||||||
|
remote-cert-tls server
|
||||||
|
auth SHA256
|
||||||
|
cipher AES-128-GCM
|
||||||
|
ignore-unknown-option block-outside-dns block-ipv6
|
||||||
|
verb 3" > /etc/openvpn/server/client-common.txt
|
||||||
|
}
|
||||||
|
|
||||||
|
start_openvpn_service() {
|
||||||
|
# Enable and start the OpenVPN service
|
||||||
|
if [ "$os" != "openSUSE" ]; then
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
systemctl enable --now openvpn-server@server.service >/dev/null 2>&1
|
||||||
|
)
|
||||||
|
else
|
||||||
|
ln -s /etc/openvpn/server/* /etc/openvpn >/dev/null 2>&1
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
systemctl enable --now openvpn@server.service >/dev/null 2>&1
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_setup() {
|
||||||
|
echo
|
||||||
|
echo "Finished!"
|
||||||
|
echo
|
||||||
|
echo "The client configuration is available in: $export_dir$client.ovpn"
|
||||||
|
echo "New clients can be added by running this script again."
|
||||||
|
}
|
||||||
|
|
||||||
show_header() {
|
show_header() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
|
|
||||||
@@ -507,6 +914,24 @@ Copyright (c) 2013-2023 Nyr
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select_menu_option() {
|
||||||
|
echo
|
||||||
|
echo "OpenVPN is already installed."
|
||||||
|
echo
|
||||||
|
echo "Select an option:"
|
||||||
|
echo " 1) Add a new client"
|
||||||
|
echo " 2) Export config for an existing client"
|
||||||
|
echo " 3) List existing clients"
|
||||||
|
echo " 4) Revoke an existing client"
|
||||||
|
echo " 5) Remove OpenVPN"
|
||||||
|
echo " 6) Exit"
|
||||||
|
read -rp "Option: " option
|
||||||
|
until [[ "$option" =~ ^[1-6]$ ]]; do
|
||||||
|
echo "$option: invalid selection."
|
||||||
|
read -rp "Option: " option
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
show_usage() {
|
show_usage() {
|
||||||
if [ -n "$1" ]; then
|
if [ -n "$1" ]; then
|
||||||
echo "Error: $1" >&2
|
echo "Error: $1" >&2
|
||||||
@@ -530,45 +955,19 @@ ovpnsetup() {
|
|||||||
|
|
||||||
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
|
||||||
if [ "$(id -u)" != 0 ]; then
|
check_root
|
||||||
exiterr "This installer must be run as root. Try 'sudo bash $0'"
|
check_shell
|
||||||
fi
|
check_kernel
|
||||||
|
|
||||||
# Detect Debian users running the script with "sh" instead of bash
|
|
||||||
if readlink /proc/$$/exe | grep -q "dash"; then
|
|
||||||
exiterr 'This installer needs to be run with "bash", not "sh".'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Detect OpenVZ 6
|
|
||||||
if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then
|
|
||||||
exiterr "The system is running an old kernel, which is incompatible with this installer."
|
|
||||||
fi
|
|
||||||
|
|
||||||
check_os
|
check_os
|
||||||
check_os_ver
|
check_os_ver
|
||||||
|
check_tun
|
||||||
|
|
||||||
if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then
|
OVPN_CONF="/etc/openvpn/server/server.conf"
|
||||||
exiterr "The system does not have the TUN device available.
|
|
||||||
TUN needs to be enabled before running this installer."
|
|
||||||
fi
|
|
||||||
|
|
||||||
auto=0
|
auto=0
|
||||||
if [[ ! -e /etc/openvpn/server/server.conf ]]; then
|
if [[ ! -e "$OVPN_CONF" ]]; then
|
||||||
check_nftables
|
check_nftables
|
||||||
while [ "$#" -gt 0 ]; do
|
parse_args "$@"
|
||||||
case $1 in
|
|
||||||
--auto)
|
|
||||||
auto=1
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-h|--help)
|
|
||||||
show_usage
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
show_usage "Unknown parameter: $1"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
install_wget
|
install_wget
|
||||||
install_iproute
|
install_iproute
|
||||||
show_start_setup
|
show_start_setup
|
||||||
@@ -593,305 +992,26 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then
|
|||||||
confirm_setup
|
confirm_setup
|
||||||
echo
|
echo
|
||||||
echo "Installing OpenVPN, please wait..."
|
echo "Installing OpenVPN, please wait..."
|
||||||
# If running inside a container, disable LimitNPROC to prevent conflicts
|
disable_limitnproc
|
||||||
if systemd-detect-virt -cq; then
|
install_pkgs
|
||||||
mkdir /etc/systemd/system/openvpn-server@server.service.d/ 2>/dev/null
|
install_easyrsa
|
||||||
echo "[Service]
|
create_pki_and_certs
|
||||||
LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf
|
create_server_config
|
||||||
fi
|
|
||||||
if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
apt-get -yqq update || apt-get -yqq update
|
|
||||||
apt-get -yqq --no-install-recommends install openvpn >/dev/null
|
|
||||||
) || exiterr2
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
apt-get -yqq install openssl ca-certificates $firewall >/dev/null
|
|
||||||
) || exiterr2
|
|
||||||
elif [[ "$os" = "centos" ]]; then
|
|
||||||
if grep -qs "Amazon Linux release 2 " /etc/system-release; then
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
amazon-linux-extras install epel -y >/dev/null
|
|
||||||
) || exit 1
|
|
||||||
else
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
yum -y -q install epel-release >/dev/null
|
|
||||||
) || exiterr3
|
|
||||||
fi
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
yum -y -q install openvpn openssl ca-certificates tar $firewall >/dev/null 2>&1
|
|
||||||
) || exiterr3
|
|
||||||
elif [[ "$os" = "fedora" ]]; then
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
dnf install -y openvpn openssl ca-certificates tar $firewall >/dev/null
|
|
||||||
) || exiterr "'dnf install' failed."
|
|
||||||
else
|
|
||||||
# Else, OS must be openSUSE
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
zypper install -y openvpn openssl ca-certificates tar $firewall >/dev/null
|
|
||||||
) || exiterr4
|
|
||||||
fi
|
|
||||||
# If firewalld was just installed, enable it
|
|
||||||
if [[ "$firewall" == "firewalld" ]]; then
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
systemctl enable --now firewalld.service >/dev/null 2>&1
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
# Get easy-rsa
|
|
||||||
easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.2.0/EasyRSA-3.2.0.tgz'
|
|
||||||
mkdir -p /etc/openvpn/server/easy-rsa/
|
|
||||||
{ wget -t 3 -T 30 -qO- "$easy_rsa_url" 2>/dev/null || curl -m 30 -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1
|
|
||||||
if [ ! -f /etc/openvpn/server/easy-rsa/easyrsa ]; then
|
|
||||||
exiterr "Failed to download EasyRSA from $easy_rsa_url."
|
|
||||||
fi
|
|
||||||
chown -R root:root /etc/openvpn/server/easy-rsa/
|
|
||||||
cd /etc/openvpn/server/easy-rsa/ || exit 1
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
# Create the PKI, set up the CA and the server and client certificates
|
|
||||||
./easyrsa --batch init-pki >/dev/null
|
|
||||||
./easyrsa --batch build-ca nopass >/dev/null 2>&1
|
|
||||||
./easyrsa --batch --days=3650 build-server-full server nopass >/dev/null 2>&1
|
|
||||||
./easyrsa --batch --days=3650 build-client-full "$client" nopass >/dev/null 2>&1
|
|
||||||
./easyrsa --batch --days=3650 gen-crl >/dev/null 2>&1
|
|
||||||
)
|
|
||||||
# Move the stuff we need
|
|
||||||
cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/server
|
|
||||||
# CRL is read with each client connection, while OpenVPN is dropped to nobody
|
|
||||||
chown nobody:"$group_name" /etc/openvpn/server/crl.pem
|
|
||||||
# Without +x in the directory, OpenVPN can't run a stat() on the CRL file
|
|
||||||
chmod o+x /etc/openvpn/server/
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
# Generate key for tls-crypt
|
|
||||||
openvpn --genkey --secret /etc/openvpn/server/tc.key >/dev/null
|
|
||||||
)
|
|
||||||
# Create the DH parameters file using the predefined ffdhe2048 group
|
|
||||||
echo '-----BEGIN DH PARAMETERS-----
|
|
||||||
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
|
||||||
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
|
||||||
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
|
||||||
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
|
||||||
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
|
||||||
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
|
||||||
-----END DH PARAMETERS-----' > /etc/openvpn/server/dh.pem
|
|
||||||
# Generate server.conf
|
|
||||||
echo "local $ip
|
|
||||||
port $port
|
|
||||||
proto $protocol
|
|
||||||
dev tun
|
|
||||||
ca ca.crt
|
|
||||||
cert server.crt
|
|
||||||
key server.key
|
|
||||||
dh dh.pem
|
|
||||||
auth SHA256
|
|
||||||
tls-crypt tc.key
|
|
||||||
topology subnet
|
|
||||||
server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf
|
|
||||||
# IPv6
|
|
||||||
if [[ -z "$ip6" ]]; then
|
|
||||||
echo 'push "block-ipv6"' >> /etc/openvpn/server/server.conf
|
|
||||||
echo 'push "ifconfig-ipv6 fddd:1194:1194:1194::2/64 fddd:1194:1194:1194::1"' >> /etc/openvpn/server/server.conf
|
|
||||||
else
|
|
||||||
echo 'server-ipv6 fddd:1194:1194:1194::/64' >> /etc/openvpn/server/server.conf
|
|
||||||
fi
|
|
||||||
echo 'push "redirect-gateway def1 ipv6 bypass-dhcp"' >> /etc/openvpn/server/server.conf
|
|
||||||
echo 'ifconfig-pool-persist ipp.txt' >> /etc/openvpn/server/server.conf
|
|
||||||
# DNS
|
|
||||||
case "$dns" in
|
|
||||||
1)
|
|
||||||
# Locate the proper resolv.conf
|
|
||||||
# Needed for systems running systemd-resolved
|
|
||||||
if grep '^nameserver' "/etc/resolv.conf" | grep -qv '127.0.0.53' ; then
|
|
||||||
resolv_conf="/etc/resolv.conf"
|
|
||||||
else
|
|
||||||
resolv_conf="/run/systemd/resolve/resolv.conf"
|
|
||||||
fi
|
|
||||||
# Obtain the resolvers from resolv.conf and use them for OpenVPN
|
|
||||||
grep -v '^#\|^;' "$resolv_conf" | grep '^nameserver' | grep -v '127.0.0.53' | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do
|
|
||||||
echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf
|
|
||||||
done
|
|
||||||
;;
|
|
||||||
2|"")
|
|
||||||
echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server/server.conf
|
|
||||||
echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server/server.conf
|
|
||||||
;;
|
|
||||||
3)
|
|
||||||
echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server/server.conf
|
|
||||||
echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server/server.conf
|
|
||||||
;;
|
|
||||||
4)
|
|
||||||
echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server/server.conf
|
|
||||||
echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf
|
|
||||||
;;
|
|
||||||
5)
|
|
||||||
echo 'push "dhcp-option DNS 9.9.9.9"' >> /etc/openvpn/server/server.conf
|
|
||||||
echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server/server.conf
|
|
||||||
;;
|
|
||||||
6)
|
|
||||||
echo 'push "dhcp-option DNS 94.140.14.14"' >> /etc/openvpn/server/server.conf
|
|
||||||
echo 'push "dhcp-option DNS 94.140.15.15"' >> /etc/openvpn/server/server.conf
|
|
||||||
;;
|
|
||||||
7)
|
|
||||||
echo "push \"dhcp-option DNS $dns1\"" >> /etc/openvpn/server/server.conf
|
|
||||||
if [ -n "$dns2" ]; then
|
|
||||||
echo "push \"dhcp-option DNS $dns2\"" >> /etc/openvpn/server/server.conf
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo 'push "block-outside-dns"' >> /etc/openvpn/server/server.conf
|
|
||||||
echo "keepalive 10 120
|
|
||||||
cipher AES-128-GCM
|
|
||||||
user nobody
|
|
||||||
group $group_name
|
|
||||||
persist-key
|
|
||||||
persist-tun
|
|
||||||
verb 3
|
|
||||||
crl-verify crl.pem" >> /etc/openvpn/server/server.conf
|
|
||||||
if [[ "$protocol" = "udp" ]]; then
|
|
||||||
echo "explicit-exit-notify" >> /etc/openvpn/server/server.conf
|
|
||||||
fi
|
|
||||||
update_sysctl
|
update_sysctl
|
||||||
if systemctl is-active --quiet firewalld.service; then
|
create_firewall_rules
|
||||||
# Using both permanent and not permanent rules to avoid a firewalld
|
|
||||||
# reload.
|
|
||||||
# We don't use --add-service=openvpn because that would only work with
|
|
||||||
# the default port and protocol.
|
|
||||||
firewall-cmd -q --add-port="$port"/"$protocol"
|
|
||||||
firewall-cmd -q --zone=trusted --add-source=10.8.0.0/24
|
|
||||||
firewall-cmd -q --permanent --add-port="$port"/"$protocol"
|
|
||||||
firewall-cmd -q --permanent --zone=trusted --add-source=10.8.0.0/24
|
|
||||||
# Set NAT for the VPN subnet
|
|
||||||
firewall-cmd -q --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
|
||||||
firewall-cmd -q --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
|
||||||
if [[ -n "$ip6" ]]; then
|
|
||||||
firewall-cmd -q --zone=trusted --add-source=fddd:1194:1194:1194::/64
|
|
||||||
firewall-cmd -q --permanent --zone=trusted --add-source=fddd:1194:1194:1194::/64
|
|
||||||
firewall-cmd -q --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
|
||||||
firewall-cmd -q --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Create a service to set up persistent iptables rules
|
|
||||||
iptables_path=$(command -v iptables)
|
|
||||||
ip6tables_path=$(command -v ip6tables)
|
|
||||||
# nf_tables is not available as standard in OVZ kernels. So use iptables-legacy
|
|
||||||
# if we are in OVZ, with a nf_tables backend and iptables-legacy is available.
|
|
||||||
if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f "$(command -v iptables)" | grep -q "nft" && hash iptables-legacy 2>/dev/null; then
|
|
||||||
iptables_path=$(command -v iptables-legacy)
|
|
||||||
ip6tables_path=$(command -v ip6tables-legacy)
|
|
||||||
fi
|
|
||||||
echo "[Unit]
|
|
||||||
Before=network.target
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=$iptables_path -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
|
||||||
ExecStart=$iptables_path -I INPUT -p $protocol --dport $port -j ACCEPT
|
|
||||||
ExecStart=$iptables_path -I FORWARD -s 10.8.0.0/24 -j ACCEPT
|
|
||||||
ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
|
||||||
ExecStop=$iptables_path -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
|
||||||
ExecStop=$iptables_path -D INPUT -p $protocol --dport $port -j ACCEPT
|
|
||||||
ExecStop=$iptables_path -D FORWARD -s 10.8.0.0/24 -j ACCEPT
|
|
||||||
ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service
|
|
||||||
if [[ -n "$ip6" ]]; then
|
|
||||||
echo "ExecStart=$ip6tables_path -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
|
||||||
ExecStart=$ip6tables_path -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
|
|
||||||
ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
|
||||||
ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
|
||||||
ExecStop=$ip6tables_path -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
|
|
||||||
ExecStop=$ip6tables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/openvpn-iptables.service
|
|
||||||
fi
|
|
||||||
echo "RemainAfterExit=yes
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
systemctl enable --now openvpn-iptables.service >/dev/null 2>&1
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
if [ "$os" != "openSUSE" ]; then
|
if [ "$os" != "openSUSE" ]; then
|
||||||
update_rclocal
|
update_rclocal
|
||||||
fi
|
fi
|
||||||
# If SELinux is enabled and a custom port was selected, we need this
|
update_selinux
|
||||||
if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
|
|
||||||
# Install semanage if not already present
|
|
||||||
if ! hash semanage 2>/dev/null; then
|
|
||||||
if [[ "$os_version" -eq 7 ]]; then
|
|
||||||
# Centos 7
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
yum -y -q install policycoreutils-python >/dev/null
|
|
||||||
) || exiterr3
|
|
||||||
else
|
|
||||||
# CentOS 8/9 or Fedora
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
dnf install -y policycoreutils-python-utils >/dev/null
|
|
||||||
) || exiterr "'dnf install' failed."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
semanage port -a -t openvpn_port_t -p "$protocol" "$port"
|
|
||||||
fi
|
|
||||||
# If the server is behind NAT, use the correct IP address
|
# If the server is behind NAT, use the correct IP address
|
||||||
[[ -n "$public_ip" ]] && ip="$public_ip"
|
[[ -n "$public_ip" ]] && ip="$public_ip"
|
||||||
# client-common.txt is created so we have a template to add further users later
|
create_client_common
|
||||||
echo "client
|
start_openvpn_service
|
||||||
dev tun
|
|
||||||
proto $protocol
|
|
||||||
remote $ip $port
|
|
||||||
resolv-retry infinite
|
|
||||||
nobind
|
|
||||||
persist-key
|
|
||||||
persist-tun
|
|
||||||
remote-cert-tls server
|
|
||||||
auth SHA256
|
|
||||||
cipher AES-128-GCM
|
|
||||||
ignore-unknown-option block-outside-dns block-ipv6
|
|
||||||
verb 3" > /etc/openvpn/server/client-common.txt
|
|
||||||
# Enable and start the OpenVPN service
|
|
||||||
if [ "$os" != "openSUSE" ]; then
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
systemctl enable --now openvpn-server@server.service >/dev/null 2>&1
|
|
||||||
)
|
|
||||||
else
|
|
||||||
ln -s /etc/openvpn/server/* /etc/openvpn >/dev/null 2>&1
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
systemctl enable --now openvpn@server.service >/dev/null 2>&1
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
# Generates the custom client.ovpn
|
|
||||||
new_client
|
new_client
|
||||||
echo
|
finish_setup
|
||||||
echo "Finished!"
|
|
||||||
echo
|
|
||||||
echo "The client configuration is available in: $export_dir$client.ovpn"
|
|
||||||
echo "New clients can be added by running this script again."
|
|
||||||
else
|
else
|
||||||
show_header
|
show_header
|
||||||
echo
|
select_menu_option
|
||||||
echo "OpenVPN is already installed."
|
|
||||||
echo
|
|
||||||
echo "Select an option:"
|
|
||||||
echo " 1) Add a new client"
|
|
||||||
echo " 2) Export config for an existing client"
|
|
||||||
echo " 3) List existing clients"
|
|
||||||
echo " 4) Revoke an existing client"
|
|
||||||
echo " 5) Remove OpenVPN"
|
|
||||||
echo " 6) Exit"
|
|
||||||
read -rp "Option: " option
|
|
||||||
until [[ "$option" =~ ^[1-6]$ ]]; do
|
|
||||||
echo "$option: invalid selection."
|
|
||||||
read -rp "Option: " option
|
|
||||||
done
|
|
||||||
case "$option" in
|
case "$option" in
|
||||||
1)
|
1)
|
||||||
echo
|
echo
|
||||||
@@ -925,7 +1045,7 @@ else
|
|||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
echo "Select the client to export:"
|
echo "Select the client to export:"
|
||||||
tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
|
show_clients
|
||||||
read -rp "Client: " client_num
|
read -rp "Client: " client_num
|
||||||
[ -z "$client_num" ] && abort_and_exit
|
[ -z "$client_num" ] && abort_and_exit
|
||||||
until [[ "$client_num" =~ ^[0-9]+$ && "$client_num" -le "$num_of_clients" ]]; do
|
until [[ "$client_num" =~ ^[0-9]+$ && "$client_num" -le "$num_of_clients" ]]; do
|
||||||
@@ -949,7 +1069,7 @@ else
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
|
show_clients
|
||||||
if [ "$num_of_clients" = 1 ]; then
|
if [ "$num_of_clients" = 1 ]; then
|
||||||
printf '\n%s\n' "Total: 1 client"
|
printf '\n%s\n' "Total: 1 client"
|
||||||
elif [ -n "$num_of_clients" ]; then
|
elif [ -n "$num_of_clients" ]; then
|
||||||
@@ -966,7 +1086,7 @@ else
|
|||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
echo "Select the client to revoke:"
|
echo "Select the client to revoke:"
|
||||||
tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
|
show_clients
|
||||||
read -rp "Client: " client_num
|
read -rp "Client: " client_num
|
||||||
[ -z "$client_num" ] && abort_and_exit
|
[ -z "$client_num" ] && abort_and_exit
|
||||||
until [[ "$client_num" =~ ^[0-9]+$ && "$client_num" -le "$num_of_clients" ]]; do
|
until [[ "$client_num" =~ ^[0-9]+$ && "$client_num" -le "$num_of_clients" ]]; do
|
||||||
@@ -1018,31 +1138,7 @@ else
|
|||||||
if [[ "$remove" =~ ^[yY]$ ]]; then
|
if [[ "$remove" =~ ^[yY]$ ]]; then
|
||||||
echo
|
echo
|
||||||
echo "Removing OpenVPN, please wait..."
|
echo "Removing OpenVPN, please wait..."
|
||||||
port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2)
|
remove_firewall_rules
|
||||||
protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2)
|
|
||||||
if systemctl is-active --quiet firewalld.service; then
|
|
||||||
ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$')
|
|
||||||
# Using both permanent and not permanent rules to avoid a firewalld reload.
|
|
||||||
firewall-cmd -q --remove-port="$port"/"$protocol"
|
|
||||||
firewall-cmd -q --zone=trusted --remove-source=10.8.0.0/24
|
|
||||||
firewall-cmd -q --permanent --remove-port="$port"/"$protocol"
|
|
||||||
firewall-cmd -q --permanent --zone=trusted --remove-source=10.8.0.0/24
|
|
||||||
firewall-cmd -q --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
|
||||||
firewall-cmd -q --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
|
|
||||||
if grep -qs "server-ipv6" /etc/openvpn/server/server.conf; then
|
|
||||||
ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$')
|
|
||||||
firewall-cmd -q --zone=trusted --remove-source=fddd:1194:1194:1194::/64
|
|
||||||
firewall-cmd -q --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64
|
|
||||||
firewall-cmd -q --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
|
||||||
firewall-cmd -q --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
systemctl disable --now openvpn-iptables.service
|
|
||||||
rm -f /etc/systemd/system/openvpn-iptables.service
|
|
||||||
fi
|
|
||||||
if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
|
|
||||||
semanage port -d -t openvpn_port_t -p "$protocol" "$port"
|
|
||||||
fi
|
|
||||||
if [ "$os" != "openSUSE" ]; then
|
if [ "$os" != "openSUSE" ]; then
|
||||||
systemctl disable --now openvpn-server@server.service
|
systemctl disable --now openvpn-server@server.service
|
||||||
else
|
else
|
||||||
@@ -1059,27 +1155,7 @@ else
|
|||||||
if grep -qs "$ipt_cmd" /etc/rc.local; then
|
if grep -qs "$ipt_cmd" /etc/rc.local; then
|
||||||
sed --follow-symlinks -i "/^$ipt_cmd/d" /etc/rc.local
|
sed --follow-symlinks -i "/^$ipt_cmd/d" /etc/rc.local
|
||||||
fi
|
fi
|
||||||
if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
|
remove_pkgs
|
||||||
(
|
|
||||||
set -x
|
|
||||||
rm -rf /etc/openvpn/server
|
|
||||||
apt-get remove --purge -y openvpn >/dev/null
|
|
||||||
)
|
|
||||||
elif [[ "$os" = "openSUSE" ]]; then
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
zypper remove -y openvpn >/dev/null
|
|
||||||
rm -rf /etc/openvpn/server
|
|
||||||
)
|
|
||||||
rm -f /etc/openvpn/ipp.txt
|
|
||||||
else
|
|
||||||
# Else, OS must be CentOS or Fedora
|
|
||||||
(
|
|
||||||
set -x
|
|
||||||
yum -y -q remove openvpn >/dev/null
|
|
||||||
rm -rf /etc/openvpn/server
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
echo
|
echo
|
||||||
echo "OpenVPN removed!"
|
echo "OpenVPN removed!"
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user