2022-11-03 15:25:58 +00:00
|
|
|
#!/bin/bash -e
|
|
|
|
|
|
2022-11-06 18:41:26 +00:00
|
|
|
APP=$(basename $0)
|
|
|
|
|
LOCKFILE="/tmp/$APP.lock"
|
|
|
|
|
|
2022-11-03 15:25:58 +00:00
|
|
|
trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT
|
2022-11-06 18:41:26 +00:00
|
|
|
if ! ln -s $APP $LOCKFILE 2>/dev/null; then
|
2022-11-08 10:16:45 +00:00
|
|
|
echo "ERROR: script LOCKED" >&2
|
2022-11-03 15:25:58 +00:00
|
|
|
exit 15
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
function usage {
|
|
|
|
|
echo "Usage: $0 [<options>] [command [arg]]"
|
|
|
|
|
echo "Options:"
|
|
|
|
|
echo " -i : Init (Create server keys and configs)"
|
|
|
|
|
echo " -c : Create new user"
|
|
|
|
|
echo " -d : Delete user"
|
2022-11-07 16:22:35 +00:00
|
|
|
echo " -L : Lock user"
|
|
|
|
|
echo " -U : Unlock user"
|
2022-11-03 15:25:58 +00:00
|
|
|
echo " -p : Print user config"
|
2024-04-24 22:54:31 +00:00
|
|
|
echo " -q : Print user QR code"
|
2022-11-03 15:25:58 +00:00
|
|
|
echo " -u <user> : User identifier (uniq field for vpn account)"
|
|
|
|
|
echo " -s <server> : Server host for user connection"
|
2022-12-08 11:14:13 +00:00
|
|
|
echo " -I : Interface (default auto)"
|
2022-11-03 15:25:58 +00:00
|
|
|
echo " -h : Usage"
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unset USER
|
|
|
|
|
umask 0077
|
|
|
|
|
|
2024-02-12 05:48:19 +00:00
|
|
|
HOME_DIR="/etc/amnezia/amneziawg"
|
|
|
|
|
SERVER_NAME="awg0"
|
2024-02-24 13:35:30 +00:00
|
|
|
SERVER_IP_PREFIX="10.20.30"
|
2022-08-31 15:36:12 +00:00
|
|
|
SERVER_PORT=39547
|
2022-12-13 19:05:13 +00:00
|
|
|
SERVER_INTERFACE=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)
|
2022-08-31 15:36:12 +00:00
|
|
|
|
|
|
|
|
while getopts ":icdpqhLUu:I:s:" opt; do
|
2022-11-03 15:25:58 +00:00
|
|
|
case $opt in
|
|
|
|
|
i) INIT=1 ;;
|
|
|
|
|
c) CREATE=1 ;;
|
|
|
|
|
d) DELETE=1 ;;
|
2022-11-07 16:22:35 +00:00
|
|
|
L) LOCK=1 ;;
|
|
|
|
|
U) UNLOCK=1 ;;
|
2022-11-03 15:25:58 +00:00
|
|
|
p) PRINT_USER_CONFIG=1 ;;
|
2024-04-24 22:54:31 +00:00
|
|
|
q) PRINT_QR_CODE=1 ;;
|
2022-11-03 15:25:58 +00:00
|
|
|
u) USER="$OPTARG" ;;
|
2022-08-31 15:36:12 +00:00
|
|
|
I) SERVER_INTERFACE="$OPTARG" ;;
|
2022-11-03 15:25:58 +00:00
|
|
|
h) usage ;;
|
|
|
|
|
s) SERVER_ENDPOINT="$OPTARG" ;;
|
|
|
|
|
\?) echo "Invalid option: -$OPTARG" ; exit 1 ;;
|
|
|
|
|
:) echo "Option -$OPTARG requires an argument" ; exit 1 ;;
|
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
[ $# -lt 1 ] && usage
|
|
|
|
|
|
|
|
|
|
function reload_server {
|
2024-02-12 05:48:19 +00:00
|
|
|
awg syncconf ${SERVER_NAME} <(awg-quick strip ${SERVER_NAME})
|
2022-11-03 15:25:58 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-07 16:22:35 +00:00
|
|
|
function get_new_ip {
|
2023-03-01 16:37:39 +00:00
|
|
|
declare -A IP_EXISTS
|
|
|
|
|
|
|
|
|
|
for IP in $(grep -i 'Address\s*=\s*' keys/*/*.conf | sed 's/\/[0-9]\+$//' | grep -Po '\d+$')
|
|
|
|
|
do
|
|
|
|
|
IP_EXISTS[$IP]=1
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
for IP in {2..255}
|
|
|
|
|
do
|
|
|
|
|
[ ${IP_EXISTS[$IP]} ] || break
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
if [ $IP -eq 255 ]; then
|
2022-11-08 10:16:45 +00:00
|
|
|
echo "ERROR: can't determine new address" >&2
|
2022-11-07 16:22:35 +00:00
|
|
|
exit 3
|
|
|
|
|
fi
|
|
|
|
|
|
2023-03-01 16:37:39 +00:00
|
|
|
echo "${SERVER_IP_PREFIX}.${IP}/32"
|
2022-11-07 16:22:35 +00:00
|
|
|
}
|
|
|
|
|
|
2024-04-24 22:54:31 +00:00
|
|
|
function encode {
|
|
|
|
|
python3 encode.py ${USER} > keys/${USER}/${USER}.vpn
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-11-07 16:22:35 +00:00
|
|
|
function add_user_to_server {
|
|
|
|
|
if [ ! -f "keys/${USER}/public.key" ]; then
|
2022-11-08 10:16:45 +00:00
|
|
|
echo "ERROR: User not exists" >&2
|
2022-11-07 16:22:35 +00:00
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
local USER_PUB_KEY=$(cat "keys/${USER}/public.key")
|
2024-05-01 21:03:34 +00:00
|
|
|
local USER_PSK_KEY=$(cat "keys/$USER/psk.key")
|
2022-11-09 14:01:42 +00:00
|
|
|
local USER_IP=$(grep -i Address "keys/${USER}/${USER}.conf" | sed 's/Address\s*=\s*//i; s/\/.*//')
|
2022-11-07 16:22:35 +00:00
|
|
|
|
2022-11-30 08:57:55 +00:00
|
|
|
if grep "# BEGIN ${USER}$" "$SERVER_NAME.conf" >/dev/null ; then
|
2022-11-07 16:22:35 +00:00
|
|
|
echo "User already exists"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
2022-11-30 08:57:55 +00:00
|
|
|
cat <<EOF >> "$SERVER_NAME.conf"
|
2022-11-07 16:22:35 +00:00
|
|
|
# BEGIN ${USER}
|
|
|
|
|
[Peer]
|
|
|
|
|
PublicKey = ${USER_PUB_KEY}
|
|
|
|
|
AllowedIPs = ${USER_IP}
|
2024-02-16 16:29:05 +00:00
|
|
|
PresharedKey = ${USER_PSK_KEY}
|
2022-11-07 16:22:35 +00:00
|
|
|
# END ${USER}
|
|
|
|
|
EOF
|
2022-11-09 14:40:53 +00:00
|
|
|
|
2022-11-09 15:00:36 +00:00
|
|
|
ip -4 route add ${USER_IP}/32 dev ${SERVER_NAME} || true
|
2022-11-07 16:22:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function remove_user_from_server {
|
2022-11-30 08:57:55 +00:00
|
|
|
sed -i "/# BEGIN ${USER}$/,/# END ${USER}$/d" "$SERVER_NAME.conf"
|
|
|
|
|
if [ -f "keys/${USER}/${USER}.conf" ]; then
|
2022-11-30 08:52:21 +00:00
|
|
|
local USER_IP=$(grep -i Address "keys/${USER}/${USER}.conf" | sed 's/Address\s*=\s*//i; s/\/.*//')
|
|
|
|
|
ip -4 route del ${USER_IP}/32 dev ${SERVER_NAME} || true
|
|
|
|
|
fi
|
2022-11-07 16:22:35 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-03 15:25:58 +00:00
|
|
|
function init {
|
|
|
|
|
if [ -z "$SERVER_ENDPOINT" ]; then
|
2022-11-08 10:16:45 +00:00
|
|
|
echo "ERROR: Server required" >&2
|
2022-11-03 15:25:58 +00:00
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2022-12-13 18:44:19 +00:00
|
|
|
if [ -z "$SERVER_INTERFACE" ]; then
|
|
|
|
|
echo "ERROR: Can't determine server interface" >&2
|
|
|
|
|
echo "DEBUG: 'ip route':"
|
|
|
|
|
ip route
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2022-12-08 11:14:13 +00:00
|
|
|
echo "Interface: $SERVER_INTERFACE"
|
|
|
|
|
|
2022-11-30 08:57:55 +00:00
|
|
|
mkdir -p "keys/${SERVER_NAME}"
|
2022-11-04 08:54:20 +00:00
|
|
|
echo -n "$SERVER_ENDPOINT" > "keys/.server"
|
|
|
|
|
|
2022-08-31 15:36:12 +00:00
|
|
|
if [ ! -f "keys/${SERVER_NAME}/private.key" ]; then
|
2024-02-12 05:48:19 +00:00
|
|
|
awg genkey | tee "keys/${SERVER_NAME}/private.key" | awg pubkey > "keys/${SERVER_NAME}/public.key"
|
2022-11-03 15:25:58 +00:00
|
|
|
fi
|
|
|
|
|
|
2023-03-01 16:38:22 +00:00
|
|
|
if [ -f "$SERVER_NAME.conf" ]; then
|
|
|
|
|
echo "Server already initialized"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
2022-11-03 15:25:58 +00:00
|
|
|
SERVER_PVT_KEY=$(cat "keys/$SERVER_NAME/private.key")
|
|
|
|
|
|
2022-11-30 08:57:55 +00:00
|
|
|
cat <<EOF > "$SERVER_NAME.conf"
|
2022-11-03 15:25:58 +00:00
|
|
|
[Interface]
|
|
|
|
|
Address = ${SERVER_IP_PREFIX}.1/32
|
|
|
|
|
ListenPort = ${SERVER_PORT}
|
|
|
|
|
PrivateKey = ${SERVER_PVT_KEY}
|
2024-02-16 16:56:25 +00:00
|
|
|
PostUp = iptables -A INPUT -i ${SERVER_NAME} -j ACCEPT; iptables -A FORWARD -i ${SERVER_NAME} -j ACCEPT; iptables -A OUTPUT -o ${SERVER_NAME} -j ACCEPT; iptables -A FORWARD -i ${SERVER_NAME} -o ${SERVER_INTERFACE} -s ${SERVER_IP_PREFIX}.0/24 -j ACCEPT; iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT; iptables -t nat -A POSTROUTING -s ${SERVER_IP_PREFIX}.0/24 -o ${SERVER_INTERFACE} -j MASQUERADE
|
|
|
|
|
PostDown = iptables -D INPUT -i ${SERVER_NAME} -j ACCEPT; iptables -D FORWARD -i ${SERVER_NAME} -j ACCEPT; iptables -D OUTPUT -o ${SERVER_NAME} -j ACCEPT; iptables -D FORWARD -i ${SERVER_NAME} -o ${SERVER_INTERFACE} -s ${SERVER_IP_PREFIX}.0/24 -j ACCEPT; iptables -D FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT; iptables -t nat -D POSTROUTING -s ${SERVER_IP_PREFIX}.0/24 -o ${SERVER_INTERFACE} -j MASQUERADE
|
2024-02-25 21:01:57 +00:00
|
|
|
Jc = 7
|
2024-02-12 05:48:19 +00:00
|
|
|
Jmin = 50
|
|
|
|
|
Jmax = 1000
|
2024-02-25 21:01:57 +00:00
|
|
|
S1 = 116
|
|
|
|
|
S2 = 61
|
|
|
|
|
H1 = 1139437039
|
|
|
|
|
H2 = 1088834137
|
|
|
|
|
H3 = 977318325
|
|
|
|
|
H4 = 1583407056
|
2022-11-03 15:25:58 +00:00
|
|
|
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
|
|
|
|
|
sysctl -p
|
|
|
|
|
|
2024-02-12 05:48:19 +00:00
|
|
|
systemctl enable awg-quick@${SERVER_NAME}
|
|
|
|
|
awg-quick up ${SERVER_NAME} || true
|
2022-11-03 15:25:58 +00:00
|
|
|
|
|
|
|
|
echo "Server initialized successfully"
|
|
|
|
|
exit 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function create {
|
2022-11-30 08:57:55 +00:00
|
|
|
if [ -f "keys/${USER}/${USER}.conf" ]; then
|
2023-01-24 17:39:49 +00:00
|
|
|
echo "WARNING: key ${USER}.conf already exists" >&2
|
|
|
|
|
return 0
|
2022-11-03 15:25:58 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
SERVER_ENDPOINT=$(cat "keys/.server")
|
2022-11-07 16:22:35 +00:00
|
|
|
USER_IP=$( get_new_ip )
|
2022-11-03 15:25:58 +00:00
|
|
|
|
|
|
|
|
mkdir "keys/${USER}"
|
2024-02-16 16:29:05 +00:00
|
|
|
awg genkey | tee "keys/${USER}/private.key" | awg pubkey > "keys/${USER}/public.key" | awg genpsk > "keys/${USER}/psk.key"
|
2022-11-03 15:25:58 +00:00
|
|
|
|
|
|
|
|
USER_PVT_KEY=$(cat "keys/${USER}/private.key")
|
|
|
|
|
USER_PUB_KEY=$(cat "keys/${USER}/public.key")
|
2024-02-16 16:29:05 +00:00
|
|
|
USER_PSK_KEY=$(cat "keys/${USER}/psk.key")
|
2022-11-03 15:25:58 +00:00
|
|
|
SERVER_PUB_KEY=$(cat "keys/$SERVER_NAME/public.key")
|
|
|
|
|
|
2022-11-30 08:57:55 +00:00
|
|
|
cat <<EOF > "keys/${USER}/${USER}.conf"
|
2022-11-03 15:25:58 +00:00
|
|
|
[Interface]
|
|
|
|
|
PrivateKey = ${USER_PVT_KEY}
|
2024-02-15 13:09:53 +00:00
|
|
|
Address = ${USER_IP}
|
2024-02-25 21:01:57 +00:00
|
|
|
Jc = 7
|
2024-02-12 05:48:19 +00:00
|
|
|
Jmin = 50
|
|
|
|
|
Jmax = 1000
|
2024-02-25 21:01:57 +00:00
|
|
|
S1 = 116
|
|
|
|
|
S2 = 61
|
|
|
|
|
H1 = 1139437039
|
|
|
|
|
H2 = 1088834137
|
|
|
|
|
H3 = 977318325
|
|
|
|
|
H4 = 1583407056
|
2022-11-03 15:25:58 +00:00
|
|
|
|
|
|
|
|
[Peer]
|
|
|
|
|
PublicKey = ${SERVER_PUB_KEY}
|
|
|
|
|
Endpoint = ${SERVER_ENDPOINT}:${SERVER_PORT}
|
|
|
|
|
AllowedIPs = 0.0.0.0/0
|
2024-02-15 13:09:53 +00:00
|
|
|
PersistentKeepalive = 20
|
2024-02-16 16:29:05 +00:00
|
|
|
PresharedKey = ${USER_PSK_KEY}
|
2022-11-03 15:25:58 +00:00
|
|
|
EOF
|
2024-04-24 22:54:31 +00:00
|
|
|
encode
|
2022-11-07 16:26:19 +00:00
|
|
|
add_user_to_server
|
2022-11-03 15:25:58 +00:00
|
|
|
reload_server
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cd $HOME_DIR
|
|
|
|
|
|
|
|
|
|
if [ $INIT ]; then
|
|
|
|
|
init
|
|
|
|
|
exit 0;
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ ! -f "keys/$SERVER_NAME/public.key" ]; then
|
2022-11-08 10:16:45 +00:00
|
|
|
echo "ERROR: Run init script before" >&2
|
2022-11-03 15:25:58 +00:00
|
|
|
exit 2
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ -z "${USER}" ]; then
|
2022-11-08 10:16:45 +00:00
|
|
|
echo "ERROR: User required" >&2
|
2022-11-03 15:25:58 +00:00
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ $CREATE ]; then
|
|
|
|
|
create
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ $DELETE ]; then
|
2022-11-07 16:26:19 +00:00
|
|
|
remove_user_from_server
|
2022-11-07 16:22:35 +00:00
|
|
|
reload_server
|
2022-11-30 09:20:54 +00:00
|
|
|
rm -rf "keys/${USER}"
|
2022-11-07 16:22:35 +00:00
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ $LOCK ]; then
|
2022-11-07 16:26:19 +00:00
|
|
|
remove_user_from_server
|
2022-11-07 16:22:35 +00:00
|
|
|
reload_server
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ $UNLOCK ]; then
|
2022-11-07 16:26:19 +00:00
|
|
|
add_user_to_server
|
2022-11-03 15:25:58 +00:00
|
|
|
reload_server
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ $PRINT_USER_CONFIG ]; then
|
2022-11-30 08:57:55 +00:00
|
|
|
cat "keys/${USER}/${USER}.conf"
|
2024-04-24 22:54:31 +00:00
|
|
|
elif [ $PRINT_QR_CODE ]; then
|
|
|
|
|
qrencode -t ansiutf8 < "keys/${USER}/${USER}.vpn"
|
2022-11-03 15:25:58 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
exit 0
|