diff --git a/doc/Authentication.md b/doc/Authentication.md index f7ae515..0678fb9 100644 --- a/doc/Authentication.md +++ b/doc/Authentication.md @@ -16,6 +16,8 @@ As opposed to the MAC address which is sent out with each packet also between ed A somewhat hurdling network sniffing attack aimed at observing the authentication ID could break this scheme. Thus, further development towards a more sophisticated crypto-based authentication scheme is intended. +In case of edges unexpectedly shutting down with no opportunity for a clean exit, this auth scheme prevents re-connection to the supernode until it internally is removed from the list (after some 90 seconds or so). Although `-M` command line option at the supernode can disable authentication ID comparison to circumvent this situation, usage of user / password based authentication scheme is highly recommended instead. + ### User / Password Based Authentication A more advanced scheme relies on username and especially password. Public key cryptography, namely Curve25519, ensures safety. Basically, the password along with the mixed in user name, serve as private key. The corresponding public key is generated by the `tools/n2n-keygen` utility. The such generated public key gets depoisted at the supernode. @@ -94,4 +96,4 @@ Tools for automizing [`.conf` file](https://github.com/ntop/n2n/blob/dev/doc/Con Implementation of a federation-wide support for user-password authentication would allow much bigger networks using this feature. Still required steps are outlined [in some earlier post](https://github.com/ntop/n2n/issues/670#issuecomment-802119568). -Let us know if you are intrerested in implementing or furthering these ideas. \ No newline at end of file +Let us know if you are intrerested in implementing or furthering these ideas. diff --git a/include/n2n_typedefs.h b/include/n2n_typedefs.h index 9636614..d1ad239 100644 --- a/include/n2n_typedefs.h +++ b/include/n2n_typedefs.h @@ -805,6 +805,7 @@ typedef struct n2n_sn { struct sn_community *federation; n2n_private_public_key_t private_key; /* private federation key derived from federation name */ n2n_auth_t auth; + uint8_t override_spoofing_protection; /* set if overriding MAC/IP spoofing protection (cli option '-M') */ n2n_resolve_parameter_t *resolve_parameter;/*Pointer to name resolver's parameter block */ } n2n_sn_t; diff --git a/src/sn.c b/src/sn.c index be77ec2..f18161a 100644 --- a/src/sn.c +++ b/src/sn.c @@ -284,6 +284,7 @@ static void help (int level) { #ifdef SN_MANUAL_MAC "[-m ] " #endif + "[-M] " "\n\n overlay network " "[-c ] " "\n configuration " @@ -300,10 +301,12 @@ static void help (int level) { "[-g ]" #endif "\n\n meaning of the " + "[-M] disable MAC and IP address spoofing protection" + "\n flag options " #if defined(N2N_HAVE_DAEMON) "[-f] do not fork but run in foreground" + "\n " #endif - "\n flag options " "[-v] make more verbose, repeat as required" "\n " "\n technically, all parameters are optional, but the supernode executable" @@ -330,6 +333,8 @@ static void help (int level) { printf(" -m | fixed MAC address for the supernode, e.g.\n" " | '-m 10:20:30:40:50:60', random otherwise\n"); #endif + printf(" -M | disable MAC and IP address spoofing protection for all\n" + " | non-username-password-authenticating communities\n"); printf ("\n"); printf (" TAP DEVICE AND OVERLAY NETWORK CONFIGURATION\n"); printf (" --------------------------------------------\n\n"); @@ -497,6 +502,9 @@ static int setOption (int optkey, char *_optarg, n2n_sn_t *sss) { break; } #endif + case 'M': /* override spoofing protection */ + sss->override_spoofing_protection = 1; + break; case 'c': /* community file */ sss->community_file = calloc(1, strlen(_optarg) + 1); if(sss->community_file) @@ -549,7 +557,7 @@ static int loadFromCLI (int argc, char * const argv[], n2n_sn_t *sss) { u_char c; while((c = getopt_long(argc, argv, - "p:l:t:a:c:F:vh" + "p:l:t:a:c:F:vhM" #ifdef SN_MANUAL_MAC "m:" #endif @@ -778,6 +786,10 @@ int main (int argc, char * const argv[]) { traceEvent(TRACE_WARNING, "Using default federation name. FOR TESTING ONLY, usage of a custom federation name (-F) is highly recommended!"); } + if(sss_node.override_spoofing_protection) { + traceEvent(TRACE_WARNING, "Disabled MAC and IP address spoofing protection. FOR TESTING ONLY, usage of user-password authentication (-I, -J, -P) recommended instead!"); + } + // generate shared secrets for user authentication; can be done only after // federation name is known (-F) and community list completely read (-c) traceEvent(TRACE_INFO, "started shared secrets calculation for edge authentication"); @@ -796,7 +808,6 @@ int main (int argc, char * const argv[]) { } traceEvent(TRACE_NORMAL, "calculated shared secrets for edge authentication"); - traceEvent(TRACE_DEBUG, "traceLevel is %d", getTraceLevel()); sss_node.sock = open_socket(sss_node.lport, 1 /*bind ANY*/, 0 /* UDP */); diff --git a/src/sn_utils.c b/src/sn_utils.c index 1828f09..c2d73ef 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -533,6 +533,15 @@ static int auth_edge (const n2n_auth_t *present, const n2n_auth_t *presented, n2 sn_user_t *user = NULL; + if(present->scheme == n2n_auth_none) { + // n2n_auth_none scheme (set at supernode if cli option '-M') + // if required, zero_token answer (not for NAK) + if(answer) + memset(answer, 0, sizeof(n2n_auth_t)); + // 0 == (always) successful + return 0; + } + if((present->scheme == n2n_auth_simple_id) && (presented->scheme == n2n_auth_simple_id)) { // n2n_auth_simple_id scheme: if required, zero_token answer (not for NAK) if(answer) @@ -598,6 +607,8 @@ static int handle_remote_auth (n2n_sn_t *sss, const n2n_auth_t *remote_auth, } switch(remote_auth->scheme) { + // we do not handle n2n_auth_none because the edge always edge always uses either id or user/password + // auth_none is sn-internal only (skipping MAC/IP address spoofing protection) case n2n_auth_simple_id: // zero_token answer memset(answer_auth, 0, sizeof(n2n_auth_t)); @@ -682,7 +693,12 @@ static int update_edge (n2n_sn_t *sss, memcpy(&(scan->last_cookie), reg->cookie, sizeof(N2N_COOKIE_SIZE)); scan->last_valid_time_stamp = initial_time_stamp(); + // store the submitted auth token memcpy(&(scan->auth), &(reg->auth), sizeof(n2n_auth_t)); + // manually set to type 'auth_none' if cli option disables MAC/IP address spoofing protection + // for id based auth communities. This will be obsolete when handling public keys only (v4.0?) + if((reg->auth.scheme == n2n_auth_simple_id) && (sss->override_spoofing_protection)) + scan->auth.scheme = n2n_auth_none; HASH_ADD_PEER(comm->edges, scan);