diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2024-11-04 02:44:29 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2024-11-04 02:44:29 +0000 |
commit | ea9b1e853898469f993df7e5f6faba8962320e66 (patch) | |
tree | b1cc04d15fd668bb67eb864d259160ffb83ba266 | |
parent | 8fdb465d47e52d1e39e1870413ae2006fb871c84 (diff) |
add a "natt" option that forces negotiation of nat-t (and udpencap).
this is like the -t command line option on iked itself, but you get
to keep the ike listener on port 500 and you can enable this on
specific policies instead of all of them.
this is useful if you're dealing with an org that can't firewall
ESP traffic well and so you need to force the traffic to be udp
encapsulated even if there's no NAT involved.
ok markus@ tobhe@
-rw-r--r-- | sbin/iked/iked.conf.5 | 8 | ||||
-rw-r--r-- | sbin/iked/iked.h | 23 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 15 | ||||
-rw-r--r-- | sbin/iked/parse.y | 22 | ||||
-rw-r--r-- | sbin/iked/print.c | 5 |
5 files changed, 49 insertions, 24 deletions
diff --git a/sbin/iked/iked.conf.5 b/sbin/iked/iked.conf.5 index c3c0fa7bb38..624f371ca16 100644 --- a/sbin/iked/iked.conf.5 +++ b/sbin/iked/iked.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: iked.conf.5,v 1.98 2024/07/13 12:58:51 jmc Exp $ +.\" $OpenBSD: iked.conf.5,v 1.99 2024/11/04 02:44:28 dlg Exp $ .\" .\" Copyright (c) 2010 - 2014 Reyk Floeter <reyk@openbsd.org> .\" Copyright (c) 2004 Mathieu Sauve-Frankel All rights reserved. @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 13 2024 $ +.Dd $Mdocdate: November 4 2024 $ .Dt IKED.CONF 5 .Os .Sh NAME @@ -348,6 +348,10 @@ and the default is .Ar tunnel . .Pp +.It Op Ar natt +.Ar natt +forces negotiation of NAT-Traversal after the initial handshake. +.Pp .It Op Ar encap .Ar encap specifies the encapsulation protocol to be used. diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h index d3da0b7b38d..367ea76047a 100644 --- a/sbin/iked/iked.h +++ b/sbin/iked/iked.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iked.h,v 1.232 2024/09/15 11:08:50 yasuoka Exp $ */ +/* $OpenBSD: iked.h,v 1.233 2024/11/04 02:44:28 dlg Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -250,16 +250,17 @@ struct iked_policy { #define IKED_SKIP_COUNT 4 struct iked_policy *pol_skip[IKED_SKIP_COUNT]; - uint8_t pol_flags; -#define IKED_POLICY_PASSIVE 0x00 -#define IKED_POLICY_DEFAULT 0x01 -#define IKED_POLICY_ACTIVE 0x02 -#define IKED_POLICY_REFCNT 0x04 -#define IKED_POLICY_QUICK 0x08 -#define IKED_POLICY_SKIP 0x10 -#define IKED_POLICY_IPCOMP 0x20 -#define IKED_POLICY_TRANSPORT 0x40 -#define IKED_POLICY_ROUTING 0x80 + unsigned int pol_flags; +#define IKED_POLICY_PASSIVE 0x000 +#define IKED_POLICY_DEFAULT 0x001 +#define IKED_POLICY_ACTIVE 0x002 +#define IKED_POLICY_REFCNT 0x004 +#define IKED_POLICY_QUICK 0x008 +#define IKED_POLICY_SKIP 0x010 +#define IKED_POLICY_IPCOMP 0x020 +#define IKED_POLICY_TRANSPORT 0x040 +#define IKED_POLICY_ROUTING 0x080 +#define IKED_POLICY_NATT_FORCE 0x100 int pol_refcnt; diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c index b6e8ecee93c..df90d3bd2f6 100644 --- a/sbin/iked/ikev2.c +++ b/sbin/iked/ikev2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2.c,v 1.388 2024/09/15 11:08:50 yasuoka Exp $ */ +/* $OpenBSD: ikev2.c,v 1.389 2024/11/04 02:44:28 dlg Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -70,7 +70,6 @@ struct iked_sa * ikev2_getimsgdata(struct iked *, struct imsg *, struct iked_sahdr *, uint8_t *, uint8_t **, size_t *); -void ikev2_recv(struct iked *, struct iked_message *); int ikev2_ike_auth_compatible(struct iked_sa *, uint8_t, uint8_t); int ikev2_ike_auth_recv(struct iked *, struct iked_sa *, struct iked_message *); @@ -2334,6 +2333,7 @@ ikev2_nat_detection(struct iked *env, struct iked_message *msg, uint64_t rspi, ispi; struct ibuf *buf; uint32_t rnd; + int natt_force = 0; if (ptr == NULL) return (mdlen); @@ -2401,7 +2401,14 @@ ikev2_nat_detection(struct iked *env, struct iked_message *msg, goto done; } - if (env->sc_nattmode == NATT_FORCE) { + if (env->sc_nattmode == NATT_FORCE) + natt_force = 1; + else if (msg->msg_policy != NULL) { + if (msg->msg_policy->pol_flags & IKED_POLICY_NATT_FORCE) + natt_force = 1; + } + + if (natt_force) { /* Enforce NAT-T/UDP-encapsulation by distorting the digest */ rnd = arc4random(); EVP_DigestUpdate(ctx, &rnd, sizeof(rnd)); @@ -3395,6 +3402,7 @@ ikev2_resp_ike_sa_init(struct iked *env, struct iked_message *msg) resp.msg_fd = msg->msg_fd; resp.msg_natt = msg->msg_natt; resp.msg_msgid = 0; + resp.msg_policy = sa->sa_policy; /* IKE header */ if ((hdr = ikev2_add_header(buf, sa, resp.msg_msgid, @@ -3702,6 +3710,7 @@ ikev2_send_init_error(struct iked *env, struct iked_message *msg) resp.msg_fd = msg->msg_fd; resp.msg_natt = msg->msg_natt; resp.msg_msgid = 0; + resp.msg_policy = sa->sa_policy; /* IKE header */ if ((hdr = ikev2_add_header(buf, sa, resp.msg_msgid, diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y index 970a9e33482..568f9ef22f9 100644 --- a/sbin/iked/parse.y +++ b/sbin/iked/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.147 2024/07/13 12:22:46 yasuoka Exp $ */ +/* $OpenBSD: parse.y,v 1.148 2024/11/04 02:44:28 dlg Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -383,7 +383,7 @@ int create_ike(char *, int, struct ipsec_addr_wrap *, int, struct ipsec_hosts *, struct ipsec_hosts *, struct ipsec_mode *, struct ipsec_mode *, uint8_t, - uint8_t, char *, char *, + unsigned int, char *, char *, uint32_t, struct iked_lifetime *, struct iked_auth *, struct ipsec_filters *, struct ipsec_addr_wrap *, char *); @@ -411,7 +411,7 @@ struct ipsec_addr_wrap *iftab; typedef struct { union { int64_t number; - uint8_t ikemode; + unsigned int ikemode; uint8_t dir; uint8_t satype; uint8_t accounting; @@ -459,7 +459,7 @@ typedef struct { %token CERTPARTIALCHAIN %token REQUEST IFACE %token RADIUS ACCOUNTING SERVER SECRET MAX_TRIES MAX_FAILOVERS -%token CLIENT DAE LISTEN ON +%token CLIENT DAE LISTEN ON NATT %token <v.string> STRING %token <v.number> NUMBER %type <v.string> string @@ -475,7 +475,8 @@ typedef struct { %type <v.id> id %type <v.transforms> transforms %type <v.filters> filters -%type <v.ikemode> ikeflags ikematch ikemode ipcomp tmode +%type <v.ikemode> ikeflags +%type <v.ikemode> ikematch ikemode ipcomp tmode natt_force %type <v.ikeauth> ikeauth %type <v.ikekey> keyspec %type <v.mode> ike_sas child_sas @@ -1022,7 +1023,9 @@ child_sa : CHILDSA { } ; -ikeflags : ikematch ikemode ipcomp tmode { $$ = $1 | $2 | $3 | $4; } +ikeflags : ikematch ikemode ipcomp tmode natt_force { + $$ = $1 | $2 | $3 | $4 | $5; + } ; ikematch : /* empty */ { $$ = 0; } @@ -1045,6 +1048,10 @@ tmode : /* empty */ { $$ = 0; } | TRANSPORT { $$ = IKED_POLICY_TRANSPORT; } ; +natt_force : /* empty */ { $$ = 0; } + | NATT { $$ = IKED_POLICY_NATT_FORCE; } + ; + ikeauth : /* empty */ { $$.auth_method = IKEV2_AUTH_SIG_ANY; /* default */ $$.auth_eap = 0; @@ -1601,6 +1608,7 @@ lookup(char *s) { "maxage", MAXAGE }, { "mobike", MOBIKE }, { "name", NAME }, + { "natt", NATT }, { "noenforcesingleikesa", NOENFORCESINGLEIKESA }, { "noesn", NOESN }, { "nofragmentation", NOFRAGMENTATION }, @@ -2707,7 +2715,7 @@ create_ike(char *name, int af, struct ipsec_addr_wrap *ipproto, int rdomain, struct ipsec_hosts *hosts, struct ipsec_hosts *peers, struct ipsec_mode *ike_sa, struct ipsec_mode *ipsec_sa, uint8_t saproto, - uint8_t flags, char *srcid, char *dstid, + unsigned int flags, char *srcid, char *dstid, uint32_t ikelifetime, struct iked_lifetime *lt, struct iked_auth *authtype, struct ipsec_filters *filter, struct ipsec_addr_wrap *ikecfg, char *iface) diff --git a/sbin/iked/print.c b/sbin/iked/print.c index 5444f950bff..05abdcd8417 100644 --- a/sbin/iked/print.c +++ b/sbin/iked/print.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print.c,v 1.4 2023/06/13 12:34:12 tb Exp $ */ +/* $OpenBSD: print.c,v 1.5 2024/11/04 02:44:28 dlg Exp $ */ /* * Copyright (c) 2019-2021 Tobias Heider <tobias.heider@stusta.de> @@ -88,6 +88,9 @@ print_policy(struct iked_policy *pol) else print_verbose(" tunnel"); + if (pol->pol_flags & IKED_POLICY_NATT_FORCE) + print_verbose(" natt"); + print_verbose(" %s", print_xf(pol->pol_saproto, 0, saxfs)); if (pol->pol_nipproto > 0) { |