How to monitor all file changes in public_html directory

propopulus

Member
Jan 29, 2013
6
0
1
cPanel Access Level
DataCenter Provider
Hello,

Basically I need a way to monitor all changes made to files in the public_html directory. Say if someone edited the index.php file then I would get an email informing me of the change. I would prefer real time, but every hour is also fine.

-This feature cannot be based off of a PHP script in the public_html directory. I am looking for something that cannot be altered if someone has the ability to inject PHP code. I would prefer some sort of cPanel/WHM add-on.

I know there is a way to do this, I just don't know how, I appreciate any feedback!

Thanks!
 

JaredR.

Well-Known Member
Feb 25, 2010
1,834
27
143
Houston, TX
cPanel Access Level
Root Administrator
I am not personally aware of an add-on that will do this, but this is what the Linux audit system is for. You can set an audit watch on any file (note that in Linux, a directory is also considered a file, so an audit watch can be set on directory). This is a tutorial I have used in the past that is helpful:

Linux audit files to see who made changes to a file

audit is likely already installed on your server, so you may not need to install the audit RPM packages mentioned.

You can get even more information about the Linux audit system by searching for "linux audit tutorial" in any search engine.
 

quietFinn

Well-Known Member
Feb 4, 2006
2,042
553
493
Finland
cPanel Access Level
Root Administrator
I have used just a simple crontab job like:

49 * * * * find /home/CPANELUSERNAME/public_html -mtime -1 \! -type d -ls
 

propopulus

Member
Jan 29, 2013
6
0
1
cPanel Access Level
DataCenter Provider
I am not personally aware of an add-on that will do this, but this is what the Linux audit system is for. You can set an audit watch on any file (note that in Linux, a directory is also considered a file, so an audit watch can be set on directory). This is a tutorial I have used in the past that is helpful:

Linux audit files to see who made changes to a file

audit is likely already installed on your server, so you may not need to install the audit RPM packages mentioned.

You can get even more information about the Linux audit system by searching for "linux audit tutorial" in any search engine.
This is very helpful thank you for directing me in the right direction.

quietFinn I do not understand what your code does.
 

mambovince

Well-Known Member
Jan 15, 2005
193
0
166
London, UK
I found the following which has a slightly different cron command:
How To Monitor File Changes On hosting account
How To Monitor File Changes On Web Server - Webmasters - Nairaland

- Login to your cPanel
- Under "Advanced" submenu, you will see "Cron Jobs". Click it
- Tweak the settings to suit you (either you want alerts hourly/daily/weekly)
- There is a section for "Commands", type in

find /home/xxxxxxxxx/public_html -type f -ctime -1 -exec ls -ls {} \;
Any experts able to clarify which would be most appropriate or what the main differences are please?
Many thanks
 

cerberusgr

Registered
Sep 25, 2013
2
0
1
cPanel Access Level
Root Administrator
Hello,

I have made a quick and ugly python script for this job, it runs every 3 hours through cron, it scans all user's public_html directory and sends me the list of files that have changed the last 182 minutes, and it has some basic exclude list to filter out garbage from caching mechanisms which create/update files all the time. I found it very useful for me at least because i can track malware faster and more efficient and keeping my server not blacklisted :)

here is the script files_changed.py
Code:
#!/usr/bin/python
import smtplib
from email.mime.text import MIMEText

# This is the send mail function
# it takes 3 strings: destination address, subject, and text as input
# Fill here your email account details i use the same server.
def send_mail(to_address, subject, text):
   from_address = '[email protected]'
   msg = MIMEText(text)
   msg['subject'] = subject
   msg['From'] = from_address
   msg['To'] = to_address

   s = smtplib.SMTP('localhost:587')
   s.ehlo()
   s.starttls()
   s.login('[email protected]', 'your_email_password')
   s.sendmail(from_address, to_address, msg.as_string())
   s.quit

import os
import subprocess
import re
import string

# this list used to exclude files that starts with this string
# keep in mind that you place here the path after /home/user/public_html
# for example if you want to exclude /home/user/public_html/wp-content/cache you just write '/wp-content/cache'
excluded_paths = ['/wp-content/cache',
                  '/wp-content/plugins/si-contact-form/captcha/cache',
                  '/magento/var/cache',
                  '/assets/cache',
]

# It takes the output of find command in one string, 
def check_lines(output, userpath):
   new_output = ""
   # split the output string to check line by line
   lines = output.split('\n')
   for line in lines:
      exclude_it = False
      # here is where the exclusion list filter works
      # 
      for ex_path in excluded_paths:
         if (re.match(userpath + ex_path , line) != None):
            exclude_it = True
            break
      # filter out files ends with error_log
      if (re.match(r'(.*error_log$)', line) != None):
         exclude_it = True
      if (exclude_it == False) and (line !=''):
         new_output += line + '\n'
   return new_output

user_list = os.listdir("/var/cpanel/users/")

message = ""

for user in user_list:
   userpath = "/home/" + user + "/public_html"
   # here is the find command, -182 is how many minutes back
   # i choose to see changes every 3 hours, i run this script every 3 hours on my server thats why i have 182
   p = subprocess.Popen(["find", userpath, "-name", "*", "-mmin", "-182", "-print"], stdout = subprocess.PIPE)
   output, err = p.communicate()
   if (output != ""):
      processed_output = check_lines(output, userpath)
      if (processed_output != ''):
         message += "username: " + user + '\n'
         message += processed_output + '\n'

# where to send the email and what subject
send_mail('[email protected]', 'File changes', message)
Hope this will help you and anyone else with the same problem :)
 

santrix

Well-Known Member
Nov 30, 2008
230
4
68
Or maybe a simple one liner run from cron that does pretty much the same :p

Code:
cd /home/user/public_html; find . \( -path './*/wp-content/cache' -o -path './*/var/cache' \) -prune -o -mmin -180 -print | /bin/mail -s "Files changed in the last 3hrs" [email protected]
 

santrix

Well-Known Member
Nov 30, 2008
230
4
68
As a customer just pointed out, this may not work with Jailshell, but sendmail should be available...

Code:
cd /home/user/public_html; find . \( -path './*/wp-content/cache' -o -path './*/var/cache' \) -prune -o -mmin -180 -print | (echo -e "Subject: Files changed in the last 3hrs\n" && cat --) | /usr/sbin/sendmail [email protected]
 

chromahoen

Registered
Oct 28, 2015
1
0
1
I'm here.
cPanel Access Level
Root Administrator
In order to authenticate through Gmail smtp servers I had to changecerberusgr's script to...
Code:
def send_mail(to_address, subject, text):
   from_address = 'MY_GMAIL_ADDRESS'
   msg = MIMEText(text)
   msg['subject'] = subject
   msg['From'] = from_address
   msg['To'] = to_address

   s = smtplib.SMTP('smtp.gmail.com',587)
   s.ehlo()
   s.starttls()
   #I had to s.ehlo() again or the script returned with error: smtplib.SMTPException: SMTP AUTH extension not supported by server
   s.ehlo()
   s.login(from_address, 'MY_PASSWORD')
   s.sendmail(from_address, to_address, msg.as_string())
   #s.quit
   s.close()
Also, on my server, the mime type wanted to be called from a different library...

import smtplib
#from email.mime.text import MIMEText
from email.MIMEText import MIMEText

It took me awhile, but I have it figured out for now. Nice script. Wow, Python's nice, eh?
 
Last edited by a moderator: