Skip to content

Instantly share code, notes, and snippets.

@aenniw
Last active May 9, 2022 08:23
Show Gist options
  • Select an option

  • Save aenniw/5dc67bd1fca572335a9ca77618dc20c4 to your computer and use it in GitHub Desktop.

Select an option

Save aenniw/5dc67bd1fca572335a9ca77618dc20c4 to your computer and use it in GitHub Desktop.
Automatically set hostname for OpenConnects VPN clients on OpenWRT
#!/bin/sh
# Set fields in /etc/ocsercv/ocserv.conf.template as below
#
# connect-script = /path/to/vpn-hostnames.sh
# disconnect-script = /path/to/vpn-hostnames.sh
# Set field in /etc/config/dhcp as below
#
# config dnsmasq
# option localservice '0'
# option domainneeded '0'
# Set crontab if using LEDE or OpenWrt newer than 15.05 and toggle comments on lines 27, 28, 35, 36
#
# * * * * * test -f /tmp/dnsmasq-reload.lock && /etc/init.d/dnsmasq reload && rm /tmp/dnsmasq-reload.lock
# Update custom firewall rules
#
# iptables -A input_rule -i vpns+ -j ACCEPT
# iptables -A forwarding_rule -i vpns+ -j ACCEPT
# iptables -A forwarding_rule -o vpns+ -j ACCEPT
# iptables -A output_rule -o vpns+ -j ACCEPT
VPN_HOST_NAME="${USERNAME}.vpn"
case "${REASON}" in
connect | CONNECT)
uci show dhcp | grep @domain | grep -q -i ${VPN_HOST_NAME} || uci add dhcp domain
HOSTNAME_ID=$(uci show dhcp | grep @domain | cut -d "[" -f2 | cut -d "]" -f1 | sort -n | uniq | tail -n 1)
uci set dhcp.@domain[${HOSTNAME_ID:--1}].name=${VPN_HOST_NAME}
uci set dhcp.@domain[${HOSTNAME_ID:--1}].ip=${IP_REMOTE}
uci commit dhcp
/etc/init.d/dnsmasq reload
;;
disconnect | DISCONNECT)
uci show dhcp | grep @domain | grep -q -i ${VPN_HOST_NAME} || exit 0
HOSTNAME_ID=$(uci show dhcp | grep @domain | grep -i ${VPN_HOST_NAME} | cut -d "[" -f2 | cut -d "]" -f1)
uci delete dhcp.@domain[${HOSTNAME_ID}]
uci commit dhcp
/etc/init.d/dnsmasq reload
;;
*)
echo "Unknown reason [${REASON}]"
exit 1
esac
exit 0
#!/bin/sh
add_route() {
DOMAIN=$(uci add dhcp domain)
uci set "dhcp.${DOMAIN}.name=${1}"
uci set "dhcp.${DOMAIN}.ip=${2}"
uci commit dhcp
}
rm_route() {
DOMAINS=$(uci show dhcp | grep -r "dhcp.@domain\[.*\].name='${1}'" | cut -d "[" -f2 | cut -d "]" -f1)
for DOMAIN in ${DOMAINS}; do
uci delete "dhcp.@domain[${DOMAIN}]"
done
uci commit dhcp
}
# */2 * * * * /usr/bin/flock -n /var/lock/ocserv-dnsw.lock /usr/bin/ocserv-dnsw
ping -c1 -w 15 -q 8.8.8.8 1>/dev/null || \
exit 0
ROUTES=$(uci show dhcp | grep -r "dhcp.@domain\[.*\]" | grep -v '=domain' | sed 'N;s/\n/ /' | sed "s/^.*name='\(.*\)' .*ip='\(.*\)'$/\1,\2/g")
SESSIONS=$(/usr/bin/occtl show users | tail -n +2 | awk '{ print $2 ".vpn," $5 }')
RELOAD_DNS=0
### ADD/UPDATE NEW ROUTES FOR SESSIONS
for SESSION in ${SESSIONS}; do
SESSION_HOST="${SESSION%,*}"
SESSION_IP="${SESSION#*,}"
SESSION_EXISTS=0
for ROUTE in ${ROUTES}; do
ROUTE_HOST="${ROUTE%,*}"
ROUTE_IP="${ROUTE#*,}"
if [ "${SESSION_HOST}" = "${ROUTE_HOST}" ]; then
if [ "${SESSION_IP}" = "${ROUTE_IP}" ]; then
SESSION_EXISTS=1;
else
rm_route ${ROUTE_HOST};
fi
break;
fi
done
if [ "${SESSION_EXISTS}" -eq 0 ]; then
add_route ${SESSION_HOST} ${SESSION_IP};
RELOAD_DNS=1
fi
done
### RM NEW ROUTES FOR SESSIONS
for ROUTE in ${ROUTES}; do
ROUTE_HOST="${ROUTE%,*}"
SESSION_EXISTS=0
for SESSION in ${SESSIONS}; do
if [ "${SESSION%,*}" = "${ROUTE_HOST}" ]; then
SESSION_EXISTS=1;
break;
fi
done
if [ "${SESSION_EXISTS}" -eq 0 ]; then
rm_route ${ROUTE_HOST};
RELOAD_DNS=1
fi
done
if [ ${RELOAD_DNS} -eq 1 ]; then
/etc/init.d/dnsmasq reload
fi
@siskai
Copy link
Copy Markdown

siskai commented May 9, 2022

When the number of hostnames is double-digit, sorting does not work. Change sort to sort -n.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment