Related-Prod: PROD-22546 Related-Prod: PROD-22664 Change-Id: I66a35ef3d2436541ef70f02e2631fa8d4d86e5e9pull/124/merge
@@ -235,7 +235,54 @@ updates): | |||
automatic_reboot: true | |||
automatic_reboot_time: "02:00" | |||
Linux with cron jobs | |||
Managing cron tasks | |||
------------------- | |||
There are two data structures that are related to managing cron itself and | |||
cron tasks: | |||
.. code-block:: yaml | |||
linux: | |||
system: | |||
cron: | |||
and | |||
.. code-block:: yaml | |||
linux: | |||
system: | |||
job: | |||
`linux:system:cron` manages cron packages, services, and '/etc/cron.allow' file. | |||
'deny' files are managed the only way - we're ensuring they are absent, that's | |||
a requirement from CIS 5.1.8 | |||
'cron' pillar structure is the following: | |||
.. code-block:: yaml | |||
linux: | |||
system: | |||
cron: | |||
enabled: true | |||
pkgs: [ <cron packages> ] | |||
services: [ <cron services> ] | |||
user: | |||
<username>: | |||
enabled: true | |||
To add user to '/etc/cron.allow' use 'enabled' key as shown above. | |||
'/etc/cron.deny' is not managed as CIS 5.1.8 requires it was removed. | |||
A user would be ignored if any of the following is true: | |||
* user is disabled in `linux:system:user:<username>` | |||
* user is disabled in `linux:system:cron:user:<username>` | |||
`linux:system:job` manages individual cron tasks. | |||
By default, it will use name as an identifier, unless identifier key is | |||
explicitly set or False (then it will use Salt's default behavior which is | |||
@@ -255,6 +302,32 @@ identifier same as command resulting in not being able to change it): | |||
hour: 2 | |||
minute: 0 | |||
Managing 'at' tasks | |||
------------------- | |||
Pillar for managing `at` tasks is similar to one for `cron` tasks: | |||
.. code-block:: yaml | |||
linux: | |||
system: | |||
at: | |||
enabled: true | |||
pkgs: [ <at packages> ] | |||
services: [ <at services> ] | |||
user: | |||
<username>: | |||
enabled: true | |||
To add a user to '/etc/at.allow' use 'enabled' key as shown above. | |||
'/etc/at.deny' is not managed as CIS 5.1.8 requires it was removed. | |||
A user will be ignored if any of the following is true: | |||
* user is disabled in `linux:system:user:<username>` | |||
* user is disabled in `linux:system:at:user:<username>` | |||
Linux security limits (limit sensu user memory usage to max 1GB): | |||
.. code-block:: yaml |
@@ -0,0 +1,5 @@ | |||
# This file is managed by Salt, do not edit | |||
{%- for user_name in users %} | |||
{{ user_name }} | |||
{%- endfor %} | |||
{# IMPORTANT: This file SHOULD ends with a newline #} |
@@ -85,6 +85,24 @@ | |||
}, | |||
}, grain='os_family', merge=salt['pillar.get']('linux:system')) %} | |||
{% set at = salt['grains.filter_by']({ | |||
'Debian': { | |||
'enabled': false, | |||
'pkgs': ['at'], | |||
'services': ['atd'], | |||
'user': {} | |||
}, | |||
}, grain='os_family', merge=salt['pillar.get']('linux:system:at')) %} | |||
{% set cron = salt['grains.filter_by']({ | |||
'Debian': { | |||
'enabled': false, | |||
'pkgs': ['cron'], | |||
'services': ['cron'], | |||
'user': {} | |||
}, | |||
}, grain='os_family', merge=salt['pillar.get']('linux:system:cron')) %} | |||
{% set banner = salt['grains.filter_by']({ | |||
'BaseDefaults': { | |||
'enabled': false, |
@@ -0,0 +1,62 @@ | |||
{%- from "linux/map.jinja" import system, at with context %} | |||
{%- if at.get('enabled', false) %} | |||
at_packages: | |||
pkg.installed: | |||
- names: {{ at.pkgs }} | |||
at_services: | |||
service.running: | |||
- enable: true | |||
- names: {{ at.services }} | |||
- require: | |||
- pkg: at_packages | |||
{%- if grains.get('noservices') %} | |||
- onlyif: /bin/false | |||
{%- endif %} | |||
{%- set allow_users = [] %} | |||
{%- for user_name, user_params in at.get('user', {}).items() %} | |||
{%- set user_enabled = user_params.get('enabled', false) and | |||
system.get('user', {}).get( | |||
user_name, {'enabled': true}).get('enabled', true) %} | |||
{%- if user_enabled %} | |||
{%- do allow_users.append(user_name) %} | |||
{%- endif %} | |||
{%- endfor %} | |||
etc_at_allow: | |||
{%- if allow_users %} | |||
file.managed: | |||
- name: /etc/at.allow | |||
- template: jinja | |||
- source: salt://linux/files/cron_users.jinja | |||
- user: root | |||
- group: root | |||
- mode: 0600 | |||
- defaults: | |||
users: {{ allow_users | yaml }} | |||
- require: | |||
- cron_packages | |||
{%- else %} | |||
file.absent: | |||
- name: /etc/at.allow | |||
{%- endif %} | |||
{# | |||
/etc/at.deny should be absent to comply with | |||
CIS 5.1.8 Ensure at/cron is restricted to authorized users | |||
#} | |||
etc_at_deny: | |||
file.absent: | |||
- name: /etc/at.deny | |||
{%- else %} | |||
fake_linux_system_at: | |||
test.nop: | |||
- comment: Fake state to satisfy 'require sls:linux.system.at' | |||
{%- endif %} |
@@ -0,0 +1,87 @@ | |||
{%- from "linux/map.jinja" import system, cron with context %} | |||
{%- if cron.get('enabled', false) %} | |||
cron_packages: | |||
pkg.installed: | |||
- names: {{ cron.pkgs }} | |||
cron_services: | |||
service.running: | |||
- enable: true | |||
- names: {{ cron.services }} | |||
- require: | |||
- pkg: cron_packages | |||
{%- if grains.get('noservices') %} | |||
- onlyif: /bin/false | |||
{%- endif %} | |||
{%- set allow_users = [] %} | |||
{%- for user_name, user_params in cron.get('user', {}).items() %} | |||
{%- set user_enabled = user_params.get('enabled', false) and | |||
system.get('user', {}).get( | |||
user_name, {'enabled': true}).get('enabled', true) %} | |||
{%- if user_enabled %} | |||
{%- do allow_users.append(user_name) %} | |||
{%- endif %} | |||
{%- endfor %} | |||
etc_cron_allow: | |||
{%- if allow_users %} | |||
file.managed: | |||
- name: /etc/cron.allow | |||
- template: jinja | |||
- source: salt://linux/files/cron_users.jinja | |||
- user: root | |||
- group: root | |||
- mode: 0600 | |||
- defaults: | |||
users: {{ allow_users | yaml }} | |||
- require: | |||
- cron_packages | |||
{%- else %} | |||
file.absent: | |||
- name: /etc/cron.allow | |||
{%- endif %} | |||
{# | |||
/etc/cron.deny should be absent to comply with | |||
CIS 5.1.8 Ensure at/cron is restricted to authorized users | |||
#} | |||
etc_cron_deny: | |||
file.absent: | |||
- name: /etc/cron.deny | |||
etc_crontab: | |||
file.managed: | |||
- name: /etc/crontab | |||
- user: root | |||
- group: root | |||
- mode: 0600 | |||
- replace: False | |||
- require: | |||
- cron_packages | |||
etc_cron_dirs: | |||
file.directory: | |||
- names: | |||
- /etc/cron.d | |||
- /etc/cron.daily | |||
- /etc/cron.hourly | |||
- /etc/cron.monthly | |||
- /etc/cron.weekly | |||
- user: root | |||
- group: root | |||
- dir_mode: 0600 | |||
- recurse: | |||
- ignore_files | |||
- require: | |||
- cron_packages | |||
{%- else %} | |||
fake_linux_system_cron: | |||
test.nop: | |||
- comment: Fake state to satisfy 'require sls:linux.system.cron' | |||
{%- endif %} |
@@ -3,6 +3,8 @@ | |||
include: | |||
- linux.system.env | |||
- linux.system.profile | |||
- linux.system.at | |||
- linux.system.cron | |||
{%- if system.repo|length > 0 %} | |||
- linux.system.repo | |||
{%- endif %} |
@@ -3,45 +3,46 @@ | |||
include: | |||
- linux.system.user | |||
- linux.system.cron | |||
{%- for name, job in system.job.items() %} | |||
{%- for name, job in system.job.items() %} | |||
{%- set job_user = job.get('user', 'root') %} | |||
linux_job_{{ job.command }}: | |||
{%- if job.enabled|default(True) %} | |||
{%- if job.get('enabled', True) %} | |||
cron.present: | |||
- name: > | |||
{{ job.command }} | |||
{%- if job.get('identifier', True) %} | |||
{%- if job.get('identifier', True) %} | |||
- identifier: {{ job.get('identifier', job.get('name', name)) }} | |||
{%- endif %} | |||
- user: {{ job.user|default("root") }} | |||
{%- if job.minute is defined %} | |||
{%- endif %} | |||
- user: {{ job_user }} | |||
{%- if job.minute is defined %} | |||
- minute: '{{ job.minute }}' | |||
{%- endif %} | |||
{%- if job.hour is defined %} | |||
{%- endif %} | |||
{%- if job.hour is defined %} | |||
- hour: '{{ job.hour }}' | |||
{%- endif %} | |||
{%- if job.daymonth is defined %} | |||
{%- endif %} | |||
{%- if job.daymonth is defined %} | |||
- daymonth: '{{ job.daymonth }}' | |||
{%- endif %} | |||
{%- if job.month is defined %} | |||
{%- endif %} | |||
{%- if job.month is defined %} | |||
- month: '{{ job.month }}' | |||
{%- endif %} | |||
{%- if job.dayweek is defined %} | |||
{%- endif %} | |||
{%- if job.dayweek is defined %} | |||
- dayweek: '{{ job.dayweek }}' | |||
{%- endif %} | |||
{%- if job.user|default("root") in system.get('user', {}).keys() %} | |||
{%- endif %} | |||
- require: | |||
- user: system_user_{{ job.user|default("root") }} | |||
{%- endif %} | |||
{%- else %} | |||
- sls: linux.system.cron | |||
{%- if job_user in system.get('user', {}).keys() %} | |||
- user: system_user_{{ job_user }} | |||
{%- endif %} | |||
{%- else %} | |||
cron.absent: | |||
- name: {{ job.command }} | |||
{%- if job.get('identifier', True) %} | |||
{%- if job.get('identifier', True) %} | |||
- identifier: {{ job.get('identifier', job.get('name', name)) }} | |||
{%- endif %} | |||
{%- endif %} | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- endfor %} | |||
{%- endif %} |
@@ -5,6 +5,20 @@ linux: | |||
fqdn: linux.ci.local | |||
system: | |||
enabled: true | |||
at: | |||
enabled: true | |||
user: | |||
root: | |||
enabled: true | |||
testuser: | |||
enabled: true | |||
cron: | |||
enabled: true | |||
user: | |||
root: | |||
enabled: true | |||
testuser: | |||
enabled: true | |||
cluster: default | |||
name: linux | |||
domain: ci.local |