mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
Added configuration option 'restrict-user-to-ports'
This option is intended to allow restricting users to accessing specific ports once they enter the VPN. The rules set using this option will be enforced by the ocserv-fw script.
This commit is contained in:
@@ -473,6 +473,12 @@ no-route = 192.168.5.0/255.255.255.0
|
||||
# --removeall. This option can be set globally or in the per-user configuration.
|
||||
#restrict-user-to-routes = true
|
||||
|
||||
# This option implies restrict-user-to-routes set to true. If set, the
|
||||
# script /usr/bin/ocserv-fw will be called to restrict the user to its
|
||||
# to accessing specific ports in the network. This option can be set globally
|
||||
# or in the per-user configuration.
|
||||
#restrict-user-to-ports = "tcp(443), tcp(80), udp(443), sctp(99), tcp(583), icmp(), icmpv6()"
|
||||
|
||||
# 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.
|
||||
@@ -501,7 +507,9 @@ no-route = 192.168.5.0/255.255.255.0
|
||||
# ipv?-network, ipv4-netmask, rx/tx-per-sec, iroute, route, no-route,
|
||||
# explicit-ipv4, explicit-ipv6, net-priority, deny-roaming, no-udp,
|
||||
# keepalive, dpd, mobile-dpd, max-same-clients, tunnel-all-dns,
|
||||
# user-profile, cgroup, stats-report-time, and session-timeout.
|
||||
# restrict-user-to-routes, user-profile, cgroup, stats-report-time,
|
||||
# mtu, idle-timeout, mobile-idle-timeout, restrict-user-to-ports,
|
||||
# and session-timeout.
|
||||
#
|
||||
# Note that the 'iroute' option allows to add routes on the server
|
||||
# based on a user or group. The syntax depends on the input accepted
|
||||
|
||||
@@ -60,7 +60,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
||||
sup-config/file.c sup-config/file.h main-sec-mod-cmd.c \
|
||||
sup-config/radius.c sup-config/radius.h \
|
||||
worker-bandwidth.c worker-bandwidth.h main-ctl.h \
|
||||
vasprintf.c vasprintf.h worker-proxyproto.c \
|
||||
vasprintf.c vasprintf.h worker-proxyproto.c config-ports.c \
|
||||
proc-search.c proc-search.h http-heads.h ip-util.c ip-util.h \
|
||||
main-ban.c main-ban.h common-config.h base64-helper.c base64-helper.h \
|
||||
str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \
|
||||
|
||||
@@ -24,10 +24,12 @@
|
||||
#include <config.h>
|
||||
#include <vpn.h>
|
||||
#include <autoopts/options.h>
|
||||
#include <ipc.pb-c.h>
|
||||
|
||||
int add_multi_line_val(void *pool, const char *name, char ***s_name, size_t *num,
|
||||
tOptionValue const *pov,
|
||||
const tOptionValue *val);
|
||||
int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const char *str);
|
||||
|
||||
#define MAX_SUBOPTIONS 5
|
||||
|
||||
|
||||
130
src/config-ports.c
Normal file
130
src/config-ports.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <common-config.h>
|
||||
#include <c-strcase.h>
|
||||
#include <c-ctype.h>
|
||||
#include <talloc.h>
|
||||
|
||||
#include <vpn.h>
|
||||
|
||||
static int append_port(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, int port, fw_proto_t proto)
|
||||
{
|
||||
FwPortSt *current;
|
||||
|
||||
*fw_ports = talloc_realloc(pool, *fw_ports, FwPortSt*, (*n_fw_ports)+1);
|
||||
if (*fw_ports == NULL)
|
||||
return -1;
|
||||
|
||||
current = talloc(pool, FwPortSt);
|
||||
fw_port_st__init(current);
|
||||
|
||||
current->port = port;
|
||||
current->proto = proto;
|
||||
|
||||
(*fw_ports)[*n_fw_ports] = current;
|
||||
(*n_fw_ports)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse strings of the format tcp(443), udp(111), and fill in
|
||||
* allowed_tcp_ports and allowed_udp_ports.
|
||||
*/
|
||||
int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const char *str)
|
||||
{
|
||||
const char *p, *p2;
|
||||
unsigned finish = 0;
|
||||
int port, ret;
|
||||
fw_proto_t proto;
|
||||
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
p = str;
|
||||
|
||||
do {
|
||||
while (c_isspace(*p))
|
||||
p++;
|
||||
|
||||
if (strncasecmp(p, "tcp", 3) == 0) {
|
||||
proto = PROTO_TCP;
|
||||
p += 3;
|
||||
} else if (strncasecmp(p, "udp", 3) == 0) {
|
||||
proto = PROTO_UDP;
|
||||
p += 3;
|
||||
} else if (strncasecmp(p, "sctp", 4) == 0) {
|
||||
proto = PROTO_SCTP;
|
||||
p += 4;
|
||||
} else if (strncasecmp(p, "icmpv6", 6) == 0) {
|
||||
proto = PROTO_ICMPv6;
|
||||
p += 6;
|
||||
} else if (strncasecmp(p, "icmp", 4) == 0) {
|
||||
proto = PROTO_ICMP;
|
||||
p += 4;
|
||||
} else if (strncasecmp(p, "esp", 3) == 0) {
|
||||
proto = PROTO_ESP;
|
||||
p += 3;
|
||||
} else {
|
||||
syslog(LOG_ERR, "unknown protocol on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p-str), str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (c_isspace(*p))
|
||||
p++;
|
||||
|
||||
if (*p != '(') {
|
||||
syslog(LOG_ERR, "expected parenthesis on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p-str), str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p++;
|
||||
port = atoi(p);
|
||||
|
||||
ret = append_port(pool, fw_ports, n_fw_ports, port, proto);
|
||||
if (ret < 0) {
|
||||
syslog(LOG_ERR, "memory error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
p2 = strchr(p, ')');
|
||||
if (p2 == NULL) {
|
||||
syslog(LOG_ERR, "expected closing parenthesis on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p2-str), str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p2++;
|
||||
while (c_isspace(*p2))
|
||||
p2++;
|
||||
|
||||
if (*p2 == 0) {
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
p=p2;
|
||||
p++;
|
||||
} while(finish == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
18
src/config.c
18
src/config.c
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 2014 Nikos Mavrogiannopoulos
|
||||
* Copyright (C) 2013, 2014, 2015 Nikos Mavrogiannopoulos
|
||||
* Copyright (C) 2014, 2015 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -134,6 +135,7 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "use-occtl", .type = OPTION_BOOLEAN, .mandatory = 0 },
|
||||
{ .name = "try-mtu-discovery", .type = OPTION_BOOLEAN, .mandatory = 0 },
|
||||
{ .name = "restrict-user-to-routes", .type = OPTION_BOOLEAN, .mandatory = 0 },
|
||||
{ .name = "restrict-user-to-ports", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "ping-leases", .type = OPTION_BOOLEAN, .mandatory = 0 },
|
||||
{ .name = "tls-priorities", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "chroot-dir", .type = OPTION_STRING, .mandatory = 0 },
|
||||
@@ -635,7 +637,7 @@ static void parse_cfg_file(void *pool, const char* file, struct perm_cfg_st *per
|
||||
{
|
||||
tOptionValue const * pov;
|
||||
const tOptionValue* val, *prev;
|
||||
unsigned j, i, mand;
|
||||
unsigned j, i, mand, ret;
|
||||
char** auth = NULL;
|
||||
size_t auth_size = 0;
|
||||
unsigned prefix = 0, auto_select_group = 0;
|
||||
@@ -834,8 +836,20 @@ size_t urlfw_size = 0;
|
||||
|
||||
READ_TF("try-mtu-discovery", config->try_mtu, 0);
|
||||
READ_TF("ping-leases", config->ping_leases, 0);
|
||||
|
||||
READ_TF("restrict-user-to-routes", config->restrict_user_to_routes, 0);
|
||||
|
||||
tmp = NULL;
|
||||
READ_STRING("restrict-user-to-ports", tmp);
|
||||
if (tmp) {
|
||||
ret = cfg_parse_ports(pool, &config->fw_ports, &config->n_fw_ports, tmp);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error parsing restrict-user-to-ports\n");
|
||||
exit(1);
|
||||
}
|
||||
talloc_free(tmp);
|
||||
}
|
||||
|
||||
READ_STRING("tls-priorities", config->priorities);
|
||||
|
||||
READ_NUMERIC("mtu", config->default_mtu);
|
||||
|
||||
@@ -13,6 +13,13 @@ message auth_cookie_request_msg
|
||||
required bytes cookie = 1;
|
||||
}
|
||||
|
||||
message fw_port_st
|
||||
{
|
||||
required uint32 port = 1;
|
||||
/* fw_proto_t */
|
||||
required uint32 proto = 2;
|
||||
}
|
||||
|
||||
/* This is a structure for per-user/group supplemental configuration.
|
||||
*/
|
||||
message group_cfg_st
|
||||
@@ -49,6 +56,7 @@ message group_cfg_st
|
||||
optional uint32 mtu = 36;
|
||||
optional uint32 idle_timeout = 37;
|
||||
optional uint32 mobile_idle_timeout = 38;
|
||||
repeated fw_port_st fw_ports = 39;
|
||||
}
|
||||
|
||||
/* AUTH_REP */
|
||||
|
||||
@@ -407,7 +407,13 @@ void apply_default_config(main_server_st *s, proc_st *proc, GroupCfgSt *gc)
|
||||
gc->mobile_idle_timeout = s->config->mobile_idle_timeout;
|
||||
gc->has_mobile_idle_timeout = 1;
|
||||
}
|
||||
|
||||
if (gc->n_fw_ports == 0 && s->config->n_fw_ports > 0) {
|
||||
gc->n_fw_ports = s->config->n_fw_ports;
|
||||
gc->fw_ports = s->config->fw_ports;
|
||||
}
|
||||
}
|
||||
|
||||
int session_open(main_server_st * s, struct proc_st *proc, const uint8_t *cookie, unsigned cookie_size)
|
||||
{
|
||||
int ret, e;
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
static void export_dns_route_info(main_server_st *s, struct proc_st* proc)
|
||||
static void export_fw_info(main_server_st *s, struct proc_st* proc)
|
||||
{
|
||||
str_st str4;
|
||||
str_st str6;
|
||||
@@ -135,6 +135,12 @@ static void export_dns_route_info(main_server_st *s, struct proc_st* proc)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (proc->config->restrict_user_to_routes) {
|
||||
if (setenv("OCSERV_RESTRICT_TO_ROUTES", "1", 1) == -1) {
|
||||
mslog(s, proc, LOG_ERR, "could not export OCSERV_RESTRICT_TO_ROUTES\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/* export the DNS servers */
|
||||
|
||||
str_reset(&str4);
|
||||
@@ -174,6 +180,47 @@ static void export_dns_route_info(main_server_st *s, struct proc_st* proc)
|
||||
str_clear(&str4);
|
||||
str_clear(&str6);
|
||||
str_clear(&str_common);
|
||||
|
||||
/* export the ports to reject */
|
||||
|
||||
str_reset(&str_common);
|
||||
|
||||
if (proc->config->n_fw_ports > 0) {
|
||||
for (i=0;i<proc->config->n_fw_ports;i++) {
|
||||
switch(proc->config->fw_ports[i]->proto) {
|
||||
case PROTO_UDP:
|
||||
ret = str_append_printf(&str_common, "udp %u ", proc->config->fw_ports[i]->port);
|
||||
break;
|
||||
case PROTO_TCP:
|
||||
ret = str_append_printf(&str_common, "tcp %u ", proc->config->fw_ports[i]->port);
|
||||
break;
|
||||
case PROTO_SCTP:
|
||||
ret = str_append_printf(&str_common, "sctp %u ", proc->config->fw_ports[i]->port);
|
||||
break;
|
||||
case PROTO_ICMP:
|
||||
ret = str_append_printf(&str_common, "icmp all ");
|
||||
break;
|
||||
case PROTO_ESP:
|
||||
ret = str_append_printf(&str_common, "esp all ");
|
||||
break;
|
||||
case PROTO_ICMPv6:
|
||||
ret = str_append_printf(&str_common, "icmpv6 all ");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
mslog(s, proc, LOG_ERR, "could not append value to environment\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
str_clear(&str_common);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -188,7 +235,7 @@ const char* script, *next_script = NULL;
|
||||
else
|
||||
script = s->config->disconnect_script;
|
||||
|
||||
if (proc->config->restrict_user_to_routes) {
|
||||
if (proc->config->restrict_user_to_routes || proc->config->n_fw_ports > 0) {
|
||||
next_script = script;
|
||||
script = OCSERV_FW_SCRIPT;
|
||||
}
|
||||
@@ -283,7 +330,7 @@ const char* script, *next_script = NULL;
|
||||
}
|
||||
|
||||
/* export DNS and route info */
|
||||
export_dns_route_info(s, proc);
|
||||
export_fw_info(s, proc);
|
||||
|
||||
/* set stdout to be stderr to avoid confusing scripts - note we have stdout closed */
|
||||
if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
|
||||
|
||||
@@ -561,6 +561,12 @@ no-route = 192.168.5.0/255.255.255.0
|
||||
# --removeall. This option can be set globally or in the per-user configuration.
|
||||
#restrict-user-to-routes = true
|
||||
|
||||
# This option implies restrict-user-to-routes set to true. If set, the
|
||||
# script /usr/bin/ocserv-fw will be called to restrict the user to its
|
||||
# to accessing specific ports in the network. This option can be set globally
|
||||
# or in the per-user configuration.
|
||||
#restrict-user-to-ports = "tcp(443), tcp(80), udp(443), sctp(99), tcp(583), icmp(), icmpv6()"
|
||||
|
||||
# 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.
|
||||
@@ -596,7 +602,8 @@ no-route = 192.168.5.0/255.255.255.0
|
||||
# explicit-ipv4, explicit-ipv6, net-priority, deny-roaming, no-udp,
|
||||
# keepalive, dpd, mobile-dpd, max-same-clients, tunnel-all-dns,
|
||||
# restrict-user-to-routes, user-profile, cgroup, stats-report-time,
|
||||
# mtu, idle-timeout, mobile-idle-timeout, and session-timeout.
|
||||
# mtu, idle-timeout, mobile-idle-timeout, restrict-user-to-ports,
|
||||
# and session-timeout.
|
||||
#
|
||||
# Note that the 'iroute' option allows to add routes on the server
|
||||
# based on a user or group. The syntax depends on the input accepted
|
||||
|
||||
152
src/ocserv-fw
152
src/ocserv-fw
@@ -3,22 +3,45 @@
|
||||
PATH=/sbin:/usr/sbin:$PATH
|
||||
|
||||
COMMENT="ocserv-fw"
|
||||
INPUT_CHAIN="INPUT"
|
||||
SEC_INPUT_CHAIN="INPUT-${COMMENT}-${DEVICE}"
|
||||
|
||||
if test "$1" = "--removeall";then
|
||||
eval "$(iptables -S | grep "comment ${COMMENT}" | sed -e 's/-A/-D/g' -e 's/^-/iptables -/g')"
|
||||
eval "$(ip6tables -S | grep "comment ${COMMENT}" | sed -e 's/-A/-D/g' -e 's/^-/ip6tables -/g')"
|
||||
|
||||
#delete chains
|
||||
eval "$(iptables -S | grep "INPUT-${COMMENT}" | sed -e 's/-N/-X/g' -e 's/^-/iptables -/g')"
|
||||
eval "$(ip6tables -S | grep "INPUT-${COMMENT}" | sed -e 's/-N/-X/g' -e 's/^-/ip6tables -/g')"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
execute_next_script() {
|
||||
if test -n "${OCSERV_NEXT_SCRIPT}";then
|
||||
TMP_SCRIPT="${OCSERV_NEXT_SCRIPT}"
|
||||
unset OCSERV_NEXT_SCRIPT
|
||||
/bin/sh "${TMP_SCRIPT}"
|
||||
fi
|
||||
}
|
||||
|
||||
clean_all_rules() {
|
||||
eval "$(iptables -S | grep "comment ${COMMENT}" | grep -e "-[io] ${DEVICE}" | sed -e 's/-A/-D/g' -e 's/^-/iptables -/g')" 2>/dev/null
|
||||
eval "$(ip6tables -S | grep "comment ${COMMENT}" | grep -e "-[io] ${DEVICE}" | sed -e 's/-A/-D/g' -e 's/^-/ip6tables -/g')" 2>/dev/null
|
||||
iptables -X ${SEC_INPUT_CHAIN} 2>/dev/null
|
||||
ip6tables -X ${SEC_INPUT_CHAIN} 2>/dev/null
|
||||
}
|
||||
|
||||
if test "${REASON}" = "connect";then
|
||||
MOD="-A"
|
||||
|
||||
#clear any leftover rules for thus device
|
||||
eval "$(iptables -S | grep "comment ${COMMENT}" | grep -e "-[io] ${DEVICE}" | sed -e 's/-A/-D/g' -e 's/^-/iptables -/g')" 2>/dev/null
|
||||
eval "$(ip6tables -S | grep "comment ${COMMENT}" | grep -e "-[io] ${DEVICE}" | sed -e 's/-A/-D/g' -e 's/^-/ip6tables -/g')" 2>/dev/null
|
||||
#clear any leftover rules for this device
|
||||
clean_all_rules
|
||||
else
|
||||
if test "${REASON}" = "disconnect";then
|
||||
MOD="-D"
|
||||
clean_all_rules
|
||||
set -e
|
||||
execute_next_script
|
||||
exit 0
|
||||
else
|
||||
logger -t ocserv-fw "unknown reason ${REASON}"
|
||||
exit 1
|
||||
@@ -28,11 +51,11 @@ fi
|
||||
set -e
|
||||
|
||||
allow_dns() {
|
||||
"$1" ${MOD} INPUT -i ${DEVICE} -p udp -d "$2" --dport 53 -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" ${MOD} OUTPUT -o ${DEVICE} -p udp -s "$2" --sport 53 -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" -A ${INPUT_CHAIN} -i ${DEVICE} -p udp -d "$2" --dport 53 -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" -A OUTPUT -o ${DEVICE} -p udp -s "$2" --sport 53 -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
|
||||
"$1" ${MOD} INPUT -i ${DEVICE} -p tcp -d "$2" --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" ${MOD} OUTPUT -o ${DEVICE} -p tcp -s "$2" --sport 53 -m state --state ESTABLISHED -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" -A ${INPUT_CHAIN} -i ${DEVICE} -p tcp -d "$2" --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" -A OUTPUT -o ${DEVICE} -p tcp -s "$2" --sport 53 -m state --state ESTABLISHED -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
}
|
||||
|
||||
allow_dns4() {
|
||||
@@ -44,8 +67,8 @@ allow_dns6() {
|
||||
}
|
||||
|
||||
allow_route() {
|
||||
"$1" ${MOD} INPUT -i ${DEVICE} -s "$2" -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" ${MOD} OUTPUT -o ${DEVICE} -d "$2" -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" -A ${INPUT_CHAIN} -i ${DEVICE} -s "$2" -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
"$1" -A OUTPUT -o ${DEVICE} -d "$2" -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
}
|
||||
|
||||
allow_route4() {
|
||||
@@ -57,8 +80,8 @@ allow_route6() {
|
||||
}
|
||||
|
||||
disallow_route() {
|
||||
"$1" ${MOD} INPUT -i ${DEVICE} -s "$2" -j DROP --match comment --comment "${COMMENT}"
|
||||
"$1" ${MOD} OUTPUT -o ${DEVICE} -d "$2" -j DROP --match comment --comment "${COMMENT}"
|
||||
"$1" -A ${INPUT_CHAIN} -i ${DEVICE} -s "$2" -j DROP --match comment --comment "${COMMENT}"
|
||||
"$1" -A OUTPUT -o ${DEVICE} -d "$2" -j DROP --match comment --comment "${COMMENT}"
|
||||
}
|
||||
|
||||
disallow_route4() {
|
||||
@@ -70,17 +93,40 @@ disallow_route6() {
|
||||
}
|
||||
|
||||
disallow_all() {
|
||||
iptables ${MOD} INPUT -i ${DEVICE} -j DROP --match comment --comment "${COMMENT}"
|
||||
iptables ${MOD} OUTPUT -o ${DEVICE} -j DROP --match comment --comment "${COMMENT}"
|
||||
ip6tables ${MOD} INPUT -i ${DEVICE} -j DROP --match comment --comment "${COMMENT}"
|
||||
ip6tables ${MOD} OUTPUT -o ${DEVICE} -j DROP --match comment --comment "${COMMENT}"
|
||||
iptables -A ${INPUT_CHAIN} -i ${DEVICE} -j DROP --match comment --comment "${COMMENT}"
|
||||
iptables -A OUTPUT -o ${DEVICE} -j DROP --match comment --comment "${COMMENT}"
|
||||
ip6tables -A ${INPUT_CHAIN} -i ${DEVICE} -j DROP --match comment --comment "${COMMENT}"
|
||||
ip6tables -A OUTPUT -o ${DEVICE} -j DROP --match comment --comment "${COMMENT}"
|
||||
}
|
||||
|
||||
allow_all() {
|
||||
iptables ${MOD} INPUT -i ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
iptables ${MOD} OUTPUT -o ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
ip6tables ${MOD} INPUT -i ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
ip6tables ${MOD} OUTPUT -o ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
iptables -A ${INPUT_CHAIN} -i ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
iptables -A OUTPUT -o ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
ip6tables -A ${INPUT_CHAIN} -i ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
ip6tables -A OUTPUT -o ${DEVICE} -j ACCEPT --match comment --comment "${COMMENT}"
|
||||
}
|
||||
|
||||
allow_port() {
|
||||
proto=$1
|
||||
port=$2
|
||||
|
||||
case "$proto" in
|
||||
icmp)
|
||||
iptables -A INPUT -i ${DEVICE} -p $proto -j ${INPUT_CHAIN} --match comment --comment "${COMMENT}"
|
||||
;;
|
||||
icmpv6)
|
||||
ip6tables -A INPUT -i ${DEVICE} -p $proto -j ${INPUT_CHAIN} --match comment --comment "${COMMENT}"
|
||||
;;
|
||||
*)
|
||||
iptables -A INPUT -i ${DEVICE} -p $proto --dport $port -j ${INPUT_CHAIN} --match comment --comment "${COMMENT}"
|
||||
ip6tables -A INPUT -i ${DEVICE} -p $proto --dport $port -j ${INPUT_CHAIN} --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}"
|
||||
}
|
||||
|
||||
# Allow DNS lookups
|
||||
@@ -88,38 +134,58 @@ for i in $OCSERV_DNS4;do
|
||||
allow_dns4 $i
|
||||
done
|
||||
|
||||
# block or allow routes
|
||||
for i in $OCSERV_DNS6;do
|
||||
allow_dns6 $i
|
||||
done
|
||||
|
||||
for i in $OCSERV_NO_ROUTES4;do
|
||||
disallow_route4 $i
|
||||
done
|
||||
# block ports - if needed
|
||||
if test -n "${OCSERV_PORTS}";then
|
||||
INPUT_CHAIN="${SEC_INPUT_CHAIN}"
|
||||
iptables -N "${INPUT_CHAIN}"
|
||||
ip6tables -N "${INPUT_CHAIN}"
|
||||
|
||||
for i in $OCSERV_NO_ROUTES6;do
|
||||
disallow_route6 $i
|
||||
done
|
||||
set ${OCSERV_PORTS}
|
||||
while test $# -gt 1; do
|
||||
proto=$1
|
||||
port=$2
|
||||
|
||||
if test -n "$OCSERV_ROUTES";then
|
||||
|
||||
for i in $OCSERV_ROUTES4;do
|
||||
allow_route4 $i
|
||||
allow_port $proto $port
|
||||
if test $# -gt 1;then
|
||||
shift 2
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
for i in $OCSERV_ROUTES6;do
|
||||
allow_route6 $i
|
||||
done
|
||||
|
||||
# no default route, don't allow anything except the configured routes
|
||||
disallow_all
|
||||
else
|
||||
allow_all
|
||||
disallow_all_ports
|
||||
fi
|
||||
|
||||
if test -n "${OCSERV_NEXT_SCRIPT}";then
|
||||
TMP_SCRIPT="${OCSERV_NEXT_SCRIPT}"
|
||||
unset OCSERV_NEXT_SCRIPT
|
||||
/bin/sh "${TMP_SCRIPT}"
|
||||
if test "${OCSERV_RESTRICT_TO_ROUTES}" = "1";then
|
||||
for i in $OCSERV_NO_ROUTES4;do
|
||||
disallow_route4 $i
|
||||
done
|
||||
|
||||
for i in $OCSERV_NO_ROUTES6;do
|
||||
disallow_route6 $i
|
||||
done
|
||||
|
||||
if test -n "$OCSERV_ROUTES";then
|
||||
|
||||
for i in $OCSERV_ROUTES4;do
|
||||
allow_route4 $i
|
||||
done
|
||||
|
||||
for i in $OCSERV_ROUTES6;do
|
||||
allow_route6 $i
|
||||
done
|
||||
|
||||
# no default route, don't allow anything except the configured routes
|
||||
disallow_all
|
||||
else
|
||||
allow_all
|
||||
fi
|
||||
fi
|
||||
|
||||
execute_next_script
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Nikos Mavrogiannopoulos
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
* Copyright (C) 2014, 2015 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <common.h>
|
||||
#include <ip-util.h>
|
||||
#include <c-strcase.h>
|
||||
#include <c-ctype.h>
|
||||
|
||||
#include <vpn.h>
|
||||
#include <main.h>
|
||||
@@ -64,6 +65,7 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "ipv6-subnet-prefix", .type = OPTION_NUMERIC },
|
||||
{ .name = "explicit-ipv4", .type = OPTION_STRING },
|
||||
{ .name = "explicit-ipv6", .type = OPTION_STRING },
|
||||
{ .name = "restrict-user-to-ports", .type = OPTION_STRING },
|
||||
{ .name = "rx-data-per-sec", .type = OPTION_NUMERIC },
|
||||
{ .name = "tx-data-per-sec", .type = OPTION_NUMERIC },
|
||||
{ .name = "net-priority", .type = OPTION_STRING },
|
||||
@@ -138,7 +140,7 @@ static struct cfg_options available_options[] = {
|
||||
|
||||
static int handle_option(const tOptionValue* val)
|
||||
{
|
||||
unsigned j;
|
||||
unsigned j;
|
||||
|
||||
for (j=0;j<sizeof(available_options)/sizeof(available_options[0]);j++) {
|
||||
if (strcasecmp(val->pzName, available_options[j].name) == 0) {
|
||||
@@ -149,6 +151,7 @@ unsigned j;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This will parse the configuration file and append/replace data into
|
||||
* config. The provided config must either be memset to zero, or be
|
||||
* already allocated using this function.
|
||||
@@ -160,6 +163,7 @@ int parse_group_cfg_file(struct cfg_st *global_config,
|
||||
{
|
||||
tOptionValue const * pov;
|
||||
const tOptionValue* val, *prev;
|
||||
char *tmp;
|
||||
unsigned prefix = 0;
|
||||
int ret;
|
||||
unsigned j;
|
||||
@@ -272,6 +276,16 @@ unsigned j;
|
||||
|
||||
READ_RAW_STRING("user-profile", msg->config->xml_config_file);
|
||||
|
||||
tmp = NULL;
|
||||
READ_RAW_STRING("restrict-user-to-ports", tmp);
|
||||
if (tmp) {
|
||||
ret = cfg_parse_ports(pool, &msg->config->fw_ports, &msg->config->n_fw_ports, tmp);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
talloc_free(tmp);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
fail:
|
||||
optionUnloadNested(pov);
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include <minmax.h>
|
||||
#include <auth/common.h>
|
||||
|
||||
#include <ipc.pb-c.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define _OCSERV_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
# if _OCSERV_GCC_VERSION >= 30000
|
||||
@@ -63,7 +65,9 @@ typedef enum fw_proto_t {
|
||||
PROTO_UDP,
|
||||
PROTO_TCP,
|
||||
PROTO_SCTP,
|
||||
PROTO_ALL
|
||||
PROTO_ESP,
|
||||
PROTO_ICMP,
|
||||
PROTO_ICMPv6
|
||||
} fw_proto_t;
|
||||
|
||||
/* Banning works with a point system. A wrong password
|
||||
@@ -363,6 +367,9 @@ struct cfg_st {
|
||||
char **known_iroutes;
|
||||
size_t known_iroutes_size;
|
||||
|
||||
FwPortSt **fw_ports;
|
||||
size_t n_fw_ports;
|
||||
|
||||
/* the tun network */
|
||||
struct vpn_st network;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user