Hi,

this diff adds a '-p' command line option which allows to configure
the used UDP encapsulation port, similar to isakmpd's '-N' flag.

UDP encapsulation is primarily used with IPsec NAT traversal
but with this diff it might as well be interesting in cases where
ESP and UDP ports 500 and 4500 are blocked or rate limited.

To receive UDP encapsulated ESP traffic on a port other than 4500
the sysctl option 'net.inet.esp.udpencap_port' has to be set
accordingly.
I am considering extending the pfkey interface in the future, so
that iked can also handle the kernel port, but for now the sysctl
has to be set manually.

ok?

Index: config.c
===================================================================
RCS file: /cvs/src/sbin/iked/config.c,v
retrieving revision 1.52
diff -u -p -r1.52 config.c
--- config.c    7 Jan 2020 15:08:28 -0000       1.52
+++ config.c    16 Jan 2020 17:15:10 -0000
@@ -988,6 +988,29 @@ config_setkeys(struct iked *env)
 }
 
 int
+config_setnattport(struct iked *env)
+{
+       in_port_t nattport;
+
+       nattport = env->sc_nattport;
+       proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CTL_NATTPORT,
+           &nattport, sizeof(nattport));
+       return (0);
+}
+
+int
+config_getnattport(struct iked *env, struct imsg *imsg)
+{
+       in_port_t nattport;
+
+       IMSG_SIZE_CHECK(imsg, &nattport);
+       memcpy(&nattport, imsg->data, sizeof(nattport));
+       env->sc_nattport = nattport;
+       log_debug("%s: nattport %u", __func__, env->sc_nattport);
+       return (0);
+}
+
+int
 config_getkey(struct iked *env, struct imsg *imsg)
 {
        size_t           len;
Index: iked.8
===================================================================
RCS file: /cvs/src/sbin/iked/iked.8,v
retrieving revision 1.23
diff -u -p -r1.23 iked.8
--- iked.8      14 Jan 2020 22:28:29 -0000      1.23
+++ iked.8      16 Jan 2020 17:15:10 -0000
@@ -75,6 +75,10 @@ as the configuration file, instead of th
 .It Fl n
 Configtest mode.
 Only check the configuration file for validity.
+.It Fl p Ar udpencap-port
+The -p option specifies the listen port for encapsulated UDP that
+the daemon will bind to as well as the udp encapsulation port set
+in resulting IPsec SAs.
 .It Fl S
 Start
 .Nm
Index: iked.c
===================================================================
RCS file: /cvs/src/sbin/iked/iked.c,v
retrieving revision 1.40
diff -u -p -r1.40 iked.c
--- iked.c      15 Jan 2020 20:30:32 -0000      1.40
+++ iked.c      16 Jan 2020 17:15:10 -0000
@@ -57,7 +57,7 @@ usage(void)
        extern char     *__progname;
 
        fprintf(stderr, "usage: %s [-dnSTtv] [-D macro=value] "
-           "[-f file]\n", __progname);
+           "[-f file] [-p udpencap_port]\n", __progname);
        exit(1);
 }
 
@@ -67,13 +67,14 @@ main(int argc, char *argv[])
        int              c;
        int              debug = 0, verbose = 0;
        int              opts = 0;
+       in_port_t        port = IKED_NATT_PORT;
        const char      *conffile = IKED_CONFIG;
        struct iked     *env = NULL;
        struct privsep  *ps;
 
        log_init(1, LOG_DAEMON);
 
-       while ((c = getopt(argc, argv, "6dD:nf:vSTt")) != -1) {
+       while ((c = getopt(argc, argv, "6dD:nf:p:vSTt")) != -1) {
                switch (c) {
                case '6':
                        log_warnx("the -6 option is ignored and will be "
@@ -107,6 +108,10 @@ main(int argc, char *argv[])
                case 't':
                        opts |= IKED_OPT_NATT;
                        break;
+               case 'p':
+                       port = atoi(optarg);
+                       opts |= IKED_OPT_NATT;
+                       break;
                default:
                        usage();
                }
@@ -121,6 +126,7 @@ main(int argc, char *argv[])
                fatal("calloc: env");
 
        env->sc_opts = opts;
+       env->sc_nattport = port;
 
        ps = &env->sc_ps;
        ps->ps_env = env;
@@ -221,18 +227,18 @@ parent_configure(struct iked *env)
        bzero(&ss, sizeof(ss));
        ss.ss_family = AF_INET;
 
-       if ((env->sc_opts & IKED_OPT_NATT) == 0)
+       if ((env->sc_opts & IKED_OPT_NATT) == 0 && env->sc_nattport == 
IKED_NATT_PORT)
                config_setsocket(env, &ss, ntohs(IKED_IKE_PORT), PROC_IKEV2);
        if ((env->sc_opts & IKED_OPT_NONATT) == 0)
-               config_setsocket(env, &ss, ntohs(IKED_NATT_PORT), PROC_IKEV2);
+               config_setsocket(env, &ss, ntohs(env->sc_nattport), PROC_IKEV2);
 
        bzero(&ss, sizeof(ss));
        ss.ss_family = AF_INET6;
 
-       if ((env->sc_opts & IKED_OPT_NATT) == 0)
+       if ((env->sc_opts & IKED_OPT_NATT) == 0 && env->sc_nattport == 
IKED_NATT_PORT)
                config_setsocket(env, &ss, ntohs(IKED_IKE_PORT), PROC_IKEV2);
        if ((env->sc_opts & IKED_OPT_NONATT) == 0)
-               config_setsocket(env, &ss, ntohs(IKED_NATT_PORT), PROC_IKEV2);
+               config_setsocket(env, &ss, ntohs(env->sc_nattport), PROC_IKEV2);
 
        /*
         * pledge in the parent process:
@@ -254,6 +260,7 @@ parent_configure(struct iked *env)
 
        config_setmobike(env);
        config_setfragmentation(env);
+       config_setnattport(env);
        config_setcoupled(env, env->sc_decoupled ? 0 : 1);
        config_setocsp(env);
        /* Must be last */
@@ -287,6 +294,7 @@ parent_reload(struct iked *env, int rese
 
                config_setmobike(env);
                config_setfragmentation(env);
+               config_setnattport(env);
                config_setcoupled(env, env->sc_decoupled ? 0 : 1);
                config_setocsp(env);
                /* Must be last */
Index: iked.h
===================================================================
RCS file: /cvs/src/sbin/iked/iked.h,v
retrieving revision 1.131
diff -u -p -r1.131 iked.h
--- iked.h      14 Jan 2020 22:28:29 -0000      1.131
+++ iked.h      16 Jan 2020 17:15:11 -0000
@@ -662,6 +662,7 @@ struct iked {
        uint32_t                         sc_opts;
        uint8_t                          sc_passive;
        uint8_t                          sc_decoupled;
+       in_port_t                        sc_nattport;
 
        uint8_t                          sc_mobike;     /* MOBIKE */
        uint8_t                          sc_frag;       /* fragmentation */
@@ -767,6 +768,8 @@ int  config_setmobike(struct iked *);
 int     config_getmobike(struct iked *, struct imsg *);
 int     config_setfragmentation(struct iked *);
 int     config_getfragmentation(struct iked *, struct imsg *);
+int     config_setnattport(struct iked *);
+int     config_getnattport(struct iked *, struct imsg *);
 
 /* policy.c */
 void    policy_init(struct iked *);
Index: ikev2.c
===================================================================
RCS file: /cvs/src/sbin/iked/ikev2.c,v
retrieving revision 1.187
diff -u -p -r1.187 ikev2.c
--- ikev2.c     8 Jan 2020 09:14:03 -0000       1.187
+++ ikev2.c     16 Jan 2020 17:15:12 -0000
@@ -213,6 +213,8 @@ ikev2_dispatch_parent(int fd, struct pri
                return (config_getmobike(env, imsg));
        case IMSG_CTL_FRAGMENTATION:
                return (config_getfragmentation(env, imsg));
+       case IMSG_CTL_NATTPORT:
+               return (config_getnattport(env, imsg));
        case IMSG_UDP_SOCKET:
                return (config_getsocket(env, imsg, ikev2_msg_cb));
        case IMSG_PFKEY_SOCKET:
@@ -1084,7 +1086,7 @@ ikev2_init_ike_sa_peer(struct iked *env,
        }
 
        if ((env->sc_opts & IKED_OPT_NONATT) == 0) {
-               if (ntohs(port) == IKED_NATT_PORT) {
+               if (ntohs(port) == env->sc_nattport) {
                        /* Enforce NAT-T on the initiator side */
                        log_debug("%s: enforcing NAT-T", __func__);
                        req.msg_natt = sa->sa_natt = sa->sa_udpencap = 1;
Index: ikev2_msg.c
===================================================================
RCS file: /cvs/src/sbin/iked/ikev2_msg.c,v
retrieving revision 1.60
diff -u -p -r1.60 ikev2_msg.c
--- ikev2_msg.c 28 Nov 2019 12:16:28 -0000      1.60
+++ ikev2_msg.c 16 Jan 2020 17:15:13 -0000
@@ -78,7 +78,7 @@ ikev2_msg_cb(int fd, short event, void *
                return;
 
        if (socket_getport((struct sockaddr *)&msg.msg_local) ==
-           IKED_NATT_PORT) {
+           env->sc_nattport) {
                if (memcmp(&natt, buf, sizeof(natt)) != 0)
                        return;
                msg.msg_natt = 1;
Index: types.h
===================================================================
RCS file: /cvs/src/sbin/iked/types.h,v
retrieving revision 1.31
diff -u -p -r1.31 types.h
--- types.h     14 Jan 2020 22:28:29 -0000      1.31
+++ types.h     16 Jan 2020 17:15:13 -0000
@@ -104,6 +104,7 @@ enum imsg_type {
        IMSG_CTL_PASSIVE,
        IMSG_CTL_MOBIKE,
        IMSG_CTL_FRAGMENTATION,
+       IMSG_CTL_NATTPORT,
        IMSG_COMPILE,
        IMSG_UDP_SOCKET,
        IMSG_PFKEY_SOCKET,

Reply via email to