diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2010-07-01 02:15:09 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2010-07-01 02:15:09 +0000 |
commit | ba20962e4d51a20b1a146917fc3756a50cf97221 (patch) | |
tree | 3c70f6dea387f618531f683733771148ca397ba5 /sbin | |
parent | 94742a9e99f2a97a4510d879de69bf00441ca028 (diff) |
Add support for the tap extension (ikev2 ... tap "enc1") that will
tell the kernel to send all IPsec traffic for derived SAs to the
specified enc(4) interface instead of enc0.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/iked/iked.conf.5 | 24 | ||||
-rw-r--r-- | sbin/iked/iked.h | 3 | ||||
-rw-r--r-- | sbin/iked/parse.y | 72 | ||||
-rw-r--r-- | sbin/iked/pfkey.c | 25 |
4 files changed, 104 insertions, 20 deletions
diff --git a/sbin/iked/iked.conf.5 b/sbin/iked/iked.conf.5 index e451dffdaf9..309ee86bc3e 100644 --- a/sbin/iked/iked.conf.5 +++ b/sbin/iked/iked.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: iked.conf.5,v 1.7 2010/06/26 18:32:34 reyk Exp $ +.\" $OpenBSD: iked.conf.5,v 1.8 2010/07/01 02:15:08 reyk Exp $ .\" $vantronix: iked.conf.5,v 1.10 2010/06/03 16:13:40 reyk Exp $ .\" .\" Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net> @@ -16,7 +16,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: June 26 2010 $ +.Dd $Mdocdate: July 1 2010 $ .Dt IKED.CONF 5 .Os .Sh NAME @@ -449,6 +449,16 @@ expands to The variable expansion for the .Ar tag directive occurs only at runtime, not during configuration file parse time. +.It Ic tap Ar interface +Send the decapsulated IPsec traffic to the specified +.Xr enc 4 +.Ar interface +instead of +.Ar enc0 +for filtering and monitoring. +The traffic will be blocked if the specified +.Ar interface +does not exist. .El .Sh PACKET FILTERING IPsec traffic appears unencrypted on the @@ -473,7 +483,7 @@ IKE NAT-Traversal traffic on the external interface. Encapsulated IPsec traffic on the external interface. .It enc0 -Interface for outgoing traffic before it's been encapsulated, +Default interface for outgoing traffic before it's been encapsulated, and incoming traffic after it's been decapsulated. State on this interface should be interface bound; see @@ -553,12 +563,14 @@ pass out on ix0 tagged ipsec-developers.example.com queue developers pass out on ix0 tagged ipsec-employees.example.com queue employees .Ed .Pp -The tags will be assigned by the following +The following example assigns the tags in the .Nm -example: +configuration and also sets an alternative +.Xr enc 4 +device: .Bd -literal -offset indent ikev2 esp from 10.1.1.0/24 to 10.1.2.0/24 peer 192.168.3.2 \e - tag ipsec-$domain + tag ipsec-$domain tap "enc1" .Ed .Sh OUTGOING NETWORK ADDRESS TRANSLATION In some network topologies it is desirable to perform NAT on traffic leaving diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h index b02d00d02b7..75f8011e014 100644 --- a/sbin/iked/iked.h +++ b/sbin/iked/iked.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iked.h,v 1.17 2010/06/29 21:04:42 reyk Exp $ */ +/* $OpenBSD: iked.h,v 1.18 2010/07/01 02:15:08 reyk Exp $ */ /* $vantronix: iked.h,v 1.61 2010/06/03 07:57:33 reyk Exp $ */ /* @@ -219,6 +219,7 @@ struct iked_policy { struct iked_auth pol_auth; char pol_tag[IKED_TAG_SIZE]; + u_int pol_tap; struct iked_proposals pol_proposals; size_t pol_nproposals; diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y index 23fd6687111..8c7e6e5fa72 100644 --- a/sbin/iked/parse.y +++ b/sbin/iked/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.8 2010/06/26 19:48:04 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.9 2010/07/01 02:15:08 reyk Exp $ */ /* $vantronix: parse.y,v 1.22 2010/06/03 11:08:34 reyk Exp $ */ /* @@ -248,6 +248,11 @@ struct ipsec_hosts { u_int16_t dport; }; +struct ipsec_filters { + char *tag; + u_int tap; +}; + struct ipsec_addr_wrap *host(const char *); struct ipsec_addr_wrap *host_v6(const char *, int); struct ipsec_addr_wrap *host_v4(const char *, int); @@ -269,7 +274,7 @@ int create_ike(char *, u_int8_t, struct ipsec_hosts *, struct ipsec_hosts *, struct ipsec_mode *, struct ipsec_mode *, u_int8_t, u_int8_t, char *, char *, struct iked_auth *, - char *, struct ipsec_addr_wrap *); + struct ipsec_filters *, struct ipsec_addr_wrap *); int create_user(const char *, const char *); int get_id_type(char *); u_int8_t x2i(unsigned char *); @@ -277,6 +282,7 @@ int parsekey(unsigned char *, size_t, struct iked_auth *); int parsekeyfile(char *, struct iked_auth *); struct ipsec_transforms *ipsec_transforms; +struct ipsec_filters *ipsec_filters; typedef struct { union { @@ -301,6 +307,7 @@ typedef struct { struct iked_auth ikeauth; struct iked_auth ikekey; struct ipsec_transforms *transforms; + struct ipsec_filters *filters; struct ipsec_mode *mode; } v; int lineno; @@ -310,7 +317,7 @@ typedef struct { %token FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK PORT %token FILENAME AUTHXF PRFXF ENCXF ERROR IKEV2 IKESA CHILDSA -%token PASSIVE ACTIVE ANY TAG PROTO LOCAL GROUP NAME CONFIG EAP USER +%token PASSIVE ACTIVE ANY TAG TAP PROTO LOCAL GROUP NAME CONFIG EAP USER %token IKEV1 FLOW SA TCPMD5 TUNNEL TRANSPORT COUPLE DECOUPLE SET %token INCLUDE %token <v.string> STRING @@ -328,11 +335,11 @@ typedef struct { %type <v.ids> ids %type <v.id> id %type <v.transforms> transforms +%type <v.filters> filters %type <v.ikemode> ikemode %type <v.ikeauth> ikeauth %type <v.ikekey> keyspec %type <v.mode> ike_sa child_sa -%type <v.string> tag %type <v.string> name %type <v.cfg> cfg ikecfg ikecfgvals %% @@ -380,7 +387,7 @@ user : USER STRING STRING { ; ikev2rule : IKEV2 name ikemode satype proto hosts_list peers - ike_sa child_sa ids ikeauth ikecfg tag { + ike_sa child_sa ids ikeauth ikecfg filters { if (create_ike($2, $5, $6, &$7, $8, $9, $4, $3, $10.srcid, $10.dstid, &$11, $13, $12) == -1) YYERROR; @@ -776,13 +783,47 @@ keyspec : STRING { } ; -tag : /* empty */ - { +filters : { + if ((ipsec_filters = calloc(1, + sizeof(struct ipsec_filters))) == NULL) + err(1, "filters: calloc"); + } + filters_l { + $$ = ipsec_filters; + } + | /* empty */ { $$ = NULL; } - | TAG STRING + ; + +filters_l : filters_l filter + | filter + ; + +filter : TAG STRING { - $$ = $2; + ipsec_filters->tag = $2; + } + | TAP STRING + { + const char *errstr = NULL; + size_t len; + + len = strcspn($2, "0123456789"); + if (strlen("enc") != len || + strncmp("enc", $2, len) != 0) { + yyerror("invalid tap interface name: %s", $2); + free($2); + YYERROR; + } + ipsec_filters->tap = + strtonum($2 + len, 0, UINT_MAX, &errstr); + free($2); + if (errstr != NULL) { + yyerror("invalid tap interface unit: %s", + errstr); + YYERROR; + } } ; @@ -912,6 +953,7 @@ lookup(char *s) { "set", SET }, { "srcid", SRCID }, { "tag", TAG }, + { "tap", TAP }, { "tcpmd5", TCPMD5 }, { "to", TO }, { "transport", TRANSPORT }, @@ -2063,6 +2105,9 @@ print_policy(struct iked_policy *pol) if (pol->pol_tag[0] != '\0') print_verbose(" tag \"%s\"", pol->pol_tag); + if (pol->pol_tap != 0) + print_verbose(" tap \"enc%u\"", pol->pol_tap); + print_verbose("\n"); } @@ -2103,7 +2148,8 @@ create_ike(char *name, u_int8_t ipproto, struct ipsec_hosts *hosts, struct ipsec_hosts *peers, struct ipsec_mode *ike_sa, struct ipsec_mode *ipsec_sa, u_int8_t saproto, u_int8_t mode, char *srcid, char *dstid, - struct iked_auth *authtype, char *tag, struct ipsec_addr_wrap *ikecfg) + struct iked_auth *authtype, struct ipsec_filters *filter, + struct ipsec_addr_wrap *ikecfg) { struct ipsec_addr_wrap *ipa, *ipb; struct iked_policy pol; @@ -2152,8 +2198,10 @@ create_ike(char *name, u_int8_t ipproto, struct ipsec_hosts *hosts, return (-1); } } - if (tag) - strlcpy(pol.pol_tag, tag, sizeof(pol.pol_tag)); + + if (filter->tag) + strlcpy(pol.pol_tag, filter->tag, sizeof(pol.pol_tag)); + pol.pol_tap = filter->tap; if (peers == NULL) { if (pol.pol_flags & IKED_POLICY_ACTIVE) { diff --git a/sbin/iked/pfkey.c b/sbin/iked/pfkey.c index 9cb945efc68..4c0eab04f96 100644 --- a/sbin/iked/pfkey.c +++ b/sbin/iked/pfkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkey.c,v 1.6 2010/06/26 18:32:34 reyk Exp $ */ +/* $OpenBSD: pfkey.c,v 1.7 2010/07/01 02:15:08 reyk Exp $ */ /* $vantronix: pfkey.c,v 1.11 2010/06/03 07:57:33 reyk Exp $ */ /* @@ -409,14 +409,22 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, struct iked_childsa *sa) struct sadb_key sa_authkey, sa_enckey; struct sadb_x_udpencap udpencap; struct sadb_x_tag sa_tag; + struct sadb_x_tap sa_tap; struct sockaddr_storage ssrc, sdst; struct sadb_ident *sa_srcid, *sa_dstid; + struct iked_policy *pol; struct iovec iov[IOV_CNT]; int iov_cnt; char *tag = NULL; sa_srcid = sa_dstid = NULL; + if (sa->csa_ikesa == NULL || sa->csa_ikesa->sa_policy == NULL) { + log_warn("%s: invalid SA and policy", __func__); + return (-1); + } + pol = sa->csa_ikesa->sa_policy; + bzero(&ssrc, sizeof(ssrc)); memcpy(&ssrc, &sa->csa_local->addr, sizeof(ssrc)); if (socket_af((struct sockaddr *)&ssrc, 0) == -1) { @@ -534,6 +542,13 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, struct iked_childsa *sa) } else tag = NULL; + if (pol->pol_tap != 0) { + bzero(&sa_tap, sizeof(sa_tap)); + sa_tap.sadb_x_tap_exttype = SADB_X_EXT_TAP; + sa_tap.sadb_x_tap_len = sizeof(sa_tap) / 8; + sa_tap.sadb_x_tap_unit = pol->pol_tap; + } + send: iov_cnt = 0; @@ -622,6 +637,14 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, struct iked_childsa *sa) iov_cnt++; } + if (pol->pol_tap != 0) { + /* enc(4) device tap unit */ + iov[iov_cnt].iov_base = &sa_tap; + iov[iov_cnt].iov_len = sizeof(sa_tap); + smsg.sadb_msg_len += sa_tap.sadb_x_tap_len; + iov_cnt++; + } + return (pfkey_write(sd, &smsg, iov, iov_cnt, NULL, NULL)); } |