Menu

YfiTechMikrotikLogin

Anonymous

Creating a central Mikrotik login page

Background

  • If you create a Hotspot with Mikrotik using the default values you will be redirected to a login page on http://10.5.50.1/login.
  • Mikrotik features the following URLs on the default gateway of the Hotspot server:

URL
Description

http://10.5.50.1/
Shows rstatus.html or status.html if not available

http://10.5.50.1/login
Used to show the login page or to log a user in

http://10.5.50.1/status
Used to show the status of a user and their usage

http://10.5.50.1/logout
Used to log the user out

Sub pages

URL
Description

http://10.5.50.1/logout/status
shows status.html or fstatus.html

http://10.5.50.1/logout/login
if logged in shows /status of logged out redirects to login page

http://10.5.50.1/logout/logout
If logged in logs the user out and redirects to login page


How does the remote login page work?

  • To host the login page on a central server is quite simple since you will modify the login.html page on the Mikrotik to submit itself to the remote server and include the variables which you require.
  • When using PHP for instance, you will be able to get the submitted POST variables through the $_POST<variable>? pattern.
  • To submit the login page hosted on the central server, you again will submit it to the login.html page on the Mikrotik box as target.

Any Page a Login Page?

  • Unfortunately the way Mikrotik use to host and submit login pages and requests is very old style when comparing for instance with Coova Chilli.
  • Coova Chilli makes use of JSONP which will allow you to make any outside web page a login page.
  • If we also want this type of functionality using Mikrotik, the closest we can do is the following (see diagram).

Some important points

  • We can authenticate a user by adding a query string to the http://10.5.50.1/login URL. So if we want to authenticate a user dvdwalt@ri we can do the following:

http://10.5.50.1/login/username=dvdwalt@ri&password=dvdwalt@ri

  • We can also inform Mikrotik to redirect the user to a specific URL by adding a dst location to the query string:

http://10.5.50.1/login/username=dvdwalt@ri&password=dvdwalt@ri&dst=http://central.login.server/login.php

  • This means that after the authentication request went through fine; the user will be redirected to http://central.login.server/login.php
  • This page can then include code that calls the status page on the Miktorik at set intervals. Below is a prove of concept page that can be used as a sample:

    <html>
     <head>                                                                  
     <script type="text/javascript" src="jquery.js"></script>          
     <script type="text/javascript">                                         
        // we will add our javascript code here 
        var count = 1;
        $(document).ready(function() {
            window.callback = function(data){
                count++;
                console.log(data,count );
            };
    
        //Loop every 2 seconds
        var tid = setInterval(refresh, 2000);
        function refresh(){
            $.getScript("http://10.5.50.1/status", function(data) {
                    console.log("Fetching of script completed");
                } 
            );
            };
        });                                   
     </script>                                                               
     </head>
     <body>
       <!-- we will add our HTML content here -->
     </body>
     </html>
    

Status info from Mikrotik

  • The Mikrotik Hotspot only supplies the user's usage through the http://10.5.50.1/status URL. All other URLs does not include the usage.
  • By default when the user is logged in; the content of status.html is displayed.
  • By default when the user is NOT logged in; and the fstatus.html file is present it will be displayed.
  • We need to change both of these files to serve a JSONP object.
  • Unfortunately Mikrotik decided that these pages can only be server ad type html (the header will specify these pages as:)

    Response Headers
    Cache-Control   no-cache
    Connection  Keep-Alive
    Content-Length  387
    Content-Type    text/html
    Date    Fri, 02 Jan 1970 00:11:40 GMT
    Expires 0
    
    Request Headers
    Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding gzip, deflate
    Accept-Language en-za,en-gb;q=0.8,en-us;q=0.5,en;q=0.3
    Connection  keep-alive
    Host    10.5.50.1
    User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0
    
  • Fortunately it seems that the main browsers except this (although not right) and will assume the content as an JSONP object.

  • So we can change for instance the status.html to the following (take care to only have this text which will reflect a JSONP object, no headers, body or script tags!!!):

    callback({
        'link-logout' :"$(link-logout)",    //Link to log out
        'username': "$(username)",          //The user's name
        'ip': "$(ip)",
        'bytes-in': "$(bytes-in)",
        'bytes-in-nice': "$(bytes-in-nice)",
        'bytes-out': "$(bytes-out)",
        'bytes-out-nice': "$(bytes-out-nice)",
        'remain-bytes-in': "$(remain-bytes-in)",
        'remain-bytes-out': "$(remain-bytes-out)",
        'packets-out': "$(packets-out)",
        'packets-in': "$(packets-in)",
        $(if session-time-left)
            'session-time-left': "$(session-time-left)"
        $(else)
            'connected':"$(uptime)"
        $(endif)
    })
    
  • The Mikrotik device will then based on the content above serve the following:

    callback({
        'link-logout' :"http://10.5.50.1/logout",   //Link to log out
        'username': "dvdwalt@ri",           //The user's name
        'ip': "10.5.50.254",
        'bytes-in': "340672",
        'bytes-in-nice': "332.9 KiB",
        'bytes-out': "980481",
        'bytes-out-nice': "957.2 KiB",
        'remain-bytes-in': "",
        'remain-bytes-out': "",
        'packets-out': "1609",
        'packets-in': "($packets-in)",
    
            'connected':"4m45s" 
    })
    
  • Although the content is served as Content-Type: text/html, the browsers seems to accept it as JSONP.

  • We can then, based on the feedback we get from the JSONP call, show the usage of the user when they are connected; or we can redirect them to the login page if they were disconnected.

Modifying a standard Mikrotik Hotspot

  • This section will discuss the various changes that has to be done to Mikrotik in order to give the best experience.
  • Modify the following pages. We will assume that the external server has a DNS name of mt-external.co.za.
  • The login.html page

    <html>
       <head>
          <title>...</title>
          <meta http-equiv="refresh" content="0; url=http://mt-external.co.za/mt_external/login_test/login.php?loginlink=$(link-login-only)">
          <meta http-equiv="pragma" content="no-cache">
          <meta http-equiv="expires" content="-1">
       </head>
       <body>
       </body>
    </html>
    
  • The status.html page:

    Mikrotik.f_status({
        'logged_in':        '$(logged-in)',         //This is crucial in status.html and fstatus.html to deterime if the user is connected
        'link_login_only':  '$(link-login-only)',           //To know where the login page is
        'link_logout':      '$(link-logout)',       //Link to log out
        'username':         '$(username)',          //The user's name
        'ip':               '$(ip)',
        'bytes_in':         '$(bytes-in)',
        'bytes_in_nice':    '$(bytes-in-nice)',
        'bytes_out':        '$(bytes-out)',
        'bytes_out_nice':   '$(bytes-out-nice)',
        'remain_bytes_in':  '$(remain-bytes-in)',
        'remain_bytes_out':     '$(remain-bytes-out)',
        'packets_out':      '$(packets-out)',
        'packets_in':       '$(packets-in)',
        'session_time_left':    '$(session-time-left)',
        'uptime':           '$(uptime)'
    })
    
  • The fstatus.html page. This page does not exists by default and you have to create it:

    Mikrotik.f_status({
        'logged_in'         : '$(logged-in)',       //This is crucial in status.html and fstatus.html to deterime if the user is connected
        'link_login_only'   : '$(link-login-only)'  //To know where the login page is
    })
    
  • The alogin.html page. This page is displayed after login, we modify it to redirect immediately to the login page which will display the stats using JSONP

    <html>
       <head>
          <title>...</title>
          <meta http-equiv="refresh" content="0; url=http://mt-external.co.za/mt_external/login_test/login.php?loginlink=$(link-login-only)">
          <meta http-equiv="pragma" content="no-cache">
          <meta http-equiv="expires" content="-1">
       </head>
       <body>
       </body>
    </html>
    
  • The logout.html page. We modify it to immediately redirect to the login page which will display the stats using JSONP

    <html>
       <head>
          <title>...</title>
          <meta http-equiv="refresh" content="0; url=http://mt-external.co.za/mt_external/login_test/login.php?loginlink=$(link-login-only)">
          <meta http-equiv="pragma" content="no-cache">
          <meta http-equiv="expires" content="-1">
       </head>
       <body>
       </body>
    </html>
    

Related

Wiki: Home