Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Disable Concurent User Is Useless

    Scheduled Pinned Locked Moved Captive Portal
    11 Posts 5 Posters 2.0k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      ayruel
      last edited by

      Pfsense Captive Portal is perfect.But i got naughty users…

      My Target is : 1 Voucher for 1 user . so i cecked Disable Concurrent user logins at captive portal feature.The scenario is running good . if user logged with voucher A , so if another user using this voucher A to login . old user terminating by system. this is good ...but..

      After Running several month i got naughty user , they are shared this voucher about 5 device. My server is busy to terminate old session every seconds...so they are logged to CP alternately.
      So i tested this problem with 2 device can share 1 voucher alternately ,especialy only for browsing or youtube.

      please any solustions besides freeradius ?
      like range login from another device for 15 minutes or denied login if logged
      Please help

      1 Reply Last reply Reply Quote 0
      • DerelictD
        Derelict LAYER 8 Netgate
        last edited by

        I would just expire that voucher if you notice and actually care.

        Chattanooga, Tennessee, USA
        A comprehensive network diagram is worth 10,000 words and 15 conference calls.
        DO NOT set a source address/port in a port forward or firewall rule unless you KNOW you need it!
        Do Not Chat For Help! NO_WAN_EGRESS(TM)

        1 Reply Last reply Reply Quote 0
        • A
          ayruel
          last edited by

          @Derelict:

          I would just expire that voucher if you notice and actually care.

          U are right but isnt my server only being busy ..me too..  :(

          1 Reply Last reply Reply Quote 0
          • GertjanG
            Gertjan
            last edited by

            Try this :

            Open /etc/inc/captiveportal.inc
            Goto line 2251.

            You will find :

            ....
            		/* on the same ip */
            		if ($cpentry[2] == $clientip) {
            			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING OLD SESSION");
            			} else {
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
            			}
            			$sessionid = $cpentry[5];
            			break;
            		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
            			// user logged in with an active voucher. Check for how long and calculate
            			// how much time we can give him (voucher credit - used time)
            			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
            			if ($remaining_time < 0) { // just in case.
            				$remaining_time = 0;
            			}
            
            			/* This user was already logged in so we disconnect the old one */
            			captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
            			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
            			$unsetindexes[] = $cpentry[5];
            			break;
            		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
            			/* on the same username */
            ....
            

            See also line https://github.com/pfsense/pfsense/blob/9dd655a0c36b907979d497586f9789170de748de/src/etc/inc/captiveportal.inc#L2277 - the
            break;
            command on line 2277 (the github version has env 20 lines more because of the constant evolving of pfSense)
            Insert like this :

            
            		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username) && (isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) ) {
            			// user logged in with an active voucher. Check for how long and calculate
            			// how much time we can give him (voucher credit - used time)
            			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
            			if ($remaining_time < 0) { // just in case.
            				$remaining_time = 0;
            			}
            
            			/* This user was already logged in so .... we do nothing because "noconcurrentlogins" is set */
            			/* See https://forum.pfsense.org/index.php?topic=147038.0 */ 
            			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING NEW SESSION - NO noconcurrentlogins !");
            			return 0;
            			break;
            
            

            Now, the entire foreach loop look like this :

            	foreach ($cpdb as $cpentry) {
            		if (empty($cpentry[11])) {
            			$cpentry[11] = 'first';
            		}
            		/* on the same ip */
            		if ($cpentry[2] == $clientip) {
            			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING OLD SESSION");
            			} else {
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
            			}
            			$sessionid = $cpentry[5];
            			break;
            
            		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
            			// user logged in with an active voucher. Check for how long and calculate
            			// how much time we can give him (voucher credit - used time)
            			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
            			if ($remaining_time < 0) { // just in case.
            				$remaining_time = 0;
            			}
            
            			/* This user was already logged in so we disconnect the old one */
            			captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
            			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
            			$unsetindexes[] = $cpentry[5];
            			break;
            
            		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
            			/* on the same username */
            			if (strcasecmp($cpentry[4], $username) == 0) {
            				/* This user was already logged in so we disconnect the old one */
            				captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
            				$unsetindexes[] = $cpentry[5];
            				break;
            			}
            		}
            	}
            

            The new special case is
            If vouchers are used and username is not "unauthenticated" and username is already present and noconcurrentlogins is set then the result will be :
            A log line : "CONCURRENT LOGIN - TERMINATING NEW SESSION - NO noconcurrentlogins !");
            And a return 0; so the user will be presented a "voucher expired" message (good english for : "use your own voucher - don't borrow !!" ;)

            Be carefull : I tested this. It worked. A second login using a voucher that was already used ones - and has an session - from another device was ignored, the user will get an error page.
            Normally, the last login using a voucher will remain if "noconcurrentlogins" is set, the old, existing session, is deleted
            You wanted the FIRST session to stay up- and no further usage of the same voucher.

            So I "abused" the "noconcurrentlogins" setting somewhat making a special case for it.

            If this works for you, you have to apply this patch every time you upgrade ( and /etc/inc/captiveportal.inc gets modified/upgraded).

            edit :
            "noconcurrentlogins" should be a tri-state flag in the GUI.
            Like not set = 0 : user can login using the same identification multiple time
            Or
            Set to 1 : user can only use 1 login, the last login will have a session - earlier session using voucher or login with user and paswword will be deleted.
            Or
            Set to 2 : user can only login ones, further logins using the same identification (voucher or login with user and paswword) will not be granted.

            Option 0 and 1 exist already - "2" will be the new one.

            No "help me" PM's please. Use the forum, the community will thank you.
            Edit : and where are the logs ??

            ? 1 Reply Last reply Reply Quote 0
            • A
              ayruel
              last edited by

              @Gertjan:

              Try this :

              Open /etc/inc/captiveportal.inc
              Goto line 2251.

              You will find :

              ....
              		/* on the same ip */
              		if ($cpentry[2] == $clientip) {
              			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
              				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING OLD SESSION");
              			} else {
              				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
              			}
              			$sessionid = $cpentry[5];
              			break;
              		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
              			// user logged in with an active voucher. Check for how long and calculate
              			// how much time we can give him (voucher credit - used time)
              			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
              			if ($remaining_time < 0) { // just in case.
              				$remaining_time = 0;
              			}
              
              			/* This user was already logged in so we disconnect the old one */
              			captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
              			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
              			$unsetindexes[] = $cpentry[5];
              			break;
              		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
              			/* on the same username */
              ....
              

              See also line https://github.com/pfsense/pfsense/blob/9dd655a0c36b907979d497586f9789170de748de/src/etc/inc/captiveportal.inc#L2277 - the
              break;
              command on line 2277 (the github version has env 20 lines more because of the constant evolving of pfSense)
              Insert like this :

              
              		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username) && (isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) ) {
              			// user logged in with an active voucher. Check for how long and calculate
              			// how much time we can give him (voucher credit - used time)
              			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
              			if ($remaining_time < 0) { // just in case.
              				$remaining_time = 0;
              			}
              
              			/* This user was already logged in so .... we do nothing because "noconcurrentlogins" is set */
              			/* See https://forum.pfsense.org/index.php?topic=147038.0 */ 
              			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING NEW SESSION - NO noconcurrentlogins !");
              			return 0;
              			break;
              
              

              Now, the entire foreach loop look like this :

              	foreach ($cpdb as $cpentry) {
              		if (empty($cpentry[11])) {
              			$cpentry[11] = 'first';
              		}
              		/* on the same ip */
              		if ($cpentry[2] == $clientip) {
              			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
              				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING OLD SESSION");
              			} else {
              				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
              			}
              			$sessionid = $cpentry[5];
              			break;
              			
              		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
              			// user logged in with an active voucher. Check for how long and calculate
              			// how much time we can give him (voucher credit - used time)
              			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
              			if ($remaining_time < 0) { // just in case.
              				$remaining_time = 0;
              			}
              
              			/* This user was already logged in so we disconnect the old one */
              			captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
              			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
              			$unsetindexes[] = $cpentry[5];
              			break;
              
              		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
              			/* on the same username */
              			if (strcasecmp($cpentry[4], $username) == 0) {
              				/* This user was already logged in so we disconnect the old one */
              				captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
              				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
              				$unsetindexes[] = $cpentry[5];
              				break;
              			}
              		}
              	}
              

              The new special case is
              If vouchers are used and username is not "unauthenticated" and username is already present and noconcurrentlogins is set then the result will be :
              A log line : "CONCURRENT LOGIN - TERMINATING NEW SESSION - NO noconcurrentlogins !");
              And a return 0; so the user will be presented a "voucher expired" message (good english for : "use your own voucher - don't borrow !!" ;)

              Be carefull : I tested this. It worked. A second login using a voucher that was already used ones - and has an session - from another device was ignored, the user will get an error page.
              Normally, the last login using a voucher will remain if "noconcurrentlogins" is set, the old, existing session, is deleted
              You wanted the FIRST session to stay up- and no further usage of the same voucher.

              So I "abused" the "noconcurrentlogins" setting somewhat making a special case for it.

              If this works for you, you have to apply this patch every time you upgrade ( and /etc/inc/captiveportal.inc gets modified/upgraded).

              edit :
              "noconcurrentlogins" should be a tri-state flag in the GUI.
              Like not set = 0 : user can login using the same identification multiple time
              Or
              Set to 1 : user can only use 1 login, the last login will have a session - earlier session using voucher or login with user and paswword will be deleted.
              Or
              Set to 2 : user can only login ones, further logins using the same identification (voucher or login with user and paswword) will not be granted.

              Option 0 and 1 exist already - "2" will be the new one.

              Thank So much

              I Hope this :

              Set to 2 : user can only login ones, further logins using the same identification (voucher or login with user and paswword) will not be granted.

              1 Reply Last reply Reply Quote 0
              • GertjanG
                Gertjan
                last edited by

                @ayruel:

                …
                I Hope this :
                Set to 2 : user can only login ones, further logins using the same identification (voucher or login with user and paswword) will not be granted.

                Ask for a Feature request here : https://redmine.pfsense.org/projects/pfsense/issues?per_page=100&set_filter=1&tracker_id=2  ;)

                No "help me" PM's please. Use the forum, the community will thank you.
                Edit : and where are the logs ??

                1 Reply Last reply Reply Quote 0
                • T
                  tattchua
                  last edited by

                  Hi,

                  i am using CP in a hotel environment, login with one password, eg. 222, changed weekly. USERNAME hidden for convenience.

                  however, i have other "monthly subscribers" to my CP, same channel, how do i limit them to 2 or 3 devices, or even 5 devices. is it 0, 1, or 3 and so on as above?

                  pfsense 2.4.4 and freeradius 3

                  TQSM!

                  rgds

                  GertjanG 1 Reply Last reply Reply Quote 0
                  • GertjanG
                    Gertjan @tattchua
                    last edited by

                    @tattchua said in Disable Concurent User Is Useless:

                    i am using CP in a hotel environment, ..
                    how do i limit them to 2 or 3 devices, or even 5 devices. is it 0, 1, or 3 and so on as above?
                    pfsense 2.4.4 and freeradius 3

                    Same here.
                    This does it for me :

                    0_1550477745115_c7338477-609d-43ab-a2af-812f5189669a-image.png

                    Limiting for 2 (or 1 ?) login.

                    No "help me" PM's please. Use the forum, the community will thank you.
                    Edit : and where are the logs ??

                    1 Reply Last reply Reply Quote 0
                    • ?
                      A Former User @Gertjan
                      last edited by

                      @Gertjan hi sir! is this still working in 2.4.4 p3? using vouchers (local database authentication) not freeradius. thanks!

                      GertjanG 1 Reply Last reply Reply Quote 0
                      • GertjanG
                        Gertjan @A Former User
                        last edited by

                        @dyobetem said in Disable Concurent User Is Useless:

                        is this still working in 2.4.4 p3?

                        Ac said, when using FreeRadius - Local database : guess not.

                        No "help me" PM's please. Use the forum, the community will thank you.
                        Edit : and where are the logs ??

                        ? 1 Reply Last reply Reply Quote 0
                        • ?
                          A Former User @Gertjan
                          last edited by

                          @Gertjan thanks and noted sir!

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post
                          Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.