Quantcast
Channel: Syed Jahanzaib – Personal Blog to Share Knowledge !
Viewing all 409 articles
Browse latest View live

Phpmyadmin – Short Notes

$
0
0


1# ROOT access error in phpmyadmin v 4.6.6deb5 with Ubuntu 18.0.4

If you have installed phpmyadmin in Ubuntu 18, & trying to login with root, you may see following error,

phpmyadmin root error

It’s recommended to add another user & use this ID to login in phpmyadmin.

Create User in Mysql:

Login to mysql & issue below commands, make sure to change user name and passwords

CREATE USER 'NEWUSER'@'%' IDENTIFIED BY 'NEWPASSWORD';
GRANT ALL PRIVILEGES ON *.* TO 'NEWUSER'@'%' WITH GRANT OPTION;
exit;

2# When viewing Tables in phpmyadmin, Popup Error Appears ‘some errors have been detected on the server, please look at the bottom of this window’

When viewing tables in Phpmyadmin v4.6.6deb5 [Ubuntu 18.0.4] , below error appears …

phpmyadmin view table error.JPG

FIX:

It seems that phpMyAdmin v4.6.6 is not fully compatible with PHP 7.x. Upgrade to new version v4.8 or above which will fix these compatibility issues.

OR following method.

Warning:

Make sure to backup sql.lib.php before any modification

cp /usr/share/phpmyadmin/libraries/sql.lib.php /usr/share/phpmyadmin/libraries/sql.lib.php.bak

Edit sql.lib.php

sudo vi /usr/share/phpmyadmin/libraries/sql.lib.php

Press CTRL + W and search for (count($analyzed_sql_results['select_expr'] == 1)

Replace it with ((count($analyzed_sql_results['select_expr']) == 1)

Save file and Exit.

Hopefully you will not see the above errors any more 🙂


Regard’s
Syed Jahanzaib


Disabling Email for CRON Job’s

$
0
0

If you have configured many cronjob’s to run every minute or so on, & also using Gmail as mail relay system on the same box, you might see following in ​​/var/log/mail.log

Jun 8 10:21:10 radius postfix/smtp[5192]: 6DA0D16E0118: to=, relay=smtp.gmail.com[74.125.71.108]:587, delay=3.3,
delays=0.01/0/2.9/0.41, dsn=5.4.5, status=bounced (host smtp.gmail.com[74.125.71.108] said:
550 5.4.5 Daily user sending quota exceeded. e188-v6sm2329623wmf.21 - gsmtp (in reply to DATA command))

gmail error.JPG
gmail error

CRON will only email you if there is some output from you job. With everything redirected to null, there is no output and hence cron will not email you.

Using > /dev/null 2>&1 will redirect all your command output (both stdout and stderr) to /dev/null, meaning no outputs are printed to terminal.

If you have configured an emailing system which is using gmail (which limits 500 messages per day) as mail relay then put the following command at the end of the cron job line that always output the result.

Example:

Before:

*/5 * * * * /temp/mybashscript.sh

After:

*/5 * * * * /temp/mybashscript.sh  >/dev/null 2>&1

Regard’s
Syed Jahaznaib

Skype for business WEBAPP stops on Loading

$
0
0

Skype for business webapp is a quick method to join meetings invitation sent by remote parties. Today when one of our user (with Windows 7 & IE8) tried to join the meeting  using Google Browser (latest version) (with S4B webapp plugin installed) , the window stuck at Loading … as showed in the image below …

SKYPE FOR BUSINESS STUCK ON LOADING ERROR

After some R&D, it found that if you have IE 8 or below, you must upgrade to new version.

After we upgraded IE from 8 to 11 , the S4B webapp worked smoothly.

skype working ok afger IExplorer 11 updates.png

Microsoft Products Short Notes – Personnel References

$
0
0

This post contains shot notes / Tips for personnel references, These are common task that we perform on daily basis in out IT slavery !
Reagrd’s
Syed Jahanzaib


PSTOOLS Related

.

Adding Local Account in remote workstation with PSTOOLS

If you are domain admin, and wanted to add local account in remote client workstation, then use pstools’s psexec 

psexec.exe \\target-pc net user /add USERNAME  USERPASSWORD
psexec.exe \\target-pc net net localgroup administrators USERNAME /add

# PSLOGGEDON COMMANDS
To check which user is logged on remote pc,

psloggedon \\remotepc

# PSEXEC COMMANDS

– To execute any command on remote pc like

psexec \\remtotepc ipconfig

– To open COMMAND prompt of remote user

psexec \\remotepc cmd

-Interacting with the Logged On User on the Remote PC

psexec \\remotepc -d -i notepad

# PSINFO COMMANDS
Getting general info with disk info as well

psinfo -d \\remotepc

# PSLIST COMMANDS

pslist \\remotepc

# PSKILL COMMANDS
– Kill remote pc program

pskill \\remotepc notepad

to query time

net time \\REMOTEPC

To change time on remote pc with domain server agpinf05

C:\pstools>PsExec.exe \\REMOTEPC -u DOMAIN\ADMIN -p PASS cmd "/c net time \\DC /set /y"

 


Batch file to change setting of network adapters to obtain IP from DHCP

Make sure to change adapter names to match your’s …

@echo off
echo Setting IP Address to AUTO DHCP [Office DHCP Server by syed.jahanzaib]...
netsh interface ip set address name="Local Area Connection" source=dhcp
netsh interface ip set dns "Local Area Connection" source=dhcp
netsh interface ip set address name="Wireless Network Connection" source=dhcp
netsh interface ip set dns "Wireless Network Connection" source=dhcp
echo Done....

Command to change IP via CMD

netsh interface ip set address name=”Local Area Connection” static 192.168.0.1 255.255.255.0 192.168.0.254
netsh interface ip set dns name=”Local Area Connection” static 192.168.0.250
netsh interface ip add dns name=”Local Area Connection” 8.8.8.8 index=2

Check Remote PC OS version & other details by CMD

systeminfo /s \\REMOTEPCNAME
# OR
systeminfo /s \\REMOTEPCNAME|findstr /i "host OS "

Result:

C:\>systeminfo /s \\syed_jahanzaib

Host Name: SYED_JAHANZAIB
OS Name: Microsoft Windows 7 Professional
OS Version: 6.1.7601 Service Pack 1 Build 7601
OS Manufacturer: Microsoft Corporation
OS Configuration: Member Workstation
OS Build Type: Multiprocessor Free
Registered Owner: Syed Jahanzaib
Registered Organization:
Product ID: xxxxxx-005-xxxx-xxxx
Original Install Date: 4/11/2017, 1:14:44 PM
System Boot Time: 6/19/2018, 7:44:47 AM
System Manufacturer: INTEL_
System Model: DH77KC__
System Type: x64-based PC
Processor(s): 1 Processor(s) Installed.
[01]: Intel64 Family 6 Model 58 Stepping 9 GenuineIntel ~3392 Mhz
BIOS Version: Intel Corp. KCH7710H.86A.0069.2012.0224.1825, 2/24/20
12
Windows Directory: C:\Windows
System Directory: C:\Windows\system32
Boot Device: \Device\HarddiskVolume1
System Locale: en-us;English (United States)
Input Locale: en-us;English (United States)
Time Zone: (UTC+05:00) Islamabad, Karachi
Total Physical Memory: 8,090 MB
Available Physical Memory: 2,450 MB
Virtual Memory: Max Size: 16,178 MB
Virtual Memory: Available: 10,455 MB
Virtual Memory: In Use: 5,723 MB
Page File Location(s): C:\pagefile.sys
Domain: DOMAIN1
Logon Server: \\DOMAIN_DC
Hotfix(s): 187 Hotfix(s) Installed.
...........................
Network Card(s): 3 NIC(s) Installed.
[01]: Intel(R) 82579V Gigabit Network Connection
Connection Name: DOMAIN - LAN
DHCP Enabled: No
IP address(es)
[01]: 192.168.100.100
[02]: 192.168.50.10
[03]: 192.168.8.23
[02]: VMware Virtual Ethernet Adapter for VMnet1
Connection Name: VMware Network Adapter VMnet1
DHCP Enabled: No
IP address(es)
[01]: 169.254.97.149
[02]: fe80::ad90:fdcb:3f81:6195
[03]: VMware Virtual Ethernet Adapter for VMnet8
Connection Name: VMware Network Adapter VMnet8
DHCP Enabled: No
IP address(es)
[01]: 169.254.80.235
[02]: fe80::5598:be9:b61d:50eb

C:\>

DCHP Related ! [Tested with W2008]

DHCP is running on windows 2008 server, IP is 192.168.0.1


#DCHP BACKUP
netsh dhcp server 192.168.0.1 dump > c:\dhcpoutput.txt all

#DHCP DELETE OLD SCOPE
netsh dhcp server delete scope 192.168.0.0 dhcpfullforce

#DHCP IMPORT
[Disable DHCP Service before import]
netsh dhcp server import c:\tools\dhcpoutput all

#DHCP DISABLE
netsh dhcp server 192.168.0.1 scope 192.168.0.0 set state 0

Disable Internet Explorer Proxy via CMD

REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f

Clear cache in windows

ipconfig /flushdns
net stop dnscache
net start dnscache

Event ID

https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/default.aspx?i=j


Excel 2010 showing Blank Sheet

in Excel 2010 , When you open any excel sheet,( any particular, either yours or sent to you by some one else , it appears blank sheet

This may also occur if your computer’s screen resolution is higher than that of the person who last saved the workbook.

In Excel 2010, go to the View tab.

Select the ‘Arrange All’ button, then choose to Cascade.

OR

Excel 2010
opening blank sheets

ctrl+shift and open file
or its related with MACRO, run macro


Display Mother board model via CMD

- To find Board number of local pc
wmic baseboard get product,Manufacturer,version,serialnumber

- To find Board number of remote pc
wmic /node:"remotepc" baseboard get product,Manufacturer,version,serialnumber

- To find remote pc Architechture liek 32bit or 64bit
wmic /node:"remotepc" os get osarchitecture

Adding Static Routes in Windows via CMD

Adding route for single host

route -p ADD 10.1.1.12 MASK 255.255.255.255 101.11.11.4 METRIC 1 IF 11

Notes:

To open a command prompt, click Start, point to All programs, point to Accessories, and then click Command prompt.

To make a static route persistent, you can either enter route add commands in a batch file that is run during system startup or use the -p option when adding routes.

Routes added by using the -p option are stored in the registry under the following key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip \Parameters\PersistentRoutes

Windows 7 Temporary profile Issue:

http://www.sysprobs.com/fix-temporary-profile-windows-7


There is no script engine for file extension .vbs

When we upgraded from win7 to windows 10/2012, our domain welcome logon script stopped working, with above error, to sort it we copied welcome vb script to domain logon folder and used this …

cscript //e:vbscript c:\path\to\script.vbs

Convert bootable USB in ISO file

The instructions for USB to .iso are as follows (for a Windows 7 installation for example):

  1. Install ImgBurn. You can even get a portable version of it, just search for it.
  2. Plug the bootable USB into the computer
  3. Start ImgBurn.
  4. Click on the “Create image file from files / folders” button on the home menu.
  5. In “Sources” browse to the USB drive.
  6. In “Destination” choose where to save the final .iso image.
  7. Go to the “Advanced” tab on the right and then “Bootable Disk”.
  8. Check the box “Make Bootable Image” and then, in the “Boot image” box browse to file “etfsboot.com” that is in the USB stick found in the folder “boot”.
  9. In the field “Developer ID” put “Microsoft Corporation” and enter “07C0” in the “Load Segment” field.
  10. Enter ‘4’ in the ‘Sectors To Load’ field if your etfsboot.com file is 2K is size, enter ‘8’ if it’s 4K. In other words, x = size of etfsboot.com in bytes / 512.
  11. Click “Build” and you’re done!

Credits: https://mindthebandgap.wordpress.com/2013/03/13/how-to-convert-bootable-usb-into-an-iso-file/


Reboot Remote Workstation from Domain Admin PC

shutdown /r /t 60 /m \\REMOTE-PC /c "YOU PC WILL REBOOT AFTER 1 MINUTE..."

 

IBM Lotus Related Short Notes

$
0
0

We are using IBM Lotus Domino 8.5.3 / FP6 (Yep its decade old version, but we are still using it). Following are some short notes for personnel reference.


Delete mail.box

tell router quit
tell smtp quit
VIEW
# quit domino
q
# Move mail boxes files (I had 2 mailbox to hold more mails)
# Move mail1.box & mail2.box out of notesdata dir via OS file explorer
# Now start domino
# Open old mail boxes and copy (valid) held messages into new one .....

Reconfigure Lotus Notes Client (Old installation)

Use the steps below to recreate the core configuration files.

1. Move the following files out of the \data directory to a backup directory.

names.nsf
desktop8.ndk
bookmark.nsf
cache.ndk

2. Copy the original notes.ini from the Notes program directory to the backup directory.

3. Delete all but the first three lines in the notes.ini in the Notes program directory and save it. The edited notes.ini should look like this:


[Notes]
KitType=1
Directory=C:\program files\notes\data

4. Launch the Notes client to run the setup program again. Notes recreates each of the files listed above and re-populates the notes.ini file.


Cannot find external name: NAMESORTVIEWPO

  1. Open your inbox
  2. Select Actions – Folder – Upgrade folder design
  3. Choose “Automatic” and complete the process.
  4. Close/reopen mail.

This should fix your problem.


Lotus Notes TEMP location for opened saved files

Goto Start / type

%temp%

and press ENTER. it will show you few folders. Look for folder name starting with “notesxxxxx” this folder contains all the temporary files.


Lotus Notes Default Browser Setting

For

IBM Lotus Notes 8.5 / Release 8.5.3FP6
Revision 20131126.1400-FP6 (Release 8.5.3FP6)
Standard Configuration

  1. Goto Files
  2. Preferences
  3. Web Browser
  4. & select ‘Use the Browser I have set as the default for this operating system’

notes default browser.JPG


Fixing Lotus Notes so the inbox opens by default

Ever opened up your mailbox in Lotus Notes and for some reason it opens up by default one of your sub-folders instead of your inbox?

Someone at work had this issue and I felt like banging my head against the wall trying to find a resolution. Anyone who has to help maintain Lotus Notes knows my pain. Considering that Notes is used by so many companies, the amount of help resources online is surprisingly few.

After much searching, I found the answer though on a vaguely worded post on IBM’s Lotus Notes forums that was over 3-years old. It really sounded like a last gasp guess by someone, but with no reply saying if it actually worked.

Which it did!

All you need to do is delete, move, or rename your bookmarks.nsf file from your local Notes client Data folder. The next time Lotus Notes starts up, the bookmarks.nsf file will be recreated and Notes will once again default to your inbox when your mailbox is opened.

Warning: Keep in mind that any other settings made to the bookmarks.nsf file will be lost. For example, any changes to the vertical toolbar on the left side will be gone. That is why the best policy is to backup bookmarks.nsf first. You have been warned.


IBM Same-time Does not Open ! (v7.5)

Fist try to upgrade with latest release, it will solve many issues !

Case # 1

Symptom:
Sametime Connect displays the splash screen but does not start.

Resolution:
Before performing an unnecessary re-installation of the Sametime client, try to resolve the issue by following these steps:

1. Close the Sametime application.

2. Locate the file C:\Documents and Settings\Administrator\IBM\RCP\Sametime\.metadata\plugins\com.ibm.collaboration.realtime.imhub\shelfmemento.xml.

3. Delete the file C:\Documents and Settings\Administrator\IBM\RCP\Sametime\.metadata\plugins\com.ibm.collaboration.realtime.imhub\shelfmemento.xml.

4. Restart the Sametime application.

5. If that does not help, delete or rename C:\Documents and Settings\Administrators\IBM\RCP\Sametime or
C:\Documents and Settings\”Username”\IBM\RCP\Sametime

If nothing works, remove same time, delete its leftover folders, restart, and re install the sametime client.

Case#2

Lotus SameTime doesn’t start when launched

Short Description: Attempting to launch Lotus Sametime results in the application being highlighted in the taskbar but not getting to the splash screen or subsequently launching.

Problem:  In my case, TaskManager will show multiple copies of “rcplauncher.exe” are running but Sametime.exe is not. It appears to be a copy of the file %APPDATA%\Lotus\Sametime\.rcp.lock is…well…locked and preventing the application from launching.

To fix step by step:

Kill all instances of rcplauncher.exe

Remove the hidden attribute from %APPDATA%\Lotus\Sametime\.rcp.lock
delete or rename .rcp.lock (I’m not sure there are a lot of situations in which you would need to back up this file, but if you’re concerned, back it up).

Or run this from command line/as a cmd file:

Taskkill /F /IM rcplauncher.exe (for earlier versions of windows kill.exe may be necessary instead of taskkill)

attrib -a -h %APPDATA%\Lotus\Sametime\.rcp.lock

del /q %APPDATA%\Lotus\Sametime\.rcp.lock

if the file isn’t found and shows in explorer, check that the APPDATA environment variable is set correctly

“set |findstr APPDATA” should return

<users>\<your username>\AppData\Roaming


Lotus Traveler

After the inreasing usage of Android back in year 2013, I installed Lotus traveler (in 2014) so that android users can use IBM Verse mail app in there mobile to sync with office server.

Case#1 ,

JVM: Traveler: Lotus Traveler task did not respond within the allotted time frame (55,000 milliseconds) for action nameLookup and operation key

There is a database or connectivity issue on the server side. If you haven’t run the defrag on the Traveler (load traveler -defrag), do so now !


rvv bucket error

The error “RRV bucket is corrupt” can’t be repaired. RRV bucket means “Record Relocation Vector” table, and if this is damaged, then it can’t be repaired. Fixup, compact, updall and replace design all will fail and will throw the same error. The only solution is to replace with the last back up copy of database. RRV bucket becomes corrupt if the OS hangs, crashes or restarted at the moment when the Record Relocation Vector table is being updated.


 

NTP Server configuration in Ubuntu

$
0
0

ntp show

Task:

We want to create a local NTP server so that our local devices like switches / routers / systems can syn time with it without requiring internet access. The NTP daemon allows a machine on your network (if you would like) to operate as an NTP time server. Doing so will allow other machines on your local network to synchronize with your LAN time server in a very quick and accurate manner, since network latency is minimized. In this way, the differences in clocks between machines on your network is kept as minimal as possible. Mac, and even Windows boxes are also able to synchronize with an NTP server.

Note: If your windows workstation is part of domain, you will not be able to see INTERNET TIME setup in DATE TIME because workstation will sync time with the Domain.


OS: Ubuntu 16.04.4 LTS with internet access

First, Install the NTP daemon

sudo aptitude remove ntpdate
sudo aptitude install ntpd

Note: Once you have found one good syncing peer,  add it to the list, putting ‘iburst’ after the most promising one. For instance:

server 91.189.91.157 iburst

This will cause ntpd to synchronize very quickly with this server after starting up.

Now restart NTPD daemon …

sudo /etc/init.d/ntp restart

It may take few seconds or up to 15-20 minutes for the initial time sync.

Next, monitor your system log to see if you synchronize with a time server:

tail -f /var/log/syslog

root@linux:~# ntpq -c lpeer
remote refid st t when poll reach delay offset jitter
==============================================================================
+alphyn.canonica 132.246.11.231 2 u 109 1024 377 195.030 -3.184 1.820
-jiro.paina.net 131.113.192.40 2 u 55 1024 377 285.680 55.800 15.483
*ntp5.mobinnet.n 85.199.214.98 2 u 1026 1024 377 208.593 -2.359 3.459
+118.140.184.98 223.255.185.2 2 u 1207 512 174 128.292 2.083 30.041
-103.47.76.177 193.0.0.229 2 u 757 1024 17 110.355 7.986 75.054

You can test if NTP Server is working or not, just download NTPTOOL and Query.
As showed in the image below …

ntp.JPG


Configure Cisco Switch to sync with ubuntu time server

enable
configure terminal
# Timezone for Asia/Karachi, you may adjust it according to your local TZ
clock timezone PST +5
service timestamps log datetime localtime
# change NTP Server IP Address
ntp server 192.168.100.1
end
show ntp associations

Before vs After (on cisco 3850 switch)

BEFORE

Switch#sh clock
*11:36:14.321 UTC Tue Jun 19 2018

enable
configure terminal
clock timezone PST +5
service timestamps log datetime localtime
ntp server 101.11.11.240
end

AFTER

Switch#sh clock
*16:37:16.103 PST Tue Jun 19 2018
Switch#show ntp associations

address ref clock st when poll reach delay offset disp
~101.11.11.240 91.189.91.157 3 11 64 1 1002.8 283436. 7937.9
* sys.peer, # selected, + candidate, - outlyer, x falseticker, ~ configured
Switch#

Done.


 

BASH Script with time & single execution per day checks

$
0
0

 

repeat

Scenario:

We have a bash script that performs various functions related to Freeradius, including expiration checkup & various groups updates functions.

Problem:

We have schedules this script to run daily at 1700 hours, What will happen if server was powered off  at 1700 hours? Script will missed its schedule resulting in expired users account will not be disabled for that day and incorrect display of users status in front gui. Alternatively we can schedule it to run hourly but it will increase the server load because of repeated task , which is supposed to be executed only once per day

Requirements:

We need to make some checks and balances so that if script must have some intelligent IF ELSE criteria in order to check following steps …

  • Script is scheduled to run hourly, so that if it misses the 1700 hour it will be relaunched next hour,
  • If time is 1700 hours or above then execute the script,
  • If the script executes successfully , then save this result, and on next run (within current date) it should detect last run status and dont repeat the code to avid recurrence,
  • If the last run was not executed for any reason, & the time is 1700 or above then execute the script and save its run status in file,
  • Once the data changes, it should re-run the script only if the time is 1700 or above.

Solution:

the SCRIPT ! Sample Purpose only

#!/bin/bash
# Bash Script to make sure script runs at specific time, and should not run again for the same date
# record date in local file, to avoic repeating running the code in todays date, once the date is changed,
# then re-run the code and match time again and so on
# Syed Jahanzaib / 26-Jun-2018
# set -x

# Setting variables
DATE=$(date +%d-%m-%Y)
FULL_DATE=`date`
FILE=/temp/1.txt
touch $FILE
CURR_HOUR=$(date +%H)

# Set time for script execution
SCR_SCHEDULED_TIME="11"
H=$(date +'%-H')

CHK_GREP=`grep -c $DATE $FILE`
echo "Current Date time is $FULL_DATE"

# If script is executed successfully then dont re-run and exit now
if grep -q $DATE $FILE >/dev/null 2>&1
then
echo "It seems the script was executed successfully today $DATE, It will run on next date change.... Exiting now."
exit 1
fi

# Check if time is matched that is greater or equals to $SCR_SCHEDULED_TIME and also check if script hae ran successfully or not previously
echo "
Stage-1: Checking if current time is equals or greater then '$SCR_SCHEDULED_TIME hours' ..."
if [ "$CURR_HOUR" -ge "$SCR_SCHEDULED_TIME" ] && [ "$CHK_GREP" == "0" ]; then
echo "
Stage-2: Time matched that is equals or greater then $SCR_SCHEDULED_TIME"
# If all matches, then run the code ! and add time stamp in file to avoid repeatingo/re-running the following script code on next RUN
echo "Finally: All conditions time + this day first execution matched, Now running the script code ...."
date +%d-%m-%Y >> $FILE
exit 1
fi

# If time have not come like its before the $SCR_SCHEDULED_TIME, then give error and exit now
echo "
Warning !
Scheudled time is equals or greater then $SCR_SCHEDULED_TIME hours : Current hour is $CURR_HOUR
Time have not came yet ! wait for your turn ..."

This way I was able to achieve the task I was thiking of.


# Actual Script which performs various functions with time checkups etc

Just for personnel reference …

#!/usr/bin/env bash
####!/bin/sh
#set -x
#trap "set +x; set -x" DEBUG
# BASH base script to discopnnect users whose expiry is today & update there GROUPS as well and update log table.
# the simple logic can be applied for about any other task as well. I tried to make it as simple as it can be
# also check if the scrpit ran successfully then dont re-run today,
# By Syed Jahanzaib
# CREATED on : 16th July, 2015
# Modified on 25h June 2018

# Local Variables
# Mysql credentials
SQLID="root"
SQLPASS="ROOTPASS"
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLID --skip-column-names -s -e"
DB="radius"
#Table which contain main users information
TBL="users"
#Rad user group in which we will update user profile like from 1mb to expired or likewise
GROUP="radusergroup"
NEXTSRV="expired"
TBL_LOG="log"

# Date Time Variables
DATE=$(date +%d-%m-%Y)
FULL_DATE=`date`
CURR_HOUR=$(date +%H)
TODAY=$(date +"%Y-%m-%d")
WEEK=`date -d "-1000 days" '+%Y-%m-%d'`
BEGIN="1970-01-01"
H=$(date +'%-H')
################################
## Set time for script execution
## IMPORTANT, donot use 0 in it
SCR_SCHEDULED_TIME="12"
################################

#Network Related
hostname=`hostname`
IP=`ip route get 8.8.8.8 | awk '{print $NF; exit}'`

# Gmail Data
GMAILID="MYGMAIL@gmail.com"
GMAILPASS="MYGMAILPASS"
SMTP="64.233.184.108:587"
ADMINMAIL1="aacableAThotmail.com"
COMPANY="ZAIB"
MAILSUB="$COMPANY INFO -$HOSTNAME-$IP- List of account expired on $TODAY"

##################################################
##################################################
# Temp folder and files setup for various actions
##################################################
##################################################
TEMP="temp"
# Temp holders to store users list
ALLEXPLIST=/$TEMP/all_time_expired_users_list.txt
TODEXPLIST=/$TEMP/only_today_expired_users_list.txt
FILE=/$TEMP/check_user_expiration_exec.txt

# Checking if /temp folder is previously present or not , if not create one ...
{
if [ ! -d "/$TEMP" ]; then
echo
mkdir /$TEMP
fi
}

# remove and recreate users list to avoid any Duplication or issue
{
if [ -f $ALLEXPLIST ]; then
rm $ALLEXPLIST
touch $ALLEXPLIST
fi
}
{
if [ -f $TODEXPLIST ]; then
rm $TODEXPLIST
touch $TODEXPLIST
fi
}
# File Holder to store last execution date
{
if [ ! -f $FILE ]; then
touch $FILE
fi
}

############################
############################
###### START thE script cOdE
############################
############################

CHK_GREP=`grep -c $DATE $FILE`
echo "Current Date time is $FULL_DATE
"
# If script is executed successfully in current date, then dont re-run and exit now
echo "Stage-1:
Checking if the script have already ran successfully for today, by getting current date from the $FILE"
if grep -q $DATE $FILE >/dev/null 2>&1
then
echo "
Result:
It seems the script was executed successfully today $DATE, It will run on next date change. Exiting now ..."
exit 1
fi

# Check if time is matched that is greater or equals to $SCR_SCHEDULED_TIME and also check if script hae ran successfully or not previously by getting date from $FILE
echo "
Stage-2: Checking if current hour is equals or greater then '$SCR_SCHEDULED_TIME hours' & previous run is not done yet ..."
if [ "$CURR_HOUR" -ge "$SCR_SCHEDULED_TIME" ] && [ "$CHK_GREP" == "0" ]; then
echo "
Stage-2:
Time matched that is equals or greater then $SCR_SCHEDULED_TIME"
# If all matches, then run the code ! and add time stamp in file to avoid repeatingo/re-running the following script code on next RUN
echo "Finally:
All conditions time + this day first execution matched, Now running the script code ..."
date +%d-%m-%Y >> $FILE

# Pull users that are expiring from beginning till TODAY, to avoid missing any part
$CMD "use $DB; select username from $TBL where expiration between '$BEGIN' AND '$TODAY';" |sort > $ALLEXPLIST
# Pull user list that are expiring today only, for email purposes
$CMD "use $DB; select username from $TBL where expiration ='$TODAY';" |sort > $TODEXPLIST

# IF no user found , show error and exit - zaib
CHK=`wc -m $ALLEXPLIST | awk {'print $1}'`
if [ "$CHK" -eq 0 ]
then
echo "No user found expiring today, exiting ..."
exit 1
fi

# Apply formula
num=0
cat $ALLEXPLIST |while read data
do
num=$[$num+1]
USERNAME=`echo $data`

# Update user status in RADgroup & users table so that he will rejected on next login
IS_EXPIRED=`$CMD "use $DB; select is_expired from users where username ='$USERNAME';"`
if [ "$IS_EXPIRED" = "N" ]; then
echo "user_IS EXIPRED is NO *************************************************************************************************"
$CMD "use $DB; update $GROUP set groupname='$NEXTSRV' where username='$USERNAME';"
$CMD "use $DB; update $TBL set is_expired='Y' where username='$USERNAME';"
$CMD "use $DB; update $TBL set is_days_expired='Y' where username='$USERNAME';"
$CMD "use $DB; INSERT into $TBL_LOG (data, msg) VALUES ('$USERNAME', '$USERNAME - User reached Expiration, Group udpated.');"
fi

# CHECK ONLINE AND KICK
# Pull account session id from radacct table, which will be used to COA OR user disconnection
ACCTSESID=`$CMD "use $DB; select acctsessionid from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
# If user is not Online , just give info that he is not online
if [ -z "$ACCTSESID" ]; then
$CMD "use $DB; INSERT into $TBL_LOG (data, msg) VALUES ('$USERNAME', '$USERNAME - User reached Expiration, Group udpated but its already offline');"
echo "$USERNAME - User reached Expiration, Group udpated but its already offline."
else
# Kick user by getting his NAS ip, secret and other info and log
# Mikrotik NAS IP and Radport and Shared Secret
NAS_IP=`$CMD "use $DB; select nasipaddress from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
NAS_SECRET=`$CMD "use $DB; select secret from nas where nasname ='$NAS_IP';"`
NAS_COA_PORT=`$CMD "use $DB; select nas_coa_port from nas where nasname ='$NAS_IP';"`
# Disconnect users now using RADCLIENT with username adn Account session ID taken from radacct table
echo user-name=$USERNAME,Acct-Session-Id=$ACCTSESID | radclient -x $NAS_IP:$NAS_COA_PORT disconnect $NAS_SECRET
# LOG into LOG TABLE in radius DB
$CMD "use $DB; INSERT into $TBL_LOG (data, msg) VALUES ('$USERNAME', '$USERNAME - User reached Expiration, kicked & updated,.');"
echo "$USERNAME - User reached Expiration, kicked & updated."
fi
done

#TOT=`cat $TODEXPLIST | wc -l`
#echo "
#-----------
#-----------

#$COMAPNY _ List of TODAY $TODAY expired users, Total = $TOT"
#cat $TODEXPLIST

# Send Email to all admin - currently 4 users
sendemail -t $GMAILID -u "$MAILSUB" -o tls=yes -s $SMTP -t $ADMINMAIL1 -xu $GMAILID -xp $GMAILPASS -f $GMAILID -o message-file=$TODEXPLIST -o message-content-type=text
fi

Regard’s
Syed Jahanzaib

FREERADIUS WITH MIKROTIK – Part #14 – Dynamic Bandwidth Change on the FLY using COA with radclient

$
0
0

fre

bandwidth

FREERADIUS WITH MIKROTIK – Part #1 – General Tip’s Click here to read more on FR tutorials …


Disclaimer! This is important!

Every Network is different , so one solution cannot be applied to all. Therefore try to understand logic & create your own solution as per your network scenario. Just dont follow copy paste.

If anybody here thinks I am an expert on this stuff, I am NOT certified in anything Mikrotik/Cisco/Linux or Windows. However I have worked with some core networks and I read , research & try stuff all of the time. So I am not speaking/posting about stuff I am formerly trained in, I pretty much go with experience and what I have learned on my own. And , If I don’t know something then I read & learn all about it.

So , please don’t hold me/my-postings to be always 100 percent correct. I make mistakes just like everybody else. However – I do my best, learn from my mistakes and always try to help others.

This particular script was tested in Virtual environment only, therefore consider this posting as an reference only, donot use it in production environment.

Regard's
Syed Jahanzaib~

Scenario:

We have a generic FreeRADIUS Version 2.2.8 based billing system in Ubuntu 16.04.3 LTS Server. Users are authenticating to NAS (Mikrotik) which is using Freeradius as its AAA Server.


Requirement:

Currently users packages are flat 1mb,  2mb and so on. We would like to introduce different bandwidth for day and night for specific services. Upgrade/Downgrade of user package should be done by dynamically with COA, so that package changes must be done on the fly without disconnecting user.

I made  a simple bash script to perform the job, but that required different cron jobs to start/end the packages, also if the server was powered off on that particular time then schedule will be missed till next run. This was major PITA. Therefore I added few more checks and balances so that if the job misses its schedule time, it will execute it self BUT avoiding re-running of same action.

Its a bit complicated piece of BASH scripting , but so far doing its job.


Software / Hardware Components Used:

  • NAS: Mikrotik CCR1036 / Firmware: 6.42.1
  • Radius: Ubuntu 16.04.3 LTS Server Edition / 64bit
  • FreeRADIUS Version: 2.2.8 using apt-get installation

SERVICES Table!

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

-- Database: `radius`
-- Table structure for table `services`
CREATE TABLE `services` (
`srvid` int(10) NOT NULL,
`srvname` varchar(128) NOT NULL,
`descr` varchar(128) DEFAULT NULL,
`enabled` varchar(1) NOT NULL DEFAULT '1',
`expdays` int(4) NOT NULL DEFAULT '0',
`dlimit` varchar(32) NOT NULL DEFAULT '0',
`ulimit` varchar(32) NOT NULL DEFAULT '0',
`qt_enabled` tinyint(1) NOT NULL,
`tot_qt` int(32) NOT NULL DEFAULT '0',
`free_quota_enabled` tinyint(1) NOT NULL DEFAULT '0',
`free_qt_start_time` time NOT NULL,
`free_qt_end_time` time NOT NULL,
`dyn_bw_change` int(1) NOT NULL DEFAULT '0',
`dn_bwpkg` varchar(16) NOT NULL DEFAULT '0',
`dn_st_time` time NOT NULL,
`dn_et_time` time NOT NULL,
`dn_st_exec` int(1) NOT NULL DEFAULT '0',
`dn_et_exec` int(1) NOT NULL DEFAULT '0',
`ippool` varchar(64) NOT NULL,
`createdon` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- Dumping data for table `services`

INSERT INTO `services` (`srvid`, `srvname`, `descr`, `enabled`, `expdays`, `dlimit`, `ulimit`, `qt_enabled`, `tot_qt`, `free_quota_enabled`, `free_qt_start_time`, `free_qt_end_time`, `dyn_bw_change`, `dn_bwpkg`, `dn_st_time`, `dn_et_time`, `dn_st_exec`, `dn_et_exec`, `ippool`, `createdon`) VALUES
(9, '1mb', '1mb 30 days expity', '1', 30, '1024k', '1024k', 1, 1024, 1, '00:00:00', '00:00:00', 1, '2048k/2048k', '13:00:00', '23:00:00', 0, 1, 'public-pool', '2018-06-27 12:13:04');

-- Indexes for dumped tables
-- Indexes for table `services`
ALTER TABLE `services`
ADD PRIMARY KEY (`srvid`),
ADD KEY `nasname` (`srvname`);

-- AUTO_INCREMENT for dumped tables
-- AUTO_INCREMENT for table `services`
ALTER TABLE `services`
MODIFY `srvid` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=10;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;


the Script !

Following is bash script which will query different tables and take action according to the results. Scheduled to run hourly (or decide as per network load)


#!/bin/bash
# Following script will check specific table, and if found any servic entry (ID),
# It will query that service and make list of users attached to this service,
# Then it will query next pacakge , start/end time, and will perform actions accordingly
# It will also check if package change is already done, then ignore as per condition
# Syed Jahanzaib
# Created: 25-Jun=2018
# Last Modified: 27-Jun-2018
# set -x
SQLID="SQLID"
SQLPASS="SQLPASSWORD"
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLID --skip-column-names -s -e"
DB="radius"
#Table which contain main users information
USER_TABLE="users"
#Table which contains users name which will be scanned for quota
SRV_BW_DB="services"
#Log table in which few actions will be logged
USER_TABLE_LOG="log"
#Rad-user group in which we will update user profile like from 1mb to different pacake as per service
GROUP="radgroupreply"
# Temp file where user list will be saved
TMP1="/tmp/bwsch_srv.txt"
TMP2="/tmp/bwsch_users.txt"

#DATE TIME FUNCTIONS
currenttime=$(date +%H:%M:%S)

# Look for services that have Dynamic bandwidth change
$CMD "use $DB; select srvid from $SRV_BW_DB where dyn_bw_change ='1';" > $TMP1
if [ ! -s $TMP1 ]
then
echo "No SERVICES found to check for bandwdith changing in $SRV_BW_DB , exit"
exit 1
fi

# If required service found then look for Users
num=0
cat $TMP1 | while read srvid
do
num=$[$num+1]
SRVID=`echo $srvid |awk '{print $1}'`
$CMD "use $DB; select username from $USER_TABLE where srvid ='$SRVID';" > $TMP2
done
if [ ! -s $TMP2 ]
then
echo "No User found for bandwidth upgrade $SRV_BW_DB , exit"
exit 1
fi

# Run loop forumla to run CMD for single or multi usernames
num=0
cat $TMP2 | while read users
do
num=$[$num+1]
USERNAME=`echo $users |awk '{print $1}'`
SRVID=`$CMD "use $DB; select srvid from $USER_TABLE where username ='$USERNAME';"`
SRVNAME=`$CMD "use $DB; select srvname from services where srvid = '$SRVID';"`
DLIMIT=`$CMD "use $DB; select dlimit from services where srvid ='$SRVID';"`
ULIMIT=`$CMD "use $DB; select ulimit from services where srvid ='$SRVID';"`
DN_BWPKG=`$CMD "use $DB; select dn_bwpkg from services where srvid ='$SRVID';"`
DN_ST=`$CMD "use $DB; select dn_st_time from services where srvid ='$SRVID';"`
DN_ET=`$CMD "use $DB; select dn_et_time from services where srvid ='$SRVID';"`
DN_ST_EXEC=`$CMD "use $DB; select dn_st_exec from services where srvid ='$SRVID';"`
DN_ET_EXEC=`$CMD "use $DB; select dn_et_exec from services where srvid ='$SRVID';"`
GRPNAME=`$CMD "use $DB; select groupname from radgroupreply where groupname ='$SRVNAME';"`

# If package UPgrade time is matched in services & packages have not changed already, then do it now - zaib
echo "* Checking for Dynamic Bandwidth Changing. Match Start/End time, Check if upgrade/downgrade is already done etc,"
if [[ "$currenttime" > "$DN_ST" ]] && [[ "$currenttime" < "$DN_ET" ]]; then
# Avoid recurrence for same
if [ "$DN_ST_EXEC" -eq 0 ]; then
# Update User group for bandwidth change
$CMD "use $DB; update $GROUP set value= '$DN_BWPKG' where groupname ='$GRPNAME';"
NAS_IP=`$CMD "use $DB; select nasipaddress from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
NAS_SECRET=`$CMD "use $DB; select secret from nas where nasname = '$NAS_IP' ;"`
NAS_COA_PORT=`$CMD "use $DB; select nas_coa_port from nas where nasname = '$NAS_IP';"`
ACCTSESID=`$CMD "use $DB; select acctsessionid from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
$CMD "use $DB; update services set dn_st_exec= '1' where srvid ='$SRVID';"
$CMD "use $DB; update services set dn_et_exec= '0' where srvid ='$SRVID';"
echo "************** Bandwidht Packages UPgraded to New as per time **************"
fi
# If user is Online
if [ ! -z "$ACCTSESID" ]; then
echo User-Name=zaib,Mikrotik-Rate-Limit=\"$DN_BWPKG\" | radclient -x $NAS_IP:$NAS_COA_PORT coa $NAS_SECRET
fi
else
# If package DOWNgrade time is matched in services & packages have not changed already, then do it now - zaib
# BUT Avoid recurrence for same
if [ "$DN_ET_EXEC" -eq 0 ]; then
NAS_IP=`$CMD "use $DB; select nasipaddress from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
NAS_SECRET=`$CMD "use $DB; select secret from nas where nasname = '$NAS_IP' ;"`
NAS_COA_PORT=`$CMD "use $DB; select nas_coa_port from nas where nasname = '$NAS_IP';"`
ACCTSESID=`$CMD "use $DB; select acctsessionid from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
$CMD "use $DB; update $GROUP set value= '$DLIMIT/$ULIMIT' where groupname ='$GRPNAME';"
$CMD "use $DB; update services set dn_st_exec= '0' where srvid ='$SRVID';"
$CMD "use $DB; update services set dn_et_exec= '1' where srvid ='$SRVID';"
echo "************** Bandwidht Packages Downgraded to original packages **************"
fi
if [ ! -z "$ACCTSESID" ]; then
echo User-Name=zaib,Mikrotik-Rate-Limit=\"$DLIMIT/$ULIMIT\" | radclient -x $NAS_IP:$NAS_COA_PORT coa $NAS_SECRET
fi
fi
done

Result:

When bandwidth time change starts …

root@radius:/temp# ./bwsch.sh
* Checking for Dynamic Bandwidth Changing. Match Start/End time, Check if upgrade/downgrade is already done etc,
************** Bandwidht Packages UPgraded to New as per time **************
Sending CoA-Request of id 94 to 10.0.0.6 port 3799
User-Name = "zaib"
Mikrotik-Rate-Limit = "2048k/2048k"
rad_recv: CoA-ACK packet from host 10.0.0.6 port 3799, id=94, length=38
NAS-Identifier = "_CCR_GW"
NAS-IP-Address = 10.0.0.6
root@radius:/temp#
root@radius:/temp# ./bwsch.sh
* Checking for Dynamic Bandwidth Changing. Match Start/End time, Check if upgrade/downgrade is already done etc,
root@radius:/temp#

**********************************

root@radius:/temp# ./bwsch.sh
* Checking for Dynamic Bandwidth Changing. Match Start/End time, Check if upgrade/downgrade is already done etc,
************** Bandwidht Packages Downgraded to original packages **************
Sending CoA-Request of id 54 to 10.0.0.6 port 3799
User-Name = "zaib"
Mikrotik-Rate-Limit = "1024k/1024k"
rad_recv: CoA-ACK packet from host 10.0.0.6 port 3799, id=54, length=38
NAS-Identifier = "_CCR_GW"
NAS-IP-Address = 10.0.0.6
root@radius:/temp# ./bwsch.sh
* Checking for Dynamic Bandwidth Changing. Match Start/End time, Check if upgrade/downgrade is already done etc,
root@radius:/temp#

BEFORE

1- before update

AFTER

2- after update

 


When bandwidth time change ends … return pkg to normal

3- after tim ends.JPG


 


FREERADIUS WITH MIKROTIK – Part #15 – Dynamic NAS Clients

$
0
0

fre

rapid change.jpg

FREERADIUS WITH MIKROTIK – Part #1 – General Tip’s Click here to read more on FR tutorials …


Disclaimer! This is important!

Every Network is different , so one solution cannot be applied to all. Therefore try to understand logic & create your own solution as per your network scenario. Just dont follow copy paste.

If anybody here thinks I am an expert on this stuff, I am NOT certified in anything Mikrotik/Cisco/Linux or Windows. However I have worked with some core networks and I read , research & try stuff all of the time. So I am not speaking/posting about stuff I am formerly trained in, I pretty much go with experience and what I have learned on my own. And , If I don’t know something then I read & learn all about it.

So , please don’t hold me/my-postings to be always 100 percent correct. I make mistakes just like everybody else. However – I do my best, learn from my mistakes and always try to help others.

Regard's
Syed Jahanzaib~

Scenario:

In freeradius , we have to add NAS client entries either in clients.conf or in nas table to allow communication from NAS  with freeradius services (for AAA requests). This is good from security perspective to allow only specific IP addresses, BUT what if your NASes are spreaded across different location (geographically different places) and have dynamic IP addresses like DSL , 3G/4G etc.

As a workaround we can setup a vpn server on our central location and connect all remote NAS (es) to this vpn server but this requires additional configuration at server end and all client end’s as well.

Another workaround is to ALLOW all ip addresses to communicate with FR service which is really a BAD idea from security perspective 🙂 As ALAN once said:

Are you willing to let anyone on the net send RADIUS packets to your RADIUS server?

Another workaround is to allow only specific IP subnet range , for this you have to inquire about the IP range that ISP is assigning to that particular NAS & allow this range in your clients.conf .


1# Howto enable freeradius to inquire about NAS clients using SQL NAS table

To enable freeradius to read clients details from NAS table in SQL, We need to modify in sql.conf file …

Edit following file /etc/freeradius/sql.conf

nano /etc/freeradius/sql.conf file

Uncomment the following

readclients = yes

So after modifications some portion of the file may look like following …

# Connection info:
server = "localhost"
#port = 3306
login = "radius"
password = "zaib1234"
readclients = yes

Now add one entry in this table & restart your Freeradius service.

mysql> select * from nas;
+---+---------------+------------+-------+------+------------+------+------+---------------+------+
| 1 | 101.11.11.255 | testmk | other | NULL | testing123 | NULL | NULL | RADIUS Client | 3799 |
+---+---------------+------------+-------+------+------------+------+------+---------------+------+
1 rows in set (0.00 sec)

This table contains data about your NASes (like mikrotik etc). It is more convenient to to maintain the NAS details in the database.

NOTE: Whenever you add / edit / remove any entry in clients.conf or NAS table, you must restart freeradius service by following cmd

service freeradius restart

 

You can use following NAS table also, adding just for reference purposes …

-- phpMyAdmin SQL Dump
-- version 4.5.4.1deb2ubuntu2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jun 29, 2018 at 03:25 PM
-- Server version: 5.7.21-0ubuntu0.16.04.1-log
-- PHP Version: 7.0.22-0ubuntu0.16.04.1

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `radius`
--

-- --------------------------------------------------------

--
-- Table structure for table `nas`
--

CREATE TABLE `nas` (
`id` int(10) NOT NULL,
`nasname` varchar(128) NOT NULL,
`shortname` varchar(32) DEFAULT NULL,
`type` varchar(30) DEFAULT 'other',
`ports` int(5) DEFAULT NULL,
`secret` varchar(60) NOT NULL DEFAULT 'secret',
`server` varchar(64) DEFAULT NULL,
`community` varchar(50) DEFAULT NULL,
`description` varchar(200) DEFAULT 'RADIUS Client',
`nas_coa_port` int(32) NOT NULL DEFAULT '3799'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `nas`
--

INSERT INTO `nas` (`id`, `nasname`, `shortname`, `type`, `ports`, `secret`, `server`, `community`, `description`, `nas_coa_port`) VALUES
(1, '10.0.0.3', 'ZAIB_CCR_GW', 'other', NULL, 'testing123', NULL, NULL, 'RADIUS Client', 3799);

--
-- Indexes for dumped tables
--

--
-- Indexes for table `nas`
--
ALTER TABLE `nas`
ADD PRIMARY KEY (`id`),
ADD KEY `nasname` (`nasname`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `nas`
--
ALTER TABLE `nas`
MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;


2# Adding NAS Clients entries in CLIENTS.CONF file

 

In /etc/freeradius/clients.conf use below format to allow either single ip, subnet, or Allow ANY IP (all all ip’s is is not recommended*)

# To allow specific NAS single IP only

# To allow ONLY specific NAS via clients.conf
client 92.168.10.1 {
secret = testing123
shortname = Mikrotik
}

# To allow specific SUBNET ip (example if remote NAS have dynamic public ip but the ip remains from specific subnet range)

client test_subnet_nas {
ipaddr = 192.168.10.0
secret = testing123
netmask = 24
}

To allow ANY ip to send request to freeradius server (not recommended)

# To allow ANY NAS client which is not recommended*
client 0.0.0.0/0 {
secret = testing123
shortname = Mikrotik
}

3# Allow NAS AAA Requests based on NAS-IDENTIFIER

In Some situations we would like to authenticate user only if its coming from SPECIFIC NAS only (not by ip, but by NAS-Identifier attribute).

Example if client request coming from NAS which have system identifiaction of ZAIB_CCR_GW , then process authentication request further ELSE REJECT !

First you need to allow NAS requests from ALL or Subnet range IP.

# To allow ANY NAS client which is not recommended*
client 0.0.0.0/0 {
secret = testing123
shortname = Mikrotik
}

Users Table Sample !

We have a user table which contains a column nas_id. We will add a SQL IF statement which will check the the connecting user NAS-Identifier & match it with users allowed nas_id in the user’s table.

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
`id` int(10) NOT NULL,
`username` varchar(128) NOT NULL,
`password` varchar(32) NOT NULL,
`firstname` text NOT NULL,
`lastname` text NOT NULL,
`email` text NOT NULL,
`mobile` text NOT NULL,
`cnic` text NOT NULL,
`srvname` text NOT NULL,
`srvid` int(3) NOT NULL,
`expiration` date DEFAULT NULL,
`mac` varchar(30) NOT NULL,
`macvendor` varchar(128) NOT NULL,
`bwpkg` varchar(256) NOT NULL,
`pool` varchar(128) DEFAULT 'other',
`is_enabled` int(1) NOT NULL,
`is_days_expired` int(1) NOT NULL,
`is_qt_expired` int(1) NOT NULL,
`is_uptime_expired` int(1) NOT NULL,
`qt_total` varchar(32) NOT NULL,
`qt_used` varchar(20) NOT NULL,
`uptime_limit` varchar(20) NOT NULL,
`uptime_used` varchar(32) NOT NULL,
`owner` text NOT NULL,
`vlanid` varchar(32) NOT NULL,
`nas_id` varchar(32) DEFAULT NULL,
`createdon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `users`
--

Now we will add a USERS entry as sample …

INSERT INTO `users` (`id`, `username`, `password`, `firstname`, `lastname`, `email`, `mobile`, `cnic`, `srvname`, `srvid`, `expiration`, `mac`, `macvendor`, `bwpkg`, `pool`, `is_enabled`, `is_days_expired`, `is_qt_expired`, `is_uptime_expired`, `qt_total`, `qt_used`, `uptime_limit`, `uptime_used`, `owner`, `vlanid`, `nas_id`, `createdon`) VALUES
(1, 'zaib', 'zaib', 'OK', 'jahanzaib', 'aacableAThotmailDOTcom', '03333021909', '1234567890-1-1', '1mb', 9, '2018-01-04', '00:0C:29:B9:D8:A0', '', '1024k/1024k', 'public-pool', 1, 0, 0, 0, '0', '2933559', '0', '', 'xxxxxx', 'ether1-LAN-DUMMY', 'someinvalid_CCR_GW', '2018-06-29 11:06:52');

Now we will add the SQL IF statement that will actually check every incoming Authentication request for matching NAS-IDENTIFIER with nas_id column in users table.

Edit Default Sites-Enabled file,

nano /etc/freeradius/sites-enabled/default

& paste following in `Authorize` Section

if ("%{sql: select nas_id from users where username = '%{User-Name}'}" != "%{NAS-Identifier}") {
update reply {
Reply-Message = 'Error: You are not allowed to connect form this NAS ! Bingo - zaib'
}
update control {
Auth-Type := "Reject"
}
}

Save & Exit.

Now reload Freeradius in Debug Mode (by freeradius -X) & monitor the debugging.

If user will connect from another NAS (which is not matched in with nas_id column in the USERS table , he will get denied with the message.

Note: For testing purposes . I have added dummy entry in user’s nas_id column.

###############################################
# Showing relevant data only for demo purposes - Syed Jahanzaib - 29-JUN-2018
###############################################
rad_recv: Access-Request packet from host 10.0.0.1 port 49453, id=150, length=124
Service-Type = Framed-User
Framed-Protocol = PPP
NAS-Port = 15729249
NAS-Port-Type = Ethernet
User-Name = "zaib"
Calling-Station-Id = "24:26:42:D4:BC:43"
Called-Station-Id = "service1"
NAS-Port-Id = "ether10"
User-Password = "zaib"
NAS-Identifier = "ZAIB_CCR_GW"
NAS-IP-Address = 10.0.0.1

# Executing section authorize from file /etc/freeradius/sites-enabled/default

++? if ("%{sql: select nas_id from users where username = '%{User-Name}'}" != "%{NAS-Identifier}")
sql_xlat
expand: %{User-Name} -> zaib
sql_set_user escaped user --> 'zaib'
expand: select nas_id from users where username = '%{User-Name}' -> select nas_id from users where username = 'zaib'
rlm_sql (sql): Reserving sql socket id: 25
sql_xlat finished
rlm_sql (sql): Released sql socket id: 25
expand: %{sql: select nas_id from users where username = '%{User-Name}'} -> ZAIB_CCR_GW1
expand: %{NAS-Identifier} -> ZAIB_CCR_GW
? Evaluating ("%{sql: select nas_id from users where username = '%{User-Name}'}" != "%{NAS-Identifier}") -> TRUE
++? if ("%{sql: select nas_id from users where username = '%{User-Name}'}" != "%{NAS-Identifier}") -> TRUE
++if ("%{sql: select nas_id from users where username = '%{User-Name}'}" != "%{NAS-Identifier}") {
+++update reply {
+++} # update reply = noop
+++update control {
+++} # update control = noop
++} # if ("%{sql: select nas_id from users where username = '%{User-Name}'}" != "%{NAS-Identifier}") = noop

Found Auth-Type = Reject
Auth-Type = Reject, rejecting user
Failed to authenticate the user.
Using Post-Auth-Type Reject

# Executing group from file /etc/freeradius/sites-enabled/default
+group REJECT {
++update reply {
++} # update reply = noop
[sql] expand: %{User-Name} -> zaib
[sql] sql_set_user escaped user --> 'zaib'

[sql] expand: INSERT into radpostauth (username, pass, mac, nasipaddress, reply, authdate, reason) values ('%{User-Name}', '%{User-Password:-Pap-Password}', '%{Calling-Station-Id}', '%{NAS-IP-Address}', '%{reply:Packet-Type}', NOW(), '%{reply:Reply-Message}') -> INSERT into radpostauth (username, pass, mac, nasipaddress, reply, authdate, reason) values ('zaib', 'zaib', '24:26:42:D4:BC:43', '10.0.0.1', 'Access-Reject', NOW(), 'Error: You are not allowed to connect form this NAS =21')
rlm_sql (sql) in sql_postauth: query is INSERT into radpostauth (username, pass, mac, nasipaddress, reply, authdate, reason) values ('zaib', 'zaib', '24:26:42:D4:BC:43', '10.0.0.1', 'Access-Reject', NOW(), 'Error: You are not allowed to connect form this NAS =21')
rlm_sql (sql): Reserving sql socket id: 24
rlm_sql (sql): Released sql socket id: 24
++[sql] = ok
[attr_filter.access_reject] expand: %{User-Name} -> zaib
attr_filter: Matched entry DEFAULT at line 11
++[attr_filter.access_reject] = updated
+} # group REJECT = updated
Delaying reject of request 3 for 1 seconds
Going to the next request
Waking up in 0.9 seconds.
Sending delayed reject for request 3
Sending Access-Reject of id 150 to 10.0.0.1 port 49453
Reply-Message = "Error: You are not allowed to connect form this NAS !"
Waking up in 4.9 seconds.
Cleaning up request 3 ID 150 with timestamp +104
Ready to process requests.

.

& if the users request matches , he will be granted access (off course after all other checks) 🙂


Regard’s
Syed Jahanzaib

 

Retrieve User Account Info via SMS in Radius Manager along with playSMS

$
0
0

sms

usereinfo

 


SCENARIO:

We are using DMASOFTLAB Radius Manager as our billing system and Playsms along with KANNEL sms gateway is installed on same server. We would like to a function in playsms that if user sends sms with specific keyword like `userinfo USERNAME` , then the scritp should trigger and retreieve user information & sms back to the sender in specified format.

In this example, we are using DMASOFTLAB Radius Manager as our billing system, and KANNEL along-with the playSMS is already configured and in working condition. Kannel+playSMS configuration details have already been described briefly with examples in my previous posts.

We have created an script on the billing system which fetches the user account status and other information from the MYSQL database and print them as per our defined format.

This is just for demonstration purpose. the script have lot of junk data and should be modified before production deployment. I am just sharing some thoughts and ideas only 🙂


REQUIREMENTS

  • Radius Manager 4.x Version
  • 127.0.0.1 must be added in ALLOWED NASes in all services
  • Kannel SMS gateway for IN/OUT sms
  • playSMS

SCRIPT !

Script is as follows FYR. Hope it may help someone

cat userinfo.sh

#!/bin/bash
#set -x
# Thsi script is designed SPECIFICALLY for dmasoftlab radius manager 4.1.x series
# This script check user status , Expiry Date, Service Plan, Data Used
# mainly it is designed to work with playsms , so that user sends sms , and playsms will execute this script with username
# and reply back with the information it fetches
# Designed by : Syed Jahanzaib
# aacable @ hotmail.com = https://aacable.wordpress.com
# Last Modified on 9th June, 2015
DATE=$(date '+%Y-%m-%d_____%H-%M-%S')
TMP="/tmp/userinfo_incoming_sms__$DATE.sms"
# Strip user name and card number separate oterhwise playsms will treat both variables as one
echo $1 > $TMP
USR=`cat $TMP | awk {' print $1 '}`

# MYSQL USER NAME AND PASSWORD Variables
SQLUSER="SQL_ROOT_USER"
SQLPASS="SQL_ROOT_PASSWORD"
SQLHOST="localhost"
SQLPORT="3306"
DB="radius"
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLUSER -p$SQLPASS -h$SQLHOST --port=$SQLPORT --skip-column-names -e"

CURRENCY="MVR"
RMAUTH="/usr/local/bin/rmauth"

###################### bytes conversion formula
bytesToHuman() {
b=${1:-0}; d=''; s=0; S=(Bytes {K,M,G,T,P,E,Z,Y}iB)
while ((b > 1024)); do
d="$(printf ".%02d" $((b % 1024 * 100 / 1024)))"
b=$((b / 1024))
let s++
done
echo "$b$d ${S[$s]}"
}
#####################

# Check User Validation, if not found exit with error , else continue
FOOTER="
Powered by Syed Jahanzaib"

if [ -z "$USR" ]; then
echo -e "(Error 0) username missing,
Usage: userinfo myusername"

exit 1
fi

# Check if user in DB or not
USRVALID=`$CMD "use $DB; SELECT username FROM rm_users WHERE username = '$USR';"`
if [ -z "$USRVALID" ]; then
echo -e "(Error 1) USER NOT FOUND !"
exit 1
fi

# Check if user quota is ended or not
IS_USER_QUOTA_AVAILABLE=`$RMAUTH 127.0.0.1 $USR 1 |grep -i -c "Total traffic limit reached!"`
if [ "$IS_USER_QUOTA_AVAILABLE" -eq 1 ];then
echo "(Error 2) Account Quota limit have finished , please recharge it first!"
exit 1
fi

# Check if user is expired or not
IS_USER_EXPIRED_OR_NOT=`$RMAUTH 127.0.0.1 $USR 1 |grep -i -c "expired!"`
if [ "$IS_USER_EXPIRED_OR_NOT" -eq 1 ];then
echo "(Error 3)Your account date expired , please recharge to continue our service"
exit 1
fi

# Check if user is enabled or disabled in radius
IS_USER_ENABLED_OR_DISABLED=`$RMAUTH 127.0.0.1 $USR 1 |grep -i -c "Invalid service reference!"`
if [ "$IS_USER_ENABLED_OR_DISABLED" -eq 1 ];then
echo "(Error 4)Your account is disabled by Admin!"
exit 1
fi

# VARIABLES
TODAY=$(date +"%Y-%m-%d")
TODAYDIGIT=`echo $TODAY | sed -e 's/-//g'`
MONTH=$(date +"-%m")
CMONTH=`echo $MONTH | sed -e 's/-//g'`
CURR_MONTHYEAR=$(date +"%Y-%m")
MONTHYEAR=$(date +"%B-%Y")
ALPHAMONTHYEAR=`echo $MONTHYEAR #| sed -e 's/-//g'`
SRVEXPIRYFULL=`$CMD "use $DB; SELECT expiration FROM rm_users WHERE username = '$USR';"`
LOGOFFDATE=`$CMD "use $DB; SELECT lastlogoff FROM rm_users WHERE username = '$USR';"`
SRVID=`$CMD "use $DB; SELECT srvid from rm_users where username = '$USR';"`
SRVEXPIRY_YES_OR_NO=`$CMD "use $DB; SELECT limitexpiration FROM rm_services WHERE srvid = '$SRVID';"`
SRV_NEXT_DAILY=`$CMD "use $DB; SELECT dailynextsrvid FROM rm_services where srvid = '$SRVID'";`
SRV_NEXT_DISABLED=`$CMD "use $DB; SELECT disnextsrvid FROM rm_services where srvid = '$SRVID'";`
SRV_NEXT=`$CMD "use $DB; SELECT nextsrvid FROM rm_services where srvid = '$SRVID'";`
SRV_QUOTA_LIMIT_IN_MB=`$CMD "use $DB; SELECT trafficunitcomb FROM rm_services where srvid = '$SRVID'";`
SRV_QUOTA_LIMIT_IN_BYTES=`echo "($SRV_QUOTA_LIMIT_IN_MB)*(1024)*(1024)" |bc`
SRVPRICE=`$CMD "use $DB; SELECT unitprice FROM rm_services WHERE srvid = $SRVID;"`
TOT_DOWN_UP_CURR_MONTH_IN_BYTES=`$CMD "use $DB; SELECT ((SUM(AcctInputOctets)+SUM(AcctOutputOctets))) FROM radacct WHERE username ='$USR' AND acctstarttime LIKE '$CURR_MONTHYEAR-%' LIMIT 0 , 30;"`

TOT_USER_DOWNLOAD_SINCE_LAST_REFRESH_IN_BYTES=`$CMD "use $DB; SELECT downlimit from rm_users where username = '$USR';" |sed 's/[\._-]//g'`
TOT_USER_UPLOAD_SINCE_LAST_REFRESH_IN_BYTES=`$CMD "use $DB; SELECT uplimit from rm_users where username = '$USR';" |sed 's/[\._-]//g'`

TOT_USER_USED_DATA_SINCE_LAST_REFRESH_IN_BYTES=`echo "($TOT_USER_DOWNLOAD_SINCE_LAST_REFRESH_IN_BYTES)+($TOT_USER_UPLOAD_SINCE_LAST_REFRESH_IN_BYTES)" |bc`
TOT_USER_DOWNUP_FROM_RADACCT=`$CMD "use radius; SELECT ((SUM(AcctInputOctets)+SUM(AcctOutputOctets))) FROM radacct WHERE username = '$USR';" |sed 's/[\._-]//g'`
TOT_USER_USED_DATA_SINCE_LAST_REFRESH_IN_HUMAN_FRIENDLY_VALUE=`bytesToHuman $TOT_USER_USED_DATA_SINCE_LAST_REFRESH_IN_BYTES`

USER_QUOTA_LEFT_SINCE_LAST_REFRESH_IN_BYTES=`echo "($SRV_QUOTA_LIMIT_IN_BYTES)-($TOT_USER_USED_DATA_SINCE_LAST_REFRESH_IN_BYTES)" |bc`
USER_QUOTA_LEFT_SINCE_LAST_REFRESH_IN_HUMAN_FRIEND_VALUE=`bytesToHuman $USER_QUOTA_LEFT_SINCE_LAST_REFRESH_IN_BYTES`

PKGNAME=`$CMD "use $DB; SELECT srvname FROM rm_services WHERE srvid = '$SRVID';"`
USER_FIRSTNAME=`$CMD "use $DB; SELECT firstname FROM rm_users WHERE username = '$USR';"`
USER_LASTNAME=`$CMD "use $DB; SELECT lastname FROM rm_users WHERE username = '$USR';"`
QTL_Y_OR_NO=`$CMD "use $DB; SELECT limitcomb FROM rm_services WHERE srvid = '$SRVID';"`

#echo "Account STATUS= OK!"

echo -e "Account Registed to = $USER_FIRSTNAME $USER_LASTNAME"
echo -e "PACKAGE = $PKGNAME"
if [ "$SRVPRICE" == "0.000000" ]; then
echo -e "Service Price = n/a"
else
echo -e "Service Price = $SRVPRICE $CURRENCY"
fi

if [ "$SRVEXPIRY_YES_OR_NO" -eq 0 ]; then
echo -e "Date Expiration = Unlimited"
else
echo -e "Date Expiration = $SRVEXPIRYFULL"
fi

# Check QUOTA value if quota is enforced
if [ "$QTL_Y_OR_NO" -eq 1 ]; then
SRV_QUOTA_LIMIT_IN_HUMAN_FRIENDLY_VALUE=`bytesToHuman $SRV_QUOTA_LIMIT_IN_BYTES`
echo "Service Quota Allowed: $SRV_QUOTA_LIMIT_IN_HUMAN_FRIENDLY_VALUE"
else
echo "Quota Allowed: No Limit"
fi

# Check If next service is allowed after expiration or over quota
if [ "$SRV_NEXT_DAILY" == "-1" ] && [ "$SRV_NEXT_DISABLED" == "-1" ] && [ "$SRV_NEXT" == "-1" ]; then
NEXT_SRV_ENABLED_OR_NOT_FRIENDLY_VALUE="Not Configured"
else
NEXT_SRV_ENABLED_OR_NOT_FRIENDLY_VALUE="Yes"
fi

#if [ "$TOT_USER_DOWNUP_FROM_RADACCT" == "NULL" ]; then
#echo "Total Data Used Since Last Renewal = NULL"
#TOT_USER_DOWNUP_FROM_RADACCT="0"
#fi

# *ZAIB
if [ "$QTL_Y_OR_NO" -eq 1 ]; then

# Allah shuker - zaib
RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE=`$CMD "use $DB; SELECT SQL_CALC_FOUND_ROWS IF (limitdl = 1, downlimit - COALESCE((SELECT SUM(acctoutputoctets) FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(dlbytes), 0) FROM rm_radacct WHERE rm_radacct.username = tmp.username), 0), 0), IF (limitul = 1, uplimit - COALESCE((SELECT SUM(acctinputoctets) FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(ulbytes), 0) FROM rm_radacct WHERE rm_radacct.username = tmp.username), 0), 0), IF (limitcomb =1, comblimit - COALESCE((SELECT SUM(acctinputoctets + acctoutputoctets) FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(ulbytes + dlbytes), 0) FROM rm_radacct WHERE rm_radacct.username = tmp.username), 0), 0), IF (limituptime = 1, uptimelimit - COALESCE((SELECT SUM(acctsessiontime) FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(acctsessiontime), 0) FROM rm_radacct WHERE rm_radacct.username = tmp.username), 0), 0) FROM ( SELECT username, firstname, lastname, address, city, zip, country, state, phone, mobile, email, company, taxid, rm_users.srvid, rm_users.downlimit, rm_users.uplimit, rm_users.comblimit, rm_users.expiration, rm_users.uptimelimit, credits, comment, enableuser, staticipcpe, staticipcm, ipmodecpe, ipmodecm, srvname, limitdl, limitul, limitcomb, limitexpiration, limituptime, createdon, verifycode, verified, selfreg, acctype, maccm, mac, groupid, contractid, contractvalid, rm_users.owner, srvtype, lastlogoff FROM rm_users JOIN rm_services USING (srvid) ORDER BY username ASC ) AS tmp WHERE 1 AND username LIKE '$USR%' AND (tmp.acctype = '0' OR tmp.acctype = '1' OR tmp.acctype = '2' OR tmp.acctype = '3' OR tmp.acctype = '4' OR tmp.acctype = '5' ) LIMIT 0, 50;" | awk '{print $3}'`
RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE_IN_HUMAN_FRIENDLY_FORMAT=`bytesToHuman $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE`
IS_QUOTA_LEFT_IN_NEGATIVE=`echo $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE_IN_HUMAN_FRIENDLY_FORMAT | grep -i -c "-"`
RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_NEGATIVE_VALUE_IN_BYTES_WITHOUT_DASH=`echo $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE_IN_HUMAN_FRIENDLY_FORMAT |sed 's/[\._-]//g'`
RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_NEGATIVE_VALUE_IN_HUMAN_FRIENDLY_VALUE=`bytesToHuman $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_NEGATIVE_VALUE_IN_BYTES_WITHOUT_DASH`

if [ "$IS_QUOTA_LEFT_IN_NEGATIVE" -eq 1 ]; then
echo "Total Quote Left = - $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_NEGATIVE_VALUE_IN_HUMAN_FRIENDLY_VALUE"
else
echo "Total Quote Left = $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE_IN_HUMAN_FRIENDLY_FORMAT"
fi
fi

echo "Next Service = $NEXT_SRV_ENABLED_OR_NOT_FRIENDLY_VALUE"

# Check for NULL DATA in download section of user
if [ "$TOT_DOWN_UP_CURR_MONTH_IN_BYTES" == "NULL" ]
then
echo "Total Data Used in $ALPHAMONTHYEAR = n/a"
else
TOT_DOWN_UP_CURR_MONTH_IN_BYTES_HUMAN_FIRNEDLY_VALUE=`bytesToHuman $TOT_DOWN_UP_CURR_MONTH_IN_BYTES`
echo -e "Total Data Used in $ALPHAMONTHYEAR = $TOT_DOWN_UP_CURR_MONTH_IN_BYTES_HUMAN_FIRNEDLY_VALUE"
fi

# check last log off date and print data accordingly
if [ "$LOGOFFDATE" == "NULL" ]; then
echo -e "LAST LOGOUT = n/a"
else
echo -e "LAST LOGOUT = $LOGOFFDATE"
fi

# Check if user is ONLINE or not
ONLINE=`$CMD "use $DB; SELECT framedipaddress FROM radacct WHERE acctstoptime IS NULL AND username = '$USR';"`
#if [ "$ONLINE" -eq 0 ]; then
if [ -z "$ONLINE" ]; then
echo -e "STATUS = Offline"
else
echo -e "STATUS = Online / IP: $ONLINE"
fi
echo "$FOOTER"

2- playSMS SECTION

Now we have to add COMMAND in playSMS which will actually receive the sms and will act accordingly if found the keyword info

userinfo-playsms-=command


 3- TEST PHASE

You can test by executing the script or send sms , as per your choice.

Both methods results are as follows …

 

by CLI


./userinfo.sh XYZUSER

Account Registed to = TEST USER
PACKAGE = 10GB with 2Mbps + After quota 1mbps (30 days)
Service Price = 500.00000 PKR
Date Expiration = 2018-07-10 00:00:00
Service Quota Allowed: 10.00 GiB
Total Quote Left = 435.42 MiB
Next Service Allowed = Yes
Total Data Used in July-2018 = 2.92 GiB
LAST LOGOUT = 2018-07-08 06:44:35
STATUS = Online / IP: 10.0.0.10

 


Regard’s
SYED JAHANZAIB

 

FREERADIUS WITH MIKROTIK – Part #16 – Loosy workaround to disconnect missing users from the NAS

$
0
0

search in croud

FREERADIUS WITH MIKROTIK – Part #1 – General Tip’s Click here to read more on FR tutorials …


Disclaimer! This is important!

Every Network is different , so one solution cannot be applied to all. Therefore try to understand the logic & create your own solution as per your network scenario. Just dont follow copy paste.

If anybody here thinks I am an expert on this stuff, I am NOT certified in anything Mikrotik/Cisco/Linux or Windows. However I have worked with some core networks and I read , research & try stuff all of the time. So I am not speaking/posting about stuff I am formerly trained in, I pretty much go with experience and what I have learned on my own. And , If I don’t know something then I read & learn all about it.

So , please don’t hold me/my-postings to be always 100 percent correct. I make mistakes just like everybody else. However – I do my best, learn from my mistakes and always try to help others.

Regard's
Syed Jahanzaib~

Scenario:

We have single NAS (Mikrotik) as pppoe server along with Freeradius as AAA server.
In NAS we have configured INTERIM UIPDATES set to 5 minutes therefore it sends accounting packets to the freeradius server after every 5 minutes. In Freeradius server web have a BASH script that closes the online sessions if the FR doesnt receive  accounting packets from the NAS for more then 10 minutes (to clear false sessions by considering that NAS is powered off).

We also have some users created locally in the NAS.


Problem:

Sometimes dueto communication disruption , Freeradius close the user session in radacct table considering the NAS is not reachable, BUT the user is still active on the NAS. When the communication restores & NAS sends the existing users accounting packets to the freeradius, they get discarded because the NAS connected user Account-Session-ID does not matches with the radacct table session id.

Freeradius will create new session (with acctstoptime is NULL value) only when

  • If new connection is made by user end , OR
  • If NAS connected user session ID is matched with the radacct Account Session ID

Workaround:

This is not a proper solution because it is limited to single NAS only, for multi NAS you should search freeradius mailing list for better approach.

Following is bash script which performs following action …

  1. Fetch NAS online active users in PPP/Active Connections, using password less ssh login from the Linux to Mikrotik,
  2. Fetch Freeradius online active users from RADACCT table (where acctstoptime value is NULL),
  3. Display difference between NAS and Freeradius Online users,
  4. If differentiated user is NAS local user, then donot take any action just move on,
  5. ELSE consider this user as RADIUS user which is online in NAS but offline in Radius RADACCT table, therefore KICK it , so that it can re-establish the new session and get re-inserted in radacct table properly.

You can modify it as per you local requirements.


Requirements:

  • Mikrotik as NAS with SSH enabled & RSA key imported so that ssh from Linux to mikrotik must work without password, explained  here , Make sure its working
  • Freeradius Server
  • Arithmetic function is performed by BC command, make sure you have it installed

the Script!

Schedule the script to run every 5 or above minutes, or as per local requirement,

#!/bin/bash
# BASH script to fetch online users list from Mikrotik NAS & compare it with local FR online users
# IF difference found, then kick the missed users from NAS, but if user is NAS local , then skip it
# This way the missing users will re-establishes there session and will be inserted properly in radacct table AGAIN ,
# This is just a workaround only, ITs not a proper solution, It also assumes you have single NAS only
# Created on : 11-JUL-2018
# Syed Jahanzaib / aacable at hotmnail dot com / https://aacable dot wordpress dot com

#set -x
# Setting various variables ...

# MYSQL related data
SQLID="root"
SQLPASS="SQLROOTPASSWORD"
DB="radius"
TBL_LOG="log"
export MYSQL_PWD=$SQLPASS
FOOTER="Script Ends Here. Thank you
Syed Jahanzaib / aacable at hotmail dot com"
# MIKROTIK related Data
MT_USER="admin"
MT_IP="10.10.0.1"
MT_PORT="10022"
MT_SECRET="RADIUS_INCOMING_SECRET"
MT_COA_PORT="3799"

# SSH commands for Mikrotik & Freeradius
MT_SSH_CMD="ssh $MT_USER@$MT_IP -p $MT_PORT"
FR_SSH_CMD="mysql -uroot --skip-column-names -s -e"

# Temporary holder for various data
MT_ACTIVE_USERS_LIST="/tmp/mt_active_users.txt"
MT_ACTIVE_USERS_NAME_ONLY_LIST="/tmp/mt_active_users_name_only_list.txt"
FR_ACTIVE_USERS_LIST="/tmp/fr_active_users_list.txt"
FR_MISSING_USERS_NAME_LIST="/tmp/fr_active_users_missing_list.txt"
> $MT_ACTIVE_USERS_LIST
> $MT_ACTIVE_USERS_NAME_ONLY_LIST
> $FR_ACTIVE_USERS_LIST
> $FR_MISSING_USERS_NAME_LIST

# Execute SSH commands & store data in temporary holders
echo "1- Getting list of Mikrotik Online users via ssh ..."
$MT_SSH_CMD "/ppp active print terse " | sed '/^\s*$/d' > $MT_ACTIVE_USERS_LIST
echo "2- Getting list of Freeradius Online users from 'RADACCT' table ..."
$FR_SSH_CMD "use radius; select username from radacct WHERE acctstoptime IS NULL;" > $FR_ACTIVE_USERS_LIST

# Run loop forumla to run CMD for single or multi usernames
echo "3- Running loop formula to fetch usernames only from the mikrotik PPP online users list ..."
num=0
cat $MT_ACTIVE_USERS_LIST | while read users
do
num=$[$num+1]
USERNAME=`echo $users |sed -n -e 's/^.*name=//p' | awk '{print $1}'`
echo "$USERNAME" >> $MT_ACTIVE_USERS_NAME_ONLY_LIST
done

# calculate and display Users from Mikrotik Active PPP list vs Freeradius Local Actvive Users List
MT_USERS_COUNT=`cat $MT_ACTIVE_USERS_LIST | wc -l`
FR_USERS_COUNT=`cat $FR_ACTIVE_USERS_LIST | wc -l`
USER_DIFFERENCE=`echo "($MT_USERS_COUNT)-($FR_USERS_COUNT)" |bc`
echo "
Result:
echo MIKROTIK ACTIVE USERS = $MT_USERS_COUNT
echo RADIUS ACTIVE USERS = $FR_USERS_COUNT
echo Freeradius Missing Users = $USER_DIFFERENCE
"
#comm -23 <(sort < $MT_ACTIVE_USERS_NAME_ONLY_LIST) <(sort < $FR_ACTIVE_USERS_LIST)

# Make separate list for users that are foung missing in Freeradius online users list
comm -23 <(sort < $MT_ACTIVE_USERS_NAME_ONLY_LIST) <(sort  $FR_MISSING_USERS_NAME_LIST

# Check if missing user is NAS local or FR user
echo "4- Running loop formula to check if missing users from FR are NAS local or radius users ...
"
cat $FR_MISSING_USERS_NAME_LIST | while read users
do
num=$[$num+1]
USERNAME=`echo $users | awk '{print $1}'`
REMOTE_OR_LOCAL=`cat $MT_ACTIVE_USERS_LIST |grep $USERNAME |awk '{print $2}'`
if [ "$REMOTE_OR_LOCAL" != "R" ]; then
echo "$USERNAME = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ..."
else
# IF user is a FR user, then consider his MISSED user & kick him so that he will reconnect & proper entries will be made in radius radacct table
echo "$USERNAME = This user is ON-LINE in NAS, but OFF-LINE in FR radacct table, kicking it so it will reconnect & session will be recreated properly **********"
#$MT_SSH_CMD "/ppp active remove [find name=$USERNAME]"
# KICK user via RADCLIENT / zaib
echo user-name=$USERNAME | radclient -x $MT_IP:$MT_COA_PORT disconnect $MT_SECRET
$FR_SSH_CMD "use $DB; INSERT into $TBL_LOG (data, msg) VALUES ('$USERNAME', '$USERNAME - Kicked from NAS dueto missing session in FR');"
fi
done

echo "$FOOTER"

OUTPUT:

root@zaibradius:/temp# ./test.sh
1- Getting list of Mikrotik Online users via ssh ...
2- Getting list of Freeradius Online users from 'RADACCT' table ...
3- Running loop formula to fetch usernames only from the mikrotik PPP online users list ...

Result:
echo MIKROTIK ACTIVE USERS = 959
echo RADIUS ACTIVE USERS = 945
echo Freeradius Missing Users = 14

4- Running loop formula to check if missing users from FR are NAS local or radius users ...

USER1 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER2 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER3 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER4 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER5 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER6 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER7 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER8 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER9 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER10 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER11 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER12 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER13 = This user is ON-LINE in NAS but OFF-LINE in FR radacct table, BUT its NAS local user, so skipping it ...
USER14 = This user is ON-LINE in NAS, but OFF-LINE in FR radacct table, kicking it so it will reconnect & session will be recreated properly **********

Sending Disconnect-Request of id 95 to 10.10.0.1 port 3799
User-Name = "USER14"
rad_recv: Disconnect-ACK packet from host 10.10.0.1 port 3799, id=95, length=36
NAS-Identifier = "MikroTik"
NAS-IP-Address = 10.10.0.1

Script Ends Here. Thank you
Syed Jahanzaib / aacable at hotmail dot com

FR stale session script result.JPG

.

Kick action entry will be logged in LOG table,

LOG ENTRY.JPG


Salam Alykum,

Windows 10 Pro Build 1803 unable to join 2008/2003 Domain

$
0
0

win10 pro 1803.JPG


Scenario:

Active Directory Domain Controller

  • Domain Controller 1 = Windows 2008 R2
  • Domain Controller 2 = Windows 2003 R2
  • Domain Name = MYCOMPANY (Single Label Domain)
  • Functional Level > Windows Server 2003

Clients:

  • Mix of Windows 7 Pro / Windows 10 / Windows 2008

Problem:

Recently we downloaded latest build of Windows 10 Pro Edition 1803. Today we we tried to join one test PC to the company domain but failed to do so with below error …

win10 error 1803 error.JPG

 

Ac active directory domain controller (AD DC) for the domain "MYCOMPANY" could not be contacted.
Ensure that the domain name is typed correctly.

Previous version of windows 10 were already joined with the domain properly. but only this new build version 1803 is not able to join domain. I can ping domain controller names via effected clients. nslookup working ok.


Workaround:

Proper Solution:

  • If you are using Single Label Domain , then rename it with full FQDN naming. joinging with full FQDN will sort the issue.
  • Upgrade 2003 DC’s to 2008 at least and raise functional level to Windows 2008,
    Or better to move to Windows 2012/2016 DC.

but if above suggestions are not doable like in my case, then follow below workaround as a temporary workaround,

Edit registry and add AllowSingleLabelDnsDomain . Full details as below ,

Open REGEDIT 

Find this subkey

  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters

Locate this > AllowSingleLabelDnsDomain.

If the key AllowSingleLabelDnsDomain does not exist, then create , New  DWORD (32 bit)

  • DWORD Key Name: AllowSingleLabelDnsDomain

Double click AllowSingleLabelDnsDomain

Set the Value to 1

  • AllowSingleLabelDnsDomain > 1

Exit regedit

Reboot Windows 10

Now try to join the AD domain.

Hopefully it will work, At least in my case it did 🙂


Regard’s
Syed Jahanzaib

Sharing Ideas … Updated Script for Renew Expired User Account via SMS in DMASOFTLAB Radius Manager

$
0
0

45705087-genius-aged-teacher-explains-a-complicated-lesson

This post contains updated script for account renewal in radius manager with many controls added. Posting it for reference purposes only for how I used various bash related stuff all together to acquire some specific results.


Script!


#!/bin/bash
#set -x
# Thsi script is designed SPECIFICALLY for dmasoftlab radius manager 4.x series
# This script can renew users based on following checks, match sender number with manager mobile,
# Expiration Date if set, Quota check IF set, Quota reset or prolong etc, insert in logs after successfull, update balance etc
# It is designed to work with playsms , so that user sends sms , and playsms will execute this script with username
# and reply back with the information it fetches
# Designed by : Syed Jahanzaib
# aacable @ hotmail.com = https://aacable.wordpress.com
# Last Modified on 9th June, 2015

# MYSQL USER NAME AND PASSWORD Variables
SQLUSER="root"
SQLPASS="sql_pass"
SQLHOST="localhost"
SQLPORT="3306"
DB="radius"
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLUSER -h$SQLHOST --port=$SQLPORT --skip-column-names -e"
CURRENCY="PKR"
RMAUTH="/usr/local/bin/rmauth"
FOOTER="
Powered by Syed Jahanzaib"
DATE=$(date '+%Y-%m-%d_%H-%M-%S')
TMP="/tmp/user_renewal_incoming_sms__$DATE.sms"
# Strip user name and card number separate oterhwise playsms will treat both variables as one
echo $1 $2 > $TMP
USR=`cat $TMP | awk {' print $1 '}`
SMS_SENDER_NO=`cat $TMP | awk {' print $2 '}`

######################
bytesToHuman() {
b=${1:-0}; d=''; s=0; S=(Bytes {K,M,G,T,P,E,Z,Y}iB)
while ((b > 1024)); do
d="$(printf ".%02d" $((b % 1024 * 100 / 1024)))"
b=$((b / 1024))
let s++
done
echo "$b$d ${S[$s]}"
}
#####################

# Check User Validation, if no user variable provided EXIT with error , else continue
if [ -z "$USR" ] || [ -z "$SMS_SENDER_NO" ] ; then
echo "(Error 0) missing parameters,
Usage: renew myusername"
exit 1
fi

# Check if user in DB or not
IS_USER_FOUND=`$CMD "use $DB; SELECT username FROM rm_users WHERE username = '$USR';"`
if [ -z "$IS_USER_FOUND" ]; then
echo "(Error 1) USER NOT FOUND !"
exit 1
fi

# Fetch Manger Name and Mobile numbers
$CMD "use $DB; SELECT managername,mobile FROM rm_managers;" > /tmp/manager_mobile_list.txt
MGR_NAME=`$CMD "use $DB; SELECT managername FROM rm_managers WHERE mobile = '$SMS_SENDER_NO';"`
if [ -z "$MGR_NAME" ]; then
echo "(Error 2) You are not authorized manager to renew this user!"
exit 1
else
echo "Manager name : $MGR_NAME" > /dev/null
fi

IS_USER_BELONG_TO_MGR=`$CMD "use $DB; select count(*) from rm_users where username = '$USR' and owner = '$MGR_NAME';"`
if [ "$IS_USER_BELONG_TO_MGR" -eq 0 ]; then
echo "(Error 3) This user does not belongs to the sender mobile / manager / $MGR_NAME $SMS_SENDER_NO !"
#exit 1
else
echo "$USR - Account found in DB & it belongss to $MGR_NAME! (Manager)"
fi

# Check if user is enabled or disabled in radius
IS_USER_ENABLED_OR_DISABLED=`rmauth 127.0.0.1 $USR 1 | grep -i -c "Invalid service reference!"`
if [ "$IS_USER_ENABLED_OR_DISABLED" -eq 1 ]; then
echo "(Error 4) Your account is disabled by Admin!"
exit 1
fi

# VARIABLES
TODAY=$(date +"%Y-%m-%d")
TODAYDIGIT=`echo $TODAY | sed -e 's/-//g'`
MONTH=$(date +"-%m")
CMONTH=`echo $MONTH | sed -e 's/-//g'`
CURR_MONTHYEAR=$(date +"%Y-%m")
MONTHYEAR=$(date +"%B-%Y")
ALPHAMONTHYEAR=`echo $MONTHYEAR`
SRVID=`$CMD "use $DB; SELECT srvid from rm_users where username = '$USR';"`
SRV_PRICE=`$CMD "use $DB; SELECT unitprice FROM rm_services WHERE srvid = $SRVID;"`
SRV_EXPIRY_YES_OR_NO=`$CMD "use $DB; SELECT limitexpiration FROM rm_services WHERE srvid = '$SRVID';"`
SRV_EXPIRY_UNIT_IS_MONTH_OR_DAYS=`$CMD "use $DB; SELECT timebaseexp FROM rm_services WHERE srvid = '$SRVID';"`
SRV_EXPIRY_UNIT=`$CMD "use $DB; SELECT timeunitexp FROM rm_services WHERE srvid = '$SRVID';"`
SRV_EXPIRY_RESET_OR_ADD_MODE_FROM_SRV=`$CMD "use $DB; SELECT timeaddmodeexp FROM rm_services WHERE srvid = '$SRVID';"`
USER_EXPIRY_DATE=`$CMD "use $DB; SELECT expiration FROM rm_users WHERE username = '$USR';" | awk '{print $1}'`
SRV_QUOTA_LIMIT_YES_OR_NO=`$CMD "use $DB; SELECT timeunitexp FROM rm_services WHERE srvid = '$SRVID';"`
SRV_QUOTA_LIMIT_IN_MB=`$CMD "use $DB; SELECT trafficunitcomb FROM rm_services where srvid = '$SRVID';"`
SRV_QUOTA_LIMIT_IN_BYTES=`echo "($SRV_QUOTA_LIMIT_IN_MB)*(1024)*(1024)" |bc`
SRV_QUOTA_RESET_OR_ADD_MODE_FROM_SRV=`$CMD "use $DB; SELECT trafficaddmode FROM rm_services WHERE srvid = '$SRVID';"`
SRV_PRICE_VAT=`$CMD "use $DB; SELECT vatpercent FROM rm_settings;"`

if [ "$SRV_PRICE_VAT" != "0.00" ]; then
SRV_PRICE_W_TAXES=`echo "$SRV_PRICE*$SRV_PRICE_VAT/100+$SRV_PRICE" |bc -l`
SRV_PRICE=`echo $SRV_PRICE_W_TAXES`
#echo $SRV_PRICE show price w tax
fi

PKGNAME=`$CMD "use $DB; SELECT srvname FROM rm_services WHERE srvid = '$SRVID';"`
QUOTA_LIMIT_YES_OR_NO=`$CMD "use $DB; SELECT limitcomb FROM rm_services WHERE srvid = '$SRVID';"`
MGR_NEGATIVE_BALANCE_ALLOWED_YES_OR_NO=`$CMD "use $DB; SELECT perm_negbalance from rm_managers where managername = '$MGR_NAME';"`
IS_DATE_EXPIRED=""

#if [ "$QUOTA_LIMIT_YES_OR_NO" -eq 1 ]; then
#USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL="1"
#fi

echo "Service Name = $PKGNAME"
if [ "$MGR_NEGATIVE_BALANCE_ALLOWED_YES_OR_NO" -eq 0 ]; then
MGR_CURRENT_BALANCE=`$CMD "use $DB; SELECT balance from rm_managers where managername = '$MGR_NAME';"`
echo "Manager Current balance = $MGR_CURRENT_BALANCE" > /dev/null
if (( $(echo "$MGR_CURRENT_BALANCE < $SRV_PRICE" | bc -l) )); then
echo "(Error 5) Not enough balance in your account to renew this account!"
exit 1
fi
fi

if [ "$SRV_PRICE" == "0.000000" ]; then
echo "Service Price = n/a"
else
echo "Service Price = $SRV_PRICE $CURRENCY"
fi

if [ "$SRV_EXPIRY_UNIT_IS_MONTH_OR_DAYS" -eq 3 ]; then
SRV_EXPIRY_UNIT_N_DAYS_FINAL=`echo "($SRV_EXPIRY_UNIT)*(30)" |bc`
fi

if [ "$SRV_EXPIRY_UNIT_IS_MONTH_OR_DAYS" -eq 2 ]; then
SRV_EXPIRY_UNIT_N_DAYS_FINAL="$SRV_EXPIRY_UNIT"
fi

if [ "$SRV_EXPIRY_YES_OR_NO" -eq 0 ]; then
echo "Service Date Expiration Limit = Unlimited"
fi

if [ "$SRV_EXPIRY_YES_OR_NO" -eq 1 ]; then
echo "Service Date Expiration Limit = Yes"
fi

# Check if user have QUOTA and EXPIRATION limit or NOT
if [ "$SRV_EXPIRY_YES_OR_NO" -eq 0 ]; then
if [ "$QUOTA_LIMIT_YES_OR_NO" -eq 0 ]; then
echo "This account type have no Quota/Expiration limit, So no need to take any action! *******"
exit 1
fi
fi

if [ "$SRV_EXPIRY_YES_OR_NO" -eq 1 ]; then
if [[ "$USER_EXPIRY_DATE" = "$TODAY" ]] ; then
USER_NEXT_EXPIRY_DATE_FROM_TODAY_TO_NEXT_EXPIRY_VALUE=`date -d "$TODAY +$SRV_EXPIRY_UNIT_N_DAYS_FINAL days" '+%F'`
# ADD DAYS VALUE TO TODAY EXPIRED USER
echo "User Account Date found expired TODAY *************** "
$CMD "use $DB; UPDATE rm_users SET expiration = '$USER_NEXT_EXPIRY_DATE_FROM_TODAY_TO_NEXT_EXPIRY_VALUE' WHERE username = '$USR';"
IS_DATE_EXPIRED="1"
fi
fi

if [ "$SRV_EXPIRY_YES_OR_NO" -eq 1 ]; then
if [[ "$USER_EXPIRY_DATE"  "$TODAY" ]] ; then
# Expiry limit yes and account nto expired , then check for reset or add mode for date addition
if [ "$SRV_EXPIRY_RESET_OR_ADD_MODE_FROM_SRV" -eq 2 ]; then
USER_NEXT_EXPIRY_DATE_PROLONG_VALUE=`date -d "$USER_EXPIRY_DATE +$SRV_EXPIRY_UNIT_N_DAYS_FINAL days" '+%F'`
echo "User Account Date NOT expired"
echo "Using Date prolong mode *************"
echo "Current Service expiration is = $USER_EXPIRY_DATE (YYYY-MM-DD)"
echo "Next Expiration after renewal will be = $USER_NEXT_EXPIRY_DATE_PROLONG_VALUE (YYYY-MM-DD)"
echo "Days Addition = $SRV_EXPIRY_UNIT_N_DAYS_FINAL (Days)"
# ADD DAYS VALUE TO NON-EXPIRED BY DATE USER ACCOUNT
$CMD "use $DB; UPDATE rm_users SET expiration = '$USER_NEXT_EXPIRY_DATE_PROLONG_VALUE' WHERE username = '$USR';"
IS_DATE_EXPIRED="0"
else
USER_NEXT_EXPIRY_DATE_FROM_TODAY_TO_NEXT_EXPIRY_VALUE=`date -d "$TODAY +$SRV_EXPIRY_UNIT_N_DAYS_FINAL days" '+%F'`
$CMD "use $DB; UPDATE rm_users SET expiration = '$USER_NEXT_EXPIRY_DATE_FROM_TODAY_TO_NEXT_EXPIRY_VALUE' WHERE username = '$USR';"
IS_DATE_EXPIRED="0"
fi
fi
fi
# Check QUOTA value if quota is enforced
if [ "$QUOTA_LIMIT_YES_OR_NO" -eq 1 ]; then
SRV_QUOTA_LIMIT_IN_HUMAN_FRIENDLY_VALUE=`bytesToHuman $SRV_QUOTA_LIMIT_IN_BYTES`
echo "Service Quota Limit: $SRV_QUOTA_LIMIT_IN_HUMAN_FRIENDLY_VALUE"
else
echo "Service Quota Limit: Unlimited"
fi

# *ZAIB
if [ "$QUOTA_LIMIT_YES_OR_NO" -eq 1 ]; then
# Allah shuker - zaib
RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE=`$CMD "use $DB; SELECT SQL_CALC_FOUND_ROWS IF (limitdl = 1, downlimit - COALESCE((SELECT SUM(acctoutputoctets) FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(dlbytes), 0) FROM rm_radacct WHERE rm_radacct.username = tmp.username), 0), 0), IF (limitul = 1, uplimit - COALESCE((SELECT SUM(acctinputoctets) FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(ulbytes), 0) FROM rm_radacct WHERE rm_radacct.username = tmp.username), 0), 0), IF (limitcomb =1, comblimit - COALESCE((SELECT SUM(acctinputoctets + acctoutputoctets) FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(ulbytes + dlbytes), 0) FROM rm_radacct WHERE rm_radacct.username = tmp.username), 0), 0), IF (limituptime = 1, uptimelimit - COALESCE((SELECT SUM(acctsessiontime) FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(acctsessiontime), 0) FROM rm_radacct WHERE rm_radacct.username = tmp.username), 0), 0) FROM ( SELECT username, firstname, lastname, address, city, zip, country, state, phone, mobile, email, company, taxid, rm_users.srvid, rm_users.downlimit, rm_users.uplimit, rm_users.comblimit, rm_users.expiration, rm_users.uptimelimit, credits, comment, enableuser, staticipcpe, staticipcm, ipmodecpe, ipmodecm, srvname, limitdl, limitul, limitcomb, limitexpiration, limituptime, createdon, verifycode, verified, selfreg, acctype, maccm, mac, groupid, contractid, contractvalid, rm_users.owner, srvtype, lastlogoff FROM rm_users JOIN rm_services USING (srvid) ORDER BY username ASC ) AS tmp WHERE 1 AND username LIKE '$USR%' AND (tmp.acctype = '0' OR tmp.acctype = '1' OR tmp.acctype = '2' OR tmp.acctype = '3' OR tmp.acctype = '4' OR tmp.acctype = '5' ) LIMIT 0, 50;" | awk '{print $3}'`
RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE_IN_HUMAN_FRIENDLY_FORMAT=`bytesToHuman $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE`
IS_QUOTA_LEFT_IN_NEGATIVE=`echo $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE_IN_HUMAN_FRIENDLY_FORMAT | grep -i -c "-"`
RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_NEGATIVE_VALUE_IN_BYTES_WITHOUT_DASH=`echo $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE_IN_HUMAN_FRIENDLY_FORMAT |sed 's/[\._-]//g'`
RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_NEGATIVE_VALUE_IN_HUMAN_FRIENDLY_VALUE=`bytesToHuman $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_NEGATIVE_VALUE_IN_BYTES_WITHOUT_DASH`
USER_UP_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE=`$CMD "use radius; SELECT (SELECT SUM(acctoutputoctets) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(dlbytes), 0) FROM rm_radacct WHERE username = '$USR'), (SELECT SUM(acctinputoctets) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(ulbytes), 0) FROM rm_radacct WHERE username = '$USR'), (SELECT SUM(acctsessiontime) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(acctsessiontime), 0) FROM rm_radacct WHERE username = '$USR');" | awk '{print $1}'`
if [ "$USER_UP_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE" == "NULL" ]; then
USER_UP_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE="1"
fi
if [ "$USER_DOWN_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE" == "NULL" ]; then
USER_DOWN_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE="1"
fi
USER_DOWN_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE=`$CMD "use radius; SELECT (SELECT SUM(acctoutputoctets) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(dlbytes), 0) FROM rm_radacct WHERE username = '$USR'), (SELECT SUM(acctinputoctets) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(ulbytes), 0) FROM rm_radacct WHERE username = '$USR'), (SELECT SUM(acctsessiontime) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(acctsessiontime), 0) FROM rm_radacct WHERE username = '$USR');" | awk '{print $2}'`
if [ "$USER_DOWN_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE" == "NULL" ] || [ "$USER_UP_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE" == "NULL" ]; then
USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE=1
else
USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE=`echo "$USER_UP_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE+$USER_DOWN_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE+$SRV_QUOTA_LIMIT_IN_BYTES" |bc -l`
fi
fi

#echo "$IS_QUOTA_LEFT_IN_NEGATIVE ***********************"
if [ -z "$IS_QUOTA_LEFT_IN_NEGATIVE" ]; then
IS_QUOTA_LEFT_IN_NEGATIVE="0"
fi
if [ "$IS_QUOTA_LEFT_IN_NEGATIVE" -eq 1 ]; then
echo "Balance is negative there QUOTA RESET MODE Found: **********************"
echo "Total Current Quota Left (Negative Balance) = - $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_NEGATIVE_VALUE_IN_HUMAN_FRIENDLY_VALUE"
echo "Resetting existing quota with new value = $SRV_QUOTA_LIMIT_IN_MB MB -OR- $SRV_QUOTA_LIMIT_IN_BYTES Bytes"
$CMD "use $DB; UPDATE rm_users SET uplimit = '$USER_UP_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE' WHERE username = '$USR';"
$CMD "use $DB; UPDATE rm_users SET downlimit = '$USER_DOWN_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE' WHERE username = '$USR';"
#USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL=`echo "$USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE+$SRV_QUOTA_LIMIT_IN_BYTES" |bc -l`
USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL="$USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE"
$CMD "use $DB; UPDATE rm_users SET comblimit = '$USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL' WHERE username = '$USR';"
fi

if [ "$IS_QUOTA_LEFT_IN_NEGATIVE" -eq 0 ]; then
echo "QUOTA ADDITION MODE: **********************"
echo "Total Current Quota Left GB = $RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE_IN_HUMAN_FRIENDLY_FORMAT"
if [ "$IS_DATE_EXPIRED" -eq 1 ]; then
echo "Date is expired therefore resetting quota ..."
$CMD "use $DB; UPDATE rm_users SET uplimit = '$USER_UP_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE' WHERE username = '$USR';"
$CMD "use $DB; UPDATE rm_users SET downlimit = '$USER_DOWN_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE' WHERE username = '$USR';"
#USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL=`echo "$USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE+$SRV_QUOTA_LIMIT_IN_BYTES" |bc -l`
USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL="$USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE"
$CMD "use $DB; UPDATE rm_users SET comblimit = '$USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL' WHERE username = '$USR';"
fi
fi

if [ "$IS_QUOTA_LEFT_IN_NEGATIVE" -eq 0 ]; then
if [ "$IS_DATE_EXPIRED" -eq 0 ]; then
if [ "$SRV_QUOTA_RESET_OR_ADD_MODE_FROM_SRV" -eq 1 ]; then
echo "Date is NOT expired therefore adding quota in existing value ..."
echo "Quota Adding in existing value = $SRV_QUOTA_LIMIT_IN_MB MB -OR- $SRV_QUOTA_LIMIT_IN_BYTES Bytes"
USER_COMB_LIMIT=`$CMD "use $DB; SELECT comblimit FROM rm_users WHERE username = '$USR';"`
USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL=`echo "$USER_COMB_LIMIT+$SRV_QUOTA_LIMIT_IN_BYTES" |bc -l`
$CMD "use $DB; UPDATE rm_users SET comblimit = '$USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE_FINAL' WHERE username = '$USR';"
fi
fi
fi

if [ "$IS_QUOTA_LEFT_IN_NEGATIVE" -eq 0 ]; then
if [ "$IS_DATE_EXPIRED" -eq 0 ]; then
if [ "$SRV_QUOTA_RESET_OR_ADD_MODE_FROM_SRV" -eq 0 ]; then
echo "Date is NOT expired AND RESET QUOTA mode found, therefore resetting quota ..."
echo "Quota Adding in existing value = $SRV_QUOTA_LIMIT_IN_MB MB -OR- $SRV_QUOTA_LIMIT_IN_BYTES Bytes"
$CMD "use $DB; UPDATE rm_users SET uplimit = '$USER_UP_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE' WHERE username = '$USR';"
$CMD "use $DB; UPDATE rm_users SET downlimit = '$USER_DOWN_LIMIT_VALUE_FOR_UPDATE_IN_RMUSERS_TABLE' WHERE username = '$USR';"
$CMD "use $DB; UPDATE rm_users SET comblimit = '$USER_COMB_LIMIT_VALUE_FOR_RMUSERS_TABLE' WHERE username = '$USR';"
fi
fi
fi

# ADD SYSLOG ENTRY
$CMD "use radius; INSERT INTO rm_syslog (datetime, ip, name, eventid, data1) VALUES (NOW(), '$SMS_SENDER_NO', '$MGR_NAME', 'Account Renewal', 'User $USR renewal by SMS by $MGR_NAME');"
# UPDATE User Balance
if [ "$MGR_NEGATIVE_BALANCE_ALLOWED_YES_OR_NO" -eq 1 ]; then
echo "Manager Negative Balance Allowed = Yes/Unlimited"
else
echo "Manager Negative Balance Allowed = No"
fi

IS_MGR_CURRENT_BALANCE_NEGATIVE=`$CMD "use $DB; SELECT balance from rm_managers where managername = '$MGR_NAME';" | grep -i -c "-"`
if [ "$IS_MGR_CURRENT_BALANCE_NEGATIVE" -eq 1 ]; then
MGR_CURRENT_BALANCE=`$CMD "use $DB; SELECT balance from rm_managers where managername = '$MGR_NAME';" | sed -e 's/-//g'`
MGR_UPDATED_BALANCE=`echo "$MGR_CURRENT_BALANCE+$SRV_PRICE"|bc -l`
echo "Manager current balance before renewal = -$MGR_CURRENT_BALANCE"
echo "Manager current balance after this renewal = -$MGR_UPDATED_BALANCE"
$CMD "use $DB; UPDATE rm_managers set balance = '-$MGR_UPDATED_BALANCE' where managername = '$MGR_NAME';"
fi

IS_MGR_CURRENT_BALANCE_NEGATIVE=`$CMD "use $DB; SELECT balance from rm_managers where managername = '$MGR_NAME';" | grep -i -c "-"`
if [ "$IS_MGR_CURRENT_BALANCE_NEGATIVE" -eq 0 ]; then
MGR_CURRENT_BALANCE=`$CMD "use $DB; SELECT balance from rm_managers where managername = '$MGR_NAME';"`
MGR_UPDATED_BALANCE=`echo "$MGR_CURRENT_BALANCE-$SRV_PRICE"|bc -l`
echo "Manager current balance before renewal = $MGR_CURRENT_BALANCE"
echo "Manager current balance after this renewal = $MGR_UPDATED_BALANCE"
$CMD "use $DB; UPDATE rm_managers set balance = '$MGR_UPDATED_BALANCE' where managername = '$MGR_NAME';"
fi

# Check if user is ONLINE or not
ONLINE=`$CMD "use $DB; SELECT framedipaddress FROM radacct WHERE acctstoptime IS NULL AND username = '$USR';"`
if [ -z "$ONLINE" ]; then
echo "STATUS = Offline"
else
echo "STATUS = Online / IP: $ONLINE , user should restart his dialer/router"
fi

$CMD "use $DB;INSERT INTO rm_invoices (managername, username, date, bytesdl, bytesul, bytescomb, downlimit, uplimit, comblimit, time, uptimelimit, days, expiration, capdl, capul, captotal, captime, capdate, service, comment, transid, amount, invnum,
address, city, zip, country, state, fullname, taxid, paymentopt, paymode, invtype, paid, price, tax, remark, balance, gwtransid, phone, mobile, vatpercent )
VALUES
('$MGR_NAME', '$USR', NOW(), '0', '0', '$SRV_QUOTA_LIMIT_IN_BYTES', '0', '0', '$RM_CMD_FOR_USER_ACTUAL_LIVE_QUOTA_VALUE', '0', '0', '$SRV_EXPIRY_UNIT_N_DAYS_FINAL', '$USER_NEXT_EXPIRY_DATE_PROLONG_VALUE', '0', '0',
'1', '0', '1', '$PKGNAME', '', '$DATE', '1', '$DATE', '', '', '', '', '', 'FIRSTNAME', '', DATE_ADD(CURDATE(), INTERVAL '10' DAY), '0', '0', '$TODAY', '$SRV_PRICE', '0.000000', '', '0.00', '', '', '', '0.00' );"

echo "$FOOTER"
# THE END SCRIPT ENDS HERE # SYED JAHANZAIB


z@iB

FREERADIUS WITH MIKROTIK – Part #17 -Retrieve User Password via SMS

$
0
0

password_en

FREERADIUS WITH MIKROTIK – Part #1 – General Tip’s Click here to read more on FR tutorials …


Disclaimer! This is important!

Every Network is different , so one solution cannot be applied to all. Therefore try to understand the logic & create your own solution as per your network scenario. Just dont follow copy paste.

If anybody here thinks I am an expert on this stuff, I am NOT certified in anything Mikrotik/Cisco/Linux or Windows. However I have worked with some core networks and I read , research & try stuff all of the time. So I am not speaking/posting about stuff I am formerly trained in, I pretty much go with experience and what I have learned on my own. And , If I don’t know something then I read & learn all about it.

So , please don’t hold me/my-postings to be always 100 percent correct. I make mistakes just like everybody else. However – I do my best, learn from my mistakes and always try to help others.

Regard's
Syed Jahanzaib~

Scenario:

We have a FREERADIUS server configured as AAA for local ppp users. All accounts username name/passwords are added in RADCHECK table as per Freeradius default scheme. Passwords are stored as Cleartext-Password As showed in the image below …

fr cleartext password in radcheck.JPG

We also have playSMS configured to facilitate various SMS base functions including user information , renewal, kicking etc with various controls and checks.


Requirements:

IF user sends sms to our billing system (to playsms server) with specific keywords like

forgotpass USERNAME

then the system should perform various checks like

  • Compare the sender number with the mobile number associate with USERNAME,
  • Check account status like IF account is active or expired either by date or quota or uptime,
  • If all replies are clear, then retrieve password from radcheck value, and send back to user as return reply.

in this example I am using dmasoftlab RADIUS Manager which provides its own builtin tool like `RMAUTH` which we will be using for some controls verification. Although DMA do provides its own method to retrieve password, but regardless of it, we are sharing idea which can be used to perform other functions as well too.

This is just for example purposes only, you can add remove your own controls.

Build your own solution, Sky is the only limit !

creativity-is-intelligence-having-fun-600x315.jpg

 


Bash Script ! forgotpass.sh

#!/bin/bash
#set -x
DATE=$(date '+%Y-%m-%d__%H-%M-%S')
# MYSQL USER NAME AND PASSWORD Variables
SQLUSER="root"
SQLPASS="SQLROOTPASS
SQLHOST="localhost"
SQLPORT="3306"
DB="radius"
export MYSQL_PWD=$SQLPASS
CURRENCY="PKR"
CMD="mysql -u$SQLUSER -p$SQLPASS -h$SQLHOST --port=$SQLPORT --skip-column-names -e"
RMAUTH=`/usr/local/bin/rmauth`

FOOTER="Powered by Syed Jahanzaib"
TMP="/tmp/forgotpass_incoming_sms__$DATE.sms"
> $TMP

# Strip user name and card number separate oterhwise playsms will treat both variables as one
echo $1 $2 > $TMP
USR=`cat $TMP | awk '{print $1}'`
SENDER_MOBILE=`cat $TMP | awk '{print $2}'`

# Check User variable if supplied or not
if [ -z "$USR" ]; then
echo "Username not supplied!"
exit 1
fi
# Check Mobile if supplied or not,
if [ -z "$SENDER_MOBILE" ]; then
echo "Mobile Number not supplied!"
exit 1
fi

#Check if user is in DB or not
IS_USER_VARIABLE_VALID=`$CMD "use $DB; SELECT username FROM rm_users WHERE username = '$USR';"`
if [ -z "$IS_USER_VARIABLE_VALID" ]; then
echo "Username not Found in the System!"
exit 1
fi

# Verify mobile number with sender number
USER_MOB_IN_DB=`$CMD "use $DB; SELECT mobile FROM rm_users WHERE username = '$USR'";`
if [ "$SENDER_MOBILE" != "$USER_MOB_IN_DB" ]; then
echo "Sender Mobile Number could not be verified with $USR account!"
exit 1
fi

IS_USER_ACTIVE=`/usr/local/bin/rmauth 127.0.0.1 $USR 1 |grep -c "Total traffic limit reached!"`
if [ "$IS_USER_ACTIVE" -eq 1 ];then
echo "Account quota limit have finished , please recharge it first!"
exit 1
fi

IS_USER_ACTIVE=`/usr/local/bin/rmauth 127.0.0.1 $USR 1 |grep -c "expired!"`
if [ "$IS_USER_ACTIVE" -eq 1 ];then
echo "Your account have expired , please recharge it first!"
exit 1
fi

#$CMD "use $DB; UPDATE rm_users SET password = MD5('$SENDER_MOBILE') WHERE username = '$USR';"
CUR_PASS=`$CMD "use $DB; select value from radcheck where attribute = 'Cleartext-Password' and username = '$USR';"`
echo "Your Password is = $CUR_PASS

$FOOTER"

* playSMS Command Setting

Copy the forgotpass.sh script in /var/lib/playsms/sms_command/1/ folder, then add command in playsms As showed in the image below …

PLAYSMS SETTING FOR FORGOT COMAMND.JPG


* RESULT:

pass forgoto result.jpg

(Note: Password is different as showed in the RADCHECK, ignore it, as it was changed later)


* PLAYSMS_LOGS


127.0.0.1 localhost 2018-07-17 16:34:38 PID5b4dd44e3d47b - L2 kannel__call # start load:/var/www/playsms/plugin/gateway/kannel/geturl.php
127.0.0.1 localhost 2018-07-17 16:34:38 PID5b4dd44e3d47b - L3 kannel__incoming # remote_addr:127.0.0.1 remote_host:localhost t:[2018-07-17 18:34:23] q:[+923333021909] a:[Forgotpass zaib] Q:[13013] smsc:[] smsc:[]
127.0.0.1 localhost 2018-07-17 16:34:38 PID5b4dd44e3d47b - L3 recvsms # isrecvsmsd:1 dt:2018-07-17 18:34:23 sender:+923333021909 m:Forgotpass zaib receiver:13013 smsc:
127.0.0.1 localhost 2018-07-17 16:34:38 PID5b4dd44e3d47b - L2 kannel__call # end load geturl
- - 2018-07-17 16:34:38 PID5b4019f3e7183 admin L3 recvsmsd # id:7861 dt:2018-07-17 18:34:23 sender:+923333021909 m:Forgotpass zaib receiver:13013 smsc:
- - 2018-07-17 16:34:38 PID5b4019f3e7183 admin L3 recvsms_process # dt:2018-07-17 18:34:23 sender:+923333021909 m:Forgotpass zaib receiver:13013 smsc:
- - 2018-07-17 16:34:38 PID5b4019f3e7183 admin L3 gateway_decide_smsc # SMSC supplied:[] configured:[] decided smsc:[]
- - 2018-07-17 16:34:38 PID5b4019f3e7183 admin L3 sms__command # command_exec:/var/lib/playsms/sms_command/1/forgotpass.sh 'zaib' '+923333021909'
- - 2018-07-17 16:34:38 PID5b4019f3e7183 admin L3 sms__command # command_output:Your Password is = mypass123 Powered by Syed Jahanzaib

 

Advertisements

FREERADIUS WITH MIKROTIK – Part #18 – MAC Login for Hotspot Users

$
0
0

FREERADIUS WITH MIKROTIK – Part #1 – General Tip’s Click here to read more on FR tutorials …


Disclaimer! This is important!

Every Network is different , so one solution cannot be applied to all. Therefore try to understand the logic & create your own solution as per your network scenario. Just dont follow copy paste.

If anybody here thinks I am an expert on this stuff, I am NOT certified in anything Mikrotik/Cisco/Linux or Windows. However I have worked with some core networks and I read , research & try stuff all of the time. So I am not speaking/posting about stuff I am formerly trained in, I pretty much go with experience and what I have learned on my own. And , If I don’t know something then I read & learn all about it.

So , please don’t hold me/my-postings to be always 100 percent correct. I make mistakes just like everybody else. However – I do my best, learn from my mistakes and always try to help others.

~ FreeRADIUS is a Dark Art ~

Regard's
Syed Jahanzaib~

Scenario:

We have a Mikrotik routerboard working as a HOTSPOT server for local guests. Freeradius is configured as billing system.

Requirements:

We want to allow user auto login by his mac address. We can do this in mikrotik itself by using bypassed but we want to authenticate user by billing system so his usage, expiry, package etc should be determined by Freeradius according to his assigned package !


Solution:

We assume that hotspot is already in working condition along with freeradius ,

Please note that this is just an example, in real production environment you should consider more better approach with safety controls. I personally never recommend HOTSPOT dueto its security weaknesses.

 

1# Mikrotik Side Configuration

 

  • Goto IP > HOTSPOT > SERVER PROFILE
  • Select working profile,
  • Goto LOGIN, & select LOGIN BY MAC, In MAC AUTH. MODE ,
  • Also select MAC AS USERNAME AND PASSWORD


2# FREERADIUS POST-AUTH Configuration

Edit `/etc/freeradius/sites-enabled/default` file

nano /etc/freeradius/sites-enabled/default

Goto `post-auth` section, & add following sql Query,

[as an example i am pasting full post-auth section]

### ZAIB radpost-auth section Starts from here ##
post-auth {
exec
Post-Auth-Type REJECT {
update reply {
Reply-Message = 'Wrong Password'
}

# This is our query to check if MAC address found in username section, you can make your own table , zaib

sql
if("%{sql:SELECT COUNT(username) FROM users WHERE username ='%{User-Name}'}" > 0){
ok
}
else{
reject
}

attr_filter.access_reject
}
}
### ZAIB radpost-auth section ENDS Here ##

Insert USER record in RADCHECK & USERS TABLE

[you can modify following section or above sql query to match your need,

Login to MYSQL and select RADIUS DB,

Now insert a Test user in USERS & RADCHECK table (replace mac address with your own test device mac address]

INSERT INTO 'radcheck' ('id', 'username', 'attribute', 'op', 'value') VALUES
(1, '2C:44:FD:68:C0:18', 'Cleartext-Password', ':=', '2C:44:FD:68:C0:18');

INSERT INTO 'users' ('id', 'username', 'password', 'firstname', 'lastname', 'email', 'mobile', 'cnic', 'srvname', 'srvid', 'expiration', 'mac', 'macvendor', 'bwpkg', 'pool', 'is_enabled', 'is_days_expired', 'is_qt_expired', 'is_uptime_expired', 'qt_total', 'qt_used', 'uptime_limit', 'uptime_used', 'owner', 'vlanid', 'nas_id', 'createdon') VALUES
(1, '2C:44:FD:68:C0:18', '2C:44:FD:68:C0:18', 'firstname', 'lastname', 'aacable@hotmail.com', '345345345', '242342420424-42-2', '2mb', 0, '2017-01-06', '2C:44:FD:68:C0:18', 'Hewlett Packard', '2048k/2048k', 'private-pool', 1, 1, 0, 0, '200', '12121613', '', '', 'zaib', '', NULL, '2018-07-24 05:30:21');


Test Ride …

Now connect your test device and you will see something like

in Freeradius DEBUG, we will be seeing …

rad_recv: Access-Request packet from host 101.11.50.50 port 40624, id=58, length=218
NAS-Port-Type = Ethernet
Calling-Station-Id = "2C:44:FD:68:C0:18"
Called-Station-Id = "hotspot1"
NAS-Port-Id = "ether10-lan"
User-Name = "2C:44:FD:68:C0:18"
NAS-Port = 2159017996
Acct-Session-Id = "80b0000c"
Framed-IP-Address = 192.168.88.2
Mikrotik-Host-IP = 192.168.88.2
User-Password = "2C:44:FD:68:C0:18"
Service-Type = Login-User
WISPr-Logoff-URL = "http://192.168.88.1/logout"
NAS-Identifier = "XYZ_RB3011_TEST"
NAS-IP-Address = 101.11.50.50
# Executing section authorize from file /etc/freeradius/sites-enabled/default
+group authorize {
[sql] expand: %{User-Name} -> 2C:44:FD:68:C0:18
[sql] sql_set_user escaped user --> '2C:44:FD:68:C0:18'
rlm_sql (sql): Reserving sql socket id: 30
[sql] expand: SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radcheck WHERE username = '2C:44:FD:68:C0:18' ORDER BY id
[sql] User found in radcheck table
[sql] expand: SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radreply WHERE username = '2C:44:FD:68:C0:18' ORDER BY id
[sql] expand: SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username = '2C:44:FD:68:C0:18' ORDER BY priority
rlm_sql (sql): Released sql socket id: 30
++[sql] = ok
++? if (notfound)
? Evaluating (notfound) -> FALSE
++? if (notfound) -> FALSE
++[preprocess] = ok
++[chap] = noop
++[mschap] = noop
++[digest] = noop
++[logintime] = noop
++? if (reject)
? Evaluating (reject) -> FALSE
++? if (reject) -> FALSE
++[expiration] = noop
++? if (userlock)
? Evaluating (userlock) -> FALSE
++? if (userlock) -> FALSE
+} # group authorize = ok
WARNING: Please update your configuration, and remove 'Auth-Type = Local'
WARNING: Use the PAP or CHAP modules instead.
User-Password in the request is correct.
# Executing section post-auth from file /etc/freeradius/sites-enabled/default
+group post-auth {
++[exec] = noop
+} # group post-auth = noop
Sending Access-Accept of id 58 to 101.11.50.50 port 40624
Finished request 0.
Going to the next request
Waking up in 4.9 seconds.


Regard’s
Syed Jahanzaib


FREERADIUS WITH MIKROTIK – Part #19 – Restricting user by Service Type

$
0
0

passport-control-3033049_960_720


FREERADIUS WITH MIKROTIK – Part #1 – General Tip’s Click here to read more on FR tutorials …


Disclaimer! This is important!

Every Network is different , so one solution cannot be applied to all. Therefore try to understand the logic & create your own solution as per your network scenario. Just dont follow copy paste.

If anybody here thinks I am an expert on this stuff, I am NOT certified in anything Mikrotik/Cisco/Linux or Windows. However I have worked with some core networks and I read , research & try stuff all of the time. So I am not speaking/posting about stuff I am formerly trained in, I pretty much go with experience and what I have learned on my own. And , If I don’t know something then I read & learn all about it.

So , please don’t hold me/my-postings to be always 100 percent correct. I make mistakes just like everybody else. However – I do my best, learn from my mistakes and always try to help others.

~ FreeRADIUS is a Dark Art ~

Regard's
Syed Jahanzaib~

Scenario:

We have a Mikrotik routerboard working as a HOTSPOT & PPPoE server for local users. Freeradius is configured as billing system.

Requirements:

We want to restrict users connection based on there service type.

Example

  1. User1 is allowed to connect from PPPoE Dialer Only,
  2. User2 is allowed to connect from HOTSPOT web login only,

Since we have our own freeradius build setup which has USERS table with various columns therefore we will manipulate this table and use the SQL famous IF statements in the AUTHORIZE section to fulfill our requirements.

the USERS table contains various information for users, Sample is attached below ,

srvtype.JPG

We will be using two columns to match user connection verification,

  1. SRVTYPE
  2. SRVTYPE_DESCR
  • SRVTYPE variable will be used to match if the requesting user have correct service type
  • if NOT matched then show SRVTYPE_DESCR variable which is actually a friendly version for display purpose in REPLY attribute 🙂

1# FREERADIUS AUTHORIZE Section Configuration

Edit `/etc/freeradius/sites-enabled/default` file

nano /etc/freeradius/sites-enabled/default

Use the following in AUTHORIZE section ,

if ("%{sql: select srvtype from users where username = '%{User-Name}'}" != "%{Service-Type}") {
update reply {
Reply-Message = "Error: %{User-Name} is allowed to connect from %{sql:SELECT srvtype_descr from users where username = '%{User-Name}';} only!"
}
update control {
Auth-Type := "Reject"
}
}

Test Ride …

From Hotspot ID, try to dial via pppoe dialer,

Sending Access-Reject of id 150 to 101.11.50.50 port 51555
Reply-Message = "Error: 2C:44:FD:68:C0:18 is allowed to connect from Hotspot only!"

Now using PPPOE account, try to login via hotspot login page,

Sending Access-Reject of id 145 to 101.11.50.50 port 52841
Reply-Message = "Error: test is allowed to connect from PPP Dialer only!"

ppp failed for hotspot id.JPG


 

Windows Server 2016 – Reference Notes

$
0
0

.


1- Start Button Doesn’t Works !

When you click on Start button, it doesn’t popup.

  • Press Windows+RUN , and type
ms-settings:personalization-start

Uncheck following two options,

  1. Show more tiles
  2. Use start full screen

 

win2016 start button not working.JPG

That’s it !


2- Show icons on Desktop

Right click on Desktop

Select Personalize

Select Themes

On Right Window, Click on Desktop Icon Settings

allow desktop icons on desktop.JPG

If you receive following error

error on desktop icon setting.JPG

then you have to enable following setting in Domain controller default group policy policy, reboot client to take changes immediately or gpupdate /force

policy for runddl32 exec error.JPG


 

WSUS 2016 – Short Notes

$
0
0

wsus-portfolio-1200x500

Recently we upgraded our infrastructure from windows 2003/2008 to 2016 servers. We have 2 DC’s on 2003/2008 and migrated them to 2016, afterwards when we added WSUS, it had many issues and it took almost 8-10 days to sort every thing. the reason why it took so many time that I tried my best NOT to re install the windows server again because this server was activated with valid license and we had limited license count on MS portal. Fixing messed up windows is far more time take taken process but yes you learn lot of new things in fixing old one, even if its not able to sort out.

I am adding few of the most annoying issues and there methods to sort them in this post. I will keep posting more.


1# Remove WSUS completely from 2016 Server

Sometimes when all sort of troubleshooting fails to restore WSUS, its better to install Fresh Windows, and add WSUS again. But in my case, this server was hosting WDS also & I really didn’t wanted to re install server OS (also to avoid licensing increment count on Microsoft Portal as we have limited license counts).

Following are steps to remove WSUS completely,

  1. Remove WSUS / IIS / Windows Internal Database (WID) Roles, (If you don’t remove the WID role and its files on a reinstall, it will re-attach to the same database)
  2. Reboot the server
  3. Now Remove following Folders
    C:\WSUS (or where ever the WSUSContent folder resides)
    C:\inetpub folder
    C:\Program Files\Update Services
    C:\Windows\WID
    C:\windows\system32\inetsrv  [Or rename this folder]
  4. Restart the server
  5. Re-add the WSUS And WID Roles (It will auto add the IIS role auto)
  6. Let it install, and then restart the Server again.
  7. Launch the WSUS console,

 


2# Post install Fatal Error: WsusPool does not exist

Please check the IIS, check Application Pools, check for WsusPool entry. If it’s not there, Add it manually as showed in the image below …

wsus pool does not exists.JPG

then run post-installation step again.


3# MMC console crashing

In one particular situation, when I added the WSUS role again, I was getting following error whenever I tried to open WSUS console …

wsus crashing.png

Since it was not a real production server, therefore I removed the WSUS (following all steps showed in Point # 1 of this guide, then executed

sfc /scannow

afterwards a reboot , & WSUS MMC worked well 🙂


4# Identify & approved required updates only

For good overview, read following

https://www.tecknowledgebase.com/43/how-to-identify-and-decline-superseded-updates-in-wsus/

.

SystemState Backup failing under Windows Server 2016

$
0
0

We recently migrated our domain controller to Windows server 2016 edition. the DC is virtualized under vmware esxi 6.5 with vmware tools ver 10.1.x. I have schedule systemstate backup by using wbadmin command line tool. Example:

wbadmin start systemstatebackup -backuptarget:d: -quiet

After migration to 2016, I observed following error …

Error in backup of C:\windows\\systemroot\ during enumerate: Error [0x8007007b] The filename, directory name, or volume label syntax is incorrect.

After some searching , we found that this error is related to vmware tools version 10.1.x which sets incorrect path for some driver location.

To exactly find what file is causing, use following

  • Open command prompt [Run as Administrator] , type below and press ENTER.
DiskShadow /L writers.txt
  • The prompt will point to DISKSHADOW>
  • Now Type
list writers detailed

and press ENTER

  • After a while, this will list all of the writers and affected volumes. After completion, EXIT.

Open the writers.txt file in notepad or any text editor, then a search for windows\\ text , it should find the following:

File List: Path = c:\windows\\systemroot\system32\drivers, Filespec = vsock.sys

So the culprit was VSOCK.SYS To sort this we need to correct the path in the windows REGISTRY.

  • Run REGEDIT , then navigate to

HKLM\SYSTEM\CurrentControlSet\Services\vsock

  • Then change the ImagePath value string data from the incorrect
\systemroot\system32\DRIVERS\vsock.sys

to

System32\DRIVERS\vsock.sys

As showed in the image below …

BEFORE …

before

AFTER …

after path change

  • No need to reboot/log off. Simply run the backup again & this time you should see SUCCESSFUL report.

successfull backup after erg modifcation.JPG


 

Regard’s
Syed Jahanzaib

COA with Radclient workaround for RM 4.1 with Mikrotik 6.4x.x

$
0
0

dealing-with-dynamic-change-2

Scenario:

  • Dmasoftlab Radius Manager 4.1 with multiple services. Some of services have dynamic dynamic bandwidth scheduling for day & night. Example some services have double up mode for day , some for evening, and some for night.
  • Mikrotik 6.42.7 server with hotspot or pppoe authentication services for LAN users

Problem:

DMA Radius Manager 4.1 ‘s API functionality is broken for Mikrotikr RouterOS newwer versions. The 4.1 code is relying on modifying dynamic queues which had worked on 5.x version (& in some 6.2x seriesas well e.g: v6.29) . Any circumstances where that was doable were bugs that MikroTik has since fixed. And relying on bugs is generally a bad practice. This can be solved by using CoA instead of modifying dynamic queues which I have used in this post.

It is highly recommended that you must upgrade radius manager to latest 4.2 version which works good with new ROS.


Workaround for RM 4.1:

If for some reasons you want to stick with 4.1 version for whatsoever reason, example 4.2 version have some strict licensing policies, and some other things that we cannot mention here 😉  & still wants to use ROS latest series like 6.42.7 (as of writing this post)  , , & if you still wants to avail dynamic bandwidth changes on the fly for particular services , you can schedule following script which will run on hourly basis and will send bandwidth change request to mikrotik according to the service time.



Limitations of the Script:

  • This is a lab testing version of the script. You must modify and tune it for production use. Example the script is doing lots of sql queries, you can minimize it by creating single combined query to fetch all data from the tables, and then read values in next cmd from local file which will be much faster then querying from Mysql.
  • The service must have single time schedule. example from 0800 to 1800. Multiple times for single service is not supported.
  • Script will run as per cron schedule , despite you have selected specific days or not.
  • In lab I have configured it to run every hour , It will query services and its associated users. If the Start time matches , it will send bandwidth change request to the NAS, and if end time matches it will send user original package values to NAS. You can overcome repeating issue by adding additional column in the respective table and update it every time script runs which will check if it have already sent or not.
  • You should disable echoing the outputs, it will save some resources.

the Script!

#!/bin/bash
# Following script is made specifically for Dmasoftlab radius manager 4.x . It will check "rm_specperbw" table, and if found any servic entry,
# It will query that service and make list of users attached to this service,
# Then it will query next package , start/end time, and will perform actions accordingly
# Syed Jahanzaib
# Created: 6-SEP-2018
# Last Modified: 9-SEP-2019
#set -x
#######################
# CHANGE these
SQLID="root"
SQLPASS="SQLROOTPASS"
NAS_COA_PORT="1700"
######################

# Script starts here
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLID --skip-column-names -s -e"
DB="radius"
#Table which contain main users information
USER_TABLE="rm_users"
SRV_BW_DB="rm_services"
#Table which contains service name id which will be scanned for user and packages
DYN_BW_TABLE="rm_specperbw"
USER_SERVICE_TABLE="rm_services"
# Temp file where services/users list will be saved
TMP1="/tmp/bwsch_srv.txt"
TMP2="/tmp/bwsch_users.txt"
TMP3="/tmp/bwsch_users_final.txt"
> $TMP1
> $TMP2
#DATE TIME FUNCTIONS
currenttime=$(date +%H:%M:%S)
# Look for services that have Dynamic bandwidth change (and remove duplicate entries as well becasue of multipel time definitiosn ins ingle service)
$CMD "use $DB; select srvid from $DYN_BW_TABLE" | sort -u >> $TMP1
TOTSRV=`cat $TMP1 | wc -l`
echo "Total number of services with Dynamic bandwidth enabled = $TOTSRV / No.s"
if [ ! -s $TMP1 ]
then
echo "No SERVICES found to check for bandwdith changing in $DYN_BW_TABLE , exit"
exit 1
fi

# If required service found then look for Users
num=0
cat $TMP1 | while read srvid
do
num=$[$num+1]
SRVID=`echo $srvid |awk '{print $1}'`
$CMD "use $DB; select username from $USER_TABLE where srvid ='$SRVID';" >> $TMP2
done
TOTUSR=`cat $TMP2 | wc -l`
echo "Total number of users with Dynamic bandwidth enabled = $TOTUSR / No.s"

sleep 5
# Remove duplicate users , If any (it was dueto the fact if the service have multiple time defined)
#sort -u $TMP2 > $TMP3
if [ ! -s $TMP2 ]
then
echo "No User found for bandwidth upgrade $DYN_BW_TABLE , exit"
exit 1
fi

# Run loop forumla to run CMD for single or multi usernames
echo "Checking for Dynamic Bandwidth Policies and implemnt change on the fly for online users , if any ..."
num=0
cat $TMP2 | while read users
do
num=$[$num+1]
USERNAME=`echo $users |awk '{print $1}'`
SRVID=`$CMD "use $DB; select srvid from $USER_TABLE where username ='$USERNAME';"`
DN_ST=`$CMD "use $DB; select starttime from $DYN_BW_TABLE where srvid ='$SRVID';" |awk 'FNR == 1'`
DN_ET=`$CMD "use $DB; select endtime from $DYN_BW_TABLE where srvid ='$SRVID';" |awk 'FNR == 1'`
#If time matches
if [[ "$currenttime" > "$DN_ST" ]] && [[ "$currenttime" < "$DN_ET" ]]; then
#######################
##### UP-GRADE SECTION
#######################
# If user is Online UPGRADE its package
ACCTSESID=`$CMD "use $DB; select acctsessionid from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
if [ ! -z "$ACCTSESID" ]; then
NAS_IP=`$CMD "use $DB; select nasipaddress from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
NAS_SECRET=`$CMD "use $DB; select secret from nas where nasname = '$NAS_IP' ;"`
USER_IP=`$CMD "use $DB; select framedipaddress from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
dlrate_c=`$CMD "use $DB; select dlrate from $DYN_BW_TABLE where srvid ='$SRVID';" |awk 'FNR == 1'`
ulrate_c=`$CMD "use $DB; select ulrate from $DYN_BW_TABLE where srvid ='$SRVID';"|awk 'FNR == 1'`
ulrate=$(echo $(( $ulrate_c / 1024 )))k
dlrate=$(echo $(( $dlrate_c / 1024 )))k
DN_BWPKG="$ulrate/$dlrate"
echo "UPGRADE ***** USER - $USERNAME / $USER_IP / $ACCTSESID is online, and eligible for package UPGRAD to new package $DN_BWPKG @ $currenttime ..."
#for pppoe
#echo User-Name=$USERNAME,Acct-Session-Id=$ACCTSESID,Framed-IP-Address=$USER_IP,Mikrotik-Rate-Limit=\"$DN_BWPKG\" | radclient -q -x $NAS_IP:$NAS_COA_PORT coa $NAS_SECRET
#for hotspot
echo Framed-IP-Address=$USER_IP,Mikrotik-Rate-Limit=\"$DN_BWPKG\" | radclient -q -x $NAS_IP:$NAS_COA_PORT coa $NAS_SECRET
#sleep 3
fi
else
#######################
##### DOWNGRADE SECTION
#######################
# If package DOWNgrade time is matched in services & packages have not changed already, then do it now - zaib
ACCTSESID=`$CMD "use $DB; select acctsessionid from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
if [ ! -z "$ACCTSESID" ]; then
NAS_IP=`$CMD "use $DB; select nasipaddress from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
NAS_SECRET=`$CMD "use $DB; select secret from nas where nasname = '$NAS_IP' ;"`
USER_IP=`$CMD "use $DB; select framedipaddress from radacct where username ='$USERNAME' AND acctstoptime is NULL;"`
dlrate_c=`$CMD "use $DB; select downrate from $USER_SERVICE_TABLE where srvid ='$SRVID';" |awk 'FNR == 1'`
ulrate_c=`$CMD "use $DB; select uprate from $USER_SERVICE_TABLE where srvid ='$SRVID';"|awk 'FNR == 1'`
ulrate=$(echo $(( $ulrate_c / 1024 )))k
dlrate=$(echo $(( $dlrate_c / 1024 )))k
DN_BWPKG="$ulrate/$dlrate"
echo "DOWNGRADE ***** USER - $USERNAME / $USER_IP / $ACCTSESID is online, and eligible for package DOWNGRADE to old package $DN_BWPKG @ $currenttime ..."
#for pppoe
#echo User-Name=$USERNAME,Acct-Session-Id=$ACCTSESID,Framed-IP-Address=$USER_IP,Mikrotik-Rate-Limit=\"$DN_BWPKG\" | radclient -q -x $NAS_IP:$NAS_COA_PORT coa $NAS_SECRET
#for hotspot
echo Framed-IP-Address=$USER_IP,Mikrotik-Rate-Limit=\"$DN_BWPKG\" | radclient -q -x $NAS_IP:$NAS_COA_PORT coa $NAS_SECRET
#sleep 3
fi
fi

done
# Script Ends Here
# Syed Jahanzaib

Regard’s
Syed Jahanzaib

 

Viewing all 409 articles
Browse latest View live