{"id":11337,"date":"2012-03-18T18:44:31","date_gmt":"2012-03-18T17:44:31","guid":{"rendered":"https:\/\/www.saasweb.agency\/blog\/how-can-you-easily-verify-the-integrity-of-installed-files-on-a-debian-system\/"},"modified":"2026-10-27T08:20:55","modified_gmt":"2026-10-27T07:20:55","slug":"how-can-you-easily-verify-the-integrity-of-installed-files-on-a-debian-system","status":"publish","type":"post","link":"https:\/\/www.saasweb.agency\/en\/blog\/how-can-you-easily-verify-the-integrity-of-installed-files-on-a-debian-system\/","title":{"rendered":"How can you easily verify the integrity of installed files on a Debian system?"},"content":{"rendered":"<p><a href=\"https:\/\/www.saasweb.agency\/wp-content\/uploads\/2012\/03\/openlogo-100.png\"><img decoding=\"async\" class=\"alignleft size-full wp-image-933\" title=\"Debian\" src=\"https:\/\/www.saasweb.agency\/wp-content\/uploads\/2012\/03\/openlogo-100.png\" alt=\"\" width=\"100\" height=\"123\" srcset=\"https:\/\/www.saasweb.agency\/wp-content\/uploads\/2012\/03\/openlogo-100.png 100w, https:\/\/www.saasweb.agency\/wp-content\/uploads\/2012\/03\/openlogo-100-50x62.png 50w, https:\/\/www.saasweb.agency\/wp-content\/uploads\/2012\/03\/openlogo-100-81x100.png 81w\" sizes=\"(max-width: 100px) 100vw, 100px\" \/><\/a><\/p>\n<p>When using monitoring tools such as <em>tripwire<\/em> or <em>rkhunter<\/em> to monitor changes to installed files, the problem is that these tools cannot detect whether the files were changed by a regular package upgrade or tampered with by an unauthorized person.<\/p>\n<p>For example, if <em>rkhunter<\/em> reports that the file <em>\/usr\/bin\/ldd<\/em> has been modified, you must manually check whether the file&#8217;s checksum corresponds to the latest version of the Debian package.<\/p>\n<p>There is a tool called <strong>debsums<\/strong> that simplifies this task. It can be installed using: <\/p>\n<div class=\"code-snippet\"># apt-get install debsums<\/div>\n<p>Once the tool is installed, you can perform the check at the package level:<\/p>\n<div class=\"code-snippet\"># debsums file<br \/>\n\/usr\/bin\/file OK<br \/>\n\/usr\/share\/bug\/file\/control OK<br \/>\n\/usr\/share\/bug\/file\/presubj OK<br \/>\n\/usr\/share\/doc\/file\/README.Debian OK<br \/>\n\/usr\/share\/doc\/file\/README.gz OK<br \/>\n\/usr\/share\/doc\/file\/changelog.Debian.gz OK<br \/>\n\/usr\/share\/doc\/file\/changelog.gz OK<br \/>\n\/usr\/share\/doc\/file\/copyright OK<br \/>\n\/usr\/share\/lintian\/overrides\/file OK<br \/>\n\/usr\/share\/man\/man1\/file.1.gz OK<\/div>\n<p>but not at the file level:<\/p>\n<div class=\"code-snippet\"># debsums \/usr\/bin\/ldd<br \/>\ndebsums: invalid package name &#8216;\/usr\/bin\/ldd&#8217;<\/div>\n<p>First, you need to find out which package the file \/usr\/bin\/ldd belongs to.<\/p>\n<div class=\"code-snippet\"># dpkg -S \/usr\/bin\/ldd<br \/>\nlibc-bin: \/usr\/bin\/ldd<\/div>\n<p>To avoid having to run the search every time, I have written a small shell script that handles this task and calls debsums with the results:<\/p>\n<div class=\"code-snippet\">#!\/bin\/bash<br \/>\nEC=0<br \/>\nPKGS=$(dpkg -S &#8220;$@&#8221; | awk -F&#8217;:&#8217; &#8216;{print $1}&#8217; | sed -e &#8216;s\/, \/\\n\/g&#8217; | sort | uniq)<br \/>\nfor i in $PKGS; do<br \/>\ndebsums &#8220;$i&#8221; | grep -v OK<br \/>\ndec=$PIPESTATUS<br \/>\necho -n &#8220;=== Package &#8216;$i&#8217; : &#8221;<br \/>\nif [ $dec -eq 0 ]; then echo OK; else echo MODIFIED; EC=$dec; fi<br \/>\ndone<br \/>\nexit $EC<\/div>\n<p>In this example, I have named the script check-inst.sh. It is easy to use: <\/p>\n<div class=\"code-snippet\"># .\/check-inst.sh \/usr\/bin\/ldd<br \/>\n=== Package &#8216;libc-bin&#8217; : OK<\/div>\n<p>You can call the script with multiple filenames:<\/p>\n<div class=\"code-snippet\"># .\/check-inst.sh \/usr\/bin\/file \/usr\/bin\/ldd<br \/>\n=== Package &#8216;file&#8217; : OK<br \/>\n=== Package &#8216;libc-bin&#8217; : OK<\/div>\n<p>If you do not use an absolute path, you will get search results for installed packages:<\/p>\n<div class=\"code-snippet\"># .\/check-inst.sh apache2<br \/>\n=== Package &#8216;apache2&#8217; : OK<br \/>\n=== Package &#8216;apache2.2-bin&#8217; : OK<br \/>\n=== Package &#8216;apache2.2-common&#8217; : OK<br \/>\n=== Package &#8216;apache2-doc&#8217; : OK<br \/>\n=== Package &#8216;apache2-mpm-prefork&#8217; : OK<br \/>\n=== Package &#8216;apache2-suexec&#8217; : OK<br \/>\n=== Package &#8216;apache2-utils&#8217; : OK<br \/>\n=== Package &#8216;bash-completion&#8217; : OK<br \/>\n=== Package &#8216;libapache2-mod-fcgid&#8217; : OK<br \/>\n=== Package &#8216;libapache2-mod-php5&#8217; : OK<br \/>\n=== Package &#8216;libapache2-mod-ruby&#8217; : OK<br \/>\n=== Package &#8216;libapache2-mod-suphp&#8217; : OK<\/div>\n<p>If the results are OK, you can update your monitoring tool with peace of mind. For example, with rkhunter: <\/p>\n<div class=\"code-snippet\"># rkhunter &#8211;propupd &#8211;update<\/div>\n<p>Here is an example output showing the files modified by the user:<\/p>\n<div class=\"code-snippet\"># .\/check-inst.sh \/usr\/bin\/pear<br \/>\n\/usr\/bin\/pear FAILED<br \/>\n\/usr\/bin\/peardev FAILED<br \/>\n\/usr\/bin\/pecl FAILED<br \/>\n&#8230;<br \/>\n\/usr\/share\/php\/pearcmd.php FAILED<br \/>\n\/usr\/share\/php\/peclcmd.php FAILED<br \/>\n=== Package &#8216;php-pear&#8217; : MODIFIED<\/div>\n<p>The script returns <strong>ExitCode 0<\/strong> if all checks were successful; otherwise, it returns the error code of the first failed check. This is useful if you are initially only interested in the exit code and want to read the error results from a log file. <\/p>\n<p>Have fun trying it out!<br \/>\nC.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When using monitoring tools such as tripwire or rkhunter to monitor changes to installed files, the problem is that these tools cannot detect whether the files were changed by a regular package upgrade or tampered with by an unauthorized person. For example, if rkhunter reports that the file \/usr\/bin\/ldd has been modified, you must manually \u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[981,983],"tags":[988,1112,960,1153,1930,1010,1078,1062,982,1001,1028],"class_list":["post-11337","post","type-post","status-publish","format-standard","hentry","category-programming","category-tutorial","tag-administration","tag-checksum","tag-debian","tag-debsums","tag-dpkg","tag-integrity","tag-monitoring","tag-monitoring-tool","tag-package-management","tag-rkhunter","tag-tripwire"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/posts\/11337","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/comments?post=11337"}],"version-history":[{"count":0,"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/posts\/11337\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/media?parent=11337"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/categories?post=11337"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.saasweb.agency\/en\/wp-json\/wp\/v2\/tags?post=11337"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}