🎉 initial codebase
This commit is contained in:
parent
6466318d8a
commit
d56054b617
8
Dockerfile
Normal file
8
Dockerfile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
FROM alpine:latest
|
||||||
|
RUN apk --update add bash openvpn iptables easy-rsa ncurses && rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
RUN ln -s /usr/share/easy-rsa/easyrsa /usr/bin/easyrsa
|
||||||
|
COPY ./entrypoint.sh /entrypoint.sh
|
||||||
|
COPY ./clientmgmt /usr/bin/clientmgmt
|
||||||
|
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
397
clientmgmt
Executable file
397
clientmgmt
Executable file
@ -0,0 +1,397 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
|
||||||
|
## CONSTANTS ##
|
||||||
|
readonly REGEX_IP_ADDRESS="^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})|(([0-9a-f]{1,4}:){7,7}[0-9a-f]{1,4}|([0-9a-f]{1,4}:){1,7}:|([0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}|([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}|([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}|([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}|([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}|[0-9a-f]{1,4}:((:[0-9a-f]{1,4}){1,6})|:((:[0-9a-f]{1,4}){1,7}|:)|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-f]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))$"
|
||||||
|
readonly DATA_DIR="/etc/openvpn-data"
|
||||||
|
readonly EASYRSA_DIR="${DATA_DIR}/easyrsa"
|
||||||
|
readonly DATA_SERVER_DIR="${DATA_DIR}/server"
|
||||||
|
readonly DATA_CLIENT_DIR="${DATA_DIR}/client"
|
||||||
|
readonly ARG_LIST=("$@")
|
||||||
|
|
||||||
|
|
||||||
|
## LIB: COLOR ##
|
||||||
|
color_bold=""
|
||||||
|
color_underline=""
|
||||||
|
color_standout=""
|
||||||
|
color_normal=""
|
||||||
|
color_black=""
|
||||||
|
color_red=""
|
||||||
|
color_green=""
|
||||||
|
color_yellow=""
|
||||||
|
color_blue=""
|
||||||
|
color_magenta=""
|
||||||
|
color_cyan=""
|
||||||
|
color_white=""
|
||||||
|
if test -t 1; then
|
||||||
|
# check count of supported colors
|
||||||
|
color_count=$(tput colors)
|
||||||
|
if [[ ! -z "$color_count" && "$color_count" -ge 8 ]]; then
|
||||||
|
color_bold="$(tput bold)"
|
||||||
|
color_underline="$(tput smul)"
|
||||||
|
color_standout="$(tput smso)"
|
||||||
|
color_normal="$(tput sgr0)"
|
||||||
|
color_black="$(tput setaf 0)"
|
||||||
|
color_red="$(tput setaf 1)"
|
||||||
|
color_green="$(tput setaf 2)"
|
||||||
|
color_yellow="$(tput setaf 3)"
|
||||||
|
color_blue="$(tput setaf 4)"
|
||||||
|
color_magenta="$(tput setaf 5)"
|
||||||
|
color_cyan="$(tput setaf 6)"
|
||||||
|
color_white="$(tput setaf 7)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
## LIB: LOG ##
|
||||||
|
log_debug(){
|
||||||
|
echo -ne "${color_green}[DEBUG]${color_normal} " 1>&2
|
||||||
|
echo "$1" 1>&2
|
||||||
|
}
|
||||||
|
log_info(){
|
||||||
|
echo -ne "${color_blue}[INFO ]${color_normal} " 1>&2
|
||||||
|
echo "$1" 1>&2
|
||||||
|
}
|
||||||
|
log_warn(){
|
||||||
|
echo -ne "${color_yellow}[WARN ]${color_normal} " 1>&2
|
||||||
|
echo "$1" 1>&2
|
||||||
|
}
|
||||||
|
log_error(){
|
||||||
|
echo -ne "${color_red}[ERROR]${color_normal} " 1>&2
|
||||||
|
echo "$1" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Explain usage of script.
|
||||||
|
#
|
||||||
|
clientmgmt_help(){
|
||||||
|
echo "Usage: $0 <command> [...args]"
|
||||||
|
echo
|
||||||
|
echo "Commands:"
|
||||||
|
echo " add [name] - Generate new client keys and output its config"
|
||||||
|
echo " list - List registered client keys"
|
||||||
|
echo " revoke [name] - Revoke a client's keys"
|
||||||
|
echo
|
||||||
|
echo " help - Display this help message and exit"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Run command `add`.
|
||||||
|
#
|
||||||
|
clientmgmt_add(){
|
||||||
|
## GET NAME ##
|
||||||
|
local exit=0
|
||||||
|
local name
|
||||||
|
name=$(clientmgmt_askname noexist) || exit=$?
|
||||||
|
[[ "$exit" -gt 0 ]] && exit 1
|
||||||
|
|
||||||
|
|
||||||
|
## GET PUBLIC IP ##
|
||||||
|
# ask whether auto-detection should be used
|
||||||
|
local answer="x"
|
||||||
|
local first=0
|
||||||
|
until [[ -z "$answer" || "$answer" =~ ^Y|y|N|n$ ]]; do
|
||||||
|
[[ "$first" -le 0 ]] && first=1 || echo "Invalid answer '$answer'"
|
||||||
|
read -ep "Auto-detect public IP-Address using icanhazip.com? [Y/n]: " answer
|
||||||
|
done
|
||||||
|
|
||||||
|
# maybe do auto-detection
|
||||||
|
local public_ip=""
|
||||||
|
if [[ ! "$answer" =~ ^N|n$ ]]; then
|
||||||
|
local exit=0
|
||||||
|
local icanhazip
|
||||||
|
icanhazip=$(wget -O - -q icanhazip.com) || exit=$?
|
||||||
|
|
||||||
|
if [[ "$exit" -le 0 && "$icanhazip" =~ $REGEX_IP_ADDRESS ]]; then
|
||||||
|
public_ip="$icanhazip"
|
||||||
|
log_info "Found public IP-Address: '$public_ip'"
|
||||||
|
|
||||||
|
else
|
||||||
|
log_warn "Failed to auto-detect public IP-Address"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# use ask as fallback
|
||||||
|
local first=0
|
||||||
|
until [[ "$public_ip" =~ $REGEX_IP_ADDRESS ]]; do
|
||||||
|
[[ "$first" -le 0 ]] && first=1 || echo "Invalid IP-Address '$public_ip'"
|
||||||
|
read -ep "Public IP-Address: " public_ip
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
## AUTO-DETECT PROTO AND PORT ##
|
||||||
|
local proto
|
||||||
|
local port
|
||||||
|
|
||||||
|
# stream server config
|
||||||
|
while IFS= read -r line; do
|
||||||
|
# trim whitespaces
|
||||||
|
line=$(echo "$line" | sed -E "s/^\s*//g" | sed -E "s/\s*$//g")
|
||||||
|
|
||||||
|
# ignore blank lines and comments
|
||||||
|
[[ "$line" == "" || "$line" =~ ^# ]] && continue
|
||||||
|
|
||||||
|
# match proto
|
||||||
|
if [[ "$line" =~ ^proto[[:blank:]] ]]; then
|
||||||
|
if [[ ! "$line" =~ ^proto[[:blank:]]+(tcp|udp)$ ]]; then
|
||||||
|
log_warn "Unexpected config line format for key 'proto': '$line'"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
proto=$(echo "$line" | sed -E "s/^proto[[:blank:]]+(tcp|udp)$/\1/g")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# match port
|
||||||
|
if [[ "$line" =~ ^port[[:blank:]] ]]; then
|
||||||
|
if [[ ! "$line" =~ ^port[[:blank:]]+([0-9]+)$ ]]; then
|
||||||
|
log_warn "Unexpected config line format for key 'port': '$line'"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
local parsed_port=$(echo "$line" | sed -E "s/^port[[:blank:]]+([0-9]+)$/\1/g")
|
||||||
|
if [[ "$parsed_port" -le 0 || "$parsed_port" -gt 65535 ]]; then
|
||||||
|
log_warn "Configured port number out of range: '$parsed_port'"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
port="$parsed_port"
|
||||||
|
fi
|
||||||
|
done < "${DATA_SERVER_DIR}/server.conf"
|
||||||
|
|
||||||
|
# validate
|
||||||
|
if [[ -z "${proto:+x}" ]]; then
|
||||||
|
proto="udp"
|
||||||
|
log_warn "Unable to auto-detect proto from server config file; using fallback: '$proto'"
|
||||||
|
fi
|
||||||
|
if [[ -z "${port:+x}" ]]; then
|
||||||
|
port="1194"
|
||||||
|
log_warn "Unable to auto-detect port from server config file; using fallback: '$port'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
## GENERATE CLIENT KEYS ##
|
||||||
|
local prev_pwd="$PWD" && cd "$EASYRSA_DIR"
|
||||||
|
log_info "Generating client keys"
|
||||||
|
/usr/bin/easyrsa --batch --days=7300 build-client-full "$name" nopass
|
||||||
|
cd "$prev_pwd"
|
||||||
|
|
||||||
|
|
||||||
|
## BUILD CLIENT CONFIG ##
|
||||||
|
# header
|
||||||
|
echo
|
||||||
|
echo -e "${color_magenta}Client Config (${name}.ovpn):${color_normal}"
|
||||||
|
echo -e "${color_magenta}----------------------------------------------------------------${color_normal}"
|
||||||
|
|
||||||
|
# static content
|
||||||
|
echo "client
|
||||||
|
dev tun
|
||||||
|
proto $proto
|
||||||
|
remote $public_ip $port
|
||||||
|
resolv-retry infinite
|
||||||
|
nobind
|
||||||
|
persist-key
|
||||||
|
persist-tun
|
||||||
|
remote-cert-tls server
|
||||||
|
auth SHA512
|
||||||
|
ignore-unknown-option block-outside-dns
|
||||||
|
verb 3"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# ca cert
|
||||||
|
echo "<ca>"
|
||||||
|
cat "${EASYRSA_DIR}/pki/ca.crt"
|
||||||
|
echo "</ca>"
|
||||||
|
|
||||||
|
# client cert
|
||||||
|
echo "<cert>"
|
||||||
|
sed -ne '/BEGIN CERTIFICATE/,$ p' "${EASYRSA_DIR}/pki/issued/${name}.crt"
|
||||||
|
echo "</cert>"
|
||||||
|
|
||||||
|
# client key
|
||||||
|
echo "<key>"
|
||||||
|
cat "${EASYRSA_DIR}/pki/private/${name}.key"
|
||||||
|
echo "</key>"
|
||||||
|
|
||||||
|
# tls-crypt key
|
||||||
|
echo "<tls-crypt>"
|
||||||
|
sed -ne '/BEGIN OpenVPN Static key/,$ p' "${DATA_SERVER_DIR}/tls-crypt.key"
|
||||||
|
echo "</tls-crypt>"
|
||||||
|
|
||||||
|
# footer
|
||||||
|
echo -e "${color_magenta}----------------------------------------------------------------${color_normal}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Run command `revoke`.
|
||||||
|
#
|
||||||
|
clientmgmt_revoke(){
|
||||||
|
## GET NAME ##
|
||||||
|
local exit=0
|
||||||
|
local name
|
||||||
|
name=$(clientmgmt_askname exist) || exit=$?
|
||||||
|
[[ "$exit" -gt 0 ]] && exit 1
|
||||||
|
|
||||||
|
|
||||||
|
## REVOKE CLIENT KEYS ##
|
||||||
|
local prev_pwd="$PWD" && cd "$EASYRSA_DIR"
|
||||||
|
log_info "Revoking client keys"
|
||||||
|
|
||||||
|
# revoke keys
|
||||||
|
/usr/bin/easyrsa --batch revoke "$name"
|
||||||
|
|
||||||
|
# update revoke list
|
||||||
|
/usr/bin/easyrsa --batch --days=7300 gen-crl
|
||||||
|
chown nobody:nobody pki/crl.pem
|
||||||
|
|
||||||
|
# restore pwd
|
||||||
|
cd "$prev_pwd"
|
||||||
|
|
||||||
|
# print info
|
||||||
|
log_info "Client revoked: '$name'"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Run command `list`.
|
||||||
|
#
|
||||||
|
clientmgmt_list(){
|
||||||
|
## GET LIST ##
|
||||||
|
list=$(clientmgmt_clientlist)
|
||||||
|
|
||||||
|
|
||||||
|
## PRINT ##
|
||||||
|
# warn if there are no clients
|
||||||
|
if [[ "$list" == "" ]]; then
|
||||||
|
log_warn "No clients registered"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# list
|
||||||
|
echo "Clients:"
|
||||||
|
for one_client_name in $list; do
|
||||||
|
echo " $one_client_name"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# HELPER: Parse name parameter or ask if not provided.
|
||||||
|
#
|
||||||
|
# @param $1 noexist: Expect this name to be unused
|
||||||
|
# exist: Expect this name to exist already.
|
||||||
|
#
|
||||||
|
# @return Name entered.
|
||||||
|
# @exit 0: Returned name is valid
|
||||||
|
# 1: Returned name is invalid.
|
||||||
|
#
|
||||||
|
clientmgmt_askname(){
|
||||||
|
## ASK ##
|
||||||
|
local answer=""
|
||||||
|
local first=0
|
||||||
|
if [[ "${ARG_LIST[1]:+x}" ]]; then
|
||||||
|
answer="${ARG_LIST[1]}"
|
||||||
|
first=1
|
||||||
|
fi
|
||||||
|
until [[ "$answer" =~ ^[abcdefghijklmnopqrstuvwxyz0123456789-]{2,64}$ ]]; do
|
||||||
|
[[ "$first" -le 0 ]] && first=1 || echo "Invalid client name '$answer'" 1>&2
|
||||||
|
read -ep "Client name: " answer
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
## VALIDATE ##
|
||||||
|
# check for reserved names
|
||||||
|
if [[ "$answer" =~ ^ca|server$ ]]; then
|
||||||
|
log_error "Name is reserved for internal use: '$answer'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# make sure name is exists or does not exist
|
||||||
|
case "$1" in
|
||||||
|
noexist)
|
||||||
|
if [[ -f "${EASYRSA_DIR}/pki/issued/${answer}.crt" ]]; then
|
||||||
|
log_error "Name already in use: '$answer'"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
exist)
|
||||||
|
if [[ ! -f "${EASYRSA_DIR}/pki/issued/${answer}.crt" ]]; then
|
||||||
|
log_error "Client does not exist: '$answer'"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
*) log_error "Unknown exist goal: '$1'";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
## RETURN ##
|
||||||
|
echo -n "$answer"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# GETTER: Get list of registered client names.
|
||||||
|
#
|
||||||
|
# @return Space separated list of registered client names.
|
||||||
|
#
|
||||||
|
clientmgmt_clientlist(){
|
||||||
|
## GET LIST ##
|
||||||
|
# get from directory
|
||||||
|
local rawlist=$(echo -n ${EASYRSA_DIR}/pki/issued/*.crt)
|
||||||
|
|
||||||
|
# build list
|
||||||
|
local list=""
|
||||||
|
for one_cert in $rawlist; do
|
||||||
|
filename=$(basename $one_cert)
|
||||||
|
[[ "$filename" == "server.crt" ]] && continue
|
||||||
|
list="$list $(echo ${filename} | sed -E 's/\.crt$//g')"
|
||||||
|
done
|
||||||
|
list="$(echo $list | xargs)"
|
||||||
|
|
||||||
|
|
||||||
|
## RETURN ##
|
||||||
|
echo -n "$list"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## MAIN ##
|
||||||
|
case ${1:-""} in
|
||||||
|
add)
|
||||||
|
clientmgmt_add
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
list)
|
||||||
|
clientmgmt_list
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
revoke)
|
||||||
|
clientmgmt_revoke
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
help)
|
||||||
|
clientmgmt_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
"")
|
||||||
|
log_error "No command given; See '$0 help' for usage information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
log_error "Invalid command '$1'; See '$0 help' for usage information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
204
entrypoint.sh
Executable file
204
entrypoint.sh
Executable file
@ -0,0 +1,204 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
|
||||||
|
## CONSTANTS ##
|
||||||
|
readonly DATA_DIR="/etc/openvpn-data"
|
||||||
|
readonly EASYRSA_DIR="${DATA_DIR}/easyrsa"
|
||||||
|
readonly DATA_SERVER_DIR="${DATA_DIR}/server"
|
||||||
|
readonly DATA_CLIENT_DIR="${DATA_DIR}/client"
|
||||||
|
|
||||||
|
|
||||||
|
## HANDLE EXIT SIGNALS ##
|
||||||
|
trap trap_exit EXIT SIGINT SIGTERM
|
||||||
|
trap_exit(){
|
||||||
|
if [[ "${openvpn_pid:+x}" ]]; then
|
||||||
|
kill -- $openvpn_pid 2> /dev/null || true
|
||||||
|
q=0
|
||||||
|
while proc_running $openvpn_pid; do
|
||||||
|
q=$(( q + 1 ))
|
||||||
|
snore 1
|
||||||
|
if [[ "$q" -ge 15 ]]; then
|
||||||
|
log_warn "Sending kill to OpenVPN"
|
||||||
|
kill -s KILL -- $openvpn_pid 2> /dev/null || true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# LIB: Efficient sleep (does not create a new process).
|
||||||
|
#
|
||||||
|
snore(){
|
||||||
|
local IFS
|
||||||
|
[[ -n "${_snore_fd:-}" ]] || exec {_snore_fd}<> <(:)
|
||||||
|
read ${1:+-t "$1"} -u $_snore_fd || true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# HELPER: Check whether given pid is running.
|
||||||
|
#
|
||||||
|
# @param $1 Process ID.
|
||||||
|
#
|
||||||
|
# @exit 0: Process is running
|
||||||
|
# 1: Process is not running.
|
||||||
|
#
|
||||||
|
proc_running(){
|
||||||
|
# try reading state
|
||||||
|
local state_path="/proc/$1/stat"
|
||||||
|
[[ ! -f "$state_path" ]] && return 1
|
||||||
|
local state=$(cat "$state_path" | cut -d ' ' -f3)
|
||||||
|
|
||||||
|
# parse state
|
||||||
|
case "$state" in
|
||||||
|
R|S|D|Z|W|W|P|I) return 0;;
|
||||||
|
*) return 1;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# HELPER: Initialize iptables rules.
|
||||||
|
#
|
||||||
|
iptables_init(){
|
||||||
|
/sbin/iptables -t nat -I POSTROUTING -s 192.168.35.0/24 ! -d 192.168.35.0/24 -j MASQUERADE
|
||||||
|
/sbin/iptables -I INPUT -i tun0 -j ACCEPT
|
||||||
|
/sbin/iptables -I INPUT -p udp --dport 1194 -j ACCEPT
|
||||||
|
/sbin/iptables -I INPUT -p tcp --dport 1194 -j ACCEPT
|
||||||
|
/sbin/iptables -I FORWARD -s 192.168.35.0/24 -j ACCEPT
|
||||||
|
/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# HELPER: Set up easyrsa.
|
||||||
|
#
|
||||||
|
easyrsa_init(){
|
||||||
|
## MAYBE CREATE VARS FILE ##
|
||||||
|
if [[ ! -f "${EASYRSA_DIR}/vars" ]]; then
|
||||||
|
touch "${EASYRSA_DIR}/vars"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# HELPER: Set up server keys.
|
||||||
|
#
|
||||||
|
easyrsa_server_keys_create(){
|
||||||
|
## IGNORE IF EXISTING ##
|
||||||
|
[[ -d "${EASYRSA_DIR}/pki" ]] && return 0
|
||||||
|
|
||||||
|
|
||||||
|
## SET UP CA AND SERVER KEYS (EASYRSA) ##
|
||||||
|
local prev_pwd="$PWD" && cd "$EASYRSA_DIR"
|
||||||
|
|
||||||
|
# new pki
|
||||||
|
/usr/bin/easyrsa --batch init-pki
|
||||||
|
|
||||||
|
# create ca
|
||||||
|
/usr/bin/easyrsa --batch --days=7300 build-ca nopass
|
||||||
|
|
||||||
|
# generate server keys
|
||||||
|
/usr/bin/easyrsa --batch --days=7300 build-server-full server nopass
|
||||||
|
|
||||||
|
# generate crl
|
||||||
|
/usr/bin/easyrsa --batch --days=7300 gen-crl
|
||||||
|
chown nobody:nobody pki/crl.pem
|
||||||
|
|
||||||
|
# restore pwd
|
||||||
|
cd "$prev_pwd"
|
||||||
|
|
||||||
|
# create symlinks
|
||||||
|
ln -s ${EASYRSA_DIR}/pki/{ca.crt,private/ca.key,issued/server.crt,private/server.key,crl.pem} "${DATA_SERVER_DIR}"
|
||||||
|
|
||||||
|
|
||||||
|
## OTHER KEYS ##
|
||||||
|
# dh parameters
|
||||||
|
openssl dhparam -out "${DATA_SERVER_DIR}/dh2048.pem" 2048
|
||||||
|
|
||||||
|
# tls-crypt key
|
||||||
|
openvpn --genkey secret "${DATA_SERVER_DIR}/tls-crypt.key"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# HELPER: Set up openvpn server config file.
|
||||||
|
#
|
||||||
|
openvpn_config_init(){
|
||||||
|
## IGNORE IF EXISTING ##
|
||||||
|
[[ -f "${DATA_SERVER_DIR}/server.conf" ]] && return 0
|
||||||
|
|
||||||
|
|
||||||
|
## WRITE SERVER CONFIG ##
|
||||||
|
echo "port 1194
|
||||||
|
proto udp
|
||||||
|
server 192.168.35.0 255.255.255.0
|
||||||
|
dev tun
|
||||||
|
user nobody
|
||||||
|
group nogroup
|
||||||
|
topology subnet
|
||||||
|
|
||||||
|
ca ca.crt
|
||||||
|
cert server.crt
|
||||||
|
key server.key
|
||||||
|
dh dh2048.pem
|
||||||
|
crl-verify crl.pem
|
||||||
|
tls-crypt tls-crypt.key
|
||||||
|
auth SHA512
|
||||||
|
|
||||||
|
client-config-dir ${DATA_CLIENT_DIR}
|
||||||
|
ifconfig-pool-persist ipp.txt
|
||||||
|
keepalive 600 720
|
||||||
|
persist-key
|
||||||
|
persist-tun
|
||||||
|
|
||||||
|
push \"dhcp-option DNS 1.1.1.1\"
|
||||||
|
push \"dhcp-option DNS 1.0.0.1\"
|
||||||
|
push \"redirect-gateway def1 bypass-dhcp\"
|
||||||
|
push \"block-outside-dns\"
|
||||||
|
|
||||||
|
verb 3" > "${DATA_SERVER_DIR}/server.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## SET UP USED DIRECTORIES ##
|
||||||
|
mkdir -p "$DATA_DIR"
|
||||||
|
mkdir -p "$EASYRSA_DIR"
|
||||||
|
mkdir -p "$DATA_SERVER_DIR"
|
||||||
|
mkdir -p "$DATA_CLIENT_DIR"
|
||||||
|
|
||||||
|
|
||||||
|
## SET UP TUN DEVICE ##
|
||||||
|
mkdir -p /dev/net
|
||||||
|
[[ ! -c /dev/net/tun ]] && mknod /dev/net/tun c 10 200
|
||||||
|
|
||||||
|
|
||||||
|
## SET UP FW AND ROUTING ##
|
||||||
|
iptables_init
|
||||||
|
|
||||||
|
|
||||||
|
## INITIALIZE CONFIG ##
|
||||||
|
# set up easyrsa
|
||||||
|
easyrsa_init
|
||||||
|
|
||||||
|
# server keys
|
||||||
|
easyrsa_server_keys_create
|
||||||
|
|
||||||
|
# server config
|
||||||
|
openvpn_config_init
|
||||||
|
|
||||||
|
|
||||||
|
## RUN OPENVPN SERVER ##
|
||||||
|
/usr/sbin/openvpn --cd "${DATA_SERVER_DIR}" --config "${DATA_SERVER_DIR}/server.conf" & openvpn_pid=$!
|
||||||
|
wait $openvpn_pid
|
Loading…
Reference in New Issue
Block a user