mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
Enhanced configuration option 'restrict-user-to-ports'
This enhancement allows to negate the rules and allow the user connecting to all ports except the specified.
This commit is contained in:
@@ -480,6 +480,9 @@ no-route = 192.168.5.0/255.255.255.0
|
||||
# or in the per-user configuration.
|
||||
#restrict-user-to-ports = "tcp(443), tcp(80), udp(443), sctp(99), tcp(583), icmp(), icmpv6()"
|
||||
|
||||
# You could also use negation, i.e., block the user from accessing these ports only.
|
||||
#restrict-user-to-ports = "!(tcp(443), tcp(80))"
|
||||
|
||||
# When set to true, all client's iroutes are made visible to all
|
||||
# connecting clients except for the ones offering them. This option
|
||||
# only makes sense if config-per-user is set.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <vpn.h>
|
||||
|
||||
static int append_port(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, int port, fw_proto_t proto)
|
||||
static int append_port(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, int port, fw_proto_t proto, unsigned negate)
|
||||
{
|
||||
FwPortSt *current;
|
||||
|
||||
@@ -45,6 +45,7 @@ static int append_port(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, int
|
||||
|
||||
current->port = port;
|
||||
current->proto = proto;
|
||||
current->negate = negate;
|
||||
|
||||
(*fw_ports)[*n_fw_ports] = current;
|
||||
(*n_fw_ports)++;
|
||||
@@ -61,13 +62,33 @@ int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const
|
||||
unsigned finish = 0;
|
||||
int port, ret;
|
||||
fw_proto_t proto;
|
||||
int negate = 0, bracket_start = 0;
|
||||
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
p = str;
|
||||
|
||||
while (c_isspace(*p))
|
||||
p++;
|
||||
|
||||
if (*p == '!') {
|
||||
negate = 1;
|
||||
p++;
|
||||
while (c_isspace(*p) || (*p == '(')) {
|
||||
if (*p == '(')
|
||||
bracket_start = 1;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (bracket_start == 0) {
|
||||
syslog(LOG_ERR, "no bracket following negation at %d '%s'", (int)(ptrdiff_t)(p-str), str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
while (c_isspace(*p))
|
||||
p++;
|
||||
|
||||
@@ -105,7 +126,7 @@ int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const
|
||||
p++;
|
||||
port = atoi(p);
|
||||
|
||||
ret = append_port(pool, fw_ports, n_fw_ports, port, proto);
|
||||
ret = append_port(pool, fw_ports, n_fw_ports, port, proto, negate);
|
||||
if (ret < 0) {
|
||||
syslog(LOG_ERR, "memory error");
|
||||
return -1;
|
||||
@@ -121,7 +142,7 @@ int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const
|
||||
while (c_isspace(*p2))
|
||||
p2++;
|
||||
|
||||
if (*p2 == 0) {
|
||||
if (*p2 == 0 || (negate != 0 && *p2 == ')')) {
|
||||
finish = 1;
|
||||
} else if (*p2 != ',') {
|
||||
syslog(LOG_ERR, "expected comma or end of line on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p2-str), str);
|
||||
|
||||
@@ -18,6 +18,8 @@ message fw_port_st
|
||||
required uint32 port = 1;
|
||||
/* fw_proto_t */
|
||||
required uint32 proto = 2;
|
||||
/* negative rule, i.e., if non zero reject this port */
|
||||
required uint32 negate = 3;
|
||||
}
|
||||
|
||||
/* This is a structure for per-user/group supplemental configuration.
|
||||
|
||||
@@ -62,7 +62,7 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
|
||||
str_st str4;
|
||||
str_st str6;
|
||||
str_st str_common;
|
||||
unsigned i;
|
||||
unsigned i, negate = 0;
|
||||
int ret;
|
||||
|
||||
str_init(&str4, proc);
|
||||
@@ -188,6 +188,9 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
|
||||
|
||||
if (proc->config->n_fw_ports > 0) {
|
||||
for (i=0;i<proc->config->n_fw_ports;i++) {
|
||||
if (proc->config->fw_ports[i]->negate)
|
||||
negate = 1;
|
||||
|
||||
switch(proc->config->fw_ports[i]->proto) {
|
||||
case PROTO_UDP:
|
||||
ret = str_append_printf(&str_common, "udp %u ", proc->config->fw_ports[i]->port);
|
||||
@@ -216,9 +219,18 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
|
||||
}
|
||||
}
|
||||
|
||||
if (str_common.length > 0 && setenv("OCSERV_PORTS", (char*)str_common.data, 1) == -1) {
|
||||
mslog(s, proc, LOG_ERR, "could not export PORTS\n");
|
||||
exit(1);
|
||||
if (str_common.length > 0) {
|
||||
if (negate) {
|
||||
if (setenv("OCSERV_DENY_PORTS", (char*)str_common.data, 1) == -1) {
|
||||
mslog(s, proc, LOG_ERR, "could not export DENY_PORTS\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if (setenv("OCSERV_ALLOW_PORTS", (char*)str_common.data, 1) == -1) {
|
||||
mslog(s, proc, LOG_ERR, "could not export ALLOW_PORTS\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
str_clear(&str_common);
|
||||
|
||||
@@ -568,6 +568,9 @@ no-route = 192.168.5.0/255.255.255.0
|
||||
# or in the per-user configuration.
|
||||
#restrict-user-to-ports = "tcp(443), tcp(80), udp(443), sctp(99), tcp(583), icmp(), icmpv6()"
|
||||
|
||||
# You could also use negation, i.e., block the user from accessing these ports only.
|
||||
#restrict-user-to-ports = "!(tcp(443), tcp(80))"
|
||||
|
||||
# When set to true, all client's iroutes are made visible to all
|
||||
# connecting clients except for the ones offering them. This option
|
||||
# only makes sense if config-per-user is set.
|
||||
|
||||
@@ -124,6 +124,24 @@ allow_port() {
|
||||
esac
|
||||
}
|
||||
|
||||
deny_port() {
|
||||
proto=$1
|
||||
port=$2
|
||||
|
||||
case "$proto" in
|
||||
icmp)
|
||||
iptables -A INPUT -i ${DEVICE} -p $proto -j REJECT --match comment --comment "${COMMENT}"
|
||||
;;
|
||||
icmpv6)
|
||||
ip6tables -A INPUT -i ${DEVICE} -p $proto -j REJECT --match comment --comment "${COMMENT}"
|
||||
;;
|
||||
*)
|
||||
iptables -A INPUT -i ${DEVICE} -p $proto --dport $port -j REJECT --match comment --comment "${COMMENT}"
|
||||
ip6tables -A INPUT -i ${DEVICE} -p $proto --dport $port -j REJECT --match comment --comment "${COMMENT}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
disallow_all_ports() {
|
||||
iptables -A INPUT -i ${DEVICE} -j REJECT --match comment --comment "${COMMENT}"
|
||||
ip6tables -A INPUT -i ${DEVICE} -j REJECT --match comment --comment "${COMMENT}"
|
||||
@@ -140,24 +158,43 @@ for i in $OCSERV_DNS6;do
|
||||
done
|
||||
|
||||
# block ports - if needed
|
||||
if test -n "${OCSERV_PORTS}";then
|
||||
if test -n "${OCSERV_DENY_PORTS}";then
|
||||
INPUT_CHAIN="${SEC_INPUT_CHAIN}"
|
||||
iptables -N "${INPUT_CHAIN}"
|
||||
ip6tables -N "${INPUT_CHAIN}"
|
||||
|
||||
set ${OCSERV_PORTS}
|
||||
set ${OCSERV_DENY_PORTS}
|
||||
while test $# -gt 1; do
|
||||
proto=$1
|
||||
port=$2
|
||||
|
||||
allow_port $proto $port
|
||||
deny_port $proto $port
|
||||
if test $# -gt 1;then
|
||||
shift 2
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
disallow_all_ports
|
||||
else
|
||||
if test -n "${OCSERV_ALLOW_PORTS}";then
|
||||
INPUT_CHAIN="${SEC_INPUT_CHAIN}"
|
||||
iptables -N "${INPUT_CHAIN}"
|
||||
ip6tables -N "${INPUT_CHAIN}"
|
||||
|
||||
set ${OCSERV_ALLOW_PORTS}
|
||||
while test $# -gt 1; do
|
||||
proto=$1
|
||||
port=$2
|
||||
|
||||
allow_port $proto $port
|
||||
if test $# -gt 1;then
|
||||
shift 2
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
disallow_all_ports
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${OCSERV_RESTRICT_TO_ROUTES}" = "1";then
|
||||
|
||||
@@ -108,5 +108,20 @@ int main()
|
||||
exit(1);
|
||||
}
|
||||
|
||||
reset(fw_ports, n_fw_ports);
|
||||
strcpy(p, "!(icmp(), tcp(88), udp(90), sctp(70), tcp(443), udp(80), icmpv6())");
|
||||
|
||||
ret = cfg_parse_ports(NULL, &fw_ports, &n_fw_ports, p);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error in %d\n", __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
check_vals(fw_ports, n_fw_ports);
|
||||
if (fw_ports[0]->negate == 0) {
|
||||
fprintf(stderr, "error in %d\n", __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user