{"id":2263,"date":"2026-06-15T13:41:08","date_gmt":"2026-06-15T06:41:08","guid":{"rendered":"https:\/\/tutorial.emka.web.id\/?p=2263"},"modified":"2026-06-15T13:41:08","modified_gmt":"2026-06-15T06:41:08","slug":"how-to-secure-linux-server-with-aide","status":"publish","type":"post","link":"https:\/\/emka.web.id\/en\/2026\/06\/how-to-secure-linux-server-with-aide.html","title":{"rendered":"How to Secure Linux Server with AIDE"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">If you run Linux server, you must make sure nobody change your files without you knowing. Sometimes hackers can enter your system and change important files like config files or system binaries so they can control your server forever. We can stop this with tool called AIDE which means Advanced Intrusion Detection Environment. It is like guard that takes pictures of all your files and compares them later to see if someone changed something. In this guide, I will show you how to set up AIDE and make it run automatically every day using systemd timer so you don&#8217;t have to do it manually.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">Before we start installing, we must understand how AIDE works. AIDE looks at directories you tell it to check in configuration file which is <code>\/etc\/aide.conf<\/code>. It reads every file and makes cryptographic hashes. A hash is like fingerprint of file. If hacker change only one character in important file, the hash will change completely and AIDE will notice it immediately. When you first setup AIDE, you make baseline database. This database is the normal state of your system. Every check after that will compare current files with this database. If they are different, AIDE will show you error and tell you which file is modified.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, we must initialize the database for AIDE. If you already install AIDE on your Ubuntu or Debian or Fedora, you can run the initialization command. To make the first database, you must open your terminal and type this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo aide --init<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This command will take some minutes because it must scan every file on your system. Do not close terminal while it is running. It will calculate hashes for thousands of files. When it is finished, it will create new database file. But this file is named <code>aide.db.new.gz<\/code> and AIDE cannot use it for checking yet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because AIDE looks for database named <code><strong>aide.db.gz<\/strong><\/code>, we must rename the file we just created. We can do this easily with move command. Type this in your terminal:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mv \/var\/lib\/aide\/aide.db.new.gz \/var\/lib\/aide\/aide.db.gz<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, the baseline database is in correct place. AIDE is ready to perform check on your system files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now we must test if check command is working correctly. We do this by typing this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo aide --check<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Since we just created database, there should be no changes on system files. The command should run and tell you that there are zero differences. If it shows some differences, it might be because some logs or temporary files changed while you were running initialization. But usually, it should be clean.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We do not want to run check command manually every day because we can forget and it is very boring. We want system to do it automatically. We can use systemd service for this. Systemd is manager for services in Linux. We will create a service file that tells systemd how to run AIDE. Let write the service file with this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo tee \/etc\/systemd\/system\/aide-check.service &gt; \/dev\/null &lt;&lt;'EOF'<br>&#091;Unit]<br>Description=AIDE file integrity check<br>After=local-fs.target<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>&#091;Service]<br>Type=oneshot<br>ExecStart=\/usr\/sbin\/aide --check<br>Nice=15<br>IOSchedulingClass=idle<br>EOF<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Let me explain what this code means. In <code>[Unit]<\/code> section, we have <code>Description<\/code> which is just text to describe service. We also have <code>After=local-fs.target<\/code> which means systemd will wait until all local hard drives are mounted before running this service. This is important because if hard drives are not ready, AIDE cannot find files. In <code>[Service]<\/code> section, we have <code>Type=oneshot<\/code>. This means the service runs once and then exits. It is not daemon that runs constantly. <code>ExecStart<\/code> is the actual command that runs AIDE check. <code>Nice=15<\/code> is very helpful because it gives service lower priority. If server is busy, AIDE will not take all CPU power. <code>IOSchedulingClass=idle<\/code> is also very good because it tells system to only let AIDE read disk when other programs are not using disk. This prevents your server from lagging.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now we need timer to trigger this service every day. Systemd timer is much better than old cron job. Let create the timer file with this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo tee \/etc\/systemd\/system\/aide-check.timer &gt; \/dev\/null &lt;&lt;'EOF'<br>&#091;Unit]<br>Description=Run AIDE file integrity check daily<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>&#091;Timer]<br>OnCalendar=daily<br>Persistent=true<br>RandomizedDelaySec=30m<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>&#091;Install]<br>WantedBy=timers.target<br>EOF<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Let me explain this timer file. In <code>[Timer]<\/code> section, we have <code>OnCalendar=daily<\/code> which means it will run once every day. <code>Persistent=true<\/code> is very important feature. If your server is turned off when timer should run, systemd will remember this and run service immediately when server starts again. If we don&#8217;t use this, we might miss many checks. <code>RandomizedDelaySec=30m<\/code> is also very useful. It adds random delay up to 30 minutes before starting check. This is good if you have many virtual machines on same physical host, so they do not all start checking files at same exact second, which can make physical disk very slow. In <code>[Install]<\/code> section, we have <code>WantedBy=timers.target<\/code> which means timer will start when system boots up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now we have created both files. But systemd does not know about them yet because we just wrote them to disk. We must tell systemd to reload its configuration files. Run this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl daemon-reload<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After reloading, we must enable and start the timer so it can start counting time. We can do both with single command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl enable --now aide-check.timer<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>--now<\/code> option is very cool because it starts timer immediately without needing separate start command.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We want to make sure our timer is active and running. We can check list of active timers in systemd with this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl list-timers aide-check.timer --no-pager<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This command will show table with information about when timer will run next time. It also shows how much time is left before execution. If you see it in list, it means everything is configured correctly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After the timer runs for first time, we want to see report of AIDE check. Systemd sends all output from services to journal system. We can read these logs by using journalctl command. Type this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo journalctl -u aide-check<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will show you everything AIDE printed during check. If there are no changes, it will tell you system is clean. If there are changes, it will list all files that were added, deleted, or modified. You must read these logs carefully.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sometimes you need to make changes to your server. For example, you might run update command like <code>sudo apt upgrade<\/code> or <code>sudo dnf upgrade<\/code>. This will update packages and change many files on your hard drive. This is legitimate change made by you. But next time AIDE runs, it will see these changes and print many alerts because it does not know you did the update. To solve this, we must tell AIDE to update its database to match new state of system. We can run update command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo aide --update<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This command will scan system again and create new database file. Just like before, this file will be named <code>\/var\/lib\/aide\/aide.db.new.gz<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We must replace old database with new updated database so next checks will be quiet again. Run this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mv \/var\/lib\/aide\/aide.db.new.gz \/var\/lib\/aide\/aide.db.gz<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now AIDE has new baseline database. Next daily check will not alert you about packages you updated. You must do this process every time you make changes to configuration files or install new software. It is important habit because if you ignore alerts, you will not notice when hacker actually changes something.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let talk about how to customize what AIDE checks. Configuration file is <code>\/etc\/aide.conf<\/code>. Inside, there are rules. Some directories change constantly, like <code>\/var\/log<\/code> or <code>\/tmp<\/code>. We do not want AIDE to check these because they change every minute and will make too many alerts. In configuration file, we can exclude them. We use exclamation mark <code>!<\/code> before directory path to tell AIDE to ignore it. For example, <code>!\/tmp<\/code> means ignore temp directory. If you have custom directory with very sensitive data, you can add it to <code>\/etc\/aide.conf<\/code> so AIDE will monitor it too. Just write directory path and rule name at bottom of file. Remember, if you change configuration file, you must run initialization or update command again.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Using AIDE with systemd timer is great way to keep your Linux system secure without spending money on expensive security tools. It runs quietly in background and only alerts you when something changes. By setting up low priority with systemd, your server will not lose performance. Make sure to check logs regularly and update database after you do system maintenance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you run Linux server, you must make sure nobody change your files without you knowing. Sometimes hackers can enter your system and change&#8230;<\/p>\n","protected":false},"author":27,"featured_media":2264,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[569],"tags":[4480,4481,4482,4483,4484,4485,4486,4487,4488,4489],"class_list":["post-2263","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-computer-security","tag-aide-conf-exclude-directory-example","tag-aide-database-update-command-linux","tag-aide-file-integrity-check-tutorial","tag-check-modified-files-linux-command","tag-how-to-configure-aide-in-centos","tag-how-to-read-aide-report-logs","tag-linux-file-integrity-monitoring-open-source","tag-setup-aide-systemd-service-ubuntu","tag-systemd-timer-daily-schedule-example","tag-systemd-timer-randomized-delay-sec"],"_links":{"self":[{"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/posts\/2263","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/comments?post=2263"}],"version-history":[{"count":0,"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/posts\/2263\/revisions"}],"wp:attachment":[{"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/media?parent=2263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/categories?post=2263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/emka.web.id\/en\/wp-json\/wp\/v2\/tags?post=2263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}