Scheduling tasks with cron: beyond the basics

Automating repetitive tasks on a Linux system can be made easy with cron, a time-honored job scheduler in Linux and other Unix-like operating systems. Whether you’re a sysadmin, a power user or an ethical hacker, mastering cron can automate tasks and save you valuable time.

This article goes beyond the basics of cron, discussing its lesser-known features and capabilities. We’ll take a look at the details of cron syntax, introduce special strings for easier scheduling, manage output and errors, troubleshoot issues, and discuss security aspects.

We’ll start with a brief overview of the basic syntax before moving into more advanced topics. By the end of this article, you’ll have a comprehensive understanding of how to use cron more efficiently for task automation. Now, let’s get started with exploring advanced uses of cron.

Understanding crontab and cron syntax

Cron is managed through the crontab command, which stands for “cron table.” The crontab is a list of tasks scheduled to run at specified times for a particular user. The crontab utility supports the following flags:

  • crontab -e: Edits the current user’s cron jobs.
  • crontab -l: Displays the current user’s cron jobs.
  • crontab -r: Deletes all the current user’s cron jobs.

Note: when crontab -e is executed for the first time, a list of installed text editors is displayed and we are prompted to select the default one. To change the editor afterwards we can use the select-editor command.

A cron job is represented by a line with six fields, separated by spaces. These fields define the job’s timing and the command to run, in this order:

[Minute] [Hour] [Day of month] [Month] [Day of week] [Command]
FieldRangeDescription
Minute0-59Specifies the minute(s) to execute the task
Hour0-23Specifies the hour(s) to execute the task
Day of the Month1-31Specifies the day(s) to execute the task
Month1-12 or January, February, etc.Specifies the month(s) to execute the task
Day of the Week0-7 (0 and 7 both represent Sunday)Specifies the day(s) of the week to execute the task
CommandPath to the executable and parametersThe command to be executed on the specified schedule
The values we can use for each field in the crontab file.

We can use single numbers for precise timing (like “5” in the hour field for a job at 5 AM), ranges (like “1-5” in the day field for the first five days of the month), or lists (like “1,15” in the day field for the 1st and 15th of the month). An asterisk (*) serves as a wildcard, meaning the task will run at every time unit in that field:

Cron ExpressionDescription
30 8 * * * /usr/bin/dateExecutes the/usr/bin/date command at 8:30 AM every day
0 0 * * 1 /usr/bin/dateExecutes the date command at midnight every Monday
0 12 * * 1,4 /usr/bin/dateExecutes the date command at noon every Monday and Thursday
Some examples

The root user and permissions

In addition to the individual user crontabs, system-wide cron jobs can be managed by the root user. These system-wide cron jobs can be found in a few different places:

  • /etc/crontab: This is the system-wide crontab file. Like user crontabs, it also contains a list of cron jobs, but unlike user crontabs, it includes an additional field for the user that should run the job (For example: 0 0 * * 1 root /usr/bin/date).
  • /etc/cron.d/: This directory can contain additional crontab files. The configuration is similar to /etc/crontab.
  • /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly: These directories contain scripts that are run automatically every hour, day, week, or month, respectively.

The root user can also manage individual user crontabs with the crontab command by specifying the username with the -u option, like crontab -u username -e to edit a user’s crontab.

Cron access on a system is controlled by two files: /etc/cron.allow and /etc/cron.deny.

  • If /etc/cron.allow exists, only the users listed in this file (one user per line) can use the crontab command.
  • If /etc/cron.allow does not exist but /etc/cron.deny does, any user not listed in /etc/cron.deny can use the crontab command.
  • If neither file exists, the ability to use the crontab command depends on the system’s specific configuration parameters. Typically, only the super user (root) or all users will be able to use the command.
  • If both files exist, /etc/cron.allow takes precedence. /etc/cron.deny is ignored and a user must be listed in /etc/cron.allow to use the crontab command.

Special strings

Cron offers a set of special strings that provide shortcuts for scheduling tasks. These strings are particularly useful for tasks that need to run on a regular cycle, such as system startup or at certain time intervals.

For instance, the @reboot string can be used to ensure that a particular task (like a script) runs every time the system boots up:

@reboot /path/to/startup_script.sh

Here’s a table that summarizes the available special strings in cron, what they mean, and an example of their usage:

Special StringDescriptionEquivalent Cron SyntaxExample
@rebootRuns the task upon system startupN/A@reboot /path/to/startup_script.sh
@yearly or @annuallyRuns the task once a year0 0 1 1 *@yearly /path/to/yearly_task.sh
@monthlyRuns the task once a month0 0 1 * *@monthly /path/to/monthly_task.sh
@weeklyRuns the task once a week0 0 * * 0@weekly /path/to/weekly_task.sh
@daily or @midnightRuns the task once a day at midnight0 0 * * *@daily /path/to/daily_task.sh
@hourlyRuns the task once an hour0 * * * *@hourly /path/to/hourly_task.sh

These special strings offer a cleaner syntax compared to the traditional cron time fields for common scheduling needs.

Output and error handling

By default cron forwards any output, both standard and errors, to the job owner via local mail. But, it’s also quite versatile; we can redirect outputs to files or even customize our recipient list.

Output and errors

To redirect output to a file, use > and >>, just like you would in the terminal. Let’s say you have a backup script that you’d like to monitor:

30 2 * * * /path/to/backup_script.sh > /path/to/output.log

This cron expression sends the output to output.log, overwriting it each run. If you prefer to keep previous logs, use >> to append the output.

Cron can also handle redirecting both stdout and stderr, again, just like you would in a terminal:

30 2 * * * /path/to/backup_script.sh > /path/to/output.log 2>&1

With this setup we’ll direct the error output (2) to where the standard output (1) is going.

Handling emails

By default cron emails are sent to the local mailbox of the user running the cron job. For example, if the user john has a cron job, the emails will be sent to john‘s local mailbox. To access these emails, the user can use a command-line mail client like mail or mutt.

However, you might prefer a more modern touch – receiving job outputs in your personal inbox. We can set the MAILTO variable in the script we are running in cron like this:

MAILTO=your-email@example.com

Note that for this to be possible a Mail Transfer Agent (like postfix or sendmail) has to be installed and configured first. If you’d rather not receive any emails, just clear the MAILTO variable.

Security considerations

Cron is a very powerful tool for automating tasks, therefore it is absolutely essential to consider the security implications when using it. In this section, we’ll briefly explore some security considerations to keep in mind when working with cron:

  1. Proper file and directory permissions: Set correct permissions and ownership for scripts and files executed by cron jobs to prevent unauthorized access or modification.
  2. Secure sensitive data: Avoid storing sensitive data like passwords or API keys in plain text within your cron job scripts. Use secure methods like environment variables or encrypted files.
  3. Restrict cron job Creation: Limit cron job creation to trusted users only by using the /etc/cron.allow or /etc/cron.deny files.
  4. Control environment variables: Instead of relying on system-wide environment variables, define the necessary variables within your cron job script.
  5. Regular review and updates: Periodically review your cron jobs, remove any that are unnecessary or outdated, and keep your system up to date with the latest security patches and updates.

Of course the same considerations apply when we are in a CTF environment (or during a penetration test). For example here are some questions we might ask ourselves:

  1. Are there any cron jobs running scripts with weak or insecure file permissions? Could these be modified or exploited?
  2. Is there sensitive information stored in plain text within the scripts run by cron jobs? Could this data be accessed or exposed?
  3. Can any user create cron jobs on the system? If so, could this be exploited to run malicious tasks?
  4. Are there cron jobs that rely on system-wide environment variables? Could these be manipulated to alter the behavior of the cron jobs?
  5. Are there any outdated or unnecessary cron jobs running? Could these be exploited due to old vulnerabilities or could they provide information useful for further attacks?
  6. Are there scripts being run as cron jobs that contain sensitive information in the source code? Could this be accessed or exposed?
  7. Are the scripts run by cron jobs properly maintained and updated with the latest security patches? Could outdated scripts be exploited?

More cron resources

In the cyber world, coffee is the potion of champions. Support my efforts by offering me a virtual cup through 'Buy Me a Coffee'! Let's unravel the enigmas of CTF challenges and fortify our cyber arsenals together!

2 thoughts on “Scheduling tasks with cron: beyond the basics”

  1. I’ve been using cron for a while now, but this is the first time I’ve seen these special strings. Thanks for sharing!

    1. Yeah, those special strings can be super useful, especially when you want to schedule something like daily or hourly tasks. Just a note, they don’t work on all systems, so it’s good to check first.

Leave a reply

Your email address will not be published. Required fields are marked *