Guest User

Untitled

a guest
Dec 2nd, 2019
171
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/perl
  2.  
  3. #
  4. #       - Track files in /etc
  5. #       - Create audit log message with diff for every changed file
  6. #
  7.  
  8. use MIME::Base64;
  9. use strict;
  10.  
  11. sub ensure_file_is_in_git {
  12.  
  13.         my ($path,$file) = @_;
  14.         my ($diff);
  15.         unless ( system("cd $path ; git ls-files --error-unmatch \"$file\" &>/dev/null") == 0 )  {
  16.                 # use git add --force since path may bin in .gitignore
  17.                 system("cd $path ; git add -f $file ; git commit -m 'added new file $path/$file' \"$file\" &>/dev/null ");
  18.                 $diff = `diff -Nru /dev/null "$path/$file"`;
  19.         }
  20.  
  21.         return $diff;
  22. }
  23.  
  24. sub exclude_matched {
  25.  
  26.         my ($file) = @_;
  27.  
  28.         # exclude irrelevant files
  29.         #       - .git directory (track-loop!)
  30.         #       - .etckeeper file/directory (track-loop!)
  31.         #       - Editor Swap-files .swp/.swx/.swy/.swz/*~
  32.  
  33.         if(
  34.                         $file =~ /(\/etc\/\.git|\.etckeeper)/
  35.                 or      $file =~ /\.[^\/]+\.sw[p-z]$/
  36.                 or      $file =~ /\~$/
  37.         ) {
  38.                 return 1;
  39.         }
  40.         return 0;
  41. }
  42.  
  43. sub process_delete {
  44.  
  45.         my ($path,$file) = @_;
  46.         my ($diff);
  47.  
  48.         # if file is contained in git repo
  49.         #
  50.         #       -> create diff
  51.         #       -> delete file from
  52.         #
  53.         # if file is not contained in git repo
  54.         #
  55.         #       -> ignore
  56.         #
  57.  
  58.         if ( system("cd $path ; git ls-files --error-unmatch \"$file\" &>/dev/null") == 0 )  {
  59.  
  60.                 $diff = `cd $path && git diff -- $file 2>/dev/null`;
  61.                 system("cd $path && git rm -- $file; git commit -m 'deleted-file-$file' $file");
  62.                 return $diff;
  63.  
  64.         }
  65. }
  66.  
  67. sub process_modify {
  68.  
  69.         my ($path,$file) = @_;
  70.         my ($diff);
  71.  
  72.         # if file is not in git repo
  73.         #
  74.         #       -> create diff
  75.         #       -> add file to git
  76.         #
  77.         # ---
  78.         # for all:
  79.         #
  80.         #
  81.  
  82.         $diff = ensure_file_is_in_git($path,$file);
  83.  
  84.         # if the prior diff is empty, we get the diff from the git command
  85.         $diff = `cd $path && git diff -- $file 2>/dev/null` unless($diff);
  86.  
  87.         if ($diff ne '') {
  88.                 # commit non-empty changes after detection
  89.                 system("cd $path && git commit -m 'auto-commit-".time()."' $file 2>/dev/null >&2");
  90.         }
  91.  
  92.         return $diff;
  93.  
  94. }
  95.  
  96. sub diff_audit_write {
  97.  
  98.         my ($time,$fullpath,$diff) = @_;
  99.  
  100.         # ignore events with empty diffs
  101.         if($diff ne '') {
  102.  
  103.                 # encode it to base64 to avoid problems with special characters
  104.                 $diff = encode_base64($diff);
  105.  
  106.                 #no linebreaks in audit message!
  107.                 $diff =~ s/\R//g ;
  108.  
  109.                 # create audit message with encoded diff
  110.                 system("auditctl -m 'file_content_tracker $fullpath " .$diff."'");
  111.  
  112.                 print("file change detected: file=$fullpath,time=$time,diff_length=".length($diff)."\n");
  113.         }
  114. }
  115.  
  116. sub main {
  117.  
  118.         my ($inotifywait,$line,$path,$file,$fullpath,$event,$diff,$time);
  119.  
  120.         # watch for file changes
  121.         open($inotifywait,"inotifywait --recursive --monitor --event modify,delete /etc /var/log/yum.log --format '%T %w%f %e' --timefmt '%s' 2>/dev/null|");
  122.  
  123.         while($line=<$inotifywait>) {
  124.  
  125.                 ($time,$fullpath,$event) = split(/[\s]+/,$line);
  126.                 next if(exclude_matched($fullpath));
  127.                 ($path,$file)            = $fullpath =~ /(.*)\/([^\/]+)$/;
  128.  
  129.                 $diff = process_delete($path,$file) if($event eq "DELETE");
  130.                 $diff = process_modify($path,$file) if($event eq "MODIFY");
  131.  
  132.                 diff_audit_write($time,$fullpath,$diff);
  133.  
  134.         }
  135. }
  136.  
  137. main();
RAW Paste Data