Skip to content

cPanel Commands and Scripts

  • Fix Permissions Script
  • Account Info script

  • Check cpHulk IP Block "iptables -S cphulk"

  • Unban IP from cpHulk - "/scripts/hulk-unban-ip customer_ip "

  • Print Ip's that successfully logged in with SSH

Connecting to Customer server via Macha/Pacha

  • After login to the Jump servers use : t ticket_number - This will log you into the server

Check account info leftover DNS for a domain

acctinfo vladmin-dev.top --cruft
alias acctinfo="/usr/local/cpanel/3rdparty/bin/perl <(curl -s https://raw.githubusercontent.com/cPanelInc/tech-acctinfo/master/acctinfo)"

Licence Troubleshooting commands

curl https://cpanel.net/showip.shtml

Official article

alias cplicensets="/usr/local/cpanel/3rdparty/bin/perl <(curl -s https://raw.githubusercontent.com/CpanelInc/tech-cp_license_troubleshooter/master/cplicensets)"

Create session for reseller

  • Create a user session for the root or reseller user
    sessWHM() { ( CPUSER=$1; whmapi1 create_user_session locale=en service=whostmgrd user=$CPUSER | grep url | grep url | awk '{print $2}' ) }
    

Create User Session cpanel/whm

  • cPanel
    whmapi1 create_user_session user=cptest service=cpaneld
    
  • Webmail

    whmapi1 create_user_session user=test@cptest.tld service=webmaild
    
  • WHM

    /scripts/whmlogin 
    
    Or
    
    whmapi1 create_user_session user=root service=whostmgrd
    

ssp sshcheck

    perl <(curl https://ssp.cpanel.net/ssp) --sshcheck

Aliases SSP

source /dev/stdin <<< "$(curl -s https://ssp.cpanel.net/aliases/aliases.txt)" > /dev/null

SSP only

perl <(curl https://ssp.cpanel.net/ssp)

SSP bugreport

perl <(curl https://ssp.cpanel.net/ssp) --bugreport
lsof -nP | grep -i deleted
whmapi1 php_get_vhost_versions | grep -B1 'vhost: maiamarques.pt'

Check Notifications

ls -lahS /var/cpanel/user_notifications/root/history/

cPanel IP addresses Huston

184.94.197.2 - cPanel Houston Office
184.94.197.3 - cPanel Houston Office
184.94.197.4 - cPanel Houston Office
184.94.197.5 - cPanel Houston Office
184.94.197.6 - cPanel Houston Office
208.74.123.98 - cPanel Houston Office

nmap

nmap -Pn -sT --reason -p 22,2083,2087,80,443

openssl test

openssl s_client -connect example.com:port
openssl s_client -connect vladmin.top:443 -servername example.com -showcerts | openssl x509 -text -noout
yum list installed | grep -Ei "^(ea-)?openssl"

Testing Auto SSL

/usr/local/cpanel/3rdparty/bin/perl -MCpanel::DnsRoots -MData::Dumper -e 'print Dumper(Cpanel::DnsRoots->new()->get_nameservers_for_domain("nowofindia.com"));'

Rename hostname with issues of SSL hostname renewal

mv -v /var/cpanel/hostname_history.json{,.bak}

Display crt openssl

openssl x509 -noout -text -in 10-2-32-93.cprapid.com.crt

Custom Commands

 mysql -e 'use mysql; select User, Host from user where User like "db_user%";'

maxr

grep MaxRequestWorkers /var/log/apache2/error_log
- max_children
echo;echo "Count of Times MaxChildren Was Hit Per Domain";for log in $(find /opt/cpanel/ea-php*/root/usr/var/log/php-fpm/ -type f -name error.log);do echo;echo $log; startdate=$( head -1 $log | awk -F"[][]" '{print $2}' );enddate=$( tail -1 $log | awk -F"[][]" '{print $2}' );if [ -z "$startdate" ];then echo "EMPTY";else printf "Log-Start: $startdate\nLog-End: $enddate" | column -t;fi;awk '/server reached max_children/{gsub("_",".",$5);split($5,d,"]");arr[d[1]]++}END{for (i in arr) print arr[i],i|"sort -nr"}' $log ;done

Recreate cpanel version file

whmapi1 version | awk 'NR==3{print $2}' >> /var/cpanel/install_version

Fix packages

  • erase package nodeps

    rpm -e --nodeps --justdb cpanel-pdns
    
  • fix cpanel packages

/scripts/check_cpanel_pkgs --fix
  • rebuild dns config
/scripts/rebuilddnsconfig

Hacked Server Guidelines

Check compromised server via CSI script

/usr/local/cpanel/3rdparty/bin/perl <(curl -s https://raw.githubusercontent.com/cPanelTechs/CSI/master/csi.pl)

check cpu limits

 systemctl show user-1003.slice | grep -i cpu

Firewalld

vim Commands

  • commment lines by number
    :7,10s/^/#/g
    

Bad Bots

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ClaudeBot/1.0 [NC]
RewriteCond %{HTTP_USER_AGENT} SemrushBot/7~bl [NC]
RewriteCond %{HTTP_USER_AGENT} PetalBot [NC]
RewriteCond %{HTTP_USER_AGENT} AhrefsBot/7.0 [NC]
RewriteCond %{HTTP_USER_AGENT} DotBot/1.2 [NC]
RewriteCond %{HTTP_USER_AGENT} Applebot/0.1 [NC]
RewriteCond %{HTTP_USER_AGENT} Meta-ExternalHit/0.9 [NC]
RewriteRule ^.* - [F,L]
</IfModule>

php dependency issue workaround

yum install ea-php84 ea-php84-pear ea-php84-php-bcmath ea-php84-php-calendar ea-php84-php-cli ea-php84-php-common ea-php84-php-curl ea-php84-php-devel ea-php84-php-exif ea-php84-php-fileinfo ea-php84-php-fpm ea-php84-php-ftp ea-php84-php-gd ea-php84-php-gmp ea-php84-php-iconv ea-php84-php-intl ea-php84-php-litespeed ea-php84-php-mbstring ea-php84-php-mysqlnd ea-php84-php-pdo ea-php84-php-posix ea-php84-php-soap ea-php84-php-sockets ea-php84-php-xml ea-php84-php-zip ea-php84-runtime

Rename Hostname history file

 mv -v /var/cpanel/hostname_history.json{,.bak}

DDoS Checks

netstat -an | egrep ":80|:443" | egrep '^tcp' | grep -v LISTEN | awk '{print $5}' | egrep '([0-9]{1,3}\.){3}[0-9]{1,3}' | sed 's/^\(.*:\)\?\(\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*$/\2/' | sort | uniq -c | sort -nr | sed 's/::ffff://' | head
netstat -plant|egrep -i "established|time_wait|syn"|awk '{print $5 " " $6}'|sort -k2,2|sed 's/:/\t/g'|awk '{print $1 " " $3}'|egrep "[0-9].*"|sort -k2,2 -k1|uniq -c|awk 'BEGIN {  EST = 0;  TW = 0;  SYN = 0;}/ESTABLISHED/ {EST += 1;}/SYN_RECV/ {SYN += 2;}/TIME_WAIT/ {TW += 3;}END {print "Established: ", EST;  print "Syn Received: ", SYN;  print "Time Wait: ", TW;}'

Renew Wordpress SSL due to curl error 60

  • In folder /public_html/wp-includes/certificates/ rename and download the new crt file
    mv -v /home/cpaneluser/public_html/wp-includes/certificates/ca-bundle{,.cpbkp}
    
  • Download using wget
    wget https://raw.githubusercontent.com/WordPress/WordPress/refs/heads/master/wp-includes/certificates/ca-bundle.crt
    

account info

curl -o acctinfo -s https://raw.githubusercontent.com/cPanelInc/tech-acctinfo/master/acctinfo

Suspend outgoing EMAIL

whmapi1 --output=jsonpretty \
  suspend_outgoing_email \
  user='institutoklass.org.br'

check where most spam come from

awk '$3 ~ /^cwd/{print $3}' /var/log/exim_mainlog | sort | uniq -c | sed "s|^ *||g" | sort -nr

Outbound connections

grep -E 'domain.com|spam|SMTP connection outbound' /var/log/exim_mainlog |wc -l

check all services

/usr/local/cpanel/libexec/tailwatchd --status

checking mysql users

mysql -e "SELECT COUNT(*) FROM mysql.user WHERE User LIKE 'user%';"
  • users using a remote IP
 mysql -e "SELECT * FROM mysql.user WHERE User LIKE 'singoo%';" | grep 47.254.91.60 | wc -l
1983

Killed processes

 grep Killed /var/log/messages | awk {'print $9'} | sort | uniq -c | sort -nr

ip check

 ip addr | awk 'BEGIN {FS="[ \t/]+"} /inet .+global/ { print $3 }' | xargs -iIP sh -c "echo -n 'internal IP - external ';wget -O - -q --tries=1 --timeout=10 --bind-address=IP http://cpanel.net/myip || echo NO REPLY"
 ```

 ## disk usage all accountsummary

```bash 
 disk_usage=$(\ls /var/cpanel/userdata/ | grep -v nobody | while read user; do repquota -a | grep "^${user}\ "| awk '{print "USER",$1,$3/1024"M"}';done | column -t | sort -k3hr); printf '%s\n' "$disk_usage" && echo -e "---------------";printf '%s\n' "$disk_usage" | awk '{sum += $3} END {print "TOTAL USER DISK: " sum"M"}'

check php versions

rpm -qa | grep -E 'ea-php[5-9][0-5]+-[0-9]\.+'

mysql user connections

 select User,Host,max_user_connections from mysql.user where User like  'storesdp_sytist'\g

apache log

tail -c 2M /etc/apache2/logs/error_log | tail -300 | grep '/home/$username'

top users by process number

ps -eo user | sort | uniq -c | sort -rn | head -5 | grep -v -E 'root|nobody'

bulk email

EMAIL_ACCT=$(for email in $(find mail/python.vladmin-dev.top -maxdepth 1);do echo  $email@python.vladmin-dev.top; done | awk -F "/" 'NR>1 {print $3}');for ACCT in $EMAIL_ACCT;do uapi --user=vmin Email add_pop email="$ACCT" password=`tr -dc '0-9A-Zaz!#!&^!#'</dev/urandom | head -c20`; done
  • Add multiple email accounts

    do uapi --user=vmin Email add_pop email=Email$n$ password=`tr -dc '0-9A-Zaz!#!&^!#'</dev/urandom | head -c20`; done
    
  • Delete the added emails

    for n in {1..50};do uapi --user=vmin Email delete_pop email=$n@python.vladmin-dev.top password=`tr -dc '0-9A-Zaz!#!&^!#'</dev/urandom | head -c20`; done
    
  • Add accounts in bulk for addon domains

    for n in {1..50};do uapi --user=vmin Email add_pop email=mymail$n domain=email-test.python.vladmin-dev.top password=`tr -dc '0-9A-Zaz!#!&^!#'</dev/urandom | head -c20`; done
    

access log bot

awk -F '"'  '$6 ~ /[bB]ot/ {split($0,x," "); print x[1]}' /home/user/access-logs/domain.{,-ssl_log} | sort | uniq -c | sort -nr | head

check spam on server

perl <(curl -s https://raw.githubusercontent.com/cPanelTechs/SSE/master/sse.pl) -s

remove debian package

  • Removing the package without its dependencies same as rpm -e --nodeps
    dpkg -r --force-depends
    
  • Package can be also purged removing all config files for that program/service
    dpkg --purge <package> 
    

strace

TSTAMP=$(date +%s); TDIR=/root/strace/strace-${TSTAMP}; mkdir -p ${TDIR} && echo "Working Directory: ${TDIR}" && strace -ff -T -t -v -s 8192 -o ${TDIR}/pid $(ps auxwww | egrep 'cpsrv[d]|whostmgr[d]|cpanel[d]' | egrep -v 'defunct' | tee ${TDIR}/process-list.txt | awk '{ printf " -p " $2; }')
strace -ttffvvs9048 -o <file> scripts/restartsrv_httpd

Breakdown of Options

  • -tt: Print absolute timestamps with microsecond precision for each system call.
  • -f: Follow child processes created with fork() or clone().
  • -ff: Like -f, but also creates separate output files for each process traced (e.g., -o trace would create trace.<pid> files).
  • -v: Print all system call arguments in full (verbose).
  • -s9048: Specifies the maximum string size to print (in this case, 9048 bytes). This is useful for capturing long strings passed to system calls.
  • -o: Specifies the output file prefix. However, you haven't provided the filename, so the command is incomplete.

    strace -ttffvvs9048 -o trace ls
    
  • If the domain isn’t loading, showing suspended, showing another domain/site

  • With User data information followed by the restart of Apache
    /scripts/updateuserdomains  
    /scripts/updateuserdatacache  
    /scripts/rebuildinstalledssldb  
    /scripts/rebuildhttpdconf
    

top 20 access log

  • for zipped logs

    zcat /var/log/nginx/access.log-202503* | awk '{print $1}' | sort | uniq -c|sort -rn|head -20
    
  • bot hits

    awk '{ print "IP ADDR: " $1, "BOT NAME:" $18 }' | sort | uniq -c | sort -rn | head -20
    
  • top 20 IP's

    perl -nle 'print $& while /(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}/g' /usr/local/cpanel/logs/login_log | awk '{print $1}' | sort | uniq -c|sort -rn|head -20
    
    awk '{print $1}' | sort | uniq -c|sort -rn|head -20
    

logrotate read-only filesystem

grep ProtectSystem /usr/lib/systemd/system/logrotate.service
- Disable ProtectSystem=full with ProtectSystem=false - Restart logrotate and enable it again to ProtectSystem=full

sar logs for the past 9 days

  • Ram

    for i in {1..9};do sar -rh -f /var/log/sa/sa0$i;done | grep -i average
    
  • CPU

    for i in {1..9};do sar -u -f /var/log/sa/sa0$i;done | grep -i average
    
  • tcpdump

    tcpdump -n udp or tcp port 80 or port 443 or port 2087
    

check cPanel services and their memory usage

for service in $(systemctl list-units| grep -i cpanel | awk '{print $1}'); do systemctl status $service;done  | grep -E 'Memory|Main PID'

change package bulk

  • Example 1

    for user in $(cat /etc/trueuserdomains  | awk '{print $2}');do whmapi1 --output=jsonpretty changepackage user=$user pkg=default;done
    
  • Example 2.

for user in $(ls -1 /var/cpanel/users);do whmapi1 --output=jsonpretty changepackage user=$user pkg=default;done

Disable features script

/scripts/featuremod --list default --feature handlers  --value disable

mysql variables and commands

mysql -sse 'SELECT @@GLOBAL.max_user_connections;'
mysql mysql -e 'SELECT User,Host,max_user_connections FROM user WHERE User LIKE "root";'
mysql -sse 'SELECT @@max_user_connections;'

get os version number universal

cat /etc/*release  | grep -o -E '2[0-9]|[0-9]{1}|[0-9]\.[0-9]' | uniq | head -1
  • DIsk usage

    du --exclude=/dev --exclude=virtfs --exclude=/run --exclude=/sys/fs/cgroup --exclude=/tmp -ch / 2>/dev/null | sort -h | tail -31
    
  • ftp passive mode check

    curl -v --ftp-pasv ftp://private_ip/
    
  • IP count access log and number of hits

echo -e "\nCount\t\tLog\t\t\tIP" ; for LoG in $(find /usr/local/apache/domlogs/ -mindepth 2 -type f) ; do awk -F "[][| ]" '$1 ~ "^[0-9]+" && $5 ~ "20/Jun/2025:20:[23]" {count[$1]++}END{for (iP in count) print count[iP],"\t",FILENAME,"\t",iP}' $LoG ; done | sort -n | tail -25 | sed -r "s:/usr/local/apache/domlogs/[a-z0-9]+/::"
- IP's connected to the server and IP hits
netstat -an | egrep ":80|:443" | egrep '^tcp' | grep -v LISTEN | awk '{print $5}' | egrep '([0-9]{1,3}\.){3}[0-9]{1,3}' | sed 's/^\(.*:\)\?\(\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*$/\2/' | sort | uniq -c | sort -nr | sed 's/::ffff://' | head -31

memory info - meminfo/memtop

ps -eo rss,pid,user,command | sort -rn | head -10 | awk '{ hr[1024**2]="GB"; hr[1024]="MB";
 for (x=1024**3; x>=1024; x/=1024) {
 if ($1>=x) { printf ("%-6.2f %s ", $1/x, hr[x]); break }
 } } { printf ("%-6s %-10s ", $2, $3) }
 { for ( x=4 ; x<=NF ; x++ ) { printf ("%s ",$x) } print ("\n") }'

Scan cPanel user with acctinfo

/usr/local/cpanel/3rdparty/bin/perl <(curl -s https://raw.githubusercontent.com/cPanelInc/tech-acctinfo/master/acctinfo) --scan $cPuser

Disable modsec vendor

/usr/local/cpanel/scripts/modsec_vendor disable comodo_apache
  • Remove the vendor
    /usr/local/cpanel/scripts/modsec_vendor remove comodo_apache
    

python requests test

python3 -c 'import requests;resp = requests.get("http://mirrors.almalinux.org");print(resp)'
python3 -c 'import requests;requests.packages.urllib3.util.connection.HAS_IPV6=False;resp = requests.get("http://mirrors.almalinux.org");print(resp)'

SNI mismatch log create

bash -lc 'CONF=/etc/apache2/conf.d/includes/pre_main_global.conf; MARK="# BEGIN sni_mismatch_421"; \grep -Fq "$MARK" "$CONF" 2>/dev/null || cat >> "$CONF" <<'"'"'EOF'"'"'# BEGIN sni_mismatch_421CustomLog /var/log/apache2/sni_mismatch_421.log "%t %a vhost=%v srv=%A:%p proto=%H alpn=%{SSL_ALPN_PROTOCOL}x tls=%{SSL_PROTOCOL}x cipher=%{SSL_CIPHER}x cert_cn=%{SSL_SERVER_S_DN_CN}x issuer_cn=%{SSL_SERVER_I_DN_CN}x sni=%{SSL_TLS_SNI}x host=%{Host}i referer=\"%{Referer}i\" ua=\"%{User-Agent}i\" uid=%{UNIQUE_ID}e \"%r\" %>s %b" "expr=(%{HTTPS} == \"on\" && %{SSL_TLS_SNI} != %{HTTP_HOST}) || (%{REQUEST_STATUS} == 421)"# END sni_mismatch_421EOF/scripts/restartsrv_apache'
  • Fix ubuntu signing keys error resulting in hash mismatch.

    /scripts/updatesigningkey
    
  • check installed php versions

    scl list-collections
    
  • license regex

    curl -s https://verify.cpanel.net/app/verify?ip=62.176.91.79 | egrep -B1 "<b>active|<b>expired on"|sed -e 's/<[^>]*>//g'
    
  • python available memory command

    python3 -c 'import psutil; available_mem = psutil.virtual_memory().available >> 30;print(f"Available Memory {available_mem}GB")'
    
  • Sed change ea-php to alt-php

    for file in $(find . -maxdepth 2 -name '.htaccess');do sed -i 's/x-httpd-ea-php/x-httpd-alt-php/g' $file;done
    
  • Enable extensions in alt-php for php-fpm

    Symlinking the shipped `php.d.all/<ext>.ini` (vs. hand-writing a line) matters specifically for ionCube: it's a Zend extension, so its directive is `zend_extension=…`, not `extension=…`. The packaged ini already has that correct and because it's a symlink to the RPM-managed file, the directive stays correct across `alt-php84` updates. For ordinary extensions you can equally just add `extension=<name>.so` to `/opt/alt/php84/link/conf/default.ini` (Ahmed's method). Same pattern for other extensions aswell. Every available module has an ini in `/opt/alt/php84/etc/php.d.all/`  That you can link from.
    
ln -s /opt/alt/php84/etc/php.d.all/ioncube_loader.ini /opt/alt/php84/link/conf/00-ioncube_loader.ini

ls -al /opt/alt/php84/link/conf/00-ioncube_loader.ini
lrwxrwxrwx 1 root root 47 May 30 12:25 /opt/alt/php84/link/conf/00-ioncube_loader.ini -> /opt/alt/php84/etc/php.d.all/ioncube_loader.ini
- Screen command
screen -dmLS upcp /scripts/upcp --force
  • Check Opened screen sessions.

     screen -ls
    
  • Backup destinations parse json dat

# All disable_reason values as an array
whmapi1 --output=json backup_destination_list | jq '[.data.destination_list[].disable_reason]'

# Full destination_list array (all fields)
whmapi1 --output=json backup_destination_list | jq '.data.destination_list[]'

# Specific index (first entry)
whmapi1 --output=json backup_destination_list | jq '.data.destination_list[0].disable_reason'

# Filter only entries where disable_reason is not empty/null
whmapi1 --output=json backup_destination_list | jq '.data.destination_list[] | select(.disable_reason != "" and .disable_reason != null) | .disable_reason'
  • Extract rpm package files manually with yumdownloader and rpm2cpio
    yumdownloader ea-libxml2
    
rpm2cpio ea-libxml2-2.15.3-1.3.1.cpanel.x86_64.rpm | cpio -idmv
  • All excluded domains on the server.

    for cpuser in $(ls -1 /var/cpanel/users/);do whmapi1  get_autossl_user_excluded_domains --output=jsonpretty username=$cpuser;done | jq -r '.data.payload[].excluded_domain'
    
  • List users with more than 2G email usage.

    for cpuser in $(find /var/cpanel/users/ -type f -not -name "nobody" -not -name "domchange" -not -name system | cut -d"/" -f5); do   size=$(du -sm "/home/$cpuser/mail" 2>/dev/null | cut -f1);   [ "${size:-0}" -gt 2048 ] && echo "$cpuser $((size/1024))G"; done