Course: Service Management and Task Scheduling on Linux
Learning Objectives
By the end of this course, you will be able to:
- Understand the difference between daemons and services
- Master systemd and systemctl
- Create and manage your own systemd services
- Schedule tasks with cron and at
- Perform backups with rsync
- Manage log rotation with logrotate
Part 1 – Introduction to Daemons and Services
1.1 Definition: What is a Daemon?
A daemon is a program that runs in the background, without a graphical interface, and works silently to provide essential services to the system or users.
Simple Examples:
sshd: allows remote connections via SSHhttpd: Apache web servercrond: schedules task executionsystemd: orchestrates all other services at startup
1.2 Technical Definition: Nature and Function of a Daemon
A daemon is an independent system process, launched:
- either at system startup
- or manually by the administrator
- and which does not stop until explicitly stopped.
It is:
- detached from any terminal or user session (
tty) - often created by the init process (PID 1), now systemd in most modern distributions.
1.3 How are Daemons Created?
3 Steps:
- Initial Launch via a configuration file or script
- Detachment from the current terminal
- Continuous Execution, often in an infinite loop, until stopped or crashed
On modern systems, systemd handles this management automatically via .service units.
1.4 Daemon Names End with d
This is a naming convention:
sshd→ Secure Shell Daemonftpd→ FTP Daemonsystemd→ System Daemonrsyslogd→ Remote SYSLOG Daemon
1.5 List of Common Daemons in Linux
| Daemon | Main Function |
|---|---|
sshd | Allows SSH connections |
crond | Manages scheduled tasks |
httpd | Provides a web service (Apache) |
systemd | Controls services and system startup |
rsyslogd | Manages system logging |
cupsd | Manages printing |
ntpd | Synchronizes time with NTP servers |
1.6 Daemons vs Services
- A daemon is a process, a service is a logical abstraction.
- A service can be a daemon, but not always (e.g.,
tmp.mountis not a process but a unit).
| Element | Daemon | Service |
|---|---|---|
| Nature | Background process | Unit managed by systemd |
| Visible? | No, except via ps, systemctl | Visible with systemctl |
| Example | sshd | sshd.service |
A service is simply systemd
| Criterion | Daemon | Service (systemd) |
|---|---|---|
| Definition | Program that runs in the background | Unit managed by systemd to launch and manage a program |
| Launch | Automatic or manual (often at startup) | Managed with systemctl (start, stop, enable, etc.) |
| Runs in the background? | Yes | Not always (e.g., a short script can be a service) |
Managed by systemctl? | No, unless integrated as a service | Yes |
Requires a .service file | No | Yes (e.g., /etc/systemd/system/my_service.service) |
Can exist without systemd | Yes (old systems, manual scripts) | No (service = systemd unit) |
| Examples | sshd, cron, infinite background script | nginx.service, docker.service, my_script.service |
Key Takeaways:
- A daemon is a program.
- A service is a way to manage this program with
systemd.
1.7 Controlling Daemons
Under systemd, all daemons are controlled via systemctl, with the following commands:
| Action | Command |
|---|---|
| Start | sudo systemctl start sshd |
| Stop | sudo systemctl stop sshd |
| Restart | sudo systemctl restart sshd |
| View status | sudo systemctl status sshd |
| Enable at boot | sudo systemctl enable sshd |
| Disable at boot | sudo systemctl disable sshd |
1.8 In Summary – Key Points to Remember
- A daemon is a process without an interface, which provides a service.
- It is often started at boot, managed by systemd.
- To view, enable, disable, or restart a daemon, use
systemctl. - All modern system services are now units managed by systemd.
Part 2 – Introduction to systemd and systemctl
2.1 What is systemd?
systemd is the default initialization system for most modern Linux distributions (Ubuntu, Fedora, Debian, CentOS, etc.). It replaces the old SysVinit system and serves to:
- Initialize the system at startup (mount disks, start services, etc.)
- Manage all system services centrally
- Offer integrated tools such as
systemctl,journalctl,systemd-analyze,systemd-nspawn, etc.
Advantages of systemd:
- Faster startup thanks to parallel initialization
- Automatic service restart in case of failure
- Advanced management of service dependencies
- Centralized logging
2.2 The Role of systemctl
systemctl is the main command-line tool for interacting with systemd.
It allows you to:
- Start, stop, or restart a service
- Enable or disable a service at startup
- Get the status of a service
- Display all active or inactive services
2.3 Fundamental Commands with systemctl
| Action | Command |
|---|---|
| Start a service | sudo systemctl start service_name |
| Stop a service | sudo systemctl stop service_name |
| Restart a service | sudo systemctl restart service_name |
| Reload configuration | sudo systemctl reload service_name |
| Check status | systemctl status service_name |
| Enable a service at startup | sudo systemctl enable service_name |
| Disable a service at startup | sudo systemctl disable service_name |
Replace service_name with the actual name of the service (e.g., sshd, nginx, apache2, etc.).
2.4 Viewing Services
Display all active services:
systemctl list-units --type=service --state=running
Display all services (active or not):
systemctl list-units --type=service
2.5 Using journalctl to View Logs
systemd integrates a centralized logging system: journald.
You can view logs with the journalctl command.
| Purpose | Command |
|---|---|
| View all logs | journalctl |
| View logs for a specific service | journalctl -u service_name |
| View logs since the last boot | journalctl -b |
| Follow logs in real-time | journalctl -f |
| View logs from the last hour | journalctl --since "1 hour ago" |
2.6 Units in systemd
A unit is an object that systemd can manage. Each unit corresponds to a file with a specific extension.
| Unit Type | Extension | Example |
|---|---|---|
| Service | .service | nginx.service |
| Mount | .mount | home.mount |
| Socket | .socket | cups.socket |
| Target | .target | multi-user.target |
| Timer | .timer | logrotate.timer |
2.7 systemd Targets
A target represents a global system state, equivalent to the old runlevels.
| Target Name | Description |
|---|---|
rescue.target | Rescue mode (root access only) |
multi-user.target | Multi-user mode without graphical interface |
graphical.target | Mode with graphical interface |
default.target | Default target at startup |
Change the current target:
sudo systemctl isolate multi-user.target
2.8 Analyzing Startup Performance
Measure total startup time:
systemd-analyze
List services sorted by loading time:
systemd-analyze blame
View the critical chain of dependencies:
systemd-analyze critical-chain
2.9 Managing Automatic Restarts
To force the automatic restart of a service after a failure, modify or create a .service unit with:
[Service]
ExecStart=/path/to/script
Restart=always
RestartSec=5
This restarts the service 5 seconds after each failure.
2.10 Summary
systemdis the modern unit manager for Linux systemssystemctlis the command-line interface for interacting withsystemd- Services, targets, sockets, and other resources are called units
journalctlallows you to view system logs- Tools like
systemd-analyzeallow you to analyze startup performance
Part 3 – Creating and Managing Your Own Services with systemd
3.1 Objective of this Part
Understand how to:
- Create a custom service unit
- Integrate a system script into systemd
- Test, enable, disable, and restart this service
3.2 Structure of a .service File
Service files are typically located in:
/etc/systemd/system/(custom and persistent units)/lib/systemd/system/(units installed by packages)
Example of webapp.service file:
[Unit]
Description=Custom service to launch a web application
After=network.target
[Service]
ExecStart=/usr/local/bin/webapp
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Explanation of Sections:
[Unit]: service dependencies, description[Service]: command to execute, restart policy[Install]: activation target (here, multi-user level)
3.3 Steps to Create a Custom systemd Service
Step 1 – Write or Locate the Script to Execute
Example:
sudo nano /usr/local/bin/webapp
Script content:
#!/bin/bash
while true; do
echo "Application running" >> /var/log/webapp.log
sleep 30
done
Make the script executable:
sudo chmod +x /usr/local/bin/webapp
Step 2 – Create the Service Unit
sudo nano /etc/systemd/system/webapp.service
Copy the following content:
[Unit]
Description=Web Application Custom Service
After=network.target
[Service]
ExecStart=/usr/local/bin/webapp
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Step 3 – Enable and Start the Service
Reload systemd to account for the new file:
sudo systemctl daemon-reload
Enable the service at startup:
sudo systemctl enable webapp
Start the service:
sudo systemctl start webapp
Step 4 – Verify Proper Functioning
Display the service status:
systemctl status webapp
Check the logs:
journalctl -u webapp
3.4 Modifying an Existing Service
If you modify the .service file:
- Save
- Reload the configuration:
sudo systemctl daemon-reload
- Restart the service:
sudo systemctl restart webapp
3.5 Removing a Custom Service
Disable the service:
sudo systemctl disable webapp
Stop the service:
sudo systemctl stop webapp
Remove the unit file:
sudo rm /etc/systemd/system/webapp.service
Reload systemd:
sudo systemctl daemon-reload
3.6 Practical Case: Automatic Restart of a Crashed Script
In the [Service] block, use:
Restart=always
RestartSec=5
This allows:
- Automatic restart after failure
- A 5-second wait between each restart
3.7 Practical Case: Temporary Non-Persistent Service
Create a service that you want to run only once, without registering it for future startups:
sudo systemctl start /etc/systemd/system/webapp.service
Without enable, the service will not start at the next reboot.
3.8 Summary
- Custom systemd services are defined in
.servicefiles - They allow integrating any script into the system
- Using the commands
daemon-reload,enable,start,statusis essential - A good service includes a robust restart policy
- The structure
[Unit],[Service],[Install]is mandatory
Appendix of Part 3 – You Cannot "Kill" a Service with kill or lsof
This appendix demonstrates that you cannot permanently stop a service managed by systemd using kill, kill -9, or by targeting the process (e.g., via lsof / ss). systemd will restart it as long as the Restart=always policy is in effect. The only proper way to stop it is systemctl stop (and possibly disable or mask).
Verify the Service is Running and Writing to the Log
cat /var/log/webapp.log
cat /var/log/webapp.log | wc -l
See the PID of the Service
sudo systemctl status webapp
You will see a line like: Main PID: 1234 (webapp).
Kill the Process with kill (SIGTERM)
sudo kill 1234
Then recheck:
sudo systemctl status webapp
You will observe that the service goes back to active (running) with a new PID: systemd has restarted it.
More Aggressive: kill -9 (SIGKILL)
sudo kill -9 <NEW_PID>
sudo systemctl status webapp
Same result: systemd restarts the process again, because Restart=always.
Live Proof
In a terminal, follow the service logs:
sudo journalctl -u webapp -f
You will see successive restarts after each kill or kill -9.
The Solution: Stop via systemd
sudo systemctl stop webapp
sudo systemctl status webapp
To prevent the service from restarting at the next boot or being relaunched by systemd:
- Option A (simple) – Disable at startup
sudo systemctl disable webapp
- Option B (strong) – Mask the service (impossible to start)
sudo systemctl mask webapp
After mask, even systemctl start webapp will not be able to start it until you do sudo systemctl unmask webapp.
Reminder: Signals and Tools
| Action | Command / Tool |
|---|---|
| "Clean" termination (SIGTERM) | kill -15 <PID> or kill <PID> |
| Force stop (SIGKILL) | kill -9 <PID> |
| See who uses ports / files | sudo lsof -i, sudo lsof -i :80 |
| See TCP/UDP ports in listening | sudo ss -ltnp, sudo ss -lunp, sudo ss -ltnp | grep -i ... |
These tools are used to diagnose (which process is listening on a port, etc.); to stop a service, you must use systemctl stop.
Appendix of Part 3 (2) – Same Exercise with the webapp Service (Exam Scenario)
This appendix repeats the same demonstration as in Appendix 1, but using only the webapp service created in step 3 of this chapter (script writing to /var/log/webapp.log), without nginx or Wiki.js. It can serve as a basis for an exam on systemd Services and Process Management.
Prerequisite: the webapp service has been created, enabled, and started as in sections 3.2 and 3.3 (script /usr/local/bin/webapp, unit /etc/systemd/system/webapp.service, Restart=always).
Step 1 – Verification of the Service and the Log
Verify that the service is running and writing to the log:
cat /var/log/webapp.log
cat /var/log/webapp.log | wc -l
sudo systemctl status webapp
In the output of systemctl status webapp, note the line Main PID: XXXX (webapp).
Step 2 – Attempt Manual Stop (kill)
Replace <PID> with the Main PID displayed:
sudo kill -15 <PID>
# or simply: sudo kill <PID>
Then recheck:
sudo systemctl status webapp
Observation: the service goes back to active (running) with a new PID; systemd has restarted it due to Restart=always.
Step 3 – More Aggressive Attempt (kill -9)
Use the new PID displayed by systemctl status webapp:
sudo kill -9 <NEW_PID>
sudo systemctl status webapp
Observation: same result — systemd restarts the process again.
Step 4 – Live Proof (journalctl)
In a terminal, follow the service logs to see the restarts after each kill:
sudo journalctl -u webapp -f
Step 5 – Service Identification (if starting from the process)
If you only had a PID or a port, you could identify the service like this:
systemctl list-units --type=service --state=running | grep -i webapp
ps aux | grep webapp
ls -l /etc/systemd/system/ | grep webapp
For a service listening on a port (e.g., 3000), you would also use:
sudo lsof -i -P -n | grep 3000
sudo ss -ltnp | grep 3000
Here, webapp does not listen on a port; it only fills /var/log/webapp.log.
Step 6 – Solution: Stop and Disable via systemd
Immediate stop:
sudo systemctl stop webapp
sudo systemctl status webapp
Disable at startup (the service will no longer restart at the next boot):
sudo systemctl disable webapp
Stronger option — mask the service (impossible to start while masked):
sudo systemctl mask webapp
To unmask later: sudo systemctl unmask webapp.
Complementary Tools (bonus) – Investigation and Diagnosis
These commands allow you to deepen the investigation on services and ports. They are useful in exams or troubleshooting.
1. systemd-cgls — Control Group Tree (cgroups)
Displays the hierarchy of cgroups managed by systemd: each service (including webapp) lives in a subtree. Useful to see how systemd groups processes.
systemd-cgls
To see only the part concerning our service:
systemd-cgls | grep -A 5 webapp
What is it for? Understand that systemd isolates and tracks each unit in a cgroup; this explains why a simple kill of the process does not "deregister" the service — systemd monitors the unit and restarts it according to Restart=always.
2. ss -lptn — Listening TCP Ports and Processes
Lists listening TCP sockets with the PID and the program associated (-l listening, -p process, -t TCP, -n ports in numeric).
sudo ss -lptn
Example output (excerpt):
LISTEN 0 128 *:80 *:* users:(("nginx",pid=1234,fd=6))
LISTEN 0 128 *:3000 *:* users:(("node",pid=5678,fd=21))
In our context: the webapp service from step 3 does not listen on any port (it only writes to /var/log/webapp.log). If you later created a service that listens on port 3000 (e.g., an API or a proxy), you would see it here. It is the modern equivalent of netstat -lptn, faster.
3. fuser -k 3000/tcp — Kill Processes Using a Port
fuser indicates which processes use a file or a port. The -k option sends SIGKILL to these processes.
Example for port 3000 (to use if a service listens on this port):
sudo fuser -k 3000/tcp
Teaching note: if a systemd service (e.g., a future "webapp-api") listened on port 3000 with Restart=always, after fuser -k 3000/tcp the process would be killed, but systemd would restart it and the port would be occupied again. To permanently free the port, you must systemctl stop <service> (and possibly disable).
Without -k, it only displays the PIDs without killing: sudo fuser -v 3000/tcp.
4. journalctl -u webapp — Service Logs (equivalent to journalctl -u wikijs.service)
Displays all journald messages for the webapp unit (starts, stops, restarts, errors).
journalctl -u webapp
Useful variants:
| Command | Effect |
|---|---|
journalctl -u webapp | All service logs |
journalctl -u webapp -f | Follow logs in real-time (like tail -f) |
journalctl -u webapp -n 50 | The last 50 lines |
journalctl -u webapp --since "1 hour ago" | Logs from the last hour |
What is it for? See the proof that systemd restarts the service after a kill or a fuser -k, and diagnose startup errors.
Synthesis (exam type)
| Action | Command | Effective? |
|---|---|---|
| Stop the process with a signal | kill -15 <PID> or kill -9 <PID> | No — systemd restarts the service |
| Properly stop the service | sudo systemctl stop webapp | Yes |
| Prevent restart at boot | sudo systemctl disable webapp | Yes |
| Prevent any start (even manual) | sudo systemctl mask webapp | Yes |
To remember: with a systemd service configured in Restart=always, kill and kill -9 are not enough; you must use systemctl stop, then disable (and possibly mask) for a definitive deactivation.
Part 4 – Task Scheduling with cron
4.1 Introduction
cron is a tool that allows you to schedule repetitive tasks on Linux.
The crond daemon runs in the background and reads crontab files to execute commands at specific dates/times.
4.2 Structure of a cron Task
* * * * * command to execute
- - - - -
| | | | |
| | | | +----- day of the week (0 to 6, Sunday = 0)
| | | +----------- month (1 to 12)
| | +----------------- day of the month (1 to 31)
| +----------------------- hour (0 to 23)
+---------------------------- minute (0 to 59)
4.3 Quick Tip for Practice
Edit the crontab for the current user:
crontab -e
Display existing cron tasks:
crontab -l
4.4 Exercise 1 – Backup /etc Every Sunday at 3 AM
Objective:
Create a script that archives /etc into /var/backups.
Steps:
- Create an exercise folder:
mkdir ~/cron_tp && cd ~/cron_tp
- Create a
backup.shfile:
nano backup.sh
Content:
#!/bin/bash
tar -czf /var/backups/etc-backup-$(date +%Y%m%d).tar.gz /etc
- Make the script executable:
chmod +x backup.sh
- Create the destination folder if needed:
sudo mkdir -p /var/backups
- Add to crontab:
crontab -e
Add the following line:
0 3 * * 0 /home/user/cron_tp/backup.sh
Replace user with your Linux username.
4.5 Exercise 2 – Have Fun with Text
Objective:
Write "Hello! Today is [date]" every 5 minutes into a file.
Command in crontab:
*/5 * * * * echo "Hello! Today is $(date)" >> /tmp/hello.txt
Then check:
tail /tmp/hello.txt
4.6 Exercise 3 – Create a Dynamic Web Page that Changes Every Minute
Objective:
Download different web pages every minute and display them in the web folder.
Steps:
- Create a
mypage.shfile:
nano ~/cron_tp/mypage.sh
Content:
#!/bin/bash
urls=("www.yahoo.com" "www.cmaisonneuve.qc.ca" "www.crosemont.qc.ca" "www.netflix.com")
index_file="/home/$USER/index.txt"
backup_dir="/var/www/html"
index=0
if [[ -f "$index_file" ]]; then
read -r index < "$index_file"
fi
url=${urls[$((index % ${#urls[@]}))]}
wget -qO "$backup_dir/index.html" --timeout=10 "$url"
next_index=$(( (index + 1) % ${#urls[@]} ))
echo "$next_index" > "$index_file"
- Make the script executable:
chmod +x ~/cron_tp/mypage.sh
- Launch the task every minute:
crontab -e
Add:
* * * * * /home/user/cron_tp/mypage.sh
- Test by accessing:
http://localhost/index.html
Every minute, the page will change automatically.
4.7 Exercise 4 – Monitor Processes and Users
Objective:
Monitor who is connected and which processes are running between 9 AM and 5 PM.
Add to crontab:
# Every hour between 9 AM and 5 PM: processes
0 9-17 * * 1-5 ps aux >> /var/log/processes.txt
# Every 5 minutes between 9 AM and 5 PM: connected users
*/5 9-17 * * 1-5 who >> /var/log/who.txt
Then view:
tail /var/log/processes.txt
tail /var/log/who.txt
4.8 Tip: Test Your cron Tasks Live
To ensure everything works:
- Set a task every minute:
* * * * * echo "Test task at $(date)" >> ~/cron.log
- Launch:
tail -f ~/cron.log
Wait a minute: the line will automatically appear.
4.9 Summary
cronallows you to execute scripts at specific times, automatically.- A cron script must be executable and specify an absolute path.
- You can observe results with
tail, or create.logfiles to verify your tests. - This system allows for backups, automated tests, or dynamically updating services.
Part 5 – One-Time Tasks with at
5.1 What is at?
The at program allows you to schedule a single task to be executed later, once (unlike cron, which is repetitive).
It is perfect for:
- Scheduling a system reboot
- Running a deferred processing script
- Automating a sensitive operation at a specific time
5.2 Checking and Installing the atd Service
First, ensure that the atd daemon is active:
sudo systemctl start atd
sudo systemctl enable atd
sudo systemctl status atd
If at is not installed:
sudo apt install at # Debian/Ubuntu
sudo yum install at # CentOS/RHEL
5.3 Basic Syntax
at <time or moment>
Examples:
at now + 1 minute
at 17:00
at 09:30 tomorrow
at now + 2 days
Once in the at> editor, type the command to execute, then finish with Ctrl + D.
5.4 Exercise 1 – Schedule a Delayed Message
Objective:
Display a message on your terminal in 1 minute.
- Launch the command:
at now + 1 minute
- In the
at>prompt, type:
echo "This is a message scheduled with at"
- Finish with:
Ctrl + D
- Wait a minute and check that the message appears.
5.5 Exercise 2 – Deferred Script on Another Terminal
Objective:
Display a message on another terminal (e.g., /dev/pts/0).
- Create a
traitement.shscript:
nano ~/cron_tp/traitement.sh
Content:
#!/bin/bash
echo "Deferred message on terminal /dev/pts/0" > /dev/pts/0
- Make the script executable:
chmod +x ~/cron_tp/traitement.sh
- Schedule the script:
at now + 2 minutes -f ~/cron_tp/traitement.sh
Open the pts/0 terminal in parallel and observe.
5.6 Managing at Tasks
| Action | Command |
|---|---|
| View scheduled tasks | atq or at -l |
| Remove a task (ID = 5 for example) | atrm 5 or at -d 5 |
| View the content of task ID 5 | at -c 5 |
5.7 Access Control for at
| File | Function |
|---|---|
/etc/at.allow | Only users listed here can use at |
/etc/at.deny | All users except those listed here can use at |
Priority:
- If
at.allowexists, only users in this file have the right. - Otherwise,
at.denyapplies.
Example: Deny toto
echo toto >> /etc/at.deny
5.8 Exercise 3 – Schedule a Reboot on Friday at 5 PM
Objective:
Automate a reboot at a specific date.
- Type:
at 17:00 Fri
- In the
at>prompt, enter:
sudo /sbin/shutdown -r now
- Finish with
Ctrl + D
Note: To test without rebooting, use echo "Scheduled reboot" instead.
5.9 Exercise 4 – Automatic Script in 2 Days
- Create a simple script:
echo "echo Processing completed in 2 days" > ~/cron_tp/futur.sh
chmod +x ~/cron_tp/futur.sh
- Schedule it:
at now + 2 days -f ~/cron_tp/futur.sh
5.10 Summary
atis useful for one-time, unique, deferred tasks.- It complements
cron, which is cyclical. - You can observe immediate effects with
echo, or build deferred scripts.
Part 6 – Advanced and Scheduled Backups with rsync
6.1 Why Use rsync?
rsync is a powerful synchronization tool that allows you to copy files:
- locally or between two machines
- in an optimized manner (it only copies modified files)
- with compression, filtering, backup, and logging
It is ideal for:
- regular backups
- server migrations
- fast differential copies
6.2 Basic Syntax
rsync [options] source destination
Simple example:
rsync -av /home/user/documents /mnt/backup/
Common options:
-a: archive (preserves permissions, links, dates)-v: verbose (displays what is copied)--delete: deletes files absent from the source--bwlimit=KBps: limits the bandwidth used
6.3 Exercise 1 – Local Backup with Bandwidth Limitation
Objective:
Backup the /home folder to /mnt/backup every evening at 8 PM, without saturating the bandwidth.
Steps:
- Create the script:
mkdir -p ~/cron_tp
nano ~/cron_tp/sync_home.sh
Content:
#!/bin/bash
rsync -av --delete --bwlimit=200 /home/ /mnt/backup/
- Make the script executable:
chmod +x ~/cron_tp/sync_home.sh
- Add to
crontab:
crontab -e
Add:
0 20 * * * /home/user/cron_tp/sync_home.sh
(Replace user with your actual name)
6.4 Exercise 2 – Remote Synchronization
Objective:
Synchronize /var/www to another server via SSH.
- Direct command (to test manually before automation):
rsync -avz -e ssh /var/www user@remote_host:/backup/www
- Automated script:
nano ~/cron_tp/rsync_remote.sh
Content:
#!/bin/bash
rsync -az -e ssh /var/www user@192.168.0.100:/backup/www
- Crontab (daily execution at 1 AM):
0 1 * * * /home/user/cron_tp/rsync_remote.sh
Prerequisites:
- SSH access without password (configured public/private key)
- write permissions on
/backup/wwwon the remote machine
6.5 Exercise 3 – Backup Only at Night
Objective:
Limit rsync execution to non-working hours (7 PM to 7 AM).
Stop any rsync process during the day.
Steps:
rsynclaunch script:
crontab -e
Add:
0 19 * * * /home/user/cron_tp/sync_home.sh
- Safety stop script:
0 7 * * * pkill rsync
This ensures that:
rsyncstarts at 7 PM- If still active at 7 AM, it is killed
6.6 Exercise 4 – Backup with Logging
- Script:
nano ~/cron_tp/rsync_logged.sh
Content:
#!/bin/bash
date >> /var/log/rsync_backup.log
rsync -av --delete /home /mnt/backup >> /var/log/rsync_backup.log 2>&1
- Daily scheduling:
0 22 * * * /home/user/cron_tp/rsync_logged.sh
- Read the log:
tail -n 20 /var/log/rsync_backup.log
6.7 Summary
rsyncis a fast, intelligent, and controllable tool- It can be bandwidth-limited with
--bwlimit - It can be automated with
cron - It can be restricted to certain time slots
- It allows for complete logging for audit and tracking
Part 7 – Log Management and Rotation with logrotate
7.1 Why Use logrotate?
System logs (in /var/log/) continuously grow over time:
- They can saturate the disk
- Become heavy to consult
- Can reduce performance if poorly managed
logrotate allows you to:
- Perform automatic log rotation
- Delete or compress old files
- Keep a limited history over time
- Execute a command after rotation (e.g., restart a service)
7.2 General Operation
logrotate is typically executed daily by cron, via:
/etc/cron.daily/logrotate
It reads the global configuration:
/etc/logrotate.conf
And the specific configurations:
/etc/logrotate.d/
7.3 Configuration File Syntax
Example:
/var/log/webapp.log {
weekly
rotate 4
compress
missingok
notifempty
postrotate
systemctl restart webapp
endscript
}
Explanations:
weekly: rotation every weekrotate 4: keep 4 old filescompress: compress old logsmissingok: do not display an error if the file is missingnotifempty: do not rotate the file if it is emptypostrotate: execute a command after rotation
7.4 Exercise 1 – Rotation of a Custom Log
Objective:
Rotate /var/log/rsync_backup.log every week, keep 4 compressed versions.
- Create the file
/etc/logrotate.d/rsync_backup:
sudo nano /etc/logrotate.d/rsync_backup
- Content:
/var/log/rsync_backup.log {
weekly
rotate 4
compress
missingok
notifempty
}
- Test the configuration:
sudo logrotate /etc/logrotate.conf --debug
- Force rotation for testing:
sudo logrotate /etc/logrotate.conf --force
- Verify:
ls -lh /var/log/rsync_backup*
7.5 Exercise 2 – Rotation with Service Restart
Objective:
Rotate /var/log/webapp.log and restart the webapp service.
- Create the file:
sudo nano /etc/logrotate.d/webapp
- Content:
/var/log/webapp.log {
weekly
rotate 2
compress
missingok
notifempty
postrotate
systemctl restart webapp
endscript
}
- Force a rotation to test:
sudo logrotate -f /etc/logrotate.conf
7.6 Exercise 3 – Rotation and Email Sending (Simulation)
Objective:
Send the last 100 lines of the /var/log/syslog file every night at midnight.
- Add to crontab:
crontab -e
Content:
0 0 * * * tail -n 100 /var/log/syslog | mail -s "Latest system logs" youraddress@email.com
- To test sending locally:
mail
Prerequisite: the system must have a mail agent installed (mailutils, sendmail, postfix...).
7.7 Exercise 4 – Custom Rotation of a Simulated File
- Create a fake log:
echo "test line" >> /tmp/test.log
- Create the file
/etc/logrotate.d/testlog:
sudo nano /etc/logrotate.d/testlog
Content:
/tmp/test.log {
daily
rotate 3
compress
missingok
notifempty
}
- Force rotation:
sudo logrotate -f /etc/logrotate.conf
- Observe the files:
ls -lh /tmp/test.log*
7.8 Summary
logrotatemanages the size, frequency, retention, and compression of logs- It integrates perfectly with
cron(via/etc/cron.daily/logrotate) - It can restart services or send emails
- Custom configuration files go in
/etc/logrotate.d/
Part 8 – Final Quiz and Practical Evaluation
8.1 Educational Objective
Validate that the learner knows how to:
- Create, enable, and monitor a custom systemd service
- Schedule repetitive and one-time tasks with
cronandat - Synchronize folders with
rsyncand limit bandwidth - Manage log rotation with
logrotate - Use the right monitoring tools (
systemctl,journalctl,logrotate, etc.)
8.2 Part A – Reading and Analyzing crontab (5 points)
Explain what each line does:
0 3 * * 0 /usr/local/bin/backup.sh*/10 9-17 * * 1-5 who >> /var/log/connected.log@reboot systemctl restart nginx0 19 * * * /home/user/sync.sh0 7 * * * pkill rsync
8.3 Part B – Creating a systemd Service (15 points)
You must create a service called weather_logger that:
- Executes a script
/usr/local/bin/weather.sh - Writes the temperature to
/var/log/weather.logevery 5 minutes (via cron) - The service must automatically restart in case of failure
- Provide the
weather_logger.servicefile - Enable and start the service
- Check its status and logs
8.4 Part C – Deferred Scheduling with at (5 points)
- Create a script
/home/user/alert.shthat sends a message "Security test completed" to a file/tmp/alert.log. - Schedule this script to execute in 2 hours exactly from now.
8.5 Part D – rsync Synchronization (10 points)
Create a script sync_project.sh that:
- Backs up the
/home/user/projects/folder to/mnt/backups/ - Deletes obsolete files (
--delete) - Limits bandwidth to 150 KB/s
- Logs actions to
/var/log/sync.log
Schedule this script to run every night at 10 PM.
8.6 Part E – Log Rotation with logrotate (10 points)
-
Create a configuration file
/etc/logrotate.d/weatherfor the file/var/log/weather.log -
Requirements:
- Weekly rotation
- 3 files retained
- Compression enabled
- Rotate even if empty
- Restart the
weather_loggerservice after rotation
8.7 Part F – Final Case Study: Complete Scenario (15 points)
Context: You manage a Linux server running a custom application (/usr/local/bin/monitor.py).
Objectives:
- Create a
monitor.servicethat executes this script at system startup. - Schedule a backup of the
/opt/monitoringdirectory every day at 1 AM to/mnt/monitor_backupwithrsync, limited to 250 KB/s. - Create a file
/etc/logrotate.d/monitoring.logfor/var/log/monitoring.log, with rotation every 2 days, retaining 5 compressed logs. - Send the last 100 lines of
/var/log/syslogby email every morning at 6 AM toadmin@example.com.
8.8 Grading (out of 60 points)
| Part | Points |
|---|---|
| A – crontab Analysis | 5 |
| B – systemd Service | 15 |
C – Scheduling with at | 5 |
| D – rsync Script | 10 |
| E – Custom logrotate | 10 |
| F – Complete Case | 15 |
8.9 Final Instructions
-
All scripts must be executable (
chmod +x) -
Paths must be absolute
-
You must show the output of:
systemctl statusjournalctl -uls -lhin log and backup directories
Chapter created on: December 2024