Syed Jahanzaib Personal Blog to Share Knowledge !

June 18, 2022

VMWARE – VCSA 7.0 Migration/Cloning

Filed under: VMware Related — Tags: , — Syed Jahanzaib / Pinochio~:) @ 10:30 PM

Moving VCSA 7.0.0 (Build 16189207) from one ESXI host to other ESXI host
(without VMOTION)

 

Recently we added one new esxi server (server02) with some beefy hardware specs including enterprise ssd storage & wanted to move old vcenter hosted to this new esxi host to get benefits of good speed.

Since we donot have shared storage, therefore I used the CLONE method which worked surprisingly accurate without any hurdle.

  • Login to your Vcsa admin panel (https://your-vcsa-ip)
  • Select the vCenter Server virtual machine from the Inventory (source esxi server01 where VCSA is currently installed)
  • Right-click the VCSA virtual machine and click Clone
  • Select the Destination ESXi host server02 (in my case it was new ssd base esxi server), & follow on the instructions

Once the Clone process is done

  • Power off vCenter Server on the source host (server01 old server)
  • Power on the vCenter Server virtual machine on the destination ESXi host (server02 – new esxi server)

VCSA takes some time to start all of its services, Be patience ! (Follow this guide for VCSA Troubleshooting)

Once done, open the VCSA admin panel, & Login.

Alhamdolillah, in my case it was quite straight forward process! your mileage may vary 😀


Backup Note:

Backup is your friend 🙂 Make sure to take regular backups of VCSA using its management panel that is https://your-vcsa-ip:5480/

We take its backup vis windows shared folder using SMB option. you can  use SMB/FTP or other methods of your choice.

When you will click on BACKUP NOW, it will ask you to enter all the details like smb/ftp etc location etc, you need to configure it first !


Regards
Syed Jahanzaib

May 18, 2022

Lenovo SR650 Corrupt GPT & ESXi install failure

Filed under: IBM Related — Tags: , , , , , , , — Syed Jahanzaib / Pinochio~:) @ 12:40 PM

Recently one of our Lenovo SR650’s disk got faulty. It had 14 x 1.2 TB 10k SAS disks. As a long term solution & to avoid any urgency, we decided to remove 2 disks (faulty one for replacement & one for cold spare backup to be used by same or other similar servers).

Once we re-created new Raid.-10 & rebooted the server , boot screen was showing below error

We tried to follow the Lenovo Note which instructed to go into Setup->System Settings->Recovery->Disk GPT Recovery and set to “Automatic.” but still the error didn’t sorted. To settle it on Server Bios level, we performed following steps

  • Update SR650 UEFI Firmware ( Lenovo Download Link )
  • Removed Raid Config, Re-create Raid Config with Full Initialization
  • Full power cycle the server once above is done.

This sorted the Bios screen error regarding GPT.

But once we started the Vmware ESXI 6.5.x installation , it was failing (between 5% and 8%) with the following error …

“partedUtil failed with message: Error: The primary GPT table states that the backup GPT is located beyond the end of disk. This may happen if the disk has shrunk or partition table is corrupted. … Error: Can’t have a partition outside the disk!  BLAH BLAH BLAH …”


Solution # 1

Boot with any windows ISO ( Must have the RAID controller driver or the OS should have in-built drivers, in my case, windows server 2019 had the raid drivers). You can also use Linux base Boot OS .

Re-create the partition , Format & Booom. Afterwards just boot from ESXI ISO/CD/USB/Networkboot , and the ESXI will install fine.


Solution # 2 (Quick & Recommended for admins)

During ESXi installer at anywhere ,

Press Alt-F1 (which will bring you to shell window asking for credentials)

Use following credentials

  • ID: root
  • Password: No password. Just press enter & you can use the CMD’s to sort the issue

Issue the below CMD which will show you list of disk device names that can be managed by partedUtil

ls -ltrh /vmfs/devices/disks

** Note the disk ‘identifier’ that we want to fix. In my case it was 6.5 TB partition in which we wanted to install the esxi.

Now issue the below cmd

partedUtil mklabel /dev/disks/naa.600062b2031e00402a165add7ff9c3ac msdos

This overwrited the brooked partition table. Now return to the installer screen and continue.

This time, esxi installation went fine without errors.


Regard’s
Syed Jahanzaib

February 14, 2022

RM: Auto Renew User if Deposit available

Filed under: Radius Manager — Tags: , , — Syed Jahanzaib / Pinochio~:) @ 11:04 AM

Revision History:

  1. 24-Jun-2015 / Added Base Script
  2. 29-Jun-2016 / Added Invoice function
  3. 14-Feb-2022 / Added multi check for quota related functions


As requested by an Valenzuela / African friends

Scenario:

In radius manager, there are few options to purchase credits via online payment gateways like paypal or others. If the user account is expired and he purchase service online, it adds the deposit into user account but it does not auto renew the service (as per my assumption, as paypal doesn’t works here in pakistan, so i have very little to no knowledge on it).

Example:

err

 

As a workaround, I made below script that can perform following functions ,,,

  1. Scheduled to run after every 5 (or x) minute(s)
  2. Fetch all users who are expired either by Date or Quota
  3. Check if these users have DEPOSIT available (credits above then 0)
  4. Check the current service price and match it with the available deposit/credits
  5. If deposit is not sufficient as per service price, Then print error
  6. If deposit is enough, renew the service , Add Expiration Days (according to the service package)
  7. Reset the QUOTA …
    * if account is fresh, add new quote as per package
    * if account is old and quota is expired, then reset it add new quota as per package
    * if account date is expired but quota is remaining, then add the new quota in existing quota (addictive mode
    * Show user Before / After Quota
    – If user is online show his IP / NAS IP / Time / NAS-IP]if any and sends email/sms to user about the renewal done by deposit : )

We can further add the SMS/EMAIL function in the script as per requirements to let know about the renewal.

Disclaimer: The script can further be customized according to the requirements. No part of this script is copied from anywhere. You are free to use it, modify it as you like [keep the header intact].
This is my own idea Just to share with anyone who is in similar requirements or just for learning purposes !


SCRIPT!

mkdir /temp
touch /temp/auto.sh
chmod +x /temp/auto.sh
nano /temp/auto.sh

& paste following, make sure to change the SQL Password !

#!/bin/bash
#set -x
clear
# Script to renew user account via check deposit and act accordingly
# For Radius Manager 4.1.x
# Created by Syed Jahanzaib
# https://aacable.wordpress.com / aacable@hotmail.com
# 24th Jun, 2016 , 18 Ramazan, 1437 Hijri
# Last modified on 14-Feb-2022
# Colors Config . . . [[ JZ . . . ]]
ESC_SEQ="\x1b["
COL_RESET=$ESC_SEQ"39;49;00m"
COL_RED=$ESC_SEQ"31;01m"
COL_YELLOW=$ESC_SEQ"33;01m"
COL_GREEN=$ESC_SEQ"32;01m"
SQLUSER="root"
SQLPASS="XXXXXXX"
export MYSQL_PWD=$SQLPASS
DB=radius
CMD="mysql -u$SQLUSER --skip-column-names -s -e"
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]}"
}
USERLIST="/tmp/deposituserlist.txt"
> $USERLIST
DATE=`date`
#Create list of users which have deposit more then 0.00 value, means valid deposite
$CMD "use $DB; SELECT SQL_CALC_FOUND_ROWS username, firstname, lastname, address, city, zip, country, state, phone, mobile,
email, company, taxid, srvid, downlimit, uplimit, comblimit, expiration, uptimelimit, credits, comment,
enableuser, staticipcpe, staticipcm, ipmodecpe, ipmodecm, srvname, limitdl, limitul, limitcomb, limitexpiration,
limituptime, createdon, verifycode, verified, selfreg, acctype, maccm, LEFT(lastlogoff, 10)
, 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 (tmp.acctype = '0' OR tmp.acctype = '1' OR tmp.acctype = '2' OR tmp.acctype = '3' OR tmp.acctype = '4' OR tmp.acctype = '5' )
AND tmp.enableuser = 1 AND
(IF (limitdl = 1, downlimit - (SELECT COALESCE(SUM(acctoutputoctets), 0)
FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(dlbytes), 0)
FROM rm_radacct WHERE rm_radacct.username = tmp.username) , 1) <= 0
OR
IF (limitul = 1, uplimit - (SELECT COALESCE(SUM(acctinputoctets), 0)
FROM radacct WHERE radacct.username = tmp.username) - (SELECT COALESCE(SUM(ulbytes), 0)
FROM rm_radacct WHERE rm_radacct.username = tmp.username) , 1) <= 0
OR
IF (limitcomb = 1, comblimit -
(SELECT COALESCE(SUM(acctinputoctets + acctoutputoctets), 0)
FROM radacct WHERE radacct.username = tmp.username) +
(SELECT COALESCE(SUM(ulbytes + dlbytes), 0)
FROM rm_radacct WHERE rm_radacct.username = tmp.username) , 1) <= 0
OR
IF (limituptime = 1, uptimelimit - (SELECT COALESCE(SUM(acctsessiontime), 0)
FROM radacct WHERE radacct.username = tmp.username) + (SELECT COALESCE(SUM(acctsessiontime), 0)
FROM rm_radacct WHERE rm_radacct.username = tmp.username) , 1) <= 0
OR
IF (limitexpiration=1, UNIX_TIMESTAMP(expiration) - UNIX_TIMESTAMP(NOW()), 1) <= 0) LIMIT 0, 50;" | awk '{print $1}' > $USERLIST
TOTUSR=`$CMD "use $DB; select username from rm_users;" | wc -l`
echo "- INFO: Total Users scanned: $TOTUSR

"
#LOOK FOR VALID USER IN FILE, IF EMPTY THEN EXIT
USRVALID=`cat $USERLIST`
if [ -z "$USRVALID" ]; then
echo "INFO: No user found with Expired Date/Quota package ... Exiting peacefully!"
exit 1
fi
# Apply Formula to read the file in which users list and act accordingly.
num=0
cat $USERLIST | while read users
do
num=$[$num+1]
USR=`echo $users | awk '{print $1}'`
DEPOSIT=`$CMD "use radius; SELECT credits FROM rm_users where username = '$USR';" | sed 's/\..*$//'`
###########################################
# ACCOUNT EXPIRY CHECK and other variables#
###########################################
TODAY=$(date +"%Y-%m-%d")
TODAYHM=$(date +"%Y-%m-%d-%H-%M")
TODAYDIGIT=`echo $TODAY | sed -e 's/-//g'`
MONTH=$(date +"-%m")
CMONTH=`echo $MONTH | sed -e 's/-//g'`
MONTHYEAR=$(date +"%B-%Y")
ALPHAMONTHYEAR=`echo $MONTHYEAR #| sed -e 's/-//g'`
CURR_MONTHYEAR=$(date +"%Y-%m")
SRVEXPIRYFULL=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT expiration FROM radius.rm_users WHERE username = '$USR';" |awk 'FNR == 2'`
FULLNAME=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT firstname, lastname FROM radius.rm_users WHERE username = '$USR';" |awk 'FNR == 2'`
MOBILE=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT mobile FROM radius.rm_users WHERE username = '$USR';" |awk 'FNR == 2'`
COUNTRY=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT country FROM radius.rm_users WHERE username = '$USR';" |awk 'FNR == 2'`
STATE=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT state FROM radius.rm_users WHERE username = '$USR';" |awk 'FNR == 2'`
ADDRESS=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT address FROM radius.rm_users WHERE username = '$USR';" |awk 'FNR == 2'`
LOGOFFDATE=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT lastlogoff FROM radius.rm_users WHERE username = '$USR';" |awk 'FNR == 2 {print $1,$2}'`
SRVID=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT srvid FROM radius.rm_users WHERE rm_users.username = '$USR';" |awk 'FNR == 2 {print $1}'`
SRVPRICE=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT unitprice FROM radius.rm_services WHERE rm_services.srvid = $SRVID;" |awk 'FNR == 2 {print $1}' | cut -f1 -d"."`
SRVEXPIRYFULLD=`mysql -u$SQLUSER -p$SQLPASS --skip-column-names -e "use radius; SELECT expiration FROM radius.rm_users WHERE username = '$USR';" |awk '{print $1}' | sed 's/expiration//'`
SRVEXPIRY=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT expiration FROM radius.rm_users WHERE username = '$USR';" |awk 'FNR == 2' | sed -e 's/-//g' | sed 's/00:.*//'`
PKGNAME=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT srvname FROM radius.rm_services WHERE rm_services.srvid = '$SRVID';" |awk 'FNR == 2'`
PKGQUOTA=`mysql -u$SQLUSER -p$SQLPASS -e "use radius; SELECT trafficunitcomb FROM rm_services WHERE srvid= '$SRVID';" |awk 'FNR == 2'`
PKGQUOTAB=$(($PKGQUOTA / 1024))
PKGQUOTABYTES=$(($PKGQUOTA * 1024 * 1024))
USR_CUR_COMBLIMIT=`$CMD "use $DB; SELECT comblimit FROM rm_users WHERE username= '$USR';"`
USR_CUR_COMBLIMIT_HUMAN=`bytesToHuman $USR_CUR_COMBLIMIT`
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'`
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`
RQT=`$CMD "use $DB; SELECT username,
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)
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
FROM rm_users JOIN rm_services USING (srvid) ORDER BY username ASC
) AS tmp
WHERE 1 AND (tmp.acctype = '0' OR tmp.acctype = '1' OR tmp.acctype = '3' OR tmp.acctype = '4')
AND username LIKE '$USR%';" | awk '{print $2}'`
RQT_OUT=`echo $RQT`
RQT_RESULT1=`echo $RQT | grep -i -c "-"`
RQT_RESULT_REMOVE_HYPHEN=`echo $RQT | sed -e 's/-//g'`
#exit 1
RQT4=`bytesToHuman $RQT_RESULT_REMOVE_HYPHEN`
QTL_Y_OR_NO=`$CMD "use $DB; SELECT limitcomb FROM rm_services WHERE srvid = '$SRVID';"`
if [ "$DEPOSIT" -eq 0 ]; then
LASTUSRBAL=0
else
LASTUSRBAL=$(($DEPOSIT - $SRVPRICE))
fi
TIMEUNITEXP=`$CMD "use $DB; SELECT timeunitexp FROM radius.rm_services WHERE srvid = '$SRVID';"`
TIMEBASEEXP=`$CMD "use $DB; SELECT timebaseexp FROM radius.rm_services WHERE srvid = '$SRVID';"`
if [ "$TIMEBASEEXP" == "2" ]; then
NEXTEXPIRYADD=$(date +"%Y-%m-%d" -d "+$TIMEUNITEXP days")
EXPERIOD="$TIMEUNITEXP Days"
fi
# Set Quota Limit variable which will be used in the end zzzzzzzzzzzz
if [ "$TIMEBASEEXP" == "3" ]; then
NEXTEXPIRYADD=$(date +"%Y-%m-%d" -d "+$TIMEUNITEXP month")
EXPERIOD="$TIMEUNITEXP Month"
fi
# Set Expiry Date/Month Unit
if [ $PKGQUOTA -eq 0 ]
then
QT="UNLIMITED"
else
QT="$PKGQUOTA MB"
fi
# Check Service Expiry Date, if Active then ignore
IS_USER_EXPIRED=`rmauth 127.0.0.1 $USR 1 |grep -i -c "The account has expired"`
if [ "$IS_USER_EXPIRED" -eq 1 ];then
USREXPORNOT=1
else
USREXPORNOT=0
fi
# Check if user quota is ended or not
IS_USER_QUOTA_END=`rmauth 127.0.0.1 $USR 1 |grep -i -c "Total traffic limit reached"`
if [ "$IS_USER_QUOTA_END" -eq 1 ];then
USRQTORNOT=1
else
USRQTORNOT=0
fi
if [ "$USREXPORNOT" -eq 1 ]; then
DATEEXP="$USR - *** Account Date Expired that is $SRVEXPIRYFULL !! **"
else
DATEEXP="$USR - Account Date is OK that is $SRVEXPIRYFULL."
fi
#IS_QUOTA_LEFT_IN_NEGATIVE zzzzzzzzzzzzzzzzzzz
if [ "$USRQTORNOT" -eq 1 ] && [ "$IS_QUOTA_LEFT_IN_NEGATIVE" -eq 1 ] ; then
RQT_in_NEGATIVE_HUMAN=`bytesToHuman $RQT_RESULT_REMOVE_HYPHEN`
QTEXP="$USR - *** Account QUOTA Expired that is Negative $RQT_in_NEGATIVE_HUMAN !! **"
fi
if [ "$USRQTORNOT" -eq 0 ]; then
RQT_in_POSITIVE_HUMAN=`bytesToHuman $RQT_RESULT_REMOVE_HYPHEN`
QTEXP="$USR - Account QUOTA is OK that is $RQT_in_POSITIVE_HUMAN "
fi
if [ "$DL" == "NULL" ]; then
QTEXP="$USR - NO QUOTA have been added yet! seems fresh account."
fi
if [ "$UL" == "NULL" ]; then
QTEXP="$USR - NO QUOTA have been added yet! seems fresh account."
fi
if [ "$RQT_OUT" == "0" ]; then
QTEXP="$USR - QUOTA INFO: No Quota hase been added yet! seems fresh account."
#echo "$USR - QUOTA INFO: NO quota hase been added yet! seems fresh account."
fi

########### ACCOUNT STATUS EXPIRED BUT NOT ENOUGH DEPOSIT to RENEW ACTION ############
if [ "$DEPOSIT" -eq 0 ]; then
USRDEPORNOT=0
fi
if [ "$DEPOSIT" -lt "$SRVPRICE" ]; then
USRDEPORNOT=0
echo "
$DATEEXP
$QTEXP
$USR - Current Expiry = $SRVEXPIRYFULLD
$USR - Pacakge Name/Price: $PKGNAME | $SRVPRICE PKR
$USR - Current Deposite Available = $DEPOSIT"
echo -e "$COL_RED$USR | ERROR: Insufficient deposit for Renewal ! Current Deposite is $DEPOSIT and SRV renewal price is $SRVPRICE $COL_RESET
"
fi
if [ "$DEPOSIT" -eq "$SRVPRICE" ] || [ "$DEPOSIT" -gt "$SRVPRICE" ]; then
USRDEPORNOT=1
echo -e "$COL_GREEN$USR INFO: | Deposit Balance: $DEPOSIT | Service Name: $PKGNAME | Price $SRVPRICE $COL_RESET"
fi
########### ACCOUNT STATUS EXPIRED and DEPOSIT IS ENOUGH TO RENEW ACTION ############
if [ "$USREXPORNOT" -eq 1 ] || [ "$USRQTORNOT" -eq 1 ]; then
if [ "$USRDEPORNOT" -eq 1 ] ; then
# RENEW USERS IF ALL CONDITIONS MATCHED / PRINT FETCHED VALUES , JUST FOR INFO / ZAIB bbbbb
echo "
$DATEEXP
$QTEXP
$USR - Resetting Date: Current Expiry = $SRVEXPIRYFULLD / Next Expiry: $NEXTEXPIRYADD | UNIT = $EXPERIOD
$USR - Pacakge Name/Price: $PKGNAME | $SRVPRICE PKR
$USR - Current Deposite Available = $DEPOSIT | Deposite Balance after Deduction: $LASTUSRBAL"
# ADD 30 DAYS VALUE TO EXPIRED USER ACCOUNTzzzzzzzzzz
$CMD "use radius; UPDATE rm_users SET expiration = '$NEXTEXPIRYADD' WHERE username = '$USR';"
# ADD COMMENTS
$CMD "use radius; UPDATE rm_users SET comment = '$USR account last renewed from previous DEPOSIT $DATE' WHERE username = '$USR';"
# ADD SYSLOG ENTRY
#$CMD "use radius; INSERT INTO rm_syslog (datetime, ip, name, eventid, data1) VALUES (NOW(), 'n/a', 'DEPOSIT_$USR', '$USR', '$USR renewd service $PKGNAME');"
# UPDATE User Balance
$CMD "use radius; UPDATE rm_users SET credits = '$LASTUSRBAL' WHERE username = '$USR';"
# ADD INVOICE
$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
('admin', '$USR', NOW(), '0', '0', '$PKGQUOTABYTES', '0', '0', '$PKGQUOTABYTES', '0', '0', '30', '$NEXTEXPIRYADD', '0', '0', '1', '0', '1', '$PKGNAME', 'This user service renewed by Deposit/Payment', '577343812eee0', '1', '$TODAYHM', '$ADDRESS', '$CITY', '00000', '$COUNTRY', '$STATE', '$FULLNAME', 'n/a',
DATE_ADD(CURDATE(), INTERVAL '10' DAY), '0', '0', '$TODAY', '$SRVPRICE', '0.000000', '$TODAYHM', '$LASTUSRBAL', '', '$MOBILE', '$MOBILE', '0.00' );"

$CMD "use $DB; INSERT INTO rm_invoices (managername, username, amount, price, tax, vatpercent, balance,
date, service, paymode, invgroup, paymentopt, transid)
VALUES ('admin', 'admin', 1, '-$SRVPRICE', '0', '0.00',
'', NOW(), 'Ref.: C-$TODAYHM', '2', '1', DATE_ADD(CURDATE(), INTERVAL '10' DAY),
'577343812eee0' );"
if [ "$RQT_RESULT1" -eq 1 ] ;then
echo "$USR - Total Data Reamining since last renewal = NO DATA REMAINING !"
else
echo "$USR - Total Data Reamining since last renewal = $RQT4"
fi
######################################################
############## QUOTA SECTION STARTS HERE #############
######################################################
# UPDATE Quota limitations if any, else ignore
DL=`$CMD "use radius; SELECT (SELECT SUM(acctoutputoctets) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(dlbytes), 0) FROM rm_radacct WHERE username = '$USR');"`
UL=`$CMD "use radius; SELECT (SELECT SUM(acctinputoctets) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(ulbytes), 0) FROM rm_radacct WHERE username = '$USR');"`
if [ "$DL" == "NULL" ]; then
DL=x
fi
if [ "$UL" == "NULL" ]; then
UL=x
fi
if [ "$RQT_OUT" == "0" ]; then
QTEXP="QUOTA INFO: NO QUOTA have been added yet! seems fresh account."
echo "QUOTA INFO: NO QUOTA have been added yet! seems fresh account."
fi
# QUOTA FRESH ADD MODE FOR NEW ACCOUNT
if [ "$DL" == "x" ] || [ "$UL" == "x" ]; then
echo "*********** QUOTA FRESH ADD MODE FOR NEW ACCOUNT"
echo "$USR - QUOTA INFO: Account Seems Fresh, Adding NEW Quota ..."
#$CMD "use $DB; UPDATE rm_users SET comblimit = '$PKGQUOTABYTES' WHERE username = '$USR';"
ADDICTIVE_COMB_LIMIT=`echo "1+$PKGQUOTABYTES" |bc -l`
$CMD "use $DB; UPDATE rm_users SET comblimit = '$ADDICTIVE_COMB_LIMIT' WHERE username = '$USR';"
fi
#exit 1
# QUOTA RESET MODE for expired QUOTA
IS_USER_QUOTA_END=`rmauth 127.0.0.1 $USR 1 |grep -i -c "Total traffic limit reached"`
if [ "$IS_USER_QUOTA_END" -eq 1 ] && [ "$RQT_RESULT1" -eq 1 ] ;then
DL=`$CMD "use radius; SELECT (SELECT SUM(acctoutputoctets) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(dlbytes), 0) FROM rm_radacct WHERE username = '$USR');"`
UL=`$CMD "use radius; SELECT (SELECT SUM(acctinputoctets) FROM radacct WHERE username = '$USR') - (SELECT COALESCE(SUM(ulbytes), 0) FROM rm_radacct WHERE username = '$USR');"`
FINAL1_COMB_LIMIT=`echo "$DL+$UL" |bc -l`
FINAL2_COMB_LIMIT=`echo "$FINAL1_COMB_LIMIT+$PKGQUOTABYTES" |bc -l`
# ADDing Quota
echo "$USR - QUOTA info: RESET MODE: Existing Quota limit is Used. Adding New Quota as per package ..."
$CMD "use radius; UPDATE rm_users SET downlimit = '- $DL', uplimit = '- $UL', comblimit = '$FINAL2_COMB_LIMIT' WHERE username = '$USR';"
fi
## QUOTA ADDICTIVE MODE
IS_USER_QUOTA_END=`rmauth 127.0.0.1 $USR 1 |grep -i -c "Total traffic limit reached"`
if [ "$IS_USER_QUOTA_END" -eq 1 ] && [ "$RQT_RESULT_REMOVE_HYPHEN" -gt 0 ] ;then
#echo "********* QUOTA ADDICTIVE MODE"
echo "$USR - QUOTA info: ADDICTIVE MODE: Existing Quota is remaining. Adding New Quota in existing quota as per pacakge (IF ANY) ..."
##echo "$USR - QUOTA setting is - ADDICTIVE ..."
ADDICTIVE_COMB_LIMIT=`echo "$USR_CUR_COMBLIMIT+$PKGQUOTABYTES" |bc -l`
$CMD "use $DB; UPDATE rm_users SET comblimit = '$ADDICTIVE_COMB_LIMIT' WHERE username = '$USR';"
fi
# QUOTA ADDICTIVE MODE for DATE EXPIRED USERS ONLY
IS_USER_QUOTA_END=`rmauth 127.0.0.1 $USR 1 |grep -i -c "Total traffic limit reached"`
if [ "$IS_USER_QUOTA_END" -eq 0 ] && [ "$RQT_RESULT1" -eq 0 ] ;then
echo "$USR - QUOTA info: ADDING quota for DATE EXPIRED USERS ONLY (Existing Quota will be added in new Quota, IF ANY) ..."
ADDICTIVE_COMB_LIMIT=`echo "$USR_CUR_COMBLIMIT+$PKGQUOTABYTES" |bc -l`
$CMD "use $DB; UPDATE rm_users SET comblimit = '$ADDICTIVE_COMB_LIMIT' WHERE username = '$USR';"
fi
#####################################################
############## QUOTA SECTION ENDS HERE ##############
#####################################################
RQT=`$CMD "use radius; SELECT username,
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)
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
FROM rm_users JOIN rm_services USING (srvid) ORDER BY username ASC
) AS tmp
WHERE 1 AND (tmp.acctype = '0' OR tmp.acctype = '1' OR tmp.acctype = '3' OR tmp.acctype = '4')
AND username LIKE '$USR%';" | awk '{print $2}'`
RQT_HUMAN_FRIENDLY=`bytesToHuman $RQT`
echo "$USR - Current Updated Quota after the renewal ... : $RQT_HUMAN_FRIENDLY"
USRIP=`$CMD "use $DB; SELECT framedipaddress FROM radacct WHERE acctstoptime IS NULL AND username = '$USR';"`
if [ -z "$USRIP" ]; then
echo "$USR - Online Status: Offline !"
else
NASIP=`$CMD "use $DB; SELECT nasipaddress FROM radacct WHERE username = '$USR' and acctstoptime IS NULL;"`
ONLINE_TIME=`$CMD "use $DB; SELECT acctsessiontime FROM radacct WHERE username = '$USR' and acctstoptime IS NULL;"`
ONLINE_START_TIME=`$CMD "use $DB; SELECT acctstarttime FROM radacct WHERE username = '$USR'and acctstoptime IS NULL;"`
ONLINE_TIME_FIN=`echo "$ONLINE_TIME/60/60" |bc -l | cut -c1-4`
echo "$USR - Online Status: IP: $USRIP | Online Since: $ONLINE_START_TIME | Online Time: $ONLINE_TIME_FIN Hour(s) | NAS: $NASIP "
fi
fi
fi
done


Result:

  • /temp/auto.sh
- INFO: Total Users scanned: 2
INFO: No user found with Expired Date/Quota package ... Exiting peacefully!
  • /temp/auto.sh
- INFO: Total Users scanned: 2

test50 INFO: | Deposit Balance: 99960 | Service Name: 2mb Speed - 30 Days - 1 GB Quota | Price 10

test50 - *** Account Date Expired that is 2022-02-14 00:00:00 !! **
test50 - Account QUOTA is OK that is 2.00 GiB
test50 - Resetting Date: Current Expiry = 2022-02-14 / Next Expiry: 2022-03-16 | UNIT = 30 Days
test50 - Package Name/Price: 2mb Speed - 30 Days - 1 GB Quota | 10 PKR
test50 - Current Deposit Available = 99960 | Deposite Balance after Deduction: 99950
test50 - Total Data Reamaining since last renewal = 2.00 GiB
test50 - QUOTA info: ADDING quota for DATE EXPIRED USERS ONLY (Existing Quota will be added in new Quota, IF ANY) ...
test50 - Current Updated Quota after the renewal ... : 3.00 GiB
test50 - Online Status: Offline !
  • /temp/auto.sh

- INFO: Total Users scanned: 2

test50 INFO: | Deposit Balance: 99950 | Service Name: 2mb Speed - 30 Days - 1 GB Quota | Price 10

test50 - Account Date is OK that is 2022-03-16 00:00:00.
test50 - *** Account QUOTA Expired that is Negative 742.69 MiB !! **
test50 - Resetting Date: Current Expiry = 2022-03-16 / Next Expiry: 2022-03-16 | UNIT = 30 Days
test50 - Pacakge Name/Price: 2mb Speed - 30 Days - 1 GB Quota | 10 PKR
test50 - Current Deposite Available = 99950 | Deposite Balance after Deduction: 99940
test50 - Total Data Reamining since last renewal = NO DATA REMAINING !
test50 - QUOTA info: RESET MODE: Existing Quota limit is Used. Adding New Quota as per package ...
test50 - Current Updated Quota after the renewal ... : 1024.00 MiB
test50 - Online Status: Offline !

January 2, 2022

SANGFOR IAM – Short Notes

Filed under: SANGFOR — Tags: , , , — Syed Jahanzaib / Pinochio~:) @ 7:25 PM

2 years ago, We acquired SANGOFR IAM m5200 hardware device (along with 3 years support/renewal bundle) as an replacement for Microsoft ISA/TMG 2010 product. It’s been 2 years since its acquisition & so far we have good experience with its usage. We tested few other products like Sophos, Fortigate & few other, but IAM was the closest replica for TMG replacement therefore we went for it. AS per our core requirements of Compliance/audit, IAM Logging details level is very impressive. It’s local support was very good and responsive & they helped us in initial demo & configuration.

As time will allow, I will try to add some guides/tips and notes for day to day task related to sangfor IAM.


Allow Office 365 / Outlook related connectivity to Particular AD Group.

In our office, all users are joined with Active Directory Domain. (there are multiple domain with cross forest trust in our company). We have allowed limited internet facility to particular active directory group only. This year we have moved away from on-prem Lotus domino email server to cloud base microsoft O365 solution, therefore we had to allow internet to every body who is now using Outlook. To limit the internet usage & after doing some extensive R&D & ‘internet activities’ lookup via sangfor , we created following ‘O365’ Object in URL DATABASE, and allowed it  to AD group ‘Internet_for_O365_Group’ & associate outlook users to this group. This way users who doesn’t have internet facility can still use O365 related services in a controlled manner.


*.office365.com
*.office.com
*.office.net
*.outlook.com
*.microsoft.com
*.onmicrosoft.com
*.microsoftstream.com
*.azure.net
*.azureedge.net
*.windows.net
*.live.com
*.atdmt.com
*.ytimg.com
*.windowsazure.com
*.msftidentity.com
*.msidentity.com
*.microsoftonline.com
*.msecnd.net
*.msftauth.net
*.msauth.net
*.azure.com
*.digicert.com
*.agp.com.pk
*.obsagp.com.pk
*.msftconnecttest.com
*.acompli.net
*.sharepoint.com
*.live.net
*.onedrive.com
*.msftstatic.com
*.windows.com
*.s-microsoft.com
*.passport.net
*.msocsp.com
*.msftncsi.com
*.msedge.net


More will be added as per time allow.

Regard’s
Syed Jahanzaib

November 22, 2021

Short Notes for Active Directory SLD to FQDN Cross Forest Migration – Using ADMT tool



FRIST ! Some DRY Theory …

What is a Single Label Domain (SLD)?  This is a term that Microsoft uses to describe domains which have only a single name, and no suffix such as “.local” or “.com.”  For example, your Active Directory domain might have a name like “company.local,” but if it were Single Label, it might be just “company.”

The problem is, Single Label Domains fall into a grey area of Microsoft support.  SLD will cause multiple issues when integrating with other applications, and even when performing something simple like joining a new computer (windows 10 for example) to the domain & you need to modify the registry as well. SKype for business will not work SLD and the long list goes on.


What is the Active Directory Migration Tool (ADMT)?

The Active Directory Migration Tool (ADMT) is a Microsoft software application that helps you manage and perform the necessary operations to move AD objects. You can move objects within the same domain forest (intraforest) or to a different forest (interforest).


Our Story!

Recently we migrated our active directory domain users from Single Label Domain SLD to FQDN. It was cross forest migration & both forest were on same LAN. We were using Lotus Domino Email server on premises & wanted to migrate on Exchange Online (office 365 cloud). To perform the migration , it was strongly recommended by the Microsoft to migrate SLD to FQDN. Our SLD AD domain was running from past 16-17 years started with windows 2000 to 2003 to 2008 to 2012 to 2016, therefore after much planning , we planned the migration , tested it multiple times in virtual labs. There are multiple 3rd party tools available for the smooth migration but for our number of users the estimated cost for tool acquisition was 4 Million+ PkR which was a huge amount, therefore we used the Microsoft free tool called ADMT, which is quite old , BUT still it did the job for us.

I may not be able to write down all details because internet is full of such step by step video tutorials, I will try to provide you details only related to some customization we applied for smoother transition.

Specs used in this guide & few tips to follow before doing ADMT execution

  • Source Domain : SLD with Windows Server 2016
  • Target Domain  : FQDN on Windows Server 2019
  • Workstations : Mostly Windows 10 PRO with multiple builds including v 1909 – OS build 18363.1556 | W10 20H2 OS build 19042.1348
    Note ADMT 3.2 Only support the migration of Operating Systems up to Windows 7, (that doesn’t mean Windows 8 and Windows 10 wont work, it just means they are not supported). Migrating Windows 8 and 10 throws a lot of security translation errors, because of the way it treats ‘Apps’, so I’d recommend you do a LOT of testing before carrying out a live migration.
  • ADMT tool version 3.2 : Installed on Target DC
  • SQL Server 2008 R2 Express / Version 10.52.4000.0 installed on Target DC
  • PSTOOLS library installed on both DC for ease of CMD execution on remote WorkStations/servers
  • To migrate machines, the ADMT Admin user needs “Local” administrative access on all the source machines. The easiest way to do this is via group policy, using ‘Restricted Groups’.  This allows you to take a group (or user) and put put them on the local groups (including administrators) of the targeted machines.

    In the OLD domain, create a group and put the ADMT Admin from the target domain in it. (I put the domain admin from the target domain in it as well, to be on the safe side, but that’s up to you).

    It can be done iva opening group policy and navigate to
    Computer Configuration > Policies  >Windows Settings > Security Settings > Restricted Groups
    Add a new one, select the group you have just created > and add it to ‘Administrators’.

  • ADMT doesn’t have a rollback function. Be sure before you migrate the objects
  • Make sure you have documented all the domain related stuff very well in sheets, Also Ensure you perform at least 1-2 test labs in isolated virtual environments
  • If you want to make life easier during migration, DISABLE windows FIREWALL. To perform computer migrations, (and security translations), ADMT needs to deploy an ‘agent’ to the machines in the OLD domain. The local firewall (if enabled) can stop this, I simply disable the users local firewall via GPO to avoid any inconvenience
    It can be done by opening group policy and navigate to
    Computer Configuration >Policies  > Administrative Templates > Network > Network Connections > Windows Firewall > Domain Profile
    Locate the “Windows Firewall protect all network connections‘ and set it to disabled.
  • Enable Remote Registry Key Service on users workstation via GPO. I have also seen the agent fail to deploy if the ‘Remote Registry Service’ is not running on the target machines, (it’s disabled by default in newer version of windows). So I use the GPO policy to turn that on as well on all workstations
    It can be done by opening group policy and navigate to
    Computer Configuration > Polices > Windows Settings > Security Settings > System Services
    Locate the ‘Remote Registry’ service, and set it’s startup to automatic.
  • It is recommended to Disable Sleep and Hibernation via GPO

Step by Step ADMT

Note: Details can be found over internet as so many guides have already been written & shared

It is assumed that new domain controller is installed along with proper DNS working.

  • Supported Operating System : Source/Target must be running Windows Server 2008 or above
  • ADMT requires a SQL server to store data, Download & install SQL Express on Target DC > Download Link for SQL Express
  • Download & install ADMT tool on Target DC > Microsoft Download Link for ADMT
  • Download & install Password Export Service on Source DC > PSE Download Link from Microsoft
    * Create the encryption key for password migration on the source DC and copy it to the target DC. (user password migration) | Install ADMT PW Migration DLL & reboot source DC could be required
  • Prepare Active Directory for the migration process. There are two main things to prepare, DNS & a domain trust
    * Create DNS CONDITIONAL FORWARDERS on source/target DC pointing to each other  / Add the DNS suffixes for each domain via GPO. The old domain needs to be able to resolve names in the new domain, and the new domain needs to be able to resolve names in the old domain. To achieve this you need to setup ‘Conditional Forwarding’ in each domain for the other one
    * In addition, we want all machines (in both domains) to set their primary DNS Suffix, to their own domain, and their DNS suffix search list to look for their own domain first, then the other domain. The easiest way to do that is via group policy.  On a domain controller > Administrative Tools > Group Policy Management Console, NAVIGATE To
    Computer Configuration > Policies > Administrative Templates > Network > DNS Client
    Setting: DNS Suffix Search List: Set to current domain ‘comma‘ other domain , Example olddomain.com,newdomain.com
    > Repeat the procedure in the new domain, (but the domain names will be the opposite way round)
  • Using, Active Directory Domains and Trusts Tool on source/target DC’s, create two way TRUST
    * You can use below guides to do so , Link#1Link#2
  • Using ADMT on Target DC, start migrating in following numbering

a) Migrate AD Groups
> There is a sequence for doing this though, there are three types of security groups and they HAVE TO be migrated in the correct order,
First: Universal Groups
Second: Global Groups
Third: Domain Local Groups

b) Migrate AD Users Account

c) Migrate Security translation of COMPUTER

Real World Note ons SID migration: This can take a while, (up to an hour for some machines, Luckily our users had most advance laptops/desktops with SSD’s Flash storage so ma time we saw was 20-25 mnts for heavy data user) and it’s best done without anyone being logged in (to prevent any profiles, or registry hives being locked). So take time to plan when this is done – rush it and you will have problems, and the very users who are too busy to be interrupted, are the very ones that shout the loudest if there’s a problem post migration.
d) Migrate COMPUTER objects in the end which will reboot the client PC upon completion, & then after reboot user can login to NEW domain (its a manual process to select OTHER USERS to see the NEW domain in the list, this is one time & next time windows will remember the last sign_IN, to avoid this manual thing, you can read the full guide in the end)

 


Following are few Tips & tricks that we followed or created on the case basis …

Force users to login to NEW domain by using OTHER USER login as by default login option

Once you migrate the user / sid translation & computer migration to new Domain & user PC gets reboot, on next Login user will still see his old domain login screen. In order to login to NEW domain, user have to click on OTHER USER option . This is because windows remembers last signed in USER. [In companies where IT Dept have strong hold on users or management its very easier to just inform all the users via email/contact or other means, but in company were your boss is kind of dept. head is afraid of informing users about change, then you have to follow the long route & in our case we had to do it too.]

  • in Source/Target ADUC, we create new OU named “Pre-Migration-Temporary-OU
  • in Source/Target DC, we created new GPO named “Pre-Migration-GPO” in which we set following setting
    Computer Configuration > Policies > Windows Settings > Security Settings > Security Options
    on right pane, we modified below setting
    “Interactive logon: Don’t display last signed-in” >set it to>  *ENABLED*
  • On source DC, we moved the user COMPUTER object to “Pre-Migration-Temporary-OU“. AS you know that it generally takes 90 minutes or more on user computer to auto refresh the Gpupdate, therefore for instant update we used PSTOOLs command PSEXEC. Using it  we executed cmd “gpupdate /force” on target user PC.PSEXEC sample CMD:
PsExec.exe \\USER1-PC -u DOMAIN\ADMINISTRATOR -p ADMINPASSWORD cmd "/c gpupdate /force"
  • Then on Target NEW DC, using ADMT console, we first moved his user account / SID translation to new DC. Finally we migrated his COMPUTER to NEW DC in “Pre-Migration-Temporary-OU” as target
  • Once his Computer migrated & rebooted, the user is now seeing OTHER USER login window (which is by default NEW DOMAIN) , once he logged IN using his username / password to new DOMAIN & he is able to see old settings desktop etc, we then moved his COMPUTER from Pre-Migration-Temporary-OU to COMPUTERS OU on the NEW DC

Disabling User Must change password After Next Logon

After the user account was migrated to new domain, it had the following option ENABLED by default

  • User must change password after next logon

This was creating problem for us because every user will change password, & as a result he have to change his Lotus Notes / SameTime chat app / Mobile app password too, because lotus notes have SINGLE LOGON option which syncs password from active directory. At the time of migration with hundreds of users & with very limited IT resource, we used following scheduled script to get rid of ti temporarily basis till the migration lasted.

Wrap below CMD in any batch file and schedule it to run every minute

powershell.exe -inputformat none -command "Get-ADUser -Filter * -SearchBase 'OU=MYMAINOU,DC=mydomain,DC=local' | Set-ADUser -ChangePasswordAtLogon:$False"

Few issues & there resolutions after user migration 

We Observed few limitations in the migration process

  • IBM SAMETIME Password wiped: Not all 3rd party applications settings can be fully migrated, this includes some apps saved password. Example we are using IBM lotus SAMETIME lan chat app, its SAVED password didn’t migrated & user have to open and enter his password & tick on remember/auto login option
  • Google chrome settings are not migrated as well. Good part is If the user is logged in to google chrome using his GMAIL account. he can re login & all of his settings will be synced back. but if the user was google chrome as GUEST, then his settings will not be migrated

Missing Profile Problem after user is migrated via ADMT

In some cases, once the user is migrated, his account was showing disabled on NEW DC, (which we didn’t noticed) and once all settings migrated, and user logged in to his PC, his profile was empty like fresh. This created very much hurdles for some executive level users.

If for some reason, if a migrated user gets a NEW FRESH profile (or in other words lost the old profile) you can use the following procedure to re-assign the old profile back to the target account

  1. Run Regedit on USER computer
  2. Go to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ProfileList
  3. Go through the ProfileList and identify the Source account (OLD PROFILE example user.old.domain). Copy the value from the ProfileImagePath key
  4. Again go through the Profile list and identify the Target account example user.new.domain). Paste the ProfileImagePath key value there
  5. Restart the user workstation

The ProfileImagePath key will be same value for both Source and Target user accounts. This ensures both source and target users will receive the same profile which is stored under C:\Documents and Settings\UserName. or c:\users\xyz (in new version of windows)

Calculator was missing from windows 10 pc

First try this

Option#1

Reset Calculator’s data

Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}

DISM /Online /Cleanup-Image /RestoreHealth

Option#2

Type the following 2 commands at the CMD prompt:

powershell

Always Wait for the Network link during Login

During the migration we observed that our users desktop/laptops had modern hardware with new generation i7 / SSD-Flash storage & they boots in just few seconds, & user logged in quickly ever before the ethernet/wifi gets IP from the DHCP. This was creating problems in MAPPED NETWORK DRIVE & new group policy implication , which was necessary for the migration & backup process as well in network drive, therefore we enabled the “Always wait for the network at computer startup and logon” using group policy & applied to all users OU’s.

It was located under

  • Computer Configuration — Policies — Administrative Templates — System — Logon

This solved our drive mapping issue along with domain WELCOME login script as well which executed few other commands as well like NTP sync, Sangfor Login Script, customized login entry in our central location etc.

When the “Always wait for network at computer startup and logon” policy is enabled, it then refers to the policy for how long it should wait for network connectivity, before dumping the policies and logging the user on with cached credentials. If the “Startup policy processing wait time” is not specified, the default is 30 seconds. If the network is already connected, the computer would log in without waiting further , but would take about 30 seconds if there was no network connectivity (or no DC available).

I set it to to wait 50 seconds for network then continue logging in “GPO Processing wait time”. Default with the setting on is 30 seconds which seemed too short.

 

 

October 26, 2021

Veeam B&R: [nbd] Error: Object reference not set to an instance of an object.

Filed under: Veeam B&R — Tags: — Syed Jahanzaib / Pinochio~:) @ 10:45 AM

Scenario:

  • Veeam B&R 9.5 (Ver 9.5.0.1922) installed on Windows Server 2012R2

We were getting failure error on Veeam daily job report for a particular VM guest ,

Preparing backup proxy VMware Backup Proxy for disk Hard disk 1 [nbd]
Error: Object reference not set to an instance of an object.

It was a VM guest that was recently restored via vcenter to another esxi host (under vcsa).

To further troubleshoot, I exported the JOB log using Veeam article, & observed following

[23.10.2021 04:56:01] < 332> cli| Waiting for the next command.
[23.10.2021 04:56:01] < 3936> cli| Next client command: [closeStg].
[23.10.2021 04:56:01] < 3936> cli| :> X:\VMBKP\Daily VM BKP job via VCSA\MY_VM_GUEST.16D2021-10-23T030322.vbk
[23.10.2021 04:56:01] < 3936> cli| Closing storage ‘X:\VMBKP\Daily VM BKP job via VCSA\MY_VM_GUEST.16D2021-10-23T030322.vbk’.
[23.10.2021 04:56:01] < 3936> cli| MTA backup apartment was created successfully, id ‘0x000001EA804A1E10’.
[23.10.2021 04:56:01] < 3048> cli| Thread started. Thread id: 3048, parent id: 3936, role: MTA invoke thread
[23.10.2021 04:56:01] < 3048> cli| Entering MTA invoke thread.
[23.10.2021 04:56:01] < 3048> stg| There is no file ‘HostFS://X:\VMBKP\Daily VM BKP job via VCSA\MY_VM_GUEST.16D2021-10-23T030322.vbk’ in the files cache.
[23.10.2021 04:56:01] < 3936> stg| There is no file ‘HostFS://X:\VMBKP\Daily VM BKP job via VCSA\MY_VM_GUEST.16D2021-10-23T030322.vbk’ in the files cache.
[23.10.2021 04:56:01] < 3936> cli| Storage is closed.

To sort the issue I did following & the issue got resolved

  • Remove the VM from the VEEAM job
  • Remove the VM from inventory from particular ESXI host,
  • Re-added the VM in ESXI
  • Added the VM in VEEAM job

Afterwards, the job ran fine without any error.

 

Veeam B&R: Win32 Error / Code: 67 Cannot connect to the host’s administrative share


Continued post from


Scenario:

  • Veeam B&R 9.5 (Ver 9.5.0.1922) installed on Windows Server 2012R2

 

After running the daily job, we were observing following failure notice for particular windows 7/10 OS.

Processing WIN10-LOG Error: Failed to connect to guest agent. Errors: ‘Cannot connect to the host’s administrative share. Host: [WIN10-LOG]. Account: [admin]. Win32 error:The network name cannot be found. Code: 67 Cannot connect to the host’s administrative share. Host: [19.168.0.10]. Account: [admin]. Win32 error:The specified network name is no longer available.

After some R&D , I had to create a new DWORD value in registry at effected windows , & afterwards the issue got resolved.

Edit the registry on effected Windows & perform following

  1. Click Start, click Run, type regedit, and then press ENTER.
  2. Locate and then click the following registry subkey:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
  3. If the LocalAccountTokenFilterPolicy registry entry doesn’t exist, follow these steps:
    1. On the Edit menu, point to New, and then select DWORD Value.
    2. Type LocalAccountTokenFilterPolicy, and then press ENTER.
  4. Right-click LocalAccountTokenFilterPolicy and then select Modify.
  5. In the Value data box, type 1, and then select OK.
  6. Exit Registry Editor.

On a safe side , perform following as well,

  • Disable windows based firewall
  • Disable windows UAC

Reboot the affected windows machine & now RUN the backup job on Veeam B&R server.


Exporting VEEAM job LOGS for troubleshooting purposes

It’s a good idea to export JOB logs in order to troubleshoot the error in depth.

Follow below veeam article


Regard’s
Syed Jahanzaib

August 27, 2021

NAT types for console | a horror tale for gamers behind NAT

Filed under: Mikrotik Related — Tags: , , , — Syed Jahanzaib / Pinochio~:) @ 4:55 PM

First of all, **What is NAT?**

Network Address Translation (NAT) is designed for IP address conservation. It enables private IP networks that use unregistered IP addresses to connect to the Internet. NAT operates on a router, usually connecting two networks together, and translates the private (not globally unique) addresses in the internal network into legal addresses, before packets are forwarded to another network.

As part of this capability, NAT can be configured to advertise only one address for the entire network to the outside world. This provides additional security by effectively hiding the entire internal network behind that address. NAT offers the dual functions of security and address conservation and is typically implemented in remote-access environments.

Basically, NAT allows a single device, such as a router, to act as an agent between the Internet (or public network) and a local network (or private network), which means that only a single unique IP address is required to represent an entire group of computers to anything outside their network.


Moving on, the 3 NAT types, when concerning gaming consoles/PCs, PS3/PS4, or the Xbox 360/Xbox One, are

  1. Open (Type 1)
  2. Moderate (Type 2) &
  3. Strict NAT (Type 3)

NAT1 is a direct connection to the internet; all ports are accessible, with no port forwarding rules required. Ultimately, an Open/Type 1 NAT will provide the best connection quality whereas Moderate and Strict NAT restrict the connections between a gaming console or PC. If your internet connection has a public IP address (non-RFC1918, non-RFC6598) on the exterior interface of your home router, you should be able to have your PS4 run in NAT2 mode. If you control the port forwarding on your home router, you should be able to get the PS4 to run in NAT1 mode, even on an internal RFC1918 address.

NAT2 is a single layer of public-to-private conversion, and requires assisted port forwarding to achieve inbound connections to the PS4. The Moderate, Type 2 NAT, as well as Strict, Type 3 NAT, limits the connections that can be created between your gaming console or PC and someone else’s gaming consoles or PCs. Users with Moderate NAT, or type 2 NAT, are only able to connect with other users also having a Moderate NAT type, type 2, or an Open NAT Type, type 1.

NAT3 is two layers of conversion, and usually involves a carrier-grade-NAT device at the ISP, as well as a NAT device at the home, making it nearly impossible to achieve direct inbound connections to the PS4; in NAT3 mode, only server-assisted connections are possible, with each PS4 establishing an outbound connection through the two layers of NAT devices, with centralized servers mediating the PS4-to-PS4 communication. Users with Strict/Type 3 NATs can only connect with other users using an Open/Type 1 NAT.Furthermore, at a smarter NAT 3 setup, If you see an address in 100.64.0.0/10 on the outside interface of your home router, you’re out of luck; you’re in NAT3 territory, may GOD have mercy on your gameplay 🙂

 

More to come from the Mikrotik Side …

July 29, 2021

MySQL: DROP tables older than X Period using BASH Script



Notes for Self:

Following script can delete single or multiple table older than X time from the mysql DB. It was pretty useful for DMASOFTLAB RADIUS MANAGER CONNTRACK table OR customized  SYSLOG-NG logging system, where table is daily created automagically in database using current date using YYYY_MM_DD format (dates have underscore sign). There are other solutions as well like creating procedure etc, but since this was older MySQL version , therefore I took this route.


1# FOR DMASOFTLAB RADIUS MANAGER

DMASOFTLAB Radius manager have its own connection tracking module which stores date wise table to store data. (YYYY-M-DD format for table), & deleting it using bash script is not possible because older versions gives syntax error, therefore we had to wrap the table name in BACKQUOTE.

Also most importantly, if we delete tables older then x period, then there is a table that dma creates to hold the conntrack details called tabxid, & eventually with date criteria, it will be deleted too, therefore I EXEMPTED in the mysql statement so that it should remain safe else conntrack table will not work.

mkdir /temp
touch /temp/conntrack_trim.sh
chmod +x /temp/conntrack_trim.sh
nano /temp/conntrack_trim.sh

Now paste following data, and modify accordingly

#!/usr/bin/env bash
####!/bin/sh
#set -x
#################
# Script to delete TABLES OLDER THEN X period from particular DB
# Made for syslog-ng to save disk space
# Created on: 2019
# Last Modified: 10-SEP-2021
# Syed Jahanzaib / aacable at hotmail dot com / aacable.wordpress.com
#################
#### MODIFY BELOW
#MYSQL DETAILS
SQLUSER="SQL_ID"
SQLPASS="SQL_PASSWORD"
DB="conntrack"
DATE=`date +'%Y-%m-%d'`
# You can change the months to days also by
#DAYS="30 DAYS" (or maybe syntax is DAY)
DAYS="3 MONTH"
TMPFILE="/tmp/conntrack_tables_list-$DATE"
#################
#################
# Don't modify below
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLUSER --skip-column-names -s -e"
logger $DB Trimmer Script started $DATE , IT WILL DELETE tables from $DB older then $DAYS
echo "syslog_ng script started $DATE , IT WILL DELETE tables from $DB older then $DAYS"
# This is one time step.
echo " Script Started @ $DATE "
# --- Now Delete $DEL_TABLE TABLE from $DB table ...
$CMD "SELECT create_time FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = '$DB' AND table_name NOT LIKE '%tabidx%' AND create_time < NOW() - INTERVAL $DAYS;" | awk '{print $1}' > $TMPFILE
# Apply Count Loop Formula
num=0
cat $TMPFILE | while read tables
do
num=$[$num+1]
TABLE_TO_DELETE=`echo $tables`
# In below CMD , I wrapped the backquote, it took an hour to sort this issue that DASH - sign is not supported in DB/table for older mysql version)
$CMD "use $DB; DROP TABLE \`$TABLE_TO_DELETE\`;"
DATE=`date +'%Y-%m-%d'`
echo "$DB_TRIMMING script deleted TABLE $TABLE_TO_DELETE FROM $DB , confirm it Please. Jz"
logger $DB TRIMMING script ENDED $DATE , $TABLE_TO_DELETE got deleted $DB , confirm it plz
done
echo "$DB TRIMMING script ended $DATE "

You can now schedule it to run daily in night at 00:00 hours by editing CRONTAB

crontab -e

& add following entry

/temp/conntrack_trim.sh

Save & Exit.


2# FOR SYSLOG-NG, to delete SINGLE table created 30 days before – JUNK TEST CODE

Syslog-NG generally creates tables with underscore _ sign, therefore I modified the script as per below

mkdir /temp
touch /temp/syslog_trim.sh
chmod +x /temp/syslog_trim.sh
nano /temp/syslog_trim.sh

Now paste following data, and modify accordingly

#!/usr/bin/env bash
####!/bin/sh
#set -x
# Script to delete XX days older single table from particular DB
# Made for syslog-ng to save disk space
# Syed Jahanzaib / aacable at hotmail dot com / aacable.wordpress.com
#################
#################
#### MODIFY BELOW
#MYSQL DETAILS
SQLUSER="sql_user"
SQLPASS="sql_password"
DB="syslog"
DAYS=30
#################
#################

# Don't modify below
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLUSER --skip-column-names -s -e"
DATE=`date +'%Y-%m-%d'`
DEL_TABLE=`date +'%Y_%m_%d' -d "$DAYS day ago"`
logger syslog_ng script started $DATE , IT WILL DELETE $DEL_TABLE TABLE FROM $DB
# This is one time step.
echo " Script Started @ $DATE "
# --- Now Delete $DEL_TABLE TABLE from $DB table ...
$CMD "use $DB; SHOW TABLES;"
$CMD "use $DB; DROP TABLE $DEL_TABLE;"
DATE=`date +'%Y-%m-%d'`
logger TABLE_TRIMMING script ENDED $DATE , $DEL_TABLE TABLE FROM $DB deleted, confirm it plz
$CMD "use $DB; SHOW TABLES;"
echo "TABLE_TRIMMING  script ENDED at $DATE , $DEL_TABLE TABLE FROM $DB deleted, confirm it Please. Jz"

Regard’s
Syed JAHANZAIB

July 2, 2021

Radius | Disconnect users after service change / user disable

Filed under: Mikrotik Related, Radius Manager — Tags: , , — Syed Jahanzaib / Pinochio~:) @ 8:50 AM


Note for self

In older version of radius manager, when OP disables any user account or change user service package , those changes doesnt take effect until the user disconnect/reconnect. Sometimes user remains connected for days. Back in those days , we made a workaround by creating a mysql trigger and script combination. 

Assuming you have fully functional radius working, along with root access to DB. Save this trigger.sql and import it in mysql radius DB.

Example: mysql -uroot -pMYPASS radius < trigger.sql

Following trigger will check for rm_users table changes, and if it found any changes in the users disable/enable or srvid changes, it will add entry in the rm_kickuserstable & our schedule script will pick the data from there and will act accordingly …

MYSQL > kickuser_trigger

-- Host: localhost Database: radius
-- Server version 5.5.54-0ubuntu0.12.04.1
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8 */ ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
/!50003 CREATE/ /!50017 DEFINER=root@localhost/ /*!50003 TRIGGER kickuser_trigger BEFORE UPDATE ON rm_users
FOR EACH ROW BEGIN
IF NEW.enableuser <> OLD.enableuser THEN
INSERT INTO rm_kickuser (datetime, username, msg) VALUES (NOW(), new.username, new.enableuser);
END IF;
IF NEW.srvid <> OLD.srvid THEN
INSERT INTO rm_kickuser (datetime, username, msg) VALUES (NOW(), new.username, new.srvid);
END IF;
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
---- Dumping routines for database 'radius'
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-07-02 8:24:05

rm_kickuser TABLE

Save following & import it in radius db 

Example: mysql -uroot -pMYPASS radius < rm_kickuser_SQL_DB_Creation.sql

root@radius-zaib:/temp# cat rm_kickuser_SQL_DB_Creation.sql

-- phpMyAdmin SQL Dump
-- version 3.4.10.1deb1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jun 13, 2016 at 10:32 AM
-- Server version: 5.5.46
-- PHP Version: 5.3.10-1ubuntu3.21
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 utf8 */;
--
-- Database: `radius`
--
-- --------------------------------------------------------
--
-- Table structure for table `rm_kickuser`
--
CREATE TABLE IF NOT EXISTS `rm_kickuser` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`username` varchar(64) NOT NULL,
`msg` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=63 ;
--
-- Dumping data for table `rm_kickuser`
--
/*!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 !

Now create the script & schedule it to run every 1 minutes

kick_user.sh

#!/bin/bash
#set -x
# Following script is made specifically for Dmasoftlab radius manager 4.1.x
# When OP disables any user or change service, it will kick the user so that either disconnects, or his package changes on reconnect
# it requires custom trigger on rm_users table, this script will be schedule to run every minute
# Created: 25-MARCH-2019
# Tested on Ubuntu OS Only
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#################
# CHANGE these
HOSTNAME=`hostname`
SQLID="root"
SQLPASS="MYPASSWORD"
NAS_COA_PORT="1700"
DB="radius"
SRV="mysql"
USR_TABLE="rm_kickuser"
MNT="1"
RADCLIENT="/usr/local/bin/radclient"
#################
#DATE TIME FUNCTIONS
currenttime=$(date +%H:%M:%S)
# Add Script start execution entry in the /var/log/syslog to see if the script got executed or not
logger "Kick Disabled/Enabled & Service Change - User poller script Started @ $currenttime by the CRON scheduler ... Powered by SYED.JAHANZAIB"
echo "- Script Start Time - $currenttime"
echo "- Checking Disabled/Enabled Users in $USR_TABLE table ..."
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLID --skip-column-names -s -e"
#Table which contain main users information
TMPUSRINFO=/tmp/_users_list.txt
TEMP="/temp"

# Checking if /temp folder is previously present or not . . .
{
if [ ! -d "$TEMP" ]; then
echo
echo "- INFO: $TEMP folder not found, Creating it now to store logs ..."
mkdir $TEMP
else
echo -e "- INFO: $TEMP folder is already present to store logs."
echo
fi
}

KICKUSER_LIST_FILE=$TEMP/kick_users_list.txt
SYSLOG="/var/log/syslog"
> $TMPUSRINFO
# Check if table exists
if [ $($CMD \
"select count(*) from information_schema.tables where \
table_schema='$DB' and table_name='$USR_TABLE';") -eq 1 ]; then
echo "- INFO: $USR_TABLE Table exists ..."
else
echo "- WARNING: $USR_TABLE Table does not exists ..."
fi
# pull user record
$CMD "use $DB; select username from $USR_TABLE WHERE datetime >= NOW() - INTERVAL $MNT MINUTE;" >> $TMPUSRINFO
if [ ! -s $TMPUSRINFO ]
then
endtime=$(date +%H:%M:%S)

echo "
- INFO: No User to KICK found in DMA RADIUS MANAGER TABLE '$USR_TABLE' , Sending EXIT signals ...

- Script Ends Here...
- EXITING peacefully...
- Script End Time - $endtime
"
exit 1
fi
# Apply Count Loop Formula while deleting first line which have junk text
num=0
cat $TMPUSRINFO | while read users
do
num=$[$num+1]
username=`echo $users | awk '{print $1}'`
USER_IP=`echo $users | awk '{print $2}'`
ACCTSESID=`$CMD "use $DB; select acctsessionid from radacct where username ='$username' AND acctstoptime is NULL;"`
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' ;"`
if [ -z "$ACCTSESID" ]; then
echo "User Found to KICK: USER: $username , BUT USER IS NOT ONLINE, no action is requiroed ..."
else
# Print Info on screen
echo " User Found to KICK: USER: $username , IP: $USER_IP, ID: $ACCTSESID, NAS: $NAS_IP @ $currenttime ... KICKING him now ..."
logger " User Found to KICK: USER: $username , IP: $USER_IP, ID: $ACCTSESID, NAS: $NAS_IP @ $currenttime ... KICKING him now ..."
echo " User Found to KICK: USER: $username , IP: $USER_IP, ID: $ACCTSESID, NAS: $NAS_IP @ $currenttime ... KICKING him now ..." >> $KICKUSER_LIST_FILE
#in below cmd, I am using SSH base method to kick the user because there were some issues in routing & NAS was not accepting radclient packets, you may use the radclient method which is better approach
ssh -p 22 admin@192.168.0.1 /ppp active remove [find name=$username]
#for pppoe , use below
#echo user-name=$username | radclient -x $NAS_IP:$NAS_COA_PORT disconnect $NAS_SECRET
#for hotspot, enable following line
#echo Framed-IP-Address=$USER_IP | radclient -x -c 1 $NAS_IP:$NAS_COA_PORT disconnect $NAS_SECRET
fi
done
# once done, we should delete the tmp files to clear the garbage
rm $TMPUSRINFO

ADDING CRON Entry

*** Schedule the script to run every minute

crontab -e

*/1 * * * * /temp/kickuser.sh > /dev/null 2>&1

Result:

root@radius-zaib:/temp# ./kickuser.sh

- Script Start Time - 08:43:58
- Checking Disabled/Enabled Users in rm_kickuser table ...
- INFO: /temp folder is already present to store logs.
- INFO: rm_kickuser Table exists ...
- INFO: No User to KICK found in DMA RADIUS MANAGER TABLE 'rm_kickuser' , Sending EXIT signals ...

- Script Ends Here...
- EXITING peacefully...
- Script End Time - 08:43:58

 


Regard’s
Syed Jahanzaib

Older Posts »

%d bloggers like this: