Update fastd

This commit is contained in:
Matthias Schiffer 2013-09-10 19:00:16 +02:00
parent 053953b68b
commit e561733c70
4 changed files with 365 additions and 160 deletions

View File

@ -8,29 +8,47 @@ config FASTD_ENABLE_METHOD_XSALSA20_POLY1305
config FASTD_ENABLE_METHOD_AES128_GCM
bool "Enable aes128-gcm method"
depends on PACKAGE_fastd
select FASTD_ENABLE_CRYPTO_AES128CTR_NACL if !FASTD_ENABLE_CRYPTO_AES128CTR_LINUX
select FASTD_ENABLE_CRYPTO_GHASH_BUILTIN if !FASTD_ENABLE_CRYPTO_GHASH_LINUX
depends on PACKAGE_fastd && (FASTD_ENABLE_CRYPTO_AES128CTR_NACL || FASTD_ENABLE_CRYPTO_AES128CTR_LINUX) && (FASTD_ENABLE_CRYPTO_GHASH_BUILTIN || FASTD_ENABLE_CRYPTO_GHASH_LINUX)
default n
config FASTD_ENABLE_CRYPTO_AES128CTR_NACL
bool "Include the AES128-CTR implementation from the NaCl library"
depends on FASTD_ENABLE_METHOD_AES128_GCM
depends on PACKAGE_fastd
default y
config FASTD_ENABLE_CRYPTO_AES128CTR_LINUX
bool "Support using the AES128-CTR implementation in the Linux kernel"
depends on FASTD_ENABLE_METHOD_AES128_GCM
default y
depends on PACKAGE_fastd
default n
config FASTD_ENABLE_CRYPTO_GHASH_BUILTIN
bool "Include the built-in GHASH implementation"
depends on FASTD_ENABLE_METHOD_AES128_GCM
depends on PACKAGE_fastd
default y
config FASTD_ENABLE_CRYPTO_GHASH_LINUX
bool "Support using the GHASH implementation in the Linux kernel"
depends on FASTD_ENABLE_METHOD_AES128_GCM
default y
depends on PACKAGE_fastd
default n
config FASTD_WITH_CMDLINE_USER
bool "Include support for setting user/group related options on the command line"
depends on PACKAGE_fastd
default n
config FASTD_WITH_CMDLINE_LOGGING
bool "Include support for setting logging related options on the command line"
depends on PACKAGE_fastd
default n
config FASTD_WITH_CMDLINE_OPERATION
bool "Include support for setting options related to the VPN operation (like mode, interface, encryption method) on the command line"
depends on PACKAGE_fastd
default n
config FASTD_WITH_CMDLINE_COMMANDS
bool "Include support for setting handler scripts (e.g. --on-up) on the command line"
depends on PACKAGE_fastd
default n
endmenu

View File

@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fastd
PKG_VERSION:=7
PKG_RELEASE:=3
PKG_VERSION:=9
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/43
PKG_MD5SUM:=17dd6049d072f24dba9d959ac9edbc16
PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/63
PKG_MD5SUM:=55dd7ce3bc1619a1cb65aea613eb1659
PKG_CONFIG_DEPENDS:=\
CONFIG_FASTD_ENABLE_METHOD_XSALSA20_POLY1305 \
@ -21,7 +21,12 @@ PKG_CONFIG_DEPENDS:=\
CONFIG_FASTD_ENABLE_CRYPTO_AES128CTR_NACL \
CONFIG_FASTD_ENABLE_CRYPTO_AES128CTR_LINUX \
CONFIG_FASTD_ENABLE_CRYPTO_GHASH_BUILTIN \
CONFIG_FASTD_ENABLE_CRYPTO_GHASH_LINUX
CONFIG_FASTD_ENABLE_CRYPTO_GHASH_LINUX \
CONFIG_FASTD_WITH_CMDLINE_USER \
CONFIG_FASTD_WITH_CMDLINE_LOGGING \
CONFIG_FASTD_WITH_CMDLINE_OPERATION \
CONFIG_FASTD_WITH_CMDLINE_COMMANDS
PKG_BUILD_DEPENDS:=nacl libuecc
@ -93,6 +98,38 @@ CMAKE_OPTIONS += \
-DWITH_CRYPTO_GHASH_LINUX:BOOL=FALSE
endif
ifeq ($(CONFIG_FASTD_WITH_CMDLINE_USER),y)
CMAKE_OPTIONS += \
-DWITH_CMDLINE_USER:BOOL=TRUE
else
CMAKE_OPTIONS += \
-DWITH_CMDLINE_USER:BOOL=FALSE
endif
ifeq ($(CONFIG_FASTD_WITH_CMDLINE_LOGGING),y)
CMAKE_OPTIONS += \
-DWITH_CMDLINE_LOGGING:BOOL=TRUE
else
CMAKE_OPTIONS += \
-DWITH_CMDLINE_LOGGING:BOOL=FALSE
endif
ifeq ($(CONFIG_FASTD_WITH_CMDLINE_OPERATION),y)
CMAKE_OPTIONS += \
-DWITH_CMDLINE_OPERATION:BOOL=TRUE
else
CMAKE_OPTIONS += \
-DWITH_CMDLINE_OPERATION:BOOL=FALSE
endif
ifeq ($(CONFIG_FASTD_WITH_CMDLINE_COMMANDS),y)
CMAKE_OPTIONS += \
-DWITH_CMDLINE_COMMANDS:BOOL=TRUE
else
CMAKE_OPTIONS += \
-DWITH_CMDLINE_COMMANDS:BOOL=FALSE
endif
define Package/fastd/description
Fast and secure tunneling daemon, which is optimized on small code size and few dependencies

View File

@ -7,13 +7,16 @@ config fastd sample_config
# Sets a static config file, optional
# Options set via UCI have higher priority that statically configured ones
# If a config file is set all other options except the interface may become optional if the are set in the file
# list config '/etc/fastd/sample_config/fastd.conf'
# Sets a directory from which peers configurations are read
# Configures a single static peer from a configuration file
# list config_peer '/etc/fastd/sample_config/sample_peer.conf'
# Sets an additional directory from which peers configurations are read
# The peer list can be reloaded without restarting fastd
# Peer can either be configured via UCI (see example below) or via peer dirs
list config_peer_dir '/etc/fastd/sample_config/peers'
# Peer can either be configured via UCI (see examples below) or via peer dirs
# Can't be used in tun mode
# list config_peer_dir '/etc/fastd/sample_config/peers'
# Sets the log level
# Possible values: error, warn, info, verbose, debug
@ -22,7 +25,7 @@ config fastd sample_config
# IP address and port of the local end, optional
# 'any' can be used to bind to both IPv4 and IPv6
# If the port is 0 fastd will bind to a random port
# If no port is given fastd will bind to a random port
# list bind 'any:1337'
# list bind '0.0.0.0:1337'
# list bind '[::]:1337'
@ -49,11 +52,29 @@ config fastd sample_config
# WARNING: Only enable this if you know what you are doing, as this can lead to forwarding loops!
option forward 0
# Limits the maximum number of connections, optional
# option peer_limit 5
# The secret key
# A keypair can be generated with `fastd --generate-key`
# When the corresponding public key is lost it can be recovered with `/etc/init.d/fastd show-key <config name>`
# option secret '0000000000000000000000000000000000000000000000000000000000000000'
# Sets the user to run fastd as. Defaults to root
# option user 'daemon'
# Sets the group to run fastd as. Defaults to the user's primary group
# option group 'daemon'
# If set to 1, the logs won't contain peers' IP addresses
# option hide_ip_addresses '0'
# If set to 1, the logs won't contain peers' MAC addresses
# option hide_mac_addresses '0'
# Read the documentation about this one. Only ever useful in severly broken networks.
# option pmtu ''
# command to configure IP addresses etc. after the tunnel interface is up; $1 will be the interface name (optional)
# option up ''
@ -63,32 +84,54 @@ config fastd sample_config
config peer sample_peer
# Set to 1 to enable this peer:
option enabled 0
# Set to 1 to enable this peer
# In tap mode peers can be reloaded dynamically
option enabled 0
# Controls which instance this peer is associated with
option net 'sample_config'
option net 'sample_config'
# Controls which peer group this peer belongs to, optional
# For most use cases peer groups aren't necessary
# option group 'sample_group'
# The peer's public key
option key '0000000000000000000000000000000000000000000000000000000000000000'
# A complete remote specification consists of an address or a hostname, and a port
# When a hostname is given, it is recommended to specify an address family to use
# A remote specification consists of an address or a hostname, and a port
# When a hostname is given, it is recommended to specify the address family to use
# It is possible to specify no, one or multiple remotes
# (but all entries must designate the same host as the public key must be unique)
# list remote '192.0.2.1:1337'
# list remote '[2001:db8::1]:1337'
# list remote '"example.com" port 1337'
# list remote 'ipv4 "example.com" port 1337'
# list remote 'ipv6 "example.com" port 1337'
# The address to connect to (optional)
# option address '192.0.2.1'
# option address '[2001:db8::1]'
# Setting float to 1 allow incoming connections with this key from other addresses/hostnames/ports than the specified remotes
# option float 0
# The hostname to connect to (optional)
# option hostname 'example.com'
# The address family to use to connect to the hostname (optional)
# Must be 'ipv4' or 'ipv6'
# Has no effect when an address is specified
# option address_family 'ipv4'
config peer_group sample_group
# The remote port to connect to (optional)
# option port 1337
# Set to 1 to enable this peer group
option enabled 0
# Setting float to 1 allow incoming connections with this key from other addresses/hostnames/ports than the specified remote
option float 0
# Controls which instance this peer group is associated with
# Peer groups can't be used in tun mode
option net 'sample_config'
# Allows configuring nested groups
# option parent 'other_group'
# Includes another config file inside the peer group definition
# list config '/etc/fastd/sample_config/sample_group.conf'
# Configures a single static peer from a configuration file
# list config_peer '/etc/fastd/sample_config/sample_peer.conf'
# Configures an additional peer directory for this group
# list config_peer_dir '/etc/fastd/sample_config/peers2'
# Limits the maximum number of connections to peers in this group (optional)
# option peer_limit 5

View File

@ -10,40 +10,6 @@ LIST_SEP="
TMP_FASTD=/tmp/fastd
FASTD_COMMAND=/usr/bin/fastd
append_opt() {
local v="$1"; local p="$2"
OPTS="$OPTS --${p//_/-} '${v//'/\\'}'"
}
append_opt_bool() {
local p="$1"
OPTS="$OPTS --${p//_/-}"
}
append_opts() {
local p; local v; local s="$1"; shift
for p in $*; do
config_get v "$s" "$p"
[ -n "$v" ] && append_opt "$v" "$p"
done
}
append_opts_bool() {
local p; local v; local s="$1"; shift
for p in $*; do
config_get_bool v "$s" "$p" 0
[ "$v" = 1 ] && append_opt_bool "$p"
done
}
append_opts_list() {
local p; local s="$1"; shift
for p in $*; do
config_list_foreach "$s" "$p" append_opt "$p"
done
}
section_enabled() {
config_get_bool enabled "$1" 'enabled' 0
@ -54,82 +20,227 @@ error() {
echo "${initscript}:" "$@" 1>&2
}
create_peer_config() {
local s="$2"; local peer="$1"
config_get net "$peer" net
[ "$net" == "$s" ] || return 0
section_enabled "$peer" || return 0
config_get key "$peer" key
config_get address "$peer" address
config_get hostname "$peer" hostname
config_get address_family "$peer" address_family
config_get port "$peer" port
config_get_bool float "$peer" float 0
if [ -z "$key" ]; then
error "peer $peer: key is not set"
return 1
fi
local remote=''
if [ "$address" -o "$hostname" ]; then
if [ "$address" -a "$hostname" ]; then
error "peer $peer: both address and hostname given"
return 1
fi
if [ "$float" = 0 ]; then
float=''
else
float='float'
fi
if [ "$port" ]; then
if [ "$address" ]; then
remote="remote $address port $port $float;"
else # $hostname
if [ "$address_family" -a "$address_family" != 'ipv4' -a "$address_family" != 'ipv6' ]; then
error "peer $peer: invalid address family given"
return 1
fi
remote="remote $address_family \"$hostname\" port $port $float;"
fi
else
error "peer $peer: address or hostname, but no port given"
return 1
fi
fi
cat > "$TMP_FASTD/fastd.$s.peers/$peer" <<EOF
key "$key";
$remote
EOF
}
update_peers_instance() {
local s="$1"
rm -rf "$TMP_FASTD/fastd.$s.peers"
mkdir -p "$TMP_FASTD/fastd.$s.peers"
config_foreach create_peer_config 'peer' "$s"
}
get_key_instance() {
local s="$1"
config_get secret "$s" secret
if [ "$secret" = 'generate' ]; then
secret=`fastd --generate-key --machine-readable`
secret=`"$FASTD_COMMAND" --generate-key --machine-readable`
uci -q set fastd."$s".secret="$secret" && uci -q commit fastd
fi
echo "$secret"
}
escape_string() {
local t=${1//\\/\\\\}
echo -n "\"${t//\"/\\\"}\""
}
guard_value() {
local t=${1//[^-a-z0-9\[\].:]/}
echo -n "$t"
}
guard_remote() {
local t=${1//[^-a-zA-Z0-9\[\].:\"% ]/}
local quotes=${t//[^\"]/}
if [ "${#quotes}" = 0 -o "${#quotes}" = 2 ]; then
echo -n "$t"
fi
}
yes_no() {
case "$1" in
0|no|off|false|disabled) echo -n no;;
*) echo -n yes;;
esac
}
config_string_config='include $(escape_string "$value");'
config_string_config_peer='include peer $(escape_string "$value");'
config_string_config_peer_dir='include peers from $(escape_string "$value");'
config_string_bind='bind $(guard_value "$value");'
config_string_method='method $(escape_string "$value");'
config_string_syslog_level='log to syslog level $(guard_value "$value");'
config_string_mode='mode $(guard_value "$value");'
config_string_interface='interface $(escape_string "$value");'
config_string_mtu='mtu $(guard_value "$value");'
config_string_peer_limit='peer limit $(guard_value "$value");'
config_string_user='user $(escape_string "$value");'
config_string_group='group $(escape_string "$value");'
config_string_pmtu='pmtu $(yes_no "$value");'
config_string_forward='forward $(yes_no "$value");'
config_string_hide_ip_addresses='hide ip addresses $(yes_no "$value");'
config_string_hide_mac_addresses='hide mac addresses $(yes_no "$value");'
config_string_peer='peer $(escape_string "$value") {'
config_string_peer_group='peer group $(escape_string "$value") {'
peer_string_key='key $(escape_string "$value");'
peer_string_float='float $(yes_no "$value");'
peer_string_remote='remote $(guard_remote "$value");'
generate_option() {
local __string=$(eval echo \"\$$2\")
local value="$1";
eval echo "\"$__string\""
}
append_option() {
local v; local len; local s="$1"; local prefix="$2"; local p="$3"
config_get len "$s" "${p}_LENGTH"
if [ -z "$len" ]; then
config_get v "$s" "$p"
[ -n "$v" ] && generate_option "$v" "${prefix}_string_${p}"
else
config_list_foreach "$s" "$p" generate_option "${prefix}_string_${p}"
fi
}
append_options() {
local p; local s="$1"; local prefix="$2"; shift; shift
for p in $*; do
append_option "$s" "$prefix" "$p"
done
}
generate_config_secret() {
echo "secret $(escape_string "$1");"
}
generate_peer_config() {
local peer="$1"
# These options are deprecated
config_get address "$peer" address
config_get hostname "$peer" hostname
config_get address_family "$peer" address_family
config_get port "$peer" port
if [ "$address" -o "$hostname" ]; then
if [ -z "$port" ]; then
error "peer $peer: address or hostname, but no port given"
return 1
fi
if [ "$hostname" ]; then
generate_option peer_string_remote "$address_family \"$hostname\" port $port"
fi
if [ "$address" ]; then
generate_option peer_string_remote "$address port $port"
fi
fi
append_options "$peer" peer \
key float remote
}
generate_single_peer_config() {
local peer="$1"; local net="$2"
config_get peer_net "$peer" net
config_get peer_group "$peer" group
[ "$net" = "$peer_net" -a "$peer_group" = '' ] || return 0
section_enabled "$peer" || return 0
generate_option "$peer" config_string_peer
generate_peer_config "$peer"
echo '}'
}
create_peer_config() {
local peer="$1"; local net="$2"; local group="$3"; local path="$4"
config_get peer_net "$peer" net
config_get peer_group "$peer" group
[ "$group" = "$peer_group" ] || return 0
if [ "$net" != "$peer_net" ]; then
[ -z "$group" ] || error "warning: the peer group of peer '$peer' doesn't match its net, the peer will be ignored"
return 0
fi
section_enabled "$peer" || return 0
generate_peer_config "$peer" >"$path/$peer"
}
update_peer_group() {
local net="$1"; local group_dir="$2"; local group="$3"; local update_only="$4"
local path="$TMP_FASTD/fastd.$net/$group_dir"
rm -rf "$path"
mkdir -p "$path"
config_foreach create_peer_config 'peer' "$net" "$group" "$path"
if [ -z "$update_only" ]; then
generate_option "$path" config_string_config_peer_dir
fi
config_foreach generate_peer_group_config 'peer_group' "$net" "$group_dir" "$update_only" "$group"
}
generate_peer_group_config() {
local group="$1"; local net="$2"; local group_dir="$3%$group"; local update_only="$4"; local parent="$5"
config_get group_net "$group" net
config_get group_parent "$group" parent
[ "$parent" = "$group_parent" ] || return 0
if [ "$net" != "$peer_net" ]; then
[ -z "$parent" ] || error "warning: the parent of peer group '$group' doesn't match its net, the peer group will be ignored"
return 0
fi
section_enabled "$group" || return 0
if [ -z "$update_only" ]; then
generate_option "$group" config_string_peer_group
append_options "$group" config \
config config_peer config_peer_dir peer_limit
fi
update_peer_group "$net" "$group_dir" "$group" "$update_only"
if [ -z "$update_only" ]; then
echo '}'
fi
}
update_peer_groups() {
local net="$1"; local update_only="$2"
update_peer_group "$net" 'peers' '' "$update_only"
}
generate_config() {
local s="$1"
generate_option 'info' config_string_syslog_level
append_options "$s" config \
config config_peer config_peer_dir bind method syslog_level mode interface mtu peer_limit \
user group pmtu forward hide_ip_addresses hide_mac_addresses
config_get mode "$s" mode
if [ "$mode" = "tun" ]; then
config_foreach generate_single_peer_config 'peer' "$s"
else
update_peer_groups "$s"
fi
}
generate_key_instance() {
local s="$1"
@ -139,9 +250,7 @@ generate_key_instance() {
uci -q set fastd."$s".secret="$secret" && uci -q commit fastd
fi
"$FASTD_COMMAND" --config - --show-key --machine-readable <<EOF
secret "$secret";
EOF
generate_config_secret "$secret" | "$FASTD_COMMAND" --config - --show-key --machine-readable
}
show_key_instance() {
@ -153,9 +262,7 @@ show_key_instance() {
return 1
fi
"$FASTD_COMMAND" --config - --show-key --machine-readable <<EOF
secret "$secret";
EOF
generate_config_secret "$secret" | "$FASTD_COMMAND" --config - --show-key --machine-readable
}
start_instance() {
@ -164,7 +271,6 @@ start_instance() {
section_enabled "$s" || return 1
SERVICE_PID_FILE="/var/run/fastd.$s.pid"
OPTS=""
config_get interface "$s" interface
if [ -z "$interface" ]; then
@ -177,21 +283,19 @@ start_instance() {
return 1
fi
config_get mode "$s" mode
if [ -z "$mode" ]; then
error "$s: mode is not set"
return 1
fi
local secret=`get_key_instance "$s"`
if [ -z "$secret" ]; then
error "$s: secret is not set"
return 1
fi
append_opts_list "$s" config config_peer_dir config_peer bind method
append_opts "$s" syslog_level mode interface mtu
append_opts_bool "$s" forward
update_peers_instance "$s"
eval service_start "'$FASTD_COMMAND'" --daemon --pid-file "'$SERVICE_PID_FILE'" --syslog-level info $OPTS --config-peer-dir "$TMP_FASTD/fastd.$s.peers" --config - <<EOF
secret "$secret";
EOF
(generate_config_secret "$secret"; generate_config "$s") | service_start "$FASTD_COMMAND" --config - --daemon --pid-file "$SERVICE_PID_FILE"
if ! ifconfig "$interface" >/dev/null 2>&1; then
error "$s: startup failed"
@ -225,18 +329,21 @@ stop_instance() {
service_stop "$FASTD_COMMAND"
rm -rf "$TMP_FASTD/fastd.$s.peers"
rm -rf "$TMP_FASTD/fastd.$s"
}
reload_instance() {
local s="$1"
local s="$1"
section_enabled "$s" || return 1
section_enabled "$s" || return 1
update_peers_instance "$s"
config_get mode "$s" mode
[ "$mode" = "tun" ] && return 1
SERVICE_PID_FILE="/var/run/fastd.$s.pid"
service_reload "$FASTD_COMMAND"
update_peer_groups "$s" true
SERVICE_PID_FILE="/var/run/fastd.$s.pid"
service_reload "$FASTD_COMMAND"
}
start() {
@ -250,8 +357,8 @@ stop() {
}
reload() {
config_load 'fastd'
config_foreach reload_instance 'fastd'
config_load 'fastd'
config_foreach reload_instance 'fastd'
}
up() {