Merge branch 'iptfs'
This adds basic support for IP-TFS/AGGFRAG (RFC 9347). The Linux kernel, since 6.14, only supports aggregation/fragmentation so far. The actual TFS features will get added later.
This commit is contained in:
@@ -16,6 +16,7 @@ options = \
|
||||
options/charon-systemd.opt \
|
||||
options/imcv.opt \
|
||||
options/imv_policy_manager.opt \
|
||||
options/iptfs.opt \
|
||||
options/manager.opt \
|
||||
options/medsrv.opt \
|
||||
options/pki.opt \
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
charon.iptfs {}
|
||||
Global settings for IP-TFS (RFC 9347). The Linux kernel supports this mode
|
||||
since 6.14. However, it currently only supports aggregation/fragmentation of
|
||||
tunneled IP packets in ESP/AGGFRAG packets. It doesn't yet support other
|
||||
IP-TFS features like sending packets at a constant rate or congestion control.
|
||||
|
||||
charon.iptfs.drop_time = 1000000
|
||||
Time in microseconds to wait for out-of-order packets when processing
|
||||
inbound traffic.
|
||||
|
||||
charon.iptfs.reorder_window = 3
|
||||
Number of packets that may arrive out of order when processing inbound
|
||||
traffic.
|
||||
|
||||
charon.iptfs.init_delay = 0
|
||||
Time in microseconds to wait for subsequent packets to aggregate together
|
||||
when sending outbound traffic. Only relevant if no packets are already
|
||||
queued to be sent.
|
||||
|
||||
charon.iptfs.max_queue_size = 1048576
|
||||
Maximum number of bytes allowed to be queued for sending on the tunnel
|
||||
(default 1 MiB). If the queue is full, packets are dropped.
|
||||
|
||||
charon.iptfs.packet_size = 0
|
||||
Maximum outer packet size (layer 3) when sending packets. The default of 0
|
||||
will use the PMTU as packet size. Note that the kernel currently doesn't
|
||||
pad smaller packets.
|
||||
|
||||
charon.iptfs.accept_fragments = yes
|
||||
Whether fragments of inner packets across multiple AGGFRAG payloads are
|
||||
accepted. This is an IKEv2 option, so if the peer doesn't adhere to this
|
||||
request and still sends such fragments, they will be processed by the
|
||||
kernel.
|
||||
|
||||
charon.iptfs.dont_frag = no
|
||||
Force disabling fragmenting inner packets across multiple AGGFRAG payloads
|
||||
when sending outbound traffic (fragmentation is automatically disabled if
|
||||
the peer indicates that it doesn't support handling such packets).
|
||||
+1
-1
@@ -1949,7 +1949,7 @@ strongswan_options=
|
||||
|
||||
AM_COND_IF([USE_AIKGEN], [strongswan_options=${strongswan_options}" aikgen"])
|
||||
AM_COND_IF([USE_ATTR_SQL], [strongswan_options=${strongswan_options}" pool"])
|
||||
AM_COND_IF([USE_CHARON], [strongswan_options=${strongswan_options}" charon charon-logging"])
|
||||
AM_COND_IF([USE_CHARON], [strongswan_options=${strongswan_options}" charon charon-logging iptfs"])
|
||||
AM_COND_IF([USE_FILE_CONFIG], [strongswan_options=${strongswan_options}" starter"])
|
||||
AM_COND_IF([USE_IMV_ATTESTATION], [strongswan_options=${strongswan_options}" attest"])
|
||||
AM_COND_IF([USE_IMCV], [strongswan_options=${strongswan_options}" imcv imv_policy_manager"])
|
||||
|
||||
@@ -154,7 +154,8 @@ enum {
|
||||
#define XFRM_MODE_ROUTEOPTIMIZATION 2
|
||||
#define XFRM_MODE_IN_TRIGGER 3
|
||||
#define XFRM_MODE_BEET 4
|
||||
#define XFRM_MODE_MAX 5
|
||||
#define XFRM_MODE_IPTFS 5
|
||||
#define XFRM_MODE_MAX 6
|
||||
|
||||
/* Netlink configuration messages. */
|
||||
enum {
|
||||
@@ -319,6 +320,12 @@ enum xfrm_attr_type_t {
|
||||
XFRMA_SA_DIR, /* __u8 */
|
||||
XFRMA_NAT_KEEPALIVE_INTERVAL, /* __u32 in seconds for NAT keepalive */
|
||||
XFRMA_SA_PCPU, /* __u32 */
|
||||
XFRMA_IPTFS_DROP_TIME, /* __u32 in: usec to wait for next seq */
|
||||
XFRMA_IPTFS_REORDER_WINDOW, /* __u16 in: reorder window size (pkts) */
|
||||
XFRMA_IPTFS_DONT_FRAG, /* out: don't use fragmentation */
|
||||
XFRMA_IPTFS_INIT_DELAY, /* __u32 out: initial packet wait delay (usec) */
|
||||
XFRMA_IPTFS_MAX_QSIZE, /* __u32 out: max ingress queue size (octets) */
|
||||
XFRMA_IPTFS_PKT_SIZE, /* __u32 out: size of outer packet, 0 for PMTU */
|
||||
__XFRMA_MAX
|
||||
|
||||
#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK /* Compatibility */
|
||||
|
||||
@@ -122,9 +122,10 @@ ENUM_NEXT(notify_type_names, USE_PPK, INTERMEDIATE_EXCHANGE_SUPPORTED, SIGNATURE
|
||||
"PPK_IDENTITY",
|
||||
"NO_PPK_AUTH",
|
||||
"INTERMEDIATE_EXCHANGE_SUPPORTED");
|
||||
ENUM_NEXT(notify_type_names, ADDITIONAL_KEY_EXCHANGE, ADDITIONAL_KEY_EXCHANGE, INTERMEDIATE_EXCHANGE_SUPPORTED,
|
||||
"ADDITIONAL_KEY_EXCHANGE");
|
||||
ENUM_NEXT(notify_type_names, SA_RESOURCE_INFO, SA_RESOURCE_INFO, ADDITIONAL_KEY_EXCHANGE,
|
||||
ENUM_NEXT(notify_type_names, ADDITIONAL_KEY_EXCHANGE, USE_AGGFRAG, INTERMEDIATE_EXCHANGE_SUPPORTED,
|
||||
"ADDITIONAL_KEY_EXCHANGE",
|
||||
"USE_AGGFRAG");
|
||||
ENUM_NEXT(notify_type_names, SA_RESOURCE_INFO, SA_RESOURCE_INFO, USE_AGGFRAG,
|
||||
"SA_RESOURCE_INFO");
|
||||
ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, SA_RESOURCE_INFO,
|
||||
"INITIAL_CONTACT");
|
||||
@@ -244,9 +245,10 @@ ENUM_NEXT(notify_type_short_names, USE_PPK, INTERMEDIATE_EXCHANGE_SUPPORTED, SIG
|
||||
"PPK_ID",
|
||||
"NO_PPK",
|
||||
"IKE_INT_SUP");
|
||||
ENUM_NEXT(notify_type_short_names, ADDITIONAL_KEY_EXCHANGE, ADDITIONAL_KEY_EXCHANGE, INTERMEDIATE_EXCHANGE_SUPPORTED,
|
||||
"ADD_KE");
|
||||
ENUM_NEXT(notify_type_short_names, SA_RESOURCE_INFO, SA_RESOURCE_INFO, ADDITIONAL_KEY_EXCHANGE,
|
||||
ENUM_NEXT(notify_type_short_names, ADDITIONAL_KEY_EXCHANGE, USE_AGGFRAG, INTERMEDIATE_EXCHANGE_SUPPORTED,
|
||||
"ADD_KE",
|
||||
"AGGFRAG");
|
||||
ENUM_NEXT(notify_type_short_names, SA_RESOURCE_INFO, SA_RESOURCE_INFO, USE_AGGFRAG,
|
||||
"RES_INFO");
|
||||
ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, SA_RESOURCE_INFO,
|
||||
"INITIAL_CONTACT");
|
||||
@@ -560,6 +562,12 @@ METHOD(payload_t, verify, status_t,
|
||||
bad_length = TRUE;
|
||||
}
|
||||
break;
|
||||
case USE_AGGFRAG:
|
||||
if (this->notify_data.len != 1)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* TODO: verify */
|
||||
break;
|
||||
|
||||
@@ -171,6 +171,8 @@ enum notify_type_t {
|
||||
|
||||
/* multiple key exchanges, RFC 9370 */
|
||||
ADDITIONAL_KEY_EXCHANGE = 16441,
|
||||
/* IP-TFS/AGGFRAG, RFC 9347 */
|
||||
USE_AGGFRAG = 16442,
|
||||
|
||||
/* Resource info for CHILD_SAs, RFC 9611 */
|
||||
SA_RESOURCE_INFO = 16444,
|
||||
|
||||
@@ -113,6 +113,8 @@ struct kernel_ipsec_add_sa_t {
|
||||
bool copy_ecn;
|
||||
/** Whether to copy the DSCP header field to/from the outer header */
|
||||
dscp_copy_t copy_dscp;
|
||||
/** TRUE if the peer doesn't support receiving fragments in AGGFRAG pkts */
|
||||
bool iptfs_dont_frag;
|
||||
/** TRUE if initiator of the exchange creating the SA */
|
||||
bool initiator;
|
||||
/** TRUE if this is an inbound SA */
|
||||
|
||||
@@ -205,6 +205,12 @@ ENUM(xfrm_attr_type_names, XFRMA_UNSPEC, __XFRMA_MAX,
|
||||
"XFRMA_SA_DIR",
|
||||
"XFRMA_NAT_KEEPALIVE_INTERVAL",
|
||||
"XFRMA_SA_PCPU",
|
||||
"XFRMA_IPTFS_DROP_TIME",
|
||||
"XFRMA_IPTFS_REORDER_WINDOW",
|
||||
"XFRMA_IPTFS_DONT_FRAG",
|
||||
"XFRMA_IPTFS_INIT_DELAY",
|
||||
"XFRMA_IPTFS_MAX_QSIZE",
|
||||
"XFRMA_IPTFS_PKT_SIZE",
|
||||
"XFRMA_MAX",
|
||||
);
|
||||
|
||||
@@ -787,6 +793,8 @@ static uint8_t mode2kernel(ipsec_mode_t mode)
|
||||
return XFRM_MODE_TUNNEL;
|
||||
case MODE_BEET:
|
||||
return XFRM_MODE_BEET;
|
||||
case MODE_IPTFS:
|
||||
return XFRM_MODE_IPTFS;
|
||||
default:
|
||||
return mode;
|
||||
}
|
||||
@@ -1304,6 +1312,23 @@ static bool add_uint32(struct nlmsghdr *hdr, int buflen,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a uint16 attribute to message
|
||||
*/
|
||||
static bool add_uint16(struct nlmsghdr *hdr, int buflen,
|
||||
enum xfrm_attr_type_t type, uint16_t value)
|
||||
{
|
||||
uint16_t *xvalue;
|
||||
|
||||
xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue));
|
||||
if (!xvalue)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*xvalue = value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a uint8 attribute to message
|
||||
*/
|
||||
@@ -1821,6 +1846,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
switch (mode)
|
||||
{
|
||||
case MODE_TUNNEL:
|
||||
case MODE_IPTFS:
|
||||
sa->flags |= XFRM_STATE_AF_UNSPEC;
|
||||
break;
|
||||
case MODE_BEET:
|
||||
@@ -2124,6 +2150,53 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
DBG2(DBG_KNL, " using CPU ID: %u", data->cpu);
|
||||
}
|
||||
|
||||
if (mode == MODE_IPTFS)
|
||||
{
|
||||
if (data->inbound)
|
||||
{
|
||||
if (!add_uint32(hdr, sizeof(request), XFRMA_IPTFS_DROP_TIME,
|
||||
lib->settings->get_int(lib->settings,
|
||||
"%s.iptfs.drop_time", 1000000, lib->ns)))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (!add_uint16(hdr, sizeof(request), XFRMA_IPTFS_REORDER_WINDOW,
|
||||
lib->settings->get_int(lib->settings,
|
||||
"%s.iptfs.reorder_window", 3, lib->ns)))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!add_uint32(hdr, sizeof(request), XFRMA_IPTFS_INIT_DELAY,
|
||||
lib->settings->get_int(lib->settings,
|
||||
"%s.iptfs.init_delay", 0, lib->ns)))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (!add_uint32(hdr, sizeof(request), XFRMA_IPTFS_MAX_QSIZE,
|
||||
lib->settings->get_int(lib->settings,
|
||||
"%s.iptfs.max_queue_size", 1024 * 1024, lib->ns)))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (!add_uint32(hdr, sizeof(request), XFRMA_IPTFS_PKT_SIZE,
|
||||
lib->settings->get_int(lib->settings,
|
||||
"%s.iptfs.packet_size", 0, lib->ns)))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if ((data->iptfs_dont_frag ||
|
||||
lib->settings->get_bool(lib->settings,
|
||||
"%s.iptfs.dont_fragment", FALSE, lib->ns)) &&
|
||||
!netlink_reserve(hdr, sizeof(request), XFRMA_IPTFS_DONT_FRAG, 0))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (id->proto != IPPROTO_COMP)
|
||||
{
|
||||
/* we don't need a replay window for outbound SAs, however, older
|
||||
@@ -3054,7 +3127,8 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
|
||||
policy->direction != POLICY_OUT;
|
||||
tmpl->family = ipsec->src->get_family(ipsec->src);
|
||||
|
||||
if (proto_mode == MODE_TUNNEL || proto_mode == MODE_BEET)
|
||||
if (proto_mode == MODE_TUNNEL || proto_mode == MODE_BEET ||
|
||||
proto_mode == MODE_IPTFS)
|
||||
{ /* only for tunnel mode */
|
||||
host2xfrm(ipsec->src, &tmpl->saddr);
|
||||
host2xfrm(ipsec->dst, &tmpl->id.daddr);
|
||||
|
||||
@@ -904,6 +904,7 @@ CALLBACK(parse_mode, bool,
|
||||
{ "tunnel", MODE_TUNNEL },
|
||||
{ "transport", MODE_TRANSPORT },
|
||||
{ "transport_proxy", MODE_TRANSPORT },
|
||||
{ "iptfs", MODE_IPTFS },
|
||||
{ "beet", MODE_BEET },
|
||||
{ "drop", MODE_DROP },
|
||||
{ "pass", MODE_PASS },
|
||||
|
||||
@@ -246,6 +246,11 @@ struct private_child_sa_t {
|
||||
*/
|
||||
ipsec_mode_t mode;
|
||||
|
||||
/**
|
||||
* Disable fragmenting packets across IP-TFS packets
|
||||
*/
|
||||
bool iptfs_dont_frag;
|
||||
|
||||
/**
|
||||
* Action to enforce if peer closes the CHILD_SA
|
||||
*/
|
||||
@@ -462,6 +467,12 @@ METHOD(child_sa_t, set_mode, void,
|
||||
this->mode = mode;
|
||||
}
|
||||
|
||||
METHOD(child_sa_t, set_iptfs_dont_fragment, void,
|
||||
private_child_sa_t *this)
|
||||
{
|
||||
this->iptfs_dont_frag = TRUE;
|
||||
}
|
||||
|
||||
METHOD(child_sa_t, has_encap, bool,
|
||||
private_child_sa_t *this)
|
||||
{
|
||||
@@ -1109,6 +1120,7 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
|
||||
.copy_df = !this->config->has_option(this->config, OPT_NO_COPY_DF),
|
||||
.copy_ecn = !this->config->has_option(this->config, OPT_NO_COPY_ECN),
|
||||
.copy_dscp = this->config->get_copy_dscp(this->config),
|
||||
.iptfs_dont_frag = this->iptfs_dont_frag,
|
||||
.label = label_for(this, LABEL_USE_SA),
|
||||
.initiator = initiator,
|
||||
.inbound = inbound,
|
||||
@@ -2168,6 +2180,7 @@ child_sa_t *child_sa_create(host_t *me, host_t *other, child_cfg_t *config,
|
||||
.has_encap = _has_encap,
|
||||
.get_ipcomp = _get_ipcomp,
|
||||
.set_ipcomp = _set_ipcomp,
|
||||
.set_iptfs_dont_fragment = _set_iptfs_dont_fragment,
|
||||
.get_close_action = _get_close_action,
|
||||
.set_close_action = _set_close_action,
|
||||
.get_dpd_action = _get_dpd_action,
|
||||
|
||||
@@ -290,6 +290,12 @@ struct child_sa_t {
|
||||
*/
|
||||
void (*set_ipcomp)(child_sa_t *this, ipcomp_transform_t ipcomp);
|
||||
|
||||
/**
|
||||
* Disable fragmenting messages across multiple IP-TFS packets. Only
|
||||
* relevant with MODE_IPTFS.
|
||||
*/
|
||||
void (*set_iptfs_dont_fragment)(child_sa_t *this);
|
||||
|
||||
/**
|
||||
* Get the action to enforce if the remote peer closes the CHILD_SA.
|
||||
*
|
||||
|
||||
@@ -43,6 +43,16 @@ typedef struct private_child_create_t private_child_create_t;
|
||||
/** Assumed minimum CPU ID, used when searching for a CPU without SA */
|
||||
#define CPU_ID_MIN 0
|
||||
|
||||
/**
|
||||
* Flags for IP-TFS
|
||||
*/
|
||||
typedef enum {
|
||||
/** Indicates that fragmentation across packets is not supported */
|
||||
IPTFS_DONT_FRAGMENT = (1 << 0),
|
||||
/** Requests periodic congestion control information from the peer */
|
||||
IPTFS_CONGESTION_CONTROL = (1 << 1),
|
||||
} iptfs_flags_t;
|
||||
|
||||
/**
|
||||
* Private members of a child_create_t task.
|
||||
*/
|
||||
@@ -207,6 +217,11 @@ struct private_child_create_t {
|
||||
*/
|
||||
ipcomp_transform_t ipcomp_received;
|
||||
|
||||
/**
|
||||
* IP-TFS flags received from the peer
|
||||
*/
|
||||
uint8_t iptfs_flags;
|
||||
|
||||
/**
|
||||
* IPsec protocol
|
||||
*/
|
||||
@@ -571,6 +586,22 @@ static bool check_mode(private_child_create_t *this, host_t *i, host_t *r)
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case MODE_IPTFS:
|
||||
if (this->config->get_mode(this->config) != MODE_IPTFS)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if ((this->iptfs_flags & IPTFS_CONGESTION_CONTROL) ||
|
||||
(this->iptfs_flags & 0xfc))
|
||||
{
|
||||
/* congestion control is not supported, neither are any of
|
||||
* the 6 reserved flags, so we disable IP-TFS if they are set */
|
||||
DBG1(DBG_IKE, "not using IP-TFS mode, peer sent unsupported "
|
||||
"flags (0x%.2x) in %N notify", this->iptfs_flags,
|
||||
notify_type_names, USE_AGGFRAG);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -706,6 +737,10 @@ static status_t install_child_sa(private_child_create_t *this)
|
||||
|
||||
this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
|
||||
this->child_sa->set_mode(this->child_sa, this->mode);
|
||||
if (this->mode == MODE_IPTFS && this->iptfs_flags & IPTFS_DONT_FRAGMENT)
|
||||
{
|
||||
this->child_sa->set_iptfs_dont_fragment(this->child_sa);
|
||||
}
|
||||
this->child_sa->set_protocol(this->child_sa,
|
||||
this->proposal->get_protocol(this->proposal));
|
||||
|
||||
@@ -1073,6 +1108,19 @@ static bool build_payloads(private_child_create_t *this, message_t *message)
|
||||
case MODE_BEET:
|
||||
message->add_notify(message, FALSE, USE_BEET_MODE, chunk_empty);
|
||||
break;
|
||||
case MODE_IPTFS:
|
||||
{
|
||||
uint8_t iptfs_flags = 0;
|
||||
|
||||
if (!lib->settings->get_bool(lib->settings,
|
||||
"%s.iptfs.accept_fragments", TRUE, lib->ns))
|
||||
{
|
||||
iptfs_flags |= IPTFS_DONT_FRAGMENT;
|
||||
}
|
||||
message->add_notify(message, FALSE, USE_AGGFRAG,
|
||||
chunk_from_thing(iptfs_flags));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1126,6 +1174,8 @@ static void add_ipcomp_notify(private_child_create_t *this,
|
||||
*/
|
||||
static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
|
||||
{
|
||||
chunk_t data;
|
||||
|
||||
switch (notify->get_notify_type(notify))
|
||||
{
|
||||
case USE_TRANSPORT_MODE:
|
||||
@@ -1142,11 +1192,15 @@ static void handle_notify(private_child_create_t *this, notify_payload_t *notify
|
||||
"mode, but peer implementation unknown, skipped");
|
||||
}
|
||||
break;
|
||||
case USE_AGGFRAG:
|
||||
this->mode = MODE_IPTFS;
|
||||
data = notify->get_notification_data(notify);
|
||||
this->iptfs_flags = *data.ptr;
|
||||
break;
|
||||
case IPCOMP_SUPPORTED:
|
||||
{
|
||||
ipcomp_transform_t ipcomp;
|
||||
uint16_t cpi;
|
||||
chunk_t data;
|
||||
|
||||
data = notify->get_notification_data(notify);
|
||||
cpi = *(uint16_t*)data.ptr;
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
#include "ipsec_types.h"
|
||||
|
||||
ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_DROP,
|
||||
ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_IPTFS,
|
||||
"TRANSPORT",
|
||||
"TUNNEL",
|
||||
"BEET",
|
||||
"PASS",
|
||||
"DROP"
|
||||
"DROP",
|
||||
"IPTFS",
|
||||
);
|
||||
|
||||
ENUM(policy_dir_names, POLICY_IN, POLICY_FWD,
|
||||
|
||||
@@ -51,7 +51,9 @@ enum ipsec_mode_t {
|
||||
/** passthrough policy for traffic without an IPsec SA */
|
||||
MODE_PASS,
|
||||
/** drop policy discarding traffic */
|
||||
MODE_DROP
|
||||
MODE_DROP,
|
||||
/** IP-TFS mode, tunnel mode with aggregation/fragmentation */
|
||||
MODE_IPTFS,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -920,12 +920,13 @@ connections.<conn>.children.<child>.hostaccess = no
|
||||
Hostaccess variable to pass to **updown** script.
|
||||
|
||||
connections.<conn>.children.<child>.mode = tunnel
|
||||
IPsec Mode to establish (_tunnel_, _transport_, _transport_proxy_, _beet_,
|
||||
_pass_ or _drop_).
|
||||
IPsec Mode to establish (_tunnel_, _transport_, _transport_proxy_, _iptfs_,
|
||||
_beet_, _pass_ or _drop_).
|
||||
|
||||
IPsec Mode to establish CHILD_SA with. _tunnel_ negotiates the CHILD_SA
|
||||
in IPsec Tunnel Mode, whereas _transport_ uses IPsec Transport Mode.
|
||||
_transport_proxy_ signifying the special Mobile IPv6 Transport Proxy Mode.
|
||||
_iptfs_ is IP-TFS tunnel mode with aggregation and fragmentation,
|
||||
_beet_ is the Bound End to End Tunnel mixture mode, working with fixed inner
|
||||
addresses without the need to include them in each packet.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+9
@@ -0,0 +1,9 @@
|
||||
A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> is set up
|
||||
enabling IP-TFS (RFC 9347) to aggregate small packets into a single ESP packets and
|
||||
fragment large packets across multiple ESP packets.
|
||||
The authentication is based on <b>X.509 certificates</b>.
|
||||
<p/>
|
||||
Upon the successful establishment of the IPsec tunnel, the updown script automatically
|
||||
inserts iptables-based firewall rules that let pass the tunneled traffic.
|
||||
In order to test both tunnel and firewall, client <b>alice</b> behind gateway <b>moon</b>
|
||||
sends several pings to client <b>bob</b> located behind gateway <b>sun</b>.
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
moon::swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=4500 local-id=moon.strongswan.org remote-host=192.168.0.2 remote-port=4500 remote-id=sun.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net-net.*state=INSTALLED mode=IPTFS.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.1.0.0/16] remote-ts=\[10.2.0.0/16]::YES
|
||||
sun:: swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.2 local-port=4500 local-id=sun.strongswan.org remote-host=192.168.0.1 remote-port=4500 remote-id=moon.strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net-net.*state=INSTALLED mode=IPTFS.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.2.0.0/16] remote-ts=\[10.1.0.0/16]::YES
|
||||
alice::ping -c 4 -i 0.1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=.::4
|
||||
sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::1
|
||||
sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::1
|
||||
@@ -0,0 +1,13 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
swanctl {
|
||||
load = pem pkcs1 revocation constraints pubkey openssl random
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce openssl pem pkcs1 revocation curl kernel-netlink socket-default updown vici
|
||||
iptfs {
|
||||
# set to 0.5 seconds for test purposes
|
||||
init_delay = 500000
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
connections {
|
||||
|
||||
gw-gw {
|
||||
local_addrs = 192.168.0.1
|
||||
remote_addrs = 192.168.0.2
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = moonCert.pem
|
||||
id = moon.strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
id = sun.strongswan.org
|
||||
}
|
||||
children {
|
||||
net-net {
|
||||
local_ts = 10.1.0.0/16
|
||||
remote_ts = 10.2.0.0/16
|
||||
|
||||
mode = iptfs
|
||||
|
||||
updown = /usr/local/libexec/ipsec/_updown iptables
|
||||
hostaccess = yes
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
proposals = aes128-sha256-x25519
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
swanctl {
|
||||
load = pem pkcs1 revocation constraints pubkey openssl random
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce openssl pem pkcs1 revocation curl kernel-netlink socket-default updown vici
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
connections {
|
||||
|
||||
gw-gw {
|
||||
local_addrs = 192.168.0.2
|
||||
remote_addrs = 192.168.0.1
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = sunCert.pem
|
||||
id = sun.strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
id = moon.strongswan.org
|
||||
}
|
||||
children {
|
||||
net-net {
|
||||
local_ts = 10.2.0.0/16
|
||||
remote_ts = 10.1.0.0/16
|
||||
|
||||
mode = iptfs
|
||||
|
||||
updown = /usr/local/libexec/ipsec/_updown iptables
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
proposals = aes128-sha256-x25519
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
moon::systemctl stop strongswan
|
||||
sun::systemctl stop strongswan
|
||||
moon::iptables-restore < /etc/iptables.flush
|
||||
sun::iptables-restore < /etc/iptables.flush
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
moon::iptables-restore < /etc/iptables.rules
|
||||
sun::iptables-restore < /etc/iptables.rules
|
||||
moon::systemctl start strongswan
|
||||
sun::systemctl start strongswan
|
||||
moon::expect-connection gw-gw
|
||||
sun::expect-connection gw-gw
|
||||
moon::swanctl --initiate --child net-net 2> /dev/null
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This configuration file provides information on the
|
||||
# guest instances used for this test
|
||||
|
||||
# All guest instances that are required for this test
|
||||
#
|
||||
VIRTHOSTS="alice moon winnetou sun bob"
|
||||
|
||||
# Corresponding block diagram
|
||||
#
|
||||
DIAGRAM="a-m-w-s-b.png"
|
||||
|
||||
# Guest instances on which tcpdump is to be started
|
||||
#
|
||||
TCPDUMPHOSTS="sun"
|
||||
|
||||
# Guest instances on which IPsec is started
|
||||
# Used for IPsec logging purposes
|
||||
#
|
||||
IPSECHOSTS="moon sun"
|
||||
|
||||
# charon controlled by swanctl
|
||||
#
|
||||
SWANCTL=1
|
||||
Reference in New Issue
Block a user