From dbd570707789739fa8d181224951abd92f119d49 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 11 May 2023 15:46:03 +0200 Subject: [PATCH 1/7] ipsec-sa: Store whether to use UDP encapsulation on the SA --- src/libipsec/ipsec_sa.c | 27 +++++++++++++++++++++------ src/libipsec/ipsec_sa.h | 16 +++++++++++++++- src/libipsec/ipsec_sa_mgr.c | 9 ++++++++- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/libipsec/ipsec_sa.c b/src/libipsec/ipsec_sa.c index cfbaaff40..e67444bcb 100644 --- a/src/libipsec/ipsec_sa.c +++ b/src/libipsec/ipsec_sa.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2023 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * @@ -69,6 +69,11 @@ struct private_ipsec_sa_t { */ ipsec_mode_t mode; + /** + * TRUE if UDP encapsulation should be used when sending + */ + bool encap; + /** * TRUE if extended sequence numbers are used */ @@ -133,6 +138,18 @@ METHOD(ipsec_sa_t, set_destination, void, this->dst = addr->clone(addr); } +METHOD(ipsec_sa_t, get_encap, bool, + private_ipsec_sa_t *this) +{ + return this->encap; +} + +METHOD(ipsec_sa_t, set_encap, void, + private_ipsec_sa_t *this, bool encap) +{ + this->encap = encap; +} + METHOD(ipsec_sa_t, get_spi, uint32_t, private_ipsec_sa_t *this) { @@ -285,11 +302,6 @@ ipsec_sa_t *ipsec_sa_create(uint32_t spi, host_t *src, host_t *dst, DBG1(DBG_ESP, " IPsec SA: protocol not supported"); return NULL; } - if (!encap) - { - DBG1(DBG_ESP, " IPsec SA: only UDP encapsulation is supported"); - return NULL; - } if (esn) { DBG1(DBG_ESP, " IPsec SA: ESN not supported"); @@ -313,6 +325,8 @@ ipsec_sa_t *ipsec_sa_create(uint32_t spi, host_t *src, host_t *dst, .get_destination = _get_destination, .set_source = _set_source, .set_destination = _set_destination, + .get_encap = _get_encap, + .set_encap = _set_encap, .get_spi = _get_spi, .get_reqid = _get_reqid, .get_protocol = _get_protocol, @@ -333,6 +347,7 @@ ipsec_sa_t *ipsec_sa_create(uint32_t spi, host_t *src, host_t *dst, .protocol = protocol, .reqid = reqid, .mode = mode, + .encap = encap, .esn = esn, .inbound = inbound, ); diff --git a/src/libipsec/ipsec_sa.h b/src/libipsec/ipsec_sa.h index bc2c3a0cf..64c584b49 100644 --- a/src/libipsec/ipsec_sa.h +++ b/src/libipsec/ipsec_sa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2023 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * @@ -66,6 +66,20 @@ struct ipsec_sa_t { */ void (*set_destination)(ipsec_sa_t *this, host_t *addr); + /** + * Get whether UDP encapsulation should be used for this SA + * + * @return TRUE if encapsulation should be used, FALSE otherwise + */ + bool (*get_encap)(ipsec_sa_t *this); + + /** + * Set whether UDP encapsulation should be used for this SA + * + * @param encap TRUE if encapsulation should be used, FALSE otherwise + */ + void (*set_encap)(ipsec_sa_t *this, bool encap); + /** * Get the SPI for this SA * diff --git a/src/libipsec/ipsec_sa_mgr.c b/src/libipsec/ipsec_sa_mgr.c index 12f5fc141..76006a851 100644 --- a/src/libipsec/ipsec_sa_mgr.c +++ b/src/libipsec/ipsec_sa_mgr.c @@ -502,7 +502,7 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t, METHOD(ipsec_sa_mgr_t, add_sa, status_t, private_ipsec_sa_mgr_t *this, host_t *src, host_t *dst, uint32_t spi, - uint8_t protocol, uint32_t reqid, mark_t mark, uint32_t tfc, + uint8_t protocol, uint32_t reqid, mark_t mark, uint32_t tfc, lifetime_cfg_t *lifetime, uint16_t enc_alg, chunk_t enc_key, uint16_t int_alg, chunk_t int_key, ipsec_mode_t mode, uint16_t ipcomp, uint16_t cpi, bool initiator, bool encap, bool esn, bool inbound, @@ -518,6 +518,12 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t, DBG2(DBG_ESP, " using integrity algorithm %N with key size %d", integrity_algorithm_names, int_alg, int_key.len * 8); + if (!encap) + { + DBG1(DBG_ESP, " IPsec SA: only UDP encapsulation is supported"); + return FAILED; + } + sa_new = ipsec_sa_create(spi, src, dst, protocol, reqid, mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode, ipcomp, cpi, encap, esn, inbound); @@ -582,6 +588,7 @@ METHOD(ipsec_sa_mgr_t, update_sa, status_t, { entry->sa->set_source(entry->sa, new_src); entry->sa->set_destination(entry->sa, new_dst); + entry->sa->set_encap(entry->sa, new_encap); /* checkin the entry */ entry->locked = FALSE; entry->condvar->signal(entry->condvar); From a049868d783899d71719ab9687081f28c7dbd9bc Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 11 May 2023 16:17:09 +0200 Subject: [PATCH 2/7] kernel-libipsec: Use CALLBACK for libipsec callbacks --- .../kernel_libipsec/kernel_libipsec_router.c | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c index 884616345..7c6d3c3ba 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c @@ -94,28 +94,21 @@ static bool tun_entry_equals(tun_entry_t *a, tun_entry_t *b) return a->addr->ip_equals(a->addr, b->addr); } -/** - * Outbound callback - */ -static void send_esp(void *data, esp_packet_t *packet) +CALLBACK(send_esp, void, + void *data, esp_packet_t *packet) { charon->sender->send_no_marker(charon->sender, (packet_t*)packet); } -/** - * Receiver callback - */ -static void receiver_esp_cb(void *data, packet_t *packet) +CALLBACK(receiver_esp_cb, void, + void *data, packet_t *packet) { ipsec->processor->queue_inbound(ipsec->processor, esp_packet_create_from_packet(packet)); } -/** - * Inbound callback - */ -static void deliver_plain(private_kernel_libipsec_router_t *this, - ip_packet_t *packet) +CALLBACK(deliver_plain, void, + private_kernel_libipsec_router_t *this, ip_packet_t *packet) { tun_device_t *tun; tun_entry_t *entry, lookup = { @@ -292,12 +285,9 @@ METHOD(kernel_libipsec_router_t, get_tun_name, char*, METHOD(kernel_libipsec_router_t, destroy, void, private_kernel_libipsec_router_t *this) { - charon->receiver->del_esp_cb(charon->receiver, - (receiver_esp_cb_t)receiver_esp_cb); - ipsec->processor->unregister_outbound(ipsec->processor, - (ipsec_outbound_cb_t)send_esp); - ipsec->processor->unregister_inbound(ipsec->processor, - (ipsec_inbound_cb_t)deliver_plain); + charon->receiver->del_esp_cb(charon->receiver, receiver_esp_cb); + ipsec->processor->unregister_outbound(ipsec->processor, send_esp); + ipsec->processor->unregister_inbound(ipsec->processor, deliver_plain); charon->kernel->remove_listener(charon->kernel, &this->public.listener); this->lock->destroy(this->lock); this->tuns->destroy(this->tuns); @@ -352,10 +342,8 @@ kernel_libipsec_router_t *kernel_libipsec_router_create() charon->kernel->add_listener(charon->kernel, &this->public.listener); ipsec->processor->register_outbound(ipsec->processor, send_esp, NULL); - ipsec->processor->register_inbound(ipsec->processor, - (ipsec_inbound_cb_t)deliver_plain, this); - charon->receiver->add_esp_cb(charon->receiver, - (receiver_esp_cb_t)receiver_esp_cb, NULL); + ipsec->processor->register_inbound(ipsec->processor, deliver_plain, this); + charon->receiver->add_esp_cb(charon->receiver, receiver_esp_cb, NULL); lib->processor->queue_job(lib->processor, (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this, NULL, (callback_job_cancel_t)return_false)); From 61f9843453f30c2a110f356c9a174a5cb9f25728 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 11 May 2023 16:21:07 +0200 Subject: [PATCH 3/7] android: Use CALLBACK for libipsec-related callbacks --- .../backend/android_service.c | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c index 179371c90..d01ca7353 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c @@ -85,19 +85,14 @@ struct private_android_service_t { bool use_dns_proxy; }; -/** - * Outbound callback - */ -static void send_esp(void *data, esp_packet_t *packet) +CALLBACK(send_esp, void, + void *data, esp_packet_t *packet) { charon->sender->send_no_marker(charon->sender, (packet_t*)packet); } -/** - * Inbound callback - */ -static void deliver_plain(private_android_service_t *this, - ip_packet_t *packet) +CALLBACK(deliver_plain, void, + private_android_service_t *this, ip_packet_t *packet) { chunk_t encoding; ssize_t len; @@ -122,10 +117,8 @@ static void deliver_plain(private_android_service_t *this, packet->destroy(packet); } -/** - * Receiver callback - */ -static void receiver_esp_cb(void *data, packet_t *packet) +CALLBACK(receiver_esp_cb, void, + void *data, packet_t *packet) { esp_packet_t *esp_packet; @@ -359,14 +352,10 @@ static bool setup_tun_device(private_android_service_t *this, if (!already_registered) { - charon->receiver->add_esp_cb(charon->receiver, - (receiver_esp_cb_t)receiver_esp_cb, NULL); - ipsec->processor->register_inbound(ipsec->processor, - (ipsec_inbound_cb_t)deliver_plain, this); - ipsec->processor->register_outbound(ipsec->processor, - (ipsec_outbound_cb_t)send_esp, NULL); - this->dns_proxy->register_cb(this->dns_proxy, - (dns_proxy_response_cb_t)deliver_plain, this); + charon->receiver->add_esp_cb(charon->receiver, receiver_esp_cb, NULL); + ipsec->processor->register_inbound(ipsec->processor, deliver_plain, this); + ipsec->processor->register_outbound(ipsec->processor, send_esp, NULL); + this->dns_proxy->register_cb(this->dns_proxy, deliver_plain, this); lib->processor->queue_job(lib->processor, (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this, @@ -422,14 +411,10 @@ static void close_tun_device(private_android_service_t *this) this->tunfd = -1; this->lock->unlock(this->lock); - this->dns_proxy->unregister_cb(this->dns_proxy, - (dns_proxy_response_cb_t)deliver_plain); - ipsec->processor->unregister_outbound(ipsec->processor, - (ipsec_outbound_cb_t)send_esp); - ipsec->processor->unregister_inbound(ipsec->processor, - (ipsec_inbound_cb_t)deliver_plain); - charon->receiver->del_esp_cb(charon->receiver, - (receiver_esp_cb_t)receiver_esp_cb); + this->dns_proxy->unregister_cb(this->dns_proxy, deliver_plain); + ipsec->processor->unregister_outbound(ipsec->processor, send_esp); + ipsec->processor->unregister_inbound(ipsec->processor, deliver_plain); + charon->receiver->del_esp_cb(charon->receiver, receiver_esp_cb); close(tunfd); } From 8ddfaf5857e0697713df6ba37206c0dee39366bf Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 11 May 2023 16:56:07 +0200 Subject: [PATCH 4/7] libipsec: Instruct ESP sender whether to use UDP encapsulation --- .../main/jni/libandroidbridge/backend/android_service.c | 2 +- .../plugins/kernel_libipsec/kernel_libipsec_router.c | 2 +- src/libipsec/ipsec_processor.c | 9 +++++---- src/libipsec/ipsec_processor.h | 6 ++++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c index d01ca7353..f7e6ec34b 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c @@ -86,7 +86,7 @@ struct private_android_service_t { }; CALLBACK(send_esp, void, - void *data, esp_packet_t *packet) + void *data, esp_packet_t *packet, bool encap) { charon->sender->send_no_marker(charon->sender, (packet_t*)packet); } diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c index 7c6d3c3ba..07a4da4a3 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c @@ -95,7 +95,7 @@ static bool tun_entry_equals(tun_entry_t *a, tun_entry_t *b) } CALLBACK(send_esp, void, - void *data, esp_packet_t *packet) + void *data, esp_packet_t *packet, bool encap) { charon->sender->send_no_marker(charon->sender, (packet_t*)packet); } diff --git a/src/libipsec/ipsec_processor.c b/src/libipsec/ipsec_processor.c index 11c587c93..2572b0880 100644 --- a/src/libipsec/ipsec_processor.c +++ b/src/libipsec/ipsec_processor.c @@ -169,12 +169,12 @@ static job_requeue_t process_inbound(private_ipsec_processor_t *this) * Send an ESP packet using the registered outbound callback */ static void send_outbound(private_ipsec_processor_t *this, - esp_packet_t *packet) + esp_packet_t *packet, bool encap) { this->lock->read_lock(this->lock); if (this->outbound.cb) { - this->outbound.cb(this->outbound.data, packet); + this->outbound.cb(this->outbound.data, packet, encap); } else { @@ -194,7 +194,7 @@ static job_requeue_t process_outbound(private_ipsec_processor_t *this) ip_packet_t *packet; ipsec_sa_t *sa; host_t *src, *dst; - bool acquire = FALSE; + bool acquire = FALSE, encap = FALSE; packet = (ip_packet_t*)this->outbound_queue->dequeue(this->outbound_queue); @@ -242,9 +242,10 @@ static job_requeue_t process_outbound(private_ipsec_processor_t *this) return JOB_REQUEUE_DIRECT; } sa->update_usestats(sa, packet->get_encoding(packet).len); + encap = sa->get_encap(sa); ipsec->sas->checkin(ipsec->sas, sa); policy->destroy(policy); - send_outbound(this, esp_packet); + send_outbound(this, esp_packet, encap); return JOB_REQUEUE_DIRECT; } diff --git a/src/libipsec/ipsec_processor.h b/src/libipsec/ipsec_processor.h index 734e8f53e..bc9d1863f 100644 --- a/src/libipsec/ipsec_processor.h +++ b/src/libipsec/ipsec_processor.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2023 Tobias Brunner * * Copyright (C) secunet Security Networks AG * @@ -43,8 +43,10 @@ typedef void (*ipsec_inbound_cb_t)(void *data, ip_packet_t *packet); * * @param data data supplied during registration of the callback * @param packet ESP packet to send + * @param encap TRUE to send the packet with UDP encapsulation */ -typedef void (*ipsec_outbound_cb_t)(void *data, esp_packet_t *packet); +typedef void (*ipsec_outbound_cb_t)(void *data, esp_packet_t *packet, + bool encap); /** * IPsec processor From 29e8cb3f903dfe329ad3ec59f10f1495f3c4373f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 11 May 2023 17:04:00 +0200 Subject: [PATCH 5/7] libipsec: Move restrictions regarding UDP encapsulation to users --- .../jni/libandroidbridge/kernel/android_ipsec.c | 12 ++++++++++++ .../plugins/kernel_libipsec/kernel_libipsec_ipsec.c | 6 ++++++ src/libipsec/ipsec_sa_mgr.c | 13 ------------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_ipsec.c b/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_ipsec.c index 7af027e75..b2caed97c 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_ipsec.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_ipsec.c @@ -71,6 +71,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t, private_kernel_android_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_add_sa_t *data) { + if (!data->encap) + { + DBG1(DBG_ESP, "failed to add SAD entry: only UDP encapsulation is " + "supported"); + return FAILED; + } return ipsec->sas->add_sa(ipsec->sas, id->src, id->dst, id->spi, id->proto, data->reqid, id->mark, data->tfc, data->lifetime, data->enc_alg, data->enc_key, data->int_alg, data->int_key, @@ -82,6 +88,12 @@ METHOD(kernel_ipsec_t, update_sa, status_t, private_kernel_android_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_update_sa_t *data) { + if (!data->new_encap) + { + DBG1(DBG_ESP, "failed to update SAD entry: can't deactivate UDP " + "encapsulation"); + return NOT_SUPPORTED; + } return ipsec->sas->update_sa(ipsec->sas, id->spi, id->proto, data->cpi, id->src, id->dst, data->new_src, data->new_dst, data->encap, data->new_encap, id->mark); diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index 8df2e3dbc..174751833 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c @@ -263,6 +263,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t, private_kernel_libipsec_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_add_sa_t *data) { + if (!data->encap) + { + DBG1(DBG_ESP, "failed to add SAD entry: only UDP encapsulation is " + "supported"); + return FAILED; + } return ipsec->sas->add_sa(ipsec->sas, id->src, id->dst, id->spi, id->proto, data->reqid, id->mark, data->tfc, data->lifetime, data->enc_alg, data->enc_key, data->int_alg, data->int_key, diff --git a/src/libipsec/ipsec_sa_mgr.c b/src/libipsec/ipsec_sa_mgr.c index 76006a851..56698f3f0 100644 --- a/src/libipsec/ipsec_sa_mgr.c +++ b/src/libipsec/ipsec_sa_mgr.c @@ -518,12 +518,6 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t, DBG2(DBG_ESP, " using integrity algorithm %N with key size %d", integrity_algorithm_names, int_alg, int_key.len * 8); - if (!encap) - { - DBG1(DBG_ESP, " IPsec SA: only UDP encapsulation is supported"); - return FAILED; - } - sa_new = ipsec_sa_create(spi, src, dst, protocol, reqid, mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode, ipcomp, cpi, encap, esn, inbound); @@ -574,13 +568,6 @@ METHOD(ipsec_sa_mgr_t, update_sa, status_t, DBG2(DBG_ESP, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H", ntohl(spi), src, dst, new_src, new_dst); - if (!new_encap) - { - DBG1(DBG_ESP, "failed to update SAD entry: can't deactivate UDP " - "encapsulation"); - return NOT_SUPPORTED; - } - this->mutex->lock(this->mutex); if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, (void**)&entry, spi, src, dst) && From e306fa5f73e874a526ddf2a76088220865a9cd2b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 11 May 2023 18:34:58 +0200 Subject: [PATCH 6/7] kernel-libipsec: Add support to send/receive raw ESP packets This is currently only supported on Linux and with the appropriate permissions. Since it's experimental, it's disabled by default. The log messages for each sent and received ESP message are logged in NET like the ones in the socket-default plugin for UDP-encapsulated messages. --- conf/plugins/kernel-libipsec.opt | 7 + .../plugins/kernel_libipsec/Makefile.am | 3 +- .../kernel_libipsec_esp_handler.c | 351 ++++++++++++++++++ .../kernel_libipsec_esp_handler.h | 54 +++ .../kernel_libipsec/kernel_libipsec_ipsec.c | 12 +- .../kernel_libipsec/kernel_libipsec_plugin.c | 25 +- .../kernel_libipsec/kernel_libipsec_router.c | 26 +- 7 files changed, 469 insertions(+), 9 deletions(-) create mode 100644 src/libcharon/plugins/kernel_libipsec/kernel_libipsec_esp_handler.c create mode 100644 src/libcharon/plugins/kernel_libipsec/kernel_libipsec_esp_handler.h diff --git a/conf/plugins/kernel-libipsec.opt b/conf/plugins/kernel-libipsec.opt index e76db63d9..a79d00d1c 100644 --- a/conf/plugins/kernel-libipsec.opt +++ b/conf/plugins/kernel-libipsec.opt @@ -5,3 +5,10 @@ charon.plugins.kernel-libipsec.allow_peer_ts = no installed for such traffic (via TUN device) usually prevents further IKE traffic. The fwmark options for the _kernel-netlink_ and _socket-default_ plugins can be used to circumvent that problem. + +charon.plugins.kernel-libipsec.fwmark = charon.plugins.socket-default.fwmark + Firewall mark to set on outbound raw ESP packets. + +charon.plugins.kernel-libipsec.raw_esp = no + Whether to send and receive ESP packets without UDP encapsulation if + supported on this platform and no NAT is detected. diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.am b/src/libcharon/plugins/kernel_libipsec/Makefile.am index 4757280b4..604d6b4fb 100644 --- a/src/libcharon/plugins/kernel_libipsec/Makefile.am +++ b/src/libcharon/plugins/kernel_libipsec/Makefile.am @@ -15,7 +15,8 @@ endif libstrongswan_kernel_libipsec_la_SOURCES = \ kernel_libipsec_plugin.h kernel_libipsec_plugin.c \ kernel_libipsec_ipsec.h kernel_libipsec_ipsec.c \ - kernel_libipsec_router.h kernel_libipsec_router.c + kernel_libipsec_router.h kernel_libipsec_router.c \ + kernel_libipsec_esp_handler.h kernel_libipsec_esp_handler.c libstrongswan_kernel_libipsec_la_LIBADD = $(top_builddir)/src/libipsec/libipsec.la diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_esp_handler.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_esp_handler.c new file mode 100644 index 000000000..095ad67b4 --- /dev/null +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_esp_handler.c @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2023 Tobias Brunner + * + * Copyright (C) secunet Security Networks AG + * + * 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. See . + * + * 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. + */ + +/* for struct in6_pktinfo */ +#define _GNU_SOURCE + +#include "kernel_libipsec_esp_handler.h" + +#ifdef __linux__ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef struct private_kernel_libipsec_esp_handler_t private_kernel_libipsec_esp_handler_t; + +/** + * Private data + */ +struct private_kernel_libipsec_esp_handler_t { + + /** + * Public interface + */ + kernel_libipsec_esp_handler_t public; + + /** + * Queue for outbound ESP packets (esp_packet_t*) + */ + blocking_queue_t *queue; + + /** + * Socket to send/receive IPv4 ESP packets + */ + int skt_v4; + + /** + * Socket to send/receive IPv6 ESP packets + */ + int skt_v6; +}; + +METHOD(kernel_libipsec_esp_handler_t, send_, void, + private_kernel_libipsec_esp_handler_t *this, esp_packet_t *packet) +{ + this->queue->enqueue(this->queue, packet); +} + +CALLBACK(send_esp, job_requeue_t, + private_kernel_libipsec_esp_handler_t *this) +{ + packet_t *packet; + host_t *source, *destination; + chunk_t data; + struct msghdr msg = {}; + struct cmsghdr *cmsg; + struct iovec iov; + char ancillary[64] = {}; + ssize_t len; + int skt; + + packet = (packet_t*)this->queue->dequeue(this->queue); + + data = packet->get_data(packet); + source = packet->get_source(packet); + destination = packet->get_destination(packet); + DBG2(DBG_NET, "sending raw ESP packet: from %H to %H (%zu data bytes)", + source, destination, data.len); + + /* the port of the destination address acts as protocol selector for RAW + * sockets, for IPv4 the kernel ignores it, for IPv6 it does not and + * complains if it isn't zero or doesn't match the one set on the socket */ + destination->set_port(destination, 0); + + msg.msg_name = destination->get_sockaddr(destination); + msg.msg_namelen = *destination->get_sockaddr_len(destination); + iov.iov_base = data.ptr; + iov.iov_len = data.len; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_flags = 0; + msg.msg_control = ancillary; + + if (source->get_family(source) == AF_INET) + { + struct in_pktinfo *pktinfo; + const struct sockaddr_in *sin; + + msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_PKTINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + + pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); + sin = (struct sockaddr_in*)source->get_sockaddr(source); + memcpy(&pktinfo->ipi_spec_dst, &sin->sin_addr, sizeof(struct in_addr)); + skt = this->skt_v4; + } + else + { + struct in6_pktinfo *pktinfo; + const struct sockaddr_in6 *sin; + + msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_PKTINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + + pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg); + sin = (struct sockaddr_in6*)source->get_sockaddr(source); + memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr)); + skt = this->skt_v6; + } + + len = sendmsg(skt, &msg, 0); + if (len != data.len) + { + DBG1(DBG_KNL, "error writing to ESP socket: %s", strerror(errno)); + } + packet->destroy(packet); + return JOB_REQUEUE_DIRECT; +} + +CALLBACK(receive_esp, bool, + private_kernel_libipsec_esp_handler_t *this, int fd, watcher_event_t event) +{ + char buf[2048]; + struct msghdr msg; + struct cmsghdr *cmsg; + struct iovec iov; + char ancillary[64]; + union { + struct sockaddr_in in4; + struct sockaddr_in6 in6; + } src; + host_t *source, *destination = NULL; + packet_t *packet; + chunk_t data; + ssize_t len; + + msg.msg_name = &src; + msg.msg_namelen = sizeof(src); + iov.iov_base = buf; + iov.iov_len = sizeof(buf); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = ancillary; + msg.msg_controllen = sizeof(ancillary); + msg.msg_flags = 0; + + len = recvmsg(fd, &msg, MSG_DONTWAIT|MSG_TRUNC); + if (len < 0) + { + if (errno != EAGAIN && errno != EWOULDBLOCK) + { + DBG1(DBG_KNL, "receiving from ESP socket failed: %s", + strerror(errno)); + } + return TRUE; + } + else if (msg.msg_flags & MSG_TRUNC) + { + DBG1(DBG_KNL, "ESP packet with length %zd exceeds buffer size of %zu", + len, sizeof(buf)); + return TRUE; + } + data = chunk_create(buf, len); + /* skip the IP header returned by IPv4 raw sockets */ + if (fd == this->skt_v4) + { + data = chunk_skip(data, sizeof(struct iphdr)); + } + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level == IPPROTO_IP && + cmsg->cmsg_type == IP_PKTINFO) + { + const struct in_pktinfo *pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); + struct sockaddr_in dst = { + .sin_family = AF_INET, + }; + + memcpy(&dst.sin_addr, &pktinfo->ipi_addr, sizeof(dst.sin_addr)); + destination = host_create_from_sockaddr((sockaddr_t*)&dst); + } + else if (cmsg->cmsg_level == IPPROTO_IPV6 && + cmsg->cmsg_type == IPV6_PKTINFO) + { + const struct in6_pktinfo *pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg); + struct sockaddr_in6 dst = { + .sin6_family = AF_INET6, + }; + + memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr)); + destination = host_create_from_sockaddr((sockaddr_t*)&dst); + } + if (destination) + { + break; + } + } + if (!destination) + { + DBG1(DBG_KNL, "error reading destination IP address for ESP packet"); + return TRUE; + } + source = host_create_from_sockaddr((sockaddr_t*)&src); + DBG2(DBG_NET, "received raw ESP packet: from %#H to %#H (%zu data bytes)", + source, destination, data.len); + + packet = packet_create(); + packet->set_source(packet, source); + packet->set_destination(packet, destination); + packet->set_data(packet, chunk_clone(data)); + ipsec->processor->queue_inbound(ipsec->processor, + esp_packet_create_from_packet(packet)); + return TRUE; +} + +METHOD(kernel_libipsec_esp_handler_t, destroy, void, + private_kernel_libipsec_esp_handler_t *this) +{ + if (this->skt_v4 >= 0) + { + lib->watcher->remove(lib->watcher, this->skt_v4); + close(this->skt_v4); + } + if (this->skt_v6 >= 0) + { + lib->watcher->remove(lib->watcher, this->skt_v6); + close(this->skt_v6); + } + this->queue->destroy_offset(this->queue, offsetof(esp_packet_t, destroy)); + free(this); +} + +/** + * Create a RAW socket for the given address family + */ +static int create_socket(int family) +{ + const char *fwmark; + mark_t mark; + int skt, on = 1; + + skt = socket(family, SOCK_RAW, IPPROTO_ESP); + if (skt == -1) + { + DBG1(DBG_KNL, "opening RAW socket for ESP failed: %s", strerror(errno)); + return -1; + } + if (setsockopt(skt, family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6, + family == AF_INET ? IP_PKTINFO : IPV6_RECVPKTINFO, + &on, sizeof(on)) == -1) + { + DBG1(DBG_KNL, "unable to set PKTINFO on ESP socket: %s", + strerror(errno)); + close(skt); + return -1; + } + fwmark = lib->settings->get_str(lib->settings, + "%s.plugins.kernel-libipsec.fwmark", + lib->settings->get_str(lib->settings, + "%s.plugins.socket-default.fwmark", NULL, lib->ns), + lib->ns); + if (fwmark && mark_from_string(fwmark, MARK_OP_NONE, &mark) && + setsockopt(skt, SOL_SOCKET, SO_MARK, &mark.value, sizeof(mark.value)) < 0) + { + DBG1(DBG_KNL, "unable to set SO_MARK on ESP socket: %s", + strerror(errno)); + } + return skt; +} + +/* + * Described in header + */ +kernel_libipsec_esp_handler_t *kernel_libipsec_esp_handler_create() +{ + private_kernel_libipsec_esp_handler_t *this; + + if (!lib->caps->keep(lib->caps, CAP_NET_RAW)) + { /* required to open SOCK_RAW sockets and according to capabilities(7) + * it is also required to use the socket */ + DBG1(DBG_KNL, "kernel-libipsec requires CAP_NET_RAW capability to send " + "and receive ESP packets without UDP encapsulation"); + return NULL; + } + + INIT(this, + .public = { + .send = _send_, + .destroy = _destroy, + }, + .queue = blocking_queue_create(), + .skt_v4 = create_socket(AF_INET), + .skt_v6 = create_socket(AF_INET6), + ); + + if (this->skt_v4 == -1 && this->skt_v6 == -1) + { + destroy(this); + return NULL; + } + if (this->skt_v4 >= 0) + { + lib->watcher->add(lib->watcher, this->skt_v4, WATCHER_READ, + receive_esp, this); + } + if (this->skt_v6 >= 0) + { + lib->watcher->add(lib->watcher, this->skt_v6, WATCHER_READ, + receive_esp, this); + } + lib->processor->queue_job(lib->processor, + (job_t*)callback_job_create(send_esp, this, NULL, + (callback_job_cancel_t)return_false)); + return &this->public; +} + +#else /* __linux__ */ + +kernel_libipsec_esp_handler_t *kernel_libipsec_esp_handler_create() +{ + return NULL; +} + +#endif /* __linux__ */ diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_esp_handler.h b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_esp_handler.h new file mode 100644 index 000000000..6b7a1082c --- /dev/null +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_esp_handler.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2023 Tobias Brunner + * + * Copyright (C) secunet Security Networks AG + * + * 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. See . + * + * 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. + */ + +/** + * @defgroup kernel_libipsec_esp_handler kernel_libipsec_esp_handler + * @{ @ingroup kernel_libipsec + */ + +#ifndef KERNEL_LIBIPSEC_ESP_HANDLER_H_ +#define KERNEL_LIBIPSEC_ESP_HANDLER_H_ + +#include + +typedef struct kernel_libipsec_esp_handler_t kernel_libipsec_esp_handler_t; + +/** + * Class that sends and receives raw ESP packets. + */ +struct kernel_libipsec_esp_handler_t { + + /** + * Send the given ESP packet without UDP encapsulation. + * + * @param packet ESP packet to send + */ + void (*send)(kernel_libipsec_esp_handler_t *this, esp_packet_t *packet); + + /** + * Destroy the given instance. + */ + void (*destroy)(kernel_libipsec_esp_handler_t *this); +}; + +/** + * Create a kernel_libipsec_esp_handler_t instance. + * + * @return created instance, NULL if not supported + */ +kernel_libipsec_esp_handler_t *kernel_libipsec_esp_handler_create(); + +#endif /** KERNEL_LIBIPSEC_ESP_HANDLER_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index 174751833..22e1200dd 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c @@ -56,6 +56,11 @@ struct private_kernel_libipsec_ipsec_t { * Whether the remote TS may equal the IKE peer */ bool allow_peer_ts; + + /** + * Whether UDP encapsulation is required + */ + bool require_encap; }; typedef struct exclude_route_t exclude_route_t; @@ -241,8 +246,8 @@ static void acquire(uint32_t reqid) METHOD(kernel_ipsec_t, get_features, kernel_feature_t, private_kernel_libipsec_ipsec_t *this) { - return KERNEL_REQUIRE_UDP_ENCAPSULATION | KERNEL_ESP_V3_TFC | - KERNEL_SA_USE_TIME; + return KERNEL_ESP_V3_TFC | KERNEL_SA_USE_TIME | + (this->require_encap ? KERNEL_REQUIRE_UDP_ENCAPSULATION : 0); } METHOD(kernel_ipsec_t, get_spi, status_t, @@ -263,7 +268,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t, private_kernel_libipsec_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_add_sa_t *data) { - if (!data->encap) + if (this->require_encap && !data->encap) { DBG1(DBG_ESP, "failed to add SAD entry: only UDP encapsulation is " "supported"); @@ -704,6 +709,7 @@ kernel_libipsec_ipsec_t *kernel_libipsec_ipsec_create() .excludes = linked_list_create(), .allow_peer_ts = lib->settings->get_bool(lib->settings, "%s.plugins.kernel-libipsec.allow_peer_ts", FALSE, lib->ns), + .require_encap = !lib->get(lib, "kernel-libipsec-esp-handler"), ); ipsec->events->register_listener(ipsec->events, &this->ipsec_listener); diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_plugin.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_plugin.c index 0b25518f4..f539693eb 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_plugin.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Tobias Brunner + * Copyright (C) 2012-2023 Tobias Brunner * * Copyright (C) secunet Security Networks AG * @@ -17,6 +17,7 @@ #include "kernel_libipsec_plugin.h" #include "kernel_libipsec_ipsec.h" #include "kernel_libipsec_router.h" +#include "kernel_libipsec_esp_handler.h" #include #include @@ -45,6 +46,11 @@ struct private_kernel_libipsec_plugin_t { * Packet router */ kernel_libipsec_router_t *router; + + /** + * Raw ESP handler + */ + kernel_libipsec_esp_handler_t *esp_handler; }; METHOD(plugin_t, get_name, char*, @@ -92,6 +98,11 @@ METHOD(plugin_t, destroy, void, lib->set(lib, "kernel-libipsec-tun", NULL); this->tun->destroy(this->tun); } + if (this->esp_handler) + { + lib->set(lib, "kernel-libipsec-esp-handler", NULL); + this->esp_handler->destroy(this->esp_handler); + } libipsec_deinit(); free(this); } @@ -146,5 +157,17 @@ plugin_t *kernel_libipsec_plugin_create() /* set TUN device as default to install VIPs */ lib->settings->set_str(lib->settings, "%s.install_virtual_ip_on", this->tun->get_name(this->tun), lib->ns); + + if (lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-libipsec.raw_esp", FALSE, lib->ns)) + { + this->esp_handler = kernel_libipsec_esp_handler_create(); + if (!this->esp_handler) + { + DBG1(DBG_KNL, "only UDP-encapsulated ESP packets supported by " + "kernel-libipsec on this platform"); + } + lib->set(lib, "kernel-libipsec-esp-handler", this->esp_handler); + } return &this->public.plugin; } diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c index 07a4da4a3..74746e251 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c @@ -18,6 +18,7 @@ #include #include "kernel_libipsec_router.h" +#include "kernel_libipsec_esp_handler.h" #include #include @@ -76,6 +77,11 @@ struct private_kernel_libipsec_router_t { * Pipe to signal handle_plain() about changes regarding TUN devices */ int notify[2]; + + /** + * ESP handler to send raw ESP packets + */ + kernel_libipsec_esp_handler_t *esp_handler; }; /** @@ -95,9 +101,20 @@ static bool tun_entry_equals(tun_entry_t *a, tun_entry_t *b) } CALLBACK(send_esp, void, - void *data, esp_packet_t *packet, bool encap) + private_kernel_libipsec_router_t *this, esp_packet_t *packet, bool encap) { - charon->sender->send_no_marker(charon->sender, (packet_t*)packet); + if (encap) + { + charon->sender->send_no_marker(charon->sender, (packet_t*)packet); + } + else if (this->esp_handler) + { + this->esp_handler->send(this->esp_handler, packet); + } + else + { /* shouldn't happen as UDP encap is forced without ESP handler */ + packet->destroy(packet); + } } CALLBACK(receiver_esp_cb, void, @@ -323,7 +340,8 @@ kernel_libipsec_router_t *kernel_libipsec_router_create() }, .tun = { .tun = lib->get(lib, "kernel-libipsec-tun"), - } + }, + .esp_handler = lib->get(lib, "kernel-libipsec-esp-handler"), ); if (pipe(this->notify) != 0 || @@ -341,7 +359,7 @@ kernel_libipsec_router_t *kernel_libipsec_router_create() this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); charon->kernel->add_listener(charon->kernel, &this->public.listener); - ipsec->processor->register_outbound(ipsec->processor, send_esp, NULL); + ipsec->processor->register_outbound(ipsec->processor, send_esp, this); ipsec->processor->register_inbound(ipsec->processor, deliver_plain, this); charon->receiver->add_esp_cb(charon->receiver, receiver_esp_cb, NULL); lib->processor->queue_job(lib->processor, From 5db9b26e32f888a7ef5425da71464ca21c011447 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 15 May 2023 15:55:30 +0200 Subject: [PATCH 7/7] testing: Add libipsec scenarios that exchange raw ESP packets --- .../host2host-cert-raw/description.txt | 11 ++++ .../libipsec/host2host-cert-raw/evaltest.dat | 5 ++ .../hosts/moon/etc/strongswan.conf | 24 ++++++++ .../hosts/moon/etc/swanctl/swanctl.conf | 26 ++++++++ .../host2host-cert-raw/hosts/moon/etc/updown | 59 +++++++++++++++++++ .../hosts/sun/etc/strongswan.conf | 24 ++++++++ .../hosts/sun/etc/swanctl/swanctl.conf | 26 ++++++++ .../host2host-cert-raw/hosts/sun/etc/updown | 59 +++++++++++++++++++ .../libipsec/host2host-cert-raw/posttest.dat | 7 +++ .../libipsec/host2host-cert-raw/pretest.dat | 9 +++ .../libipsec/host2host-cert-raw/test.conf | 25 ++++++++ .../description.txt | 0 .../evaltest.dat | 4 +- .../hosts/moon/etc/strongswan.conf | 0 .../hosts/moon/etc/swanctl/swanctl.conf | 0 .../hosts/moon/etc/updown | 0 .../hosts/sun/etc/strongswan.conf | 0 .../hosts/sun/etc/swanctl/swanctl.conf | 0 .../hosts/sun/etc/updown | 0 .../posttest.dat | 0 .../pretest.dat | 0 .../test.conf | 0 .../description.txt | 11 ++++ .../net2net-cert-ip6-in-ip6-raw/evaltest.dat | 5 ++ .../hosts/moon/etc/strongswan.conf | 15 +++++ .../hosts/moon/etc/swanctl/swanctl.conf | 36 +++++++++++ .../hosts/moon/etc/updown | 59 +++++++++++++++++++ .../hosts/sun/etc/strongswan.conf | 15 +++++ .../hosts/sun/etc/swanctl/swanctl.conf | 37 ++++++++++++ .../hosts/sun/etc/updown | 59 +++++++++++++++++++ .../net2net-cert-ip6-in-ip6-raw/posttest.dat | 11 ++++ .../net2net-cert-ip6-in-ip6-raw/pretest.dat | 13 ++++ .../net2net-cert-ip6-in-ip6-raw/test.conf | 29 +++++++++ .../libipsec/net2net-cert-raw/description.txt | 9 +++ .../libipsec/net2net-cert-raw/evaltest.dat | 5 ++ .../hosts/moon/etc/strongswan.conf | 15 +++++ .../hosts/moon/etc/swanctl/swanctl.conf | 29 +++++++++ .../net2net-cert-raw/hosts/moon/etc/updown | 59 +++++++++++++++++++ .../hosts/sun/etc/strongswan.conf | 15 +++++ .../hosts/sun/etc/swanctl/swanctl.conf | 30 ++++++++++ .../net2net-cert-raw/hosts/sun/etc/updown | 59 +++++++++++++++++++ .../libipsec/net2net-cert-raw/posttest.dat | 5 ++ .../libipsec/net2net-cert-raw/pretest.dat | 7 +++ .../tests/libipsec/net2net-cert-raw/test.conf | 25 ++++++++ 44 files changed, 825 insertions(+), 2 deletions(-) create mode 100644 testing/tests/libipsec/host2host-cert-raw/description.txt create mode 100644 testing/tests/libipsec/host2host-cert-raw/evaltest.dat create mode 100644 testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/swanctl/swanctl.conf create mode 100755 testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/updown create mode 100644 testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/strongswan.conf create mode 100755 testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/swanctl/swanctl.conf create mode 100755 testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/updown create mode 100644 testing/tests/libipsec/host2host-cert-raw/posttest.dat create mode 100644 testing/tests/libipsec/host2host-cert-raw/pretest.dat create mode 100644 testing/tests/libipsec/host2host-cert-raw/test.conf rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/description.txt (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/evaltest.dat (85%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/hosts/moon/etc/strongswan.conf (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/hosts/moon/etc/swanctl/swanctl.conf (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/hosts/moon/etc/updown (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/hosts/sun/etc/strongswan.conf (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/hosts/sun/etc/swanctl/swanctl.conf (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/hosts/sun/etc/updown (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/posttest.dat (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/pretest.dat (100%) rename testing/tests/libipsec/{net2net-cert-ipv6 => net2net-cert-ip6-in-ip4}/test.conf (100%) create mode 100644 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/description.txt create mode 100644 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/evaltest.dat create mode 100644 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/swanctl/swanctl.conf create mode 100755 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/updown create mode 100644 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/strongswan.conf create mode 100755 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/swanctl/swanctl.conf create mode 100755 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/updown create mode 100644 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/posttest.dat create mode 100644 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/pretest.dat create mode 100644 testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/test.conf create mode 100644 testing/tests/libipsec/net2net-cert-raw/description.txt create mode 100644 testing/tests/libipsec/net2net-cert-raw/evaltest.dat create mode 100644 testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/swanctl/swanctl.conf create mode 100755 testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/updown create mode 100644 testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/strongswan.conf create mode 100755 testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/swanctl/swanctl.conf create mode 100755 testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/updown create mode 100644 testing/tests/libipsec/net2net-cert-raw/posttest.dat create mode 100644 testing/tests/libipsec/net2net-cert-raw/pretest.dat create mode 100644 testing/tests/libipsec/net2net-cert-raw/test.conf diff --git a/testing/tests/libipsec/host2host-cert-raw/description.txt b/testing/tests/libipsec/host2host-cert-raw/description.txt new file mode 100644 index 000000000..3c2ee919a --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/description.txt @@ -0,0 +1,11 @@ +A connection between the hosts moon and sun is set up. +The authentication is based on X.509 certificates and the kernel-libipsec +plugin is used for userland IPsec ESP encryption. In this scenario, UDP encapsulation +isn't enforced by the plugin as sending of raw ESP packets is enabled. +Firewall marks are used to make the direct ESP connection possible and +still allow IKE traffic to flow freely between the two hosts. +

+Upon the successful establishment of the IPsec tunnel, an updown script automatically +inserts iptables-based firewall rules that let pass the traffic tunneled via the +ipsec0 tun interface. In order to test both host-to-host tunnel and firewall, +moon pings sun. diff --git a/testing/tests/libipsec/host2host-cert-raw/evaltest.dat b/testing/tests/libipsec/host2host-cert-raw/evaltest.dat new file mode 100644 index 000000000..6bcf6e9a3 --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/evaltest.dat @@ -0,0 +1,5 @@ +moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_.eq=1::YES +moon::swanctl --list-sas --raw 2> /dev/null::host-host.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=500 local-id=moon.strongswan.org remote-host=192.168.0.2 remote-port=500 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.*host-host.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[192.168.0.1/32] remote-ts=\[192.168.0.2/32]::YES +sun::swanctl --list-sas --raw 2> /dev/null::host-host.*version=2 state=ESTABLISHED local-host=192.168.0.2 local-port=500 local-id=sun.strongswan.org remote-host=192.168.0.1 remote-port=500 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.*host-host.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128.*local-ts=\[192.168.0.2/32] remote-ts=\[192.168.0.1/32]::YES +sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES +sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES diff --git a/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/strongswan.conf b/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..ac1b85564 --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/strongswan.conf @@ -0,0 +1,24 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon-systemd { + load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-libipsec kernel-netlink socket-default updown + + multiple_authentication = no + + plugins { + kernel-netlink { + fwmark = !0x42 + } + socket-default { + fwmark = 0x42 + } + kernel-libipsec { + allow_peer_ts = yes + raw_esp = yes + } + } +} diff --git a/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/swanctl/swanctl.conf new file mode 100755 index 000000000..f5553c0af --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/swanctl/swanctl.conf @@ -0,0 +1,26 @@ +connections { + + host-host { + 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 { + host-host { + updown = /etc/updown + esp_proposals = aes128-sha256-x25519 + } + } + version = 2 + mobike = no + proposals = aes128-sha256-x25519 + } +} diff --git a/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/updown b/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/updown new file mode 100755 index 000000000..c56509b61 --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/hosts/moon/etc/updown @@ -0,0 +1,59 @@ +#!/bin/sh + +TUN_NAME=ipsec0 + +# use protocol specific options to set ports +case "$PLUTO_MY_PROTOCOL" in +1) # ICMP + ICMP_TYPE_OPTION="--icmp-type" + ;; +58) # ICMPv6 + ICMP_TYPE_OPTION="--icmpv6-type" + ;; +*) + ;; +esac + +# are there port numbers? +if [ "$PLUTO_MY_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + else + S_MY_PORT="--sport $PLUTO_MY_PORT" + D_MY_PORT="--dport $PLUTO_MY_PORT" + fi +fi +if [ "$PLUTO_PEER_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + # the syntax is --icmp[v6]-type type[/code], so add it to the existing option + S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT" + D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT" + else + S_PEER_PORT="--sport $PLUTO_PEER_PORT" + D_PEER_PORT="--dport $PLUTO_PEER_PORT" + fi +fi + +case "$PLUTO_VERB" in +up-host) + iptables -I OUTPUT 1 -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + iptables -I INPUT 1 -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +down-host) + iptables -D OUTPUT -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + iptables -D INPUT -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +esac diff --git a/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/strongswan.conf b/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/strongswan.conf new file mode 100644 index 000000000..ac1b85564 --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/strongswan.conf @@ -0,0 +1,24 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon-systemd { + load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-libipsec kernel-netlink socket-default updown + + multiple_authentication = no + + plugins { + kernel-netlink { + fwmark = !0x42 + } + socket-default { + fwmark = 0x42 + } + kernel-libipsec { + allow_peer_ts = yes + raw_esp = yes + } + } +} diff --git a/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/swanctl/swanctl.conf b/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/swanctl/swanctl.conf new file mode 100755 index 000000000..cf11e7547 --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/swanctl/swanctl.conf @@ -0,0 +1,26 @@ +connections { + + host-host { + 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 { + host-host { + updown = /etc/updown + esp_proposals = aes128-sha256-x25519 + } + } + version = 2 + mobike = no + proposals = aes128-sha256-x25519 + } +} diff --git a/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/updown b/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/updown new file mode 100755 index 000000000..c56509b61 --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/hosts/sun/etc/updown @@ -0,0 +1,59 @@ +#!/bin/sh + +TUN_NAME=ipsec0 + +# use protocol specific options to set ports +case "$PLUTO_MY_PROTOCOL" in +1) # ICMP + ICMP_TYPE_OPTION="--icmp-type" + ;; +58) # ICMPv6 + ICMP_TYPE_OPTION="--icmpv6-type" + ;; +*) + ;; +esac + +# are there port numbers? +if [ "$PLUTO_MY_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + else + S_MY_PORT="--sport $PLUTO_MY_PORT" + D_MY_PORT="--dport $PLUTO_MY_PORT" + fi +fi +if [ "$PLUTO_PEER_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + # the syntax is --icmp[v6]-type type[/code], so add it to the existing option + S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT" + D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT" + else + S_PEER_PORT="--sport $PLUTO_PEER_PORT" + D_PEER_PORT="--dport $PLUTO_PEER_PORT" + fi +fi + +case "$PLUTO_VERB" in +up-host) + iptables -I OUTPUT 1 -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + iptables -I INPUT 1 -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +down-host) + iptables -D OUTPUT -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + iptables -D INPUT -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +esac diff --git a/testing/tests/libipsec/host2host-cert-raw/posttest.dat b/testing/tests/libipsec/host2host-cert-raw/posttest.dat new file mode 100644 index 000000000..557ee303d --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/posttest.dat @@ -0,0 +1,7 @@ +moon::swanctl --terminate --ike host-host 2> /dev/null +moon::systemctl stop strongswan +sun::systemctl stop strongswan +moon::iptables-restore < /etc/iptables.flush +sun::iptables-restore < /etc/iptables.flush +moon::sysctl --pattern net.ipv4.conf.all.rp_filter --system +sun::sysctl --pattern net.ipv4.conf.all.rp_filter --system diff --git a/testing/tests/libipsec/host2host-cert-raw/pretest.dat b/testing/tests/libipsec/host2host-cert-raw/pretest.dat new file mode 100644 index 000000000..624728eac --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/pretest.dat @@ -0,0 +1,9 @@ +moon::sysctl -w net.ipv4.conf.all.rp_filter=2 +sun::sysctl -w net.ipv4.conf.all.rp_filter=2 +moon::iptables-restore < /etc/iptables.rules +sun::iptables-restore < /etc/iptables.rules +moon::systemctl start strongswan +sun::systemctl start strongswan +sun::expect-connection host-host +moon::expect-connection host-host +moon::swanctl --initiate --child host-host 2> /dev/null diff --git a/testing/tests/libipsec/host2host-cert-raw/test.conf b/testing/tests/libipsec/host2host-cert-raw/test.conf new file mode 100644 index 000000000..52d886dcc --- /dev/null +++ b/testing/tests/libipsec/host2host-cert-raw/test.conf @@ -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="moon winnetou sun" + +# Corresponding block diagram +# +DIAGRAM="m-w-s.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 diff --git a/testing/tests/libipsec/net2net-cert-ipv6/description.txt b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/description.txt similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/description.txt rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/description.txt diff --git a/testing/tests/libipsec/net2net-cert-ipv6/evaltest.dat b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/evaltest.dat similarity index 85% rename from testing/tests/libipsec/net2net-cert-ipv6/evaltest.dat rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/evaltest.dat index cdb8ead3c..b92e71683 100644 --- a/testing/tests/libipsec/net2net-cert-ipv6/evaltest.dat +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/evaltest.dat @@ -1,5 +1,5 @@ alice::ping6 -c 3 -W 1 -i 0.2 -s 8184 -p deadbeef ip6-bob.strongswan.org::8192 bytes from ip6-bob.strongswan.org.*: icmp_seq=3::YES -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.*nat-remote=yes nat-any=yes encr-alg=AES_CBC encr-keysize=256 integ-alg=HMAC_SHA2_384_192 prf-alg=PRF_HMAC_SHA2_384 dh-group=ECP_384.*child-sas.*net-net.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP encap=yes.*encr-alg=AES_GCM_16 encr-keysize=256.*local-ts=\[fec1::/16\[ipv6-icmp]] remote-ts=\[fec2::/16\[ipv6-icmp]]::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.*nat-remote=yes nat-any=yes encr-alg=AES_CBC encr-keysize=256 integ-alg=HMAC_SHA2_384_192 prf-alg=PRF_HMAC_SHA2_384 dh-group=ECP_384.*child-sas.*net-net.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP encap=yes.*encr-alg=AES_GCM_16 encr-keysize=256.*local-ts=\[fec2::/16\[ipv6-icmp]] remote-ts=\[fec1::/16\[ipv6-icmp]]::YES +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.*nat-remote=yes nat-any=yes encr-alg=AES_CBC encr-keysize=256 integ-alg=HMAC_SHA2_384_192 prf-alg=PRF_HMAC_SHA2_384 dh-group=ECP_384.*child-sas.*net-net.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP encap=yes.*encr-alg=AES_GCM_16 encr-keysize=256.*local-ts=\[fec1:\:/16\[ipv6-icmp]] remote-ts=\[fec2:\:/16\[ipv6-icmp]]::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.*nat-remote=yes nat-any=yes encr-alg=AES_CBC encr-keysize=256 integ-alg=HMAC_SHA2_384_192 prf-alg=PRF_HMAC_SHA2_384 dh-group=ECP_384.*child-sas.*net-net.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP encap=yes.*encr-alg=AES_GCM_16 encr-keysize=256.*local-ts=\[fec2:\:/16\[ipv6-icmp]] remote-ts=\[fec1:\:/16\[ipv6-icmp]]::YES sun::tcpdump::IP moon.strongswan.org.\(4500\|ipsec-nat-t\) > sun.strongswan.org.\(4500\|ipsec-nat-t\): UDP-encap: ESP::YES sun::tcpdump::IP sun.strongswan.org.\(4500\|ipsec-nat-t\) > moon.strongswan.org.\(4500\|ipsec-nat-t\): UDP-encap: ESP::YES diff --git a/testing/tests/libipsec/net2net-cert-ipv6/hosts/moon/etc/strongswan.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/moon/etc/strongswan.conf similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/hosts/moon/etc/strongswan.conf rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/moon/etc/strongswan.conf diff --git a/testing/tests/libipsec/net2net-cert-ipv6/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/moon/etc/swanctl/swanctl.conf similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/hosts/moon/etc/swanctl/swanctl.conf rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/moon/etc/swanctl/swanctl.conf diff --git a/testing/tests/libipsec/net2net-cert-ipv6/hosts/moon/etc/updown b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/moon/etc/updown similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/hosts/moon/etc/updown rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/moon/etc/updown diff --git a/testing/tests/libipsec/net2net-cert-ipv6/hosts/sun/etc/strongswan.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/sun/etc/strongswan.conf similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/hosts/sun/etc/strongswan.conf rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/sun/etc/strongswan.conf diff --git a/testing/tests/libipsec/net2net-cert-ipv6/hosts/sun/etc/swanctl/swanctl.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/sun/etc/swanctl/swanctl.conf similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/hosts/sun/etc/swanctl/swanctl.conf rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/sun/etc/swanctl/swanctl.conf diff --git a/testing/tests/libipsec/net2net-cert-ipv6/hosts/sun/etc/updown b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/sun/etc/updown similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/hosts/sun/etc/updown rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/hosts/sun/etc/updown diff --git a/testing/tests/libipsec/net2net-cert-ipv6/posttest.dat b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/posttest.dat similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/posttest.dat rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/posttest.dat diff --git a/testing/tests/libipsec/net2net-cert-ipv6/pretest.dat b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/pretest.dat similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/pretest.dat rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/pretest.dat diff --git a/testing/tests/libipsec/net2net-cert-ipv6/test.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip4/test.conf similarity index 100% rename from testing/tests/libipsec/net2net-cert-ipv6/test.conf rename to testing/tests/libipsec/net2net-cert-ip6-in-ip4/test.conf diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/description.txt b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/description.txt new file mode 100644 index 000000000..1461b5e56 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/description.txt @@ -0,0 +1,11 @@ +An IPv6 ESP tunnel connection between the gateways moon and sun is set up. +It connects the two IPv6 subnets hiding behind their respective gateways. +The authentication is based on X.509 certificates and the kernel-libipsec +plugin is used for userland IPsec ESP encryption. In this scenario, UDP encapsulation +isn't enforced by the plugin as sending of raw ESP packets is enabled. +

+Upon the successful establishment of the IPsec tunnel, an updown script automatically +inserts iptables-based firewall rules that let pass the traffic tunneled via the +ipsec0 tun interface. In order to test both tunnel and firewall, client alice +behind gateway moon sends an IPv6 ICMP request to client bob behind sun +using the ping6 command. diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/evaltest.dat b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/evaltest.dat new file mode 100644 index 000000000..34e90c759 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/evaltest.dat @@ -0,0 +1,5 @@ +alice::ping6 -c 1 -p deadbeef ip6-bob.strongswan.org::64 bytes from ip6-bob.strongswan.org.*: icmp_seq=1::YES +moon::swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=fec0:\:1 local-port=500 local-id=moon.strongswan.org remote-host=fec0:\:2 remote-port=500 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.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[fec1:\:/16] remote-ts=\[fec2:\:/16]::YES +sun ::swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=fec0:\:2 local-port=500 local-id=sun.strongswan.org remote-host=fec0:\:1 remote-port=500 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.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[fec2:\:/16] remote-ts=\[fec1:\:/16]::YES +sun::tcpdump::IP6 ip6-moon.strongswan.org > ip6-sun.strongswan.org: ESP::YES +sun::tcpdump::IP6 ip6-sun.strongswan.org > ip6-moon.strongswan.org: ESP::YES diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/strongswan.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..e2c90b0bf --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/strongswan.conf @@ -0,0 +1,15 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon-systemd { + load = random nonce aes sha1 sha2 gcm pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-libipsec kernel-netlink socket-default updown + multiple_authentication = no + plugins { + kernel-libipsec { + raw_esp = yes + } + } +} diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/swanctl/swanctl.conf new file mode 100755 index 000000000..070310c18 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/swanctl/swanctl.conf @@ -0,0 +1,36 @@ +connections { + + gw-gw { + local_addrs = fec0::1 + remote_addrs = fec0::2 + + local { + auth = pubkey + certs = moonCert.pem + id = moon.strongswan.org + } + remote { + auth = pubkey + id = sun.strongswan.org + } + children { + net-net { + local_ts = fec1::0/16 + remote_ts = fec2::0/16 + + updown = /etc/updown + esp_proposals = aes128gcm128-x25519 + } + } + version = 2 + mobike = no + proposals = aes128-sha256-x25519 + } +} + +authorities { + strongswan { + cacert = strongswanCert.pem + crl_uris = http://ip6-winnetou.strongswan.org/strongswan.crl + } +} \ No newline at end of file diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/updown b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/updown new file mode 100755 index 000000000..40b8fd303 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/moon/etc/updown @@ -0,0 +1,59 @@ +#!/bin/sh + +TUN_NAME=ipsec0 + +# use protocol specific options to set ports +case "$PLUTO_MY_PROTOCOL" in +1) # ICMP + ICMP_TYPE_OPTION="--icmp-type" + ;; +58) # ICMPv6 + ICMP_TYPE_OPTION="--icmpv6-type" + ;; +*) + ;; +esac + +# are there port numbers? +if [ "$PLUTO_MY_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + else + S_MY_PORT="--sport $PLUTO_MY_PORT" + D_MY_PORT="--dport $PLUTO_MY_PORT" + fi +fi +if [ "$PLUTO_PEER_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + # the syntax is --icmp[v6]-type type[/code], so add it to the existing option + S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT" + D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT" + else + S_PEER_PORT="--sport $PLUTO_PEER_PORT" + D_PEER_PORT="--dport $PLUTO_PEER_PORT" + fi +fi + +case "$PLUTO_VERB" in +up-client-v6) + ip6tables -I FORWARD 1 -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + ip6tables -I FORWARD 1 -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +down-client-v6) + ip6tables -D FORWARD -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + ip6tables -D FORWARD -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +esac diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/strongswan.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/strongswan.conf new file mode 100644 index 000000000..fa2a2a49c --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/strongswan.conf @@ -0,0 +1,15 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon-systemd { + load = random nonce aes sha1 sha2 gcm pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici ker_nel-libipsec kernel-netlink socket-default updown + multiple_authentication = no + plugins { + kernel-libipsec { + raw_esp = yes + } + } +} diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/swanctl/swanctl.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/swanctl/swanctl.conf new file mode 100755 index 000000000..6d3bb7226 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/swanctl/swanctl.conf @@ -0,0 +1,37 @@ +connections { + + gw-gw { + local_addrs = fec0::2 + remote_addrs = fec0::1 + + local { + auth = pubkey + certs = sunCert.pem + id = sun.strongswan.org + } + remote { + auth = pubkey + id = moon.strongswan.org + } + children { + net-net { + local_ts = fec2::0/16 + remote_ts = fec1::0/16 + + updown = /etc/updown + updown = /usr/local/libexec/ipsec/_updown iptables + esp_proposals = aes128gcm128-x25519 + } + } + version = 2 + mobike = no + proposals = aes128-sha256-x25519 + } +} + +authorities { + strongswan { + cacert = strongswanCert.pem + crl_uris = http://ip6-winnetou.strongswan.org/strongswan.crl + } +} \ No newline at end of file diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/updown b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/updown new file mode 100755 index 000000000..40b8fd303 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/hosts/sun/etc/updown @@ -0,0 +1,59 @@ +#!/bin/sh + +TUN_NAME=ipsec0 + +# use protocol specific options to set ports +case "$PLUTO_MY_PROTOCOL" in +1) # ICMP + ICMP_TYPE_OPTION="--icmp-type" + ;; +58) # ICMPv6 + ICMP_TYPE_OPTION="--icmpv6-type" + ;; +*) + ;; +esac + +# are there port numbers? +if [ "$PLUTO_MY_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + else + S_MY_PORT="--sport $PLUTO_MY_PORT" + D_MY_PORT="--dport $PLUTO_MY_PORT" + fi +fi +if [ "$PLUTO_PEER_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + # the syntax is --icmp[v6]-type type[/code], so add it to the existing option + S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT" + D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT" + else + S_PEER_PORT="--sport $PLUTO_PEER_PORT" + D_PEER_PORT="--dport $PLUTO_PEER_PORT" + fi +fi + +case "$PLUTO_VERB" in +up-client-v6) + ip6tables -I FORWARD 1 -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + ip6tables -I FORWARD 1 -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +down-client-v6) + ip6tables -D FORWARD -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + ip6tables -D FORWARD -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +esac diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/posttest.dat b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/posttest.dat new file mode 100644 index 000000000..74281868f --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/posttest.dat @@ -0,0 +1,11 @@ +moon::swanctl --terminate --ike gw-gw 2> /dev/null +moon::systemctl stop strongswan +sun::systemctl stop strongswan +alice::"ip route del fec2:\:/16 via fec1:\:1" +moon::"ip route del fec2:\:/16 via fec0:\:2" +sun::"ip route del fec1:\:/16 via fec0:\:1" +bob::"ip route del fec1:\:/16 via fec2:\:1" +moon::iptables-restore < /etc/iptables.flush +sun::iptables-restore < /etc/iptables.flush +moon::ip6tables-restore < /etc/ip6tables.flush +sun::ip6tables-restore < /etc/ip6tables.flush diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/pretest.dat b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/pretest.dat new file mode 100644 index 000000000..4ae22dc24 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/pretest.dat @@ -0,0 +1,13 @@ +moon::iptables-restore < /etc/iptables.drop +sun::iptables-restore < /etc/iptables.drop +moon::ip6tables-restore < /etc/ip6tables.rules +sun::ip6tables-restore < /etc/ip6tables.rules +alice::"ip route add fec2:\:/16 via fec1:\:1" +moon::"ip route add fec2:\:/16 via fec0:\:2" +sun::"ip route add fec1:\:/16 via fec0:\:1" +bob::"ip route add fec1:\:/16 via fec2:\:1" +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 diff --git a/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/test.conf b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/test.conf new file mode 100644 index 000000000..5906883b1 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-ip6-in-ip6-raw/test.conf @@ -0,0 +1,29 @@ +#!/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-ip6.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" + +# IP protocol used by IPsec is IPv6 +# +IPV6=1 + +# charon controlled by swanctl +# +SWANCTL=1 diff --git a/testing/tests/libipsec/net2net-cert-raw/description.txt b/testing/tests/libipsec/net2net-cert-raw/description.txt new file mode 100644 index 000000000..240f6e8e8 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/description.txt @@ -0,0 +1,9 @@ +A connection between the subnets behind the gateways moon and sun is set up. +The authentication is based on X.509 certificates and the kernel-libipsec +plugin is used for userland IPsec ESP encryption. In this scenario, UDP encapsulation +isn't enforced by the plugin as sending of raw ESP packets is enabled. +

+Upon the successful establishment of the IPsec tunnel, an updown script automatically +inserts iptables-based firewall rules that let pass the traffic tunneled via the +ipsec0 tun interface. In order to test both tunnel and firewall, client alice +behind gateway moon pings client bob located behind gateway sun. diff --git a/testing/tests/libipsec/net2net-cert-raw/evaltest.dat b/testing/tests/libipsec/net2net-cert-raw/evaltest.dat new file mode 100644 index 000000000..1b4b3fb10 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/evaltest.dat @@ -0,0 +1,5 @@ +alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=1::YES +moon:: swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=500 local-id=moon.strongswan.org remote-host=192.168.0.2 remote-port=500 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.*reqid=1 state=INSTALLED mode=TUNNEL protocol=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=500 local-id=sun.strongswan.org remote-host=192.168.0.1 remote-port=500 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.*reqid=1 state=INSTALLED mode=TUNNEL protocol=ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.2.0.0/16] remote-ts=\[10.1.0.0/16]::YES +sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES +sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES diff --git a/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/strongswan.conf b/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..e2c90b0bf --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/strongswan.conf @@ -0,0 +1,15 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon-systemd { + load = random nonce aes sha1 sha2 gcm pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-libipsec kernel-netlink socket-default updown + multiple_authentication = no + plugins { + kernel-libipsec { + raw_esp = yes + } + } +} diff --git a/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/swanctl/swanctl.conf new file mode 100755 index 000000000..b063e600d --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/swanctl/swanctl.conf @@ -0,0 +1,29 @@ +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 + + updown = /etc/updown + esp_proposals = aes128gcm128-x25519 + } + } + version = 2 + mobike = no + proposals = aes128-sha256-x25519 + } +} diff --git a/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/updown b/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/updown new file mode 100755 index 000000000..682ccc701 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/hosts/moon/etc/updown @@ -0,0 +1,59 @@ +#!/bin/sh + +TUN_NAME=ipsec0 + +# use protocol specific options to set ports +case "$PLUTO_MY_PROTOCOL" in +1) # ICMP + ICMP_TYPE_OPTION="--icmp-type" + ;; +58) # ICMPv6 + ICMP_TYPE_OPTION="--icmpv6-type" + ;; +*) + ;; +esac + +# are there port numbers? +if [ "$PLUTO_MY_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + else + S_MY_PORT="--sport $PLUTO_MY_PORT" + D_MY_PORT="--dport $PLUTO_MY_PORT" + fi +fi +if [ "$PLUTO_PEER_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + # the syntax is --icmp[v6]-type type[/code], so add it to the existing option + S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT" + D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT" + else + S_PEER_PORT="--sport $PLUTO_PEER_PORT" + D_PEER_PORT="--dport $PLUTO_PEER_PORT" + fi +fi + +case "$PLUTO_VERB" in +up-client) + iptables -I FORWARD 1 -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + iptables -I FORWARD 1 -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +down-client) + iptables -D FORWARD -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + iptables -D FORWARD -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +esac diff --git a/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/strongswan.conf b/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/strongswan.conf new file mode 100644 index 000000000..fa2a2a49c --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/strongswan.conf @@ -0,0 +1,15 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon-systemd { + load = random nonce aes sha1 sha2 gcm pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici ker_nel-libipsec kernel-netlink socket-default updown + multiple_authentication = no + plugins { + kernel-libipsec { + raw_esp = yes + } + } +} diff --git a/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/swanctl/swanctl.conf b/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/swanctl/swanctl.conf new file mode 100755 index 000000000..36229552b --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/swanctl/swanctl.conf @@ -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 + + updown = /etc/updown + updown = /usr/local/libexec/ipsec/_updown iptables + esp_proposals = aes128gcm128-x25519 + } + } + version = 2 + mobike = no + proposals = aes128-sha256-x25519 + } +} diff --git a/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/updown b/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/updown new file mode 100755 index 000000000..682ccc701 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/hosts/sun/etc/updown @@ -0,0 +1,59 @@ +#!/bin/sh + +TUN_NAME=ipsec0 + +# use protocol specific options to set ports +case "$PLUTO_MY_PROTOCOL" in +1) # ICMP + ICMP_TYPE_OPTION="--icmp-type" + ;; +58) # ICMPv6 + ICMP_TYPE_OPTION="--icmpv6-type" + ;; +*) + ;; +esac + +# are there port numbers? +if [ "$PLUTO_MY_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT" + else + S_MY_PORT="--sport $PLUTO_MY_PORT" + D_MY_PORT="--dport $PLUTO_MY_PORT" + fi +fi +if [ "$PLUTO_PEER_PORT" != 0 ] +then + if [ -n "$ICMP_TYPE_OPTION" ] + then + # the syntax is --icmp[v6]-type type[/code], so add it to the existing option + S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT" + D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT" + else + S_PEER_PORT="--sport $PLUTO_PEER_PORT" + D_PEER_PORT="--dport $PLUTO_PEER_PORT" + fi +fi + +case "$PLUTO_VERB" in +up-client) + iptables -I FORWARD 1 -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + iptables -I FORWARD 1 -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +down-client) + iptables -D FORWARD -o $TUN_NAME -p $PLUTO_PEER_PROTOCOL \ + -s $PLUTO_MY_CLIENT $S_MY_PORT \ + -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT + iptables -D FORWARD -i $TUN_NAME -p $PLUTO_MY_PROTOCOL \ + -s $PLUTO_PEER_CLIENT $S_PEER_PORT \ + -d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT + ;; +esac diff --git a/testing/tests/libipsec/net2net-cert-raw/posttest.dat b/testing/tests/libipsec/net2net-cert-raw/posttest.dat new file mode 100644 index 000000000..cc6a5bff7 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/posttest.dat @@ -0,0 +1,5 @@ +moon::swanctl --terminate --ike gw-gw 2> /dev/null +moon::systemctl stop strongswan +sun::systemctl stop strongswan +moon::iptables-restore < /etc/iptables.flush +sun::iptables-restore < /etc/iptables.flush diff --git a/testing/tests/libipsec/net2net-cert-raw/pretest.dat b/testing/tests/libipsec/net2net-cert-raw/pretest.dat new file mode 100644 index 000000000..2d3c8c1e2 --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/pretest.dat @@ -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 diff --git a/testing/tests/libipsec/net2net-cert-raw/test.conf b/testing/tests/libipsec/net2net-cert-raw/test.conf new file mode 100644 index 000000000..87abc763b --- /dev/null +++ b/testing/tests/libipsec/net2net-cert-raw/test.conf @@ -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