vhost: do not require setting device per vhost

It is not necessary to specify the device config directive on
each virtual host configuration. Ensure that we don't require it
by mistake. This also introduces a traffic test when operating
with virtual hosts.

Resolves: #480

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This commit is contained in:
Nikos Mavrogiannopoulos
2023-07-12 11:16:28 +02:00
parent 870086600c
commit c393d4d7b4
7 changed files with 311 additions and 4 deletions

1
NEWS
View File

@@ -1,5 +1,6 @@
* Version 1.2.1 (unreleased)
- Accept the Clavister OneConnect VPN Android client (#485)
- No longer require to set device name per vhost (#480)
* Version 1.2.0 (released 2023-07-11)

View File

@@ -1347,6 +1347,8 @@ static void check_cfg(vhost_cfg_st *vhost, vhost_cfg_st *defvhost, unsigned sile
unsigned j, i;
struct cfg_st *config;
assert(vhost->name == NULL || defvhost != NULL);
config = vhost->perm_config.config;
if (vhost->perm_config.auth[0].enabled == 0) {
@@ -1494,9 +1496,13 @@ static void check_cfg(vhost_cfg_st *vhost, vhost_cfg_st *defvhost, unsigned sile
exit(EXIT_FAILURE);
}
if (!vhost->name && config->network.name[0] == 0) {
fprintf(stderr, ERRSTR"%sthe 'device' configuration option must be specified!\n", PREFIX_VHOST(vhost));
exit(EXIT_FAILURE);
if (config->network.name[0] == 0) {
if (!vhost->name) {
fprintf(stderr, ERRSTR"%sthe 'device' configuration option must be specified!\n", PREFIX_VHOST(vhost));
exit(EXIT_FAILURE);
} else {
strlcpy(config->network.name, defvhost->perm_config.config->network.name, sizeof(config->network.name));
}
}
if (config->mobile_dpd == 0)

View File

@@ -64,7 +64,7 @@ dist_check_SCRIPTS += haproxy-connect test-iroute test-multi-cookie test-pass-sc
multiple-routes json test-udp-listen-host test-max-same-1 test-script-multi-user \
apple-ios ipv6-iface test-namespace-listen disconnect-user disconnect-user2 \
ping-leases test-ban-local test-client-bypass-protocol ipv6-small-net test-camouflage \
test-camouflage-norealm
test-camouflage-norealm vhost-traffic defvhost-traffic
if RADIUS_ENABLED
dist_check_SCRIPTS += radius-group radius-multi-group radius-otp

View File

@@ -129,6 +129,9 @@ pid-file = ocserv-vhost.pid
# It must be accessible within the chroot environment (if any)
socket-file = ocserv-socket-vhost
occtl-socket-file = @OCCTL_SOCKET@
use-occtl = true
# The user the worker processes will be run as. It should be
# unique (no other services run as this user).
run-as-user = @USERNAME@

141
tests/defvhost-traffic Executable file
View File

@@ -0,0 +1,141 @@
#!/bin/bash
#
# Copyright (C) 2018 Nikos Mavrogiannopoulos
#
# This file is part of ocserv.
#
# ocserv is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# ocserv is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This tests operation/traffic under vhost
OCCTL="${OCCTL:-../src/occtl/occtl}"
SERV="${SERV:-../src/ocserv}"
srcdir=${srcdir:-.}
PIDFILE=ocserv-pid.$$.tmp
CLIPID=oc-pid.$$.tmp
PATH=${PATH}:/usr/sbin
IP=$(which ip)
OUTFILE=traffic.$$.tmp
. `dirname $0`/common.sh
eval "${GETPORT}"
if test -z "${IP}";then
echo "no IP tool is present"
exit 77
fi
if test "$(id -u)" != "0";then
echo "This test must be run as root"
exit 77
fi
echo "Testing ocserv connection traffic with default vhost... "
function finish {
set +e
echo " * Cleaning up..."
test -n "${PID}" && kill ${PID} >/dev/null 2>&1
test -n "${PIDFILE}" && rm -f ${PIDFILE} >/dev/null 2>&1
test -n "${CLIPID}" && kill $(cat ${CLIPID}) >/dev/null 2>&1
test -n "${CLIPID}" && rm -f ${CLIPID} >/dev/null 2>&1
test -n "${CONFIG}" && rm -f ${CONFIG} >/dev/null 2>&1
rm -f ${OUTFILE} 2>&1
}
trap finish EXIT
# server address
ADDRESS=10.223.22.1
CLI_ADDRESS=10.223.21.1
VPNNET=192.168.1.0/24
VPNADDR=192.168.1.1
#VPNNET6=fd91:6d87:7341:dc6a::/112
#VPNADDR6=fd91:6d87:7341:dc6a::1
OCCTL_SOCKET=./occtl-defvhost-$$.socket
USERNAME=vhost
. `dirname $0`/ns.sh
# Run servers
update_config test-vhost-pass-cert.config
if test "$VERBOSE" = 1;then
DEBUG="-d 3"
fi
${CMDNS2} ${SERV} -p ${PIDFILE} -f -c ${CONFIG} ${DEBUG} & PID=$!
sleep 4
# Run clients
echo " * Getting cookie from ${ADDRESS}:${PORT} with wrong vhost credentials..."
( echo "${USERNAME}" | ${CMDNS1} ${OPENCONNECT} ${ADDRESS}:${PORT} -u ${USERNAME} --servercert="pin-sha256:xp3scfzy3rOQsv9NcOve/8YVVv+pHr4qNCXEXrNl5s8=" --cookieonly )
if test $? = 0;then
echo "Connected at wrong vhost"
exit 1
fi
USERNAME=test
echo " * Getting cookie from ${ADDRESS}:${PORT}..."
( echo "${USERNAME}" | ${CMDNS1} ${OPENCONNECT} ${ADDRESS}:${PORT} -u ${USERNAME} --servercert="pin-sha256:xp3scfzy3rOQsv9NcOve/8YVVv+pHr4qNCXEXrNl5s8=" --cookieonly )
if test $? != 0;then
echo "Could not get cookie from server"
exit 1
fi
echo " * Connecting to ${ADDRESS}:${PORT}..."
( echo "${USERNAME}" | ${CMDNS1} ${OPENCONNECT} ${ADDRESS}:${PORT} -u ${USERNAME} --servercert="pin-sha256:xp3scfzy3rOQsv9NcOve/8YVVv+pHr4qNCXEXrNl5s8=" -s ${srcdir}/scripts/vpnc-script --pid-file=${CLIPID} --passwd-on-stdin -b )
if test $? != 0;then
echo "Could not connect to server"
exit 1
fi
set -e
echo " * ping remote address"
${CMDNS1} ping -c 3 ${VPNADDR}
sleep 2
set +e
${OCCTL} -s ${OCCTL_SOCKET} show users|grep ${USERNAME}
if test $? != 0;then
echo "occtl didn't find connected user!"
exit 1
fi
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME} >${OUTFILE}
if test $? != 0;then
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME}
echo "occtl didn't find connected user!"
exit 1
fi
grep "Username: ${USERNAME}" ${OUTFILE}
if test $? != 0;then
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME}
echo "occtl show user didn't find connected user!"
exit 1
fi
grep ${CLI_ADDRESS} ${OUTFILE}
if test $? != 0;then
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME}
echo "occtl show user didn't find client address!"
exit 1
fi
exit 0

View File

@@ -22,6 +22,7 @@ SERV="${SERV:-../src/ocserv}"
srcdir=${srcdir:-.}
NO_NEED_ROOT=1
TMPFILE=pid.$$.tmp
OCCTL_SOCKET=./occtl-vhost0-$$.socket
VERBOSE=1

155
tests/vhost-traffic Executable file
View File

@@ -0,0 +1,155 @@
#!/bin/bash
#
# Copyright (C) 2018 Nikos Mavrogiannopoulos
#
# This file is part of ocserv.
#
# ocserv is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# ocserv is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This tests operation/traffic under vhost
OCCTL="${OCCTL:-../src/occtl/occtl}"
SERV="${SERV:-../src/ocserv}"
srcdir=${srcdir:-.}
PIDFILE=ocserv-pid.$$.tmp
CLIPID=oc-pid.$$.tmp
PATH=${PATH}:/usr/sbin
IP=$(which ip)
OUTFILE=traffic.$$.tmp
. `dirname $0`/common.sh
eval "${GETPORT}"
if test -z "${IP}";then
echo "no IP tool is present"
exit 77
fi
if test "$(id -u)" != "0";then
echo "This test must be run as root"
exit 77
fi
echo "Testing ocserv connection traffic with vhost... "
function finish {
set +e
echo " * Cleaning up..."
test -n "${PID}" && kill ${PID} >/dev/null 2>&1
test -n "${PIDFILE}" && rm -f ${PIDFILE} >/dev/null 2>&1
test -n "${CLIPID}" && kill $(cat ${CLIPID}) >/dev/null 2>&1
test -n "${CLIPID}" && rm -f ${CLIPID} >/dev/null 2>&1
test -n "${CONFIG}" && rm -f ${CONFIG} >/dev/null 2>&1
rm -f ${OUTFILE} 2>&1
}
trap finish EXIT
# server address
ADDRESS=10.223.2.1
CLI_ADDRESS=10.223.1.1
VPNNET=192.168.3.0/24
VPNADDR=192.168.3.1
#VPNNET6=fd91:6d87:7341:dc6a::/112
#VPNADDR6=fd91:6d87:7341:dc6a::1
OCCTL_SOCKET=./occtl-vhost-$$.socket
USERNAME=test
SNI=pass2.example.com
${OPENCONNECT} --help|grep 'sni' >/dev/null 2>&1
if test $? != 0;then
echo "openconnect doesn't support sni option"
exit 77
fi
. `dirname $0`/ns.sh
# Run servers
update_config test-vhost-pass-cert.config
if test "$VERBOSE" = 1;then
DEBUG="-d 3"
fi
${CMDNS2} ${SERV} -p ${PIDFILE} -f -c ${CONFIG} ${DEBUG} & PID=$!
sleep 4
# Run clients
echo " * Getting cookie from ${ADDRESS}:${PORT} with wrong vhost credentials..."
( echo "test" | ${CMDNS1} ${OPENCONNECT} ${ADDRESS}:${PORT} --sni "${SNI}" -u ${USERNAME} --servercert="sha1:8e253ef2a87dd9188fe444702f2fe349d30af816" --cookieonly )
if test $? = 0;then
echo "Connected at wrong vhost"
exit 1
fi
USERNAME=vhost
echo " * Getting cookie from ${ADDRESS}:${PORT}..."
( echo "${USERNAME}" | ${CMDNS1} ${OPENCONNECT} ${ADDRESS}:${PORT} --sni "${SNI}" -u ${USERNAME} --servercert="sha1:8e253ef2a87dd9188fe444702f2fe349d30af816" --cookieonly )
if test $? != 0;then
echo "Could not get cookie from server"
exit 1
fi
echo " * Connecting to ${ADDRESS}:${PORT}..."
( echo "${USERNAME}" | ${CMDNS1} ${OPENCONNECT} ${ADDRESS}:${PORT} --sni "${SNI}" -u ${USERNAME} --servercert="sha1:8e253ef2a87dd9188fe444702f2fe349d30af816" -s ${srcdir}/scripts/vpnc-script --pid-file=${CLIPID} --passwd-on-stdin -b )
if test $? != 0;then
echo "Could not connect to server"
exit 1
fi
set -e
echo " * ping remote address"
${CMDNS1} ping -c 3 ${VPNADDR}
sleep 2
set +e
${OCCTL} -s ${OCCTL_SOCKET} show users|grep ${USERNAME}
if test $? != 0;then
echo "occtl didn't find connected user!"
exit 1
fi
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME} >${OUTFILE}
if test $? != 0;then
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME}
echo "occtl didn't find connected user!"
exit 1
fi
grep "Username: ${USERNAME}" ${OUTFILE}
if test $? != 0;then
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME}
echo "occtl show user didn't find connected user!"
exit 1
fi
grep ${CLI_ADDRESS} ${OUTFILE}
if test $? != 0;then
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME}
echo "occtl show user didn't find client address!"
exit 1
fi
grep ${SNI} ${OUTFILE}
if test $? != 0;then
${OCCTL} -s ${OCCTL_SOCKET} show user ${USERNAME}
echo "occtl show user didn't find the vhost name!"
exit 1
fi
exit 0