added manual MAC/IP address spoofing protection override at supernode (-M) (#716)

This commit is contained in:
Logan oos Even 2021-06-21 17:03:07 +05:45 committed by GitHub
parent 3a7ce700f2
commit 39aa50b4cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 4 deletions

View File

@ -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.

View File

@ -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;

View File

@ -284,6 +284,7 @@ static void help (int level) {
#ifdef SN_MANUAL_MAC
"[-m <mac address>] "
#endif
"[-M] "
"\n\n overlay network "
"[-c <community list file>] "
"\n configuration "
@ -300,10 +301,12 @@ static void help (int level) {
"[-g <numerical group id>]"
#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 <mac> | 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 */);

View File

@ -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);