LOCAL_PREFIX \
MODE \
PEER \
+ POOLS \
PSK \
REMOTE_ID \
REMOTE_PREFIX \
SECURITY_POLICY \
START_ACTION \
+ TYPE \
ENABLED"
IPSEC_POOL_CONFIG_SETTINGS="\
- DNS_SERVERS \
- NETWORKS"
+ DNS_SERVER \
+ NETWORK \
+ TYPE"
# Default values
IPSEC_DEFAULT_AUTH_MODE="PSK"
IPSEC_DEFAULT_MODE="tunnel"
IPSEC_DEFAULT_SECURITY_POLICY="system"
IPSEC_DEFAULT_START_ACTION="on-demand"
+IPSEC_DEFAULT_TYPE="net-to-net"
IPSEC_VALID_MODES="gre-transport tunnel vti"
IPSEC_VALID_AUTH_MODES="PSK"
case "${action}" in
connection)
- cli_ipsec_connection $@
+ cli_ipsec_connection "$@"
;;
pool)
- cli_ipsec_pool $@
+ cli_ipsec_pool "$@"
;;
*)
error "Unrecognized argument: ${action}"
shift 2
case "${key}" in
- authentication|down|disable|dpd|enable|inactivity_timeout|local|mode|peer|remote|security_policy|start_action|up)
- ipsec_connection_${key} ${connection} $@
+ authentication|down|disable|dpd|enable|inactivity_timeout|local|mode|peer|pool|remote|security_policy|start_action|up)
+ ipsec_connection_${key} ${connection} "$@"
;;
show)
cli_ipsec_connection_show "${connection}"
case "${action}" in
new)
- ipsec_connection_new $@
+ ipsec_connection_new "$@"
;;
destroy)
- cli_ipsec_connection_destroy $@
+ cli_ipsec_connection_destroy "$@"
;;
""|*)
if [ -n "${action}" ]; then
case "${key}" in
dns_server|network)
- ipsec_pool_${key} ${pool} $@
+ ipsec_pool_${key} ${pool} "$@"
;;
show)
cli_ipsec_pool_show "${pool}"
case "${action}" in
new)
- ipsec_pool_new $@
+ ipsec_pool_new "$@"
;;
destroy)
- ipsec_pool_destroy $@
+ ipsec_pool_destroy "$@"
;;
""|*)
if [ -n "${action}" ]; then
if [ $# -eq 0 ] && [ -n "${IPSEC_CONNECTION_CONFIG_SETTINGS}" ]; then
list_append args ${IPSEC_CONNECTION_CONFIG_SETTINGS}
else
- list_append args $@
+ list_append args "$@"
fi
local path="${NETWORK_IPSEC_CONNS_DIR}/${connection}/settings"
case ${cmd} in
mode)
- ipsec_connection_authentication_mode "${connection}" $@
+ ipsec_connection_authentication_mode "${connection}" "$@"
;;
pre-shared-key)
- ipsec_connection_authentication_psk "${connection}" $@
+ ipsec_connection_authentication_psk "${connection}" "$@"
;;
*)
log ERROR "Unrecognized argument: ${cmd}"
case ${cmd} in
action)
- ipsec_connection_dpd_action "${connection}" $@
+ ipsec_connection_dpd_action "${connection}" "$@"
;;
delay)
- ipsec_connection_dpd_delay "${connection}" $@
+ ipsec_connection_dpd_delay "${connection}" "$@"
;;
timeout)
- ipsec_connection_dpd_timeout "${connection}" $@
+ ipsec_connection_dpd_timeout "${connection}" "$@"
;;
*)
log ERROR "Unrecognized argument: ${cmd}"
local value=$@
if ! isinteger value; then
- value=$(parse_time $@)
+ value=$(parse_time "$@")
if [ ! $? -eq 0 ]; then
log ERROR "Parsing the passed time was not sucessful please check the passed values."
return ${EXIT_ERROR}
local value=$@
if ! isinteger value; then
- value=$(parse_time $@)
+ value=$(parse_time "$@")
if [ ! $? -eq 0 ]; then
log ERROR "Parsing the passed time was not sucessful please check the passed values."
return ${EXIT_ERROR}
case ${cmd} in
address)
- ipsec_connection_local_address "${connection}" $@
+ ipsec_connection_local_address "${connection}" "$@"
;;
id)
- ipsec_connection_id "${connection}" "LOCAL" $@
+ ipsec_connection_id "${connection}" "LOCAL" "$@"
;;
prefix)
- ipsec_connection_prefix "${connection}" "LOCAL" $@
+ ipsec_connection_prefix "${connection}" "LOCAL" "$@"
;;
*)
log ERROR "Unrecognized argument: ${cmd}"
log ERROR "Id '${id}' is invalid"
return ${EXIT_ERROR}
fi
-
+
if ! ipsec_connection_write_config_key "${connection}" "${type}_ID" ${id}; then
log ERROR "Could not write configuration settings"
return ${EXIT_ERROR}
fi
-
+
return ${EXIT_OK}
}
-# Set the local or remote prefix
+# Set the local or remote prefix
ipsec_connection_prefix() {
if [ ! $# -ge 3 ]; then
log ERROR "Not enough arguments"
local connection=${1}
local type=${2}
shift 2
-
+
local _prefix="${type}_PREFIX"
local "${_prefix}"
if ! ipsec_connection_read_config "${connection}" "${_prefix}"; then
return ${EXIT_OK}
}
+# Set the pools to use
+ipsec_connection_pool() {
+ if [ ! $# -ge 2 ]; then
+ log ERROR "Not enough arguments"
+ return ${EXIT_ERROR}
+ fi
+ local connection=${1}
+ shift
+
+ local POOLS
+ if ! ipsec_connection_read_config "${connection}" "POOLS"; then
+ return ${EXIT_ERROR}
+ fi
+
+ # Remove duplicated entries to proceed the list safely
+ assign "POOLS" "$(list_unique ${POOLS})"
+
+ local pools_added
+ local pools_removed
+ local pools_set
+
+ while [ $# -gt 0 ]; do
+ local arg="${1}"
+
+ case "${arg}" in
+ +*)
+ list_append pools_added "${arg:1}"
+ ;;
+ -*)
+ list_append pools_removed "${arg:1}"
+ ;;
+ [A-Za-z0-9]*)
+ list_append pools_set "${arg}"
+ ;;
+ *)
+ error "Invalid argument: ${arg}"
+ return ${EXIT_ERROR}
+ ;;
+ esac
+ shift
+ done
+
+ # Check if the user is trying a mixed operation
+ if ! list_is_empty pools_set && (! list_is_empty pools_added || ! list_is_empty pools_removed); then
+ error "You cannot reset the pools list and add or remove pools at the same time"
+ return ${EXIT_ERROR}
+ fi
+
+ # Set new pools list
+ if ! list_is_empty pools_set; then
+ # Check if all pools are valid
+ local pool
+ for pool in ${pools_set}; do
+ if ! ipsec_pool_exists ${pool} || ! ipsec_pool_check_config ${pool}; then
+ error "Pool ${pool} is not valid"
+ return ${EXIT_ERROR}
+ fi
+ done
+
+ assign "POOLS" "${pools_set}"
+
+ # Perform incremental updates
+ else
+ local pool
+
+ # Perform all removals
+ for pool in ${pools_removed}; do
+ if ! list_remove "POOLS" ${pool}; then
+ warning "${pool} was not on the list and could not be removed"
+ fi
+ done
+
+
+ for pool in ${pools_added}; do
+ if ipsec_pool_exists ${pool} && ipsec_pool_check_config ${pool}; then
+ if ! list_append_unique "POOLS" ${pool}; then
+ warning "${pool} is already on the prefix list"
+ fi
+ else
+ warning "${pool} is not a valid pool"
+ fi
+ done
+ fi
+
+ # Check if the list contain at least one valid pool
+ if list_is_empty POOLS; then
+ error "Cannot save an empty pool list"
+ return ${EXIT_ERROR}
+ fi
+
+ # Save everything
+ if ! ipsec_connection_write_config_key "${connection}" "POOLS" ${POOLS}; then
+ log ERROR "Could not write configuration settings"
+ fi
+
+ return ${EXIT_OK}
+}
+
# Handle the cli after remote
ipsec_connection_remote() {
if [ ! $# -ge 2 ]; then
case ${cmd} in
id)
- ipsec_connection_id "${connection}" "REMOTE" $@
+ ipsec_connection_id "${connection}" "REMOTE" "$@"
;;
prefix)
- ipsec_connection_prefix "${connection}" "REMOTE" $@
+ ipsec_connection_prefix "${connection}" "REMOTE" "$@"
;;
*)
log ERROR "Unrecognized argument: ${cmd}"
local value=$@
if ! isinteger value; then
- value=$(parse_time $@)
+ value=$(parse_time "$@")
if [ ! $? -eq 0 ]; then
log ERROR "Parsing the passed time was not sucessful please check the passed values."
return ${EXIT_ERROR}
# Function that creates one VPN IPsec connection
ipsec_connection_new() {
- if [ $# -gt 1 ]; then
+ if [ $# -gt 2 ]; then
error "Too many arguments"
return ${EXIT_ERROR}
fi
local connection="${1}"
+ local type="${2}"
+
if ! isset connection; then
error "Please provide a connection name"
return ${EXIT_ERROR}
return ${EXIT_ERROR}
fi
+ # Set TYPE to default if not set by the user
+ if ! isset type; then
+ type="${IPSEC_DEFAULT_TYPE}"
+ fi
+
+ if ! isoneof "type" "net-to-net" "host-to-net"; then
+ error "Type is invalid"
+ return ${EXIT_ERROR}
+ fi
+
log DEBUG "Creating VPN IPsec connection ${connection}"
if ! mkdir -p "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
ENABLED=${IPSEC_DEFAULT_ENABLED}
MODE=${IPSEC_DEFAULT_MODE}
START_ACTION=${IPSEC_DEFAULT_START_ACTION}
+ TYPE="${type}"
INACTIVITY_TIMEOUT=${IPSEC_DEFAULT_INACTIVITY_TIMEOUT}
SECURITY_POLICY=${IPSEC_DEFAULT_SECURITY_POLICY}
# Function that deletes based on the passed parameters one ore more vpn security policies
ipsec_connection_destroy() {
local connection
- for connection in $@; do
+ for connection in "$@"; do
if ! ipsec_connection_exists "${connection}"; then
log ERROR "The VPN IPsec connection ${connection} does not exist."
continue
ipsec_connection_to_strongswan() {
local connection="${1}"
+ log DEBUG "Generating IPsec configuration for ${connection}"
# Read the config settings
local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
print_indent 2 "fragmentation = yes"
print
+
+ # Host-to-Net specific settings
+ case "${TYPE}" in
+ host-to-net)
+ # Pools
+ if isset POOLS; then
+ print_indent 2 "# Pools"
+ print_indent 2 "pools = $(list_join POOLS ", ")"
+ print
+ fi
+ ;;
+ esac
+
# Local
print_indent 2 "local {"
print
fi
- # Start Action
- print_indent 4 "# Start Action"
- case "${START_ACTION}" in
- on-demand)
- print_indent 4 "start_action = trap"
- print_indent 4 "close_action = trap"
- ;;
- wait)
- print_indent 4 "start_action = none"
- print_indent 4 "close_action = none"
- ;;
- always-on|*)
- print_indent 4 "start_action = start"
- print_indent 4 "close_action = start"
+ # Net-to-Net specific settings
+ case "${TYPE}" in
+ net-to-net)
+ # Start Action
+ print_indent 4 "# Start Action"
+ case "${START_ACTION}" in
+ on-demand)
+ print_indent 4 "start_action = trap"
+ print_indent 4 "close_action = trap"
+ ;;
+ wait)
+ print_indent 4 "start_action = none"
+ print_indent 4 "close_action = none"
+ ;;
+ always-on|*)
+ print_indent 4 "start_action = start"
+ print_indent 4 "close_action = start"
+ ;;
+ esac
+ print
;;
esac
- print
print_indent 3 "}"
print_indent 2 "}"
log ERROR "Could not write configuration settings for VPN IPsec pool ${pool}"
return ${EXIT_ERROR}
fi
+
+ if ! ipsec_pool_reload ${pool}; then
+ log WARNING "Could not reload IPsec pool ${pool}"
+ fi
+
+ # When we get here the writing of the config file was successful
+ return ${EXIT_OK}
}
# This funtion writes the value for one key to a via ${connection} specificated
if [ $# -eq 0 ] && [ -n "${IPSEC_POOL_CONFIG_SETTINGS}" ]; then
list_append args ${IPSEC_POOL_CONFIG_SETTINGS}
else
- list_append args $@
+ list_append args "$@"
fi
local path="${NETWORK_IPSEC_POOLS_DIR}/${pool}/settings"
# one ore more vpn ipsec pools
ipsec_pool_destroy() {
local pool
- for pool in $@; do
+ for pool in "$@"; do
if ! ipsec_pool_exists "${pool}"; then
log ERROR "The VPN IPsec pool ${pool} does not exist."
continue
done
}
+ipsec_pool_set_type() {
+ local pool=${1}
+ local ip=${2}
+ assert isset pool
+ assert isset ip
+
+ local type=$(ip_detect_protocol ${ip})
+
+ if ! isset type; then
+ error "Cannot detect IP protocol of ${ip}"
+ return ${EXIT_ERROR}
+ else
+ log DEBUG "IP protocol of ${ip} is ${type}"
+ if ! ipsec_pool_write_config_key "${pool}" "TYPE" ${type}; then
+ log ERROR "Could not write configuration settings"
+ return ${EXIT_ERROR}
+ fi
+ fi
+}
+
ipsec_pool_network() {
- if [ ! $# -ge 2 ]; then
+ if [ ! $# -eq 2 ]; then
log ERROR "Not enough arguments"
return ${EXIT_ERROR}
fi
local pool=${1}
- shift 1
+ local network=${2}
- local NETWORKS
- if ! ipsec_pool_read_config "${pool}" "NETWORKS"; then
+ local TYPE
+ if ! ipsec_pool_read_config ${pool} "TYPE"; then
+ error "Failed to read configuration settings for pool '${pool}'"
return ${EXIT_ERROR}
fi
- # Remove duplicated entries to proceed the list safely
- assign "NETWORKS" "$(list_unique ${NETWORKS})"
-
- local networks_added
- local networks_removed
- local networks_set
+ if ! isset TYPE; then
+ if ! ip_net_is_valid ${network}; then
+ log ERROR "Network '${network}' is invalid"
+ return ${EXIT_ERROR}
+ fi
- while [ $# -gt 0 ]; do
- local arg="${1}"
+ if ! ipsec_pool_set_type ${pool} ${network}; then
+ log ERROR "Could not set type for IPsec pool ${pool}"
+ return ${EXIT_ERROR}
+ fi
+ else
+ if ! ${TYPE}_net_is_valid ${network}; then
+ log ERROR "Network '${network}' is invalid"
+ return ${EXIT_ERROR}
+ fi
+ fi
- case "${arg}" in
- +*)
- list_append networks_added "${arg:1}"
- ;;
- -*)
- list_append networks_removed "${arg:1}"
- ;;
- [A-Fa-f0-9]*)
- list_append networks_set "${arg}"
- ;;
- *)
- error "Invalid argument: ${arg}"
- return ${EXIT_ERROR}
- ;;
- esac
- shift
- done
+ if ! ipsec_pool_write_config_key "${pool}" "NETWORK" ${network}; then
+ log ERROR "Could not write configuration settings"
+ return ${EXIT_ERROR}
+ fi
+}
- # Check if the user is trying a mixed operation
- if ! list_is_empty networks_set && (! list_is_empty networks_added || ! list_is_empty networks_removed); then
- error "You cannot reset the networks list and add or remove networks at the same time"
+ipsec_pool_dns_server() {
+ if [ ! $# -eq 2 ]; then
+ log ERROR "Not enough arguments"
return ${EXIT_ERROR}
fi
+ local pool=${1}
+ local dns_server=${2}
- # Set new prefix list
- if ! list_is_empty networks_set; then
- # Check if all networks are valid
- local network
- for network in ${networks_set}; do
- if ! ip_net_is_valid ${network}; then
- error "Unsupported prefix: ${network}"
- return ${EXIT_ERROR}
- fi
- done
+ local TYPE
+ if ! ipsec_pool_read_config ${pool} "TYPE"; then
+ error "Failed to read configuration settings for pool '${pool}'"
+ return ${EXIT_ERROR}
+ fi
- assign "NETWORKS" "${networks_set}"
+ if ! isset TYPE; then
+ if ! ip_is_valid ${dns_server}; then
+ log ERROR "DNS server '${dns_server}' is invalid"
+ return ${EXIT_ERROR}
+ fi
- # Perform incremental updates
+ if ! ipsec_pool_set_type ${pool} ${dns_server}; then
+ log ERROR "Could not set type for IPsec pool ${pool}"
+ return ${EXIT_ERROR}
+ fi
else
- # Perform all removals
- local network
- for network in ${networks_removed}; do
- if ! list_remove "NETWORKS" ${network}; then
- warning "${network} was not on the list and could not be removed"
- fi
- done
-
- for network in ${networks_added}; do
- if ip_net_is_valid ${network}; then
- if ! list_append_unique "NETWORKS" ${network}; then
- warning "${network} is already on the network list"
- fi
- else
- warning "${network} is not a valid IP network and could not be added"
- fi
- done
- fi
-
- # Check if the list contain at least one valid network
- if list_is_empty "NETWORKS"; then
- error "Cannot save an empty network list"
- return ${EXIT_ERROR}
+ if ! ${TYPE}_is_valid ${dns_server}; then
+ log ERROR "DNS server '${dns_server}' is invalid"
+ return ${EXIT_ERROR}
+ fi
fi
- # Save everything
- if ! ipsec_pool_write_config_key "${pool}" "NETWORKS" "${NETWORKS}"; then
+ if ! ipsec_pool_write_config_key "${pool}" "DNS_SERVER" ${dns_server}; then
log ERROR "Could not write configuration settings"
+ return ${EXIT_ERROR}
fi
-
- return ${EXIT_OK}
}
-ipsec_pool_dns_server() {
- if [ ! $# -ge 2 ]; then
- log ERROR "Not enough arguments"
+ipsec_pool_check_config() {
+ local pool=${1}
+ assert isset pool
+
+ local ${IPSEC_POOL_CONFIG_SETTINGS}
+ if ! ipsec_pool_read_config "${pool}"; then
+ log ERROR "Could not read configuration settings"
return ${EXIT_ERROR}
fi
- local pool=${1}
- shift 1
- local NETWORK
- if ! ipsec_pool_read_config "${pool}" "DNS_SERVERS"; then
+ if ! isset NETWORK; then
+ log ERROR "Network for IPSec pool ${pool} is not set"
return ${EXIT_ERROR}
fi
- # Remove duplicated entries to proceed the list safely
- assign "DNS_SERVERS" "$(list_unique ${DNS_SERVERS})"
+ if ! isset TYPE; then
+ TYPE=$(ip_detect_protocol ${NETWORK})
+ log DEBUG "IP protocol of ${NETWORK} is ${TYPE}"
+ if ! isset TYPE; then
+ error "Cannot detect IP protocol of ${NETWORK}"
+ return ${EXIT_ERROR}
+ else
+ if ! ipsec_pool_write_config_key "${pool}" "TYPE" ${TYPE}; then
+ log ERROR "Could not write configuration settings"
+ return ${EXIT_ERROR}
+ fi
+ fi
+ else
+ if ! ${TYPE}_net_is_valid ${NETWORK}; then
+ log ERROR "NETWORK '${NETWORK}' is invalid"
+ return ${EXIT_ERROR}
+ fi
- local dns_servers_added
- local dns_servers_removed
- local dns_servers_set
+ if isset DNS_SERVER && ! ${TYPE}_is_valid ${DNS_SERVER}; then
+ log ERROR "DNS server '${DNS_SERVER}' is invalid"
+ return ${EXIT_ERROR}
+ fi
+ fi
- while [ $# -gt 0 ]; do
- local arg="${1}"
+ return ${EXIT_OK}
+}
- case "${arg}" in
- +*)
- list_append dns_servers_added "${arg:1}"
- ;;
- -*)
- list_append dns_servers_removed "${arg:1}"
- ;;
- [A-Fa-f0-9]*)
- list_append dns_servers_set "${arg}"
- ;;
- *)
- error "Invalid argument: ${arg}"
- return ${EXIT_ERROR}
- ;;
- esac
- shift
- done
+ipsec_pool_reload() {
+ local pool=${1}
- # Check if the user is trying a mixed operation
- if ! list_is_empty dns_servers_set && (! list_is_empty dns_servers_added || ! list_is_empty dns_servers_removed); then
- error "You cannot reset the DNS servers list and add or remove DNS servers at the same time"
+ if ! ipsec_pool_to_strongswan ${pool}; then
+ log ERROR "Could not generate strongswan config for ${pool}"
return ${EXIT_ERROR}
fi
- # Set new dns server list
- if ! list_is_empty dns_servers_set; then
- # Check if all dns servers are valid
- local dns_server
- for dns_server in ${dns_servers_set}; do
- if ! ip_is_valid ${dns_server}; then
- error "Invalid DNS server: ${dns_server}"
- return ${EXIT_ERROR}
- fi
- done
+ ipsec_strongswan_load
+}
- assign "DNS_SERVERS" "${dns_servers_set}"
+ipsec_pool_to_strongswan() {
+ local pool=${1}
- # Perform incremental updates
- else
- # Perform all removals
- local dns_server
- for dns_server in ${dns_servers_removed}; do
- if ! list_remove "DNS_SERVERS" ${dns_server}; then
- warning "${dns_server} was not on the list and could not be removed"
- fi
- done
+ log DEBUG "Generating IPsec pool config for ${pool}"
- for dns_server in ${dns_servers_added}; do
- if ip_is_valid ${dns_server}; then
- if ! list_append_unique "DNS_SERVERS" ${dns_server}; then
- warning "${dns_server} is already on the DNS server list"
- fi
- else
- warning "${dns_server} is not a valid DNS server and could not be added"
- fi
- done
+ local ${IPSEC_POOL_CONFIG_SETTINGS}
+ if ! ipsec_pool_read_config "${pool}"; then
+ return ${EXIT_ERROR}
fi
- # Check if the list contain at least one valid prefix
- if list_is_empty "DNS_SERVERS"; then
- error "Cannot save an empty DNS server list"
+ if isset NETWORK && ! ipsec_pool_check_config "${pool}"; then
+ log ERROR "Configuration of ${pool} seems to be invalid"
return ${EXIT_ERROR}
fi
- # Save everything
- if ! ipsec_pool_write_config_key "${pool}" "DNS_SERVERS" "${DNS_SERVER}"; then
- log ERROR "Could not write configuration settings"
- fi
+ local path="${NETWORK_IPSEC_SWANCTL_POOLS_DIR}/${pool}.conf"
- return ${EXIT_OK}
+ (
+ config_header "strongSwan pool configuration"
+
+ if isset NETWORK; then
+ print_indent 0 "pools {"
+
+ print_indent 1 "${pool} {"
+ print_indent 2 "addrs = ${NETWORK}"
+
+ if isset DNS_SERVER; then
+ print_indent 2 "dns = ${DNS_SERVER}"
+ fi
+
+ print_indent 1 "}"
+ print_indent 0 "}"
+ fi
+ ) > ${path}
}