.kitchen | .kitchen | ||||
.bundle | |||||
bundle/ | |||||
tests/build/ | tests/build/ | ||||
*.swp | *.swp | ||||
*.pyc | *.pyc | ||||
.ropeproject | .ropeproject | ||||
Gemfile* |
--- | |||||
driver: | |||||
name: vagrant | |||||
vm_hostname: linux.ci.local | |||||
use_sudo: false | |||||
customize: | |||||
memory: 1024 | |||||
provisioner: | |||||
name: salt_solo | |||||
salt_install: bootstrap | |||||
salt_bootstrap_url: https://bootstrap.saltstack.com | |||||
salt_version: latest | |||||
require_chef: false | |||||
log_level: error | |||||
formula: linux | |||||
grains: | |||||
noservices: true | |||||
state_top: | |||||
base: | |||||
"*": | |||||
- linux | |||||
pillars: | |||||
top.sls: | |||||
base: | |||||
"*": | |||||
- linux | |||||
platforms: | |||||
- name: ubuntu-16.04 | |||||
- name: ubuntu-14.04 | |||||
- name: centos-7.3 | |||||
- name: centos-6.8 | |||||
# vim: ft=yaml sw=2 ts=2 sts=2 tw=125 |
--- | --- | ||||
driver: | driver: | ||||
name: docker | name: docker | ||||
hostname: linux.ci.local | |||||
use_sudo: false | |||||
hostname: linux-formula | |||||
run_options: -v /dev/log:/dev/log:ro | |||||
provisioner: | provisioner: | ||||
name: salt_solo | name: salt_solo | ||||
sudo: true | sudo: true | ||||
platforms: | platforms: | ||||
- name: <%=ENV['PLATFORM'] || 'ubuntu-xenial-2017.7'%> | |||||
- name: <%=ENV['PLATFORM'] || 'saltstack-ubuntu-xenial-salt-stable' %> | |||||
driver_config: | driver_config: | ||||
image: <%=ENV['PLATFORM'] || 'trevorj/salty-whales:xenial-2017.7'%> | |||||
image: <%=ENV['PLATFORM'] || 'epcim/salt:saltstack-ubuntu-xenial-salt-stable'%> | |||||
platform: ubuntu | platform: ubuntu | ||||
pillars-from-files: | pillars-from-files: | ||||
linux.sls: tests/pillar/system.sls | linux.sls: tests/pillar/system.sls | ||||
- name: system_file | |||||
provisioner: | |||||
pillars-from-files: | |||||
linux.sls: tests/pillar/system_file.sls | |||||
pillars_from_directories: | |||||
- source: tests/example | |||||
dest: srv/salt/linux/files/test | |||||
- name: duo | |||||
provisioner: | |||||
pillars-from-files: | |||||
linux.sls: tests/pillar/system_duo.sls | |||||
# vim: ft=yaml sw=2 ts=2 sts=2 tw=125 | # vim: ft=yaml sw=2 ts=2 sts=2 tw=125 |
language: python | |||||
python: | |||||
- "2.7.13" | |||||
sudo: required | sudo: required | ||||
services: | services: | ||||
- docker | - docker | ||||
gem 'test-kitchen' | gem 'test-kitchen' | ||||
gem 'kitchen-docker' | gem 'kitchen-docker' | ||||
gem 'kitchen-inspec' | gem 'kitchen-inspec' | ||||
gem 'inspec' | |||||
gem 'inspec', '<3.0.0' | |||||
#Version was frozen, because of issues in the version of inspec >3.0.0 -- see https://mirantis.jira.com/browse/PROD-24324 for more info | |||||
gem 'kitchen-salt', :git => 'https://github.com/salt-formulas/kitchen-salt.git' | gem 'kitchen-salt', :git => 'https://github.com/salt-formulas/kitchen-salt.git' | ||||
- bundle install | - bundle install | ||||
env: | env: | ||||
- PLATFORM=trevorj/salty-whales:trusty-2017.7 SUITE=network | |||||
- PLATFORM=trevorj/salty-whales:xenial-2017.7 SUITE=network | |||||
# - PLATFORM=trevorj/salty-whales:trusty-2017.7 SUITE=storage | |||||
# - PLATFORM=trevorj/salty-whales:xenial-2017.7 SUITE=storage | |||||
- PLATFORM=trevorj/salty-whales:trusty-2017.7 SUITE=system | |||||
- PLATFORM=trevorj/salty-whales:xenial-2017.7 SUITE=system | |||||
- PLATFORM=trevorj/salty-whales:trusty SUITE=network | |||||
- PLATFORM=trevorj/salty-whales:xenial SUITE=network | |||||
# - PLATFORM=trevorj/salty-whales:trusty SUITE=storage | |||||
# - PLATFORM=trevorj/salty-whales:xenial SUITE=storage | |||||
- PLATFORM=trevorj/salty-whales:trusty SUITE=system | |||||
- PLATFORM=trevorj/salty-whales:xenial SUITE=system | |||||
## Test on both Salt version until there is new test policy accepted | |||||
- PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2016.3 SUITE=network | |||||
- PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2016.3 SUITE=system | |||||
- PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2017.7 SUITE=network | |||||
- PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2017.7 SUITE=system | |||||
- PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2018.3 SUITE=network | |||||
- PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2018.3 SUITE=system | |||||
- PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2018.3 SUITE=duo | |||||
# - PLATFORM=epcim/salt:saltstack-ubuntu-bionic-salt-2017.7 SUITE=network | |||||
# - PLATFORM=epcim/salt:saltstack-ubuntu-bionic-salt-2017.7 SUITE=system | |||||
# - PLATFORM=epcim/salt:saltstack-ubuntu-bionic-salt-2018.3 SUITE=network | |||||
# - PLATFORM=epcim/salt:saltstack-ubuntu-bionic-salt-2018.3 SUITE=system | |||||
before_script: | before_script: | ||||
- set -o pipefail | - set -o pipefail |
from jinja2 import Undefined | from jinja2 import Undefined | ||||
def __virtual__(): | |||||
return 'linux_hosts' | |||||
def fqdn_sort_fn(n1, n2): | def fqdn_sort_fn(n1, n2): | ||||
l1 = n1.split('.') | l1 = n1.split('.') | ||||
l2 = n2.split('.') | l2 = n2.split('.') |
import re | import re | ||||
def __virtual__(): | |||||
return 'linux_netlink' | |||||
def ls(regex): | def ls(regex): | ||||
""" | """ |
from os import listdir, path | |||||
from subprocess import Popen,PIPE | |||||
from re import findall as refindall | |||||
from re import search as research | |||||
import salt.utils | |||||
import socket, struct, fcntl | |||||
import logging | |||||
logger = logging.getLogger(__name__) | |||||
stream = logging.StreamHandler() | |||||
logger.addHandler(stream) | |||||
def get_ip(iface='ens2'): | |||||
''' Get ip address from an interface if applicable | |||||
:param iface: Interface name. Type: str | |||||
''' | |||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||||
sockfd = sock.fileno() | |||||
SIOCGIFADDR = 0x8915 | |||||
ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14) | |||||
try: | |||||
res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq) | |||||
except: | |||||
logger.debug("No ip addresses assigned to %s" % iface) | |||||
return None | |||||
ip = struct.unpack('16sH2x4s8x', res)[2] | |||||
return socket.inet_ntoa(ip) | |||||
def get_nics(): | |||||
''' List nics ''' | |||||
nics = [] | |||||
nics_list = listdir('/sys/class/net/') | |||||
for nic_name in nics_list: | |||||
if research('(br|bond|ens|enp|eth|one|ten|fourty)[0-9]+', nic_name): | |||||
# Interface should be in "up" state in order to get carrier status | |||||
Popen("ip li set dev " + nic_name + " up", shell=True, stdout=PIPE) | |||||
with open("/sys/class/net/" + nic_name + "/carrier", 'r') as f: | |||||
try: | |||||
carrier = int(f.read()) | |||||
except: | |||||
carrier = 0 | |||||
bond = "" | |||||
if path.isfile("/sys/class/net/" + nic_name + "/master/uevent"): | |||||
with open("/sys/class/net/" + nic_name + "/master/uevent", 'r') as f: | |||||
for line in f: | |||||
sline = line.strip() | |||||
if 'INTERFACE=bond' in sline: | |||||
bond = sline.split('=')[1] | |||||
if len(bond) == 0: | |||||
with open("/sys/class/net/" + nic_name + "/address", 'r') as f: | |||||
macaddr = f.read().strip() | |||||
else: | |||||
with open("/proc/net/bonding/" + bond, 'r') as f: | |||||
line = f.readline() | |||||
if_struct = False | |||||
while line: | |||||
sline = line.strip() | |||||
if 'Slave Interface: ' + nic_name in sline and not if_struct: | |||||
if_struct = True | |||||
if 'Permanent HW addr: ' in sline and if_struct: | |||||
macaddr = sline.split()[3] | |||||
break | |||||
line = f.readline() | |||||
with open("/sys/class/net/" + nic_name + "/mtu", 'r') as f: | |||||
mtu = f.read() | |||||
ip = str(get_ip(nic_name)) | |||||
nics.append([nic_name, ip, macaddr, carrier, mtu]) | |||||
return sorted(nics) | |||||
def get_ten_pci(): | |||||
''' List ten nics pci addresses ''' | |||||
nics = [] | |||||
nics_list = listdir('/sys/class/net/') | |||||
for nic_name in nics_list: | |||||
if research('ten[0-9]+', nic_name): | |||||
with open("/sys/class/net/" + nic_name + "/device/uevent", 'r') as f: | |||||
for line in f: | |||||
sline = line.strip() | |||||
if "PCI_SLOT_NAME=" in sline: | |||||
nics.append([nic_name , sline.split("=")[1]]) | |||||
return sorted(nics) | |||||
def mesh_ping(mesh): | |||||
''' One to many ICMP check | |||||
:param hosts: Target hosts. Type: list of ip addresses | |||||
''' | |||||
io = [] | |||||
minion_id = __salt__['config.get']('id') | |||||
for host, hostobj in mesh: | |||||
if host == minion_id: | |||||
for mesh_net, addr, targets in hostobj: | |||||
if addr in targets: | |||||
targets.remove(addr) | |||||
for tgt in targets: | |||||
# This one will run in parallel with everyone else | |||||
worker = Popen("ping -c 1 -w 1 -W 1 " + str(tgt), \ | |||||
shell=True, stdout=PIPE, stderr=PIPE) | |||||
ping_out = worker.communicate()[0] | |||||
if worker.returncode != 0: | |||||
io.append(mesh_net + ': ' + addr + ' -> ' + tgt + ': Failed') | |||||
return io | |||||
def minion_list(): | |||||
''' List registered minions ''' | |||||
return listdir('/etc/salt/pki/master/minions/') | |||||
def verify_addresses(): | |||||
''' Verify addresses taken from pillars ''' | |||||
nodes = nodes_addresses() | |||||
verifier = {} | |||||
failed = [] | |||||
for node, nodeobj in nodes: | |||||
for item in nodeobj: | |||||
addr = item[1] | |||||
if addr in verifier: | |||||
failed.append([node,verifier[addr],addr]) | |||||
else: | |||||
verifier[addr] = node | |||||
if failed: | |||||
logger.error("FAILED. Duplicates found") | |||||
logger.error(failed) | |||||
return False | |||||
else: | |||||
logger.setLevel(logging.INFO) | |||||
logger.info(["PASSED"]) | |||||
return True | |||||
def nodes_addresses(): | |||||
''' List servers addresses ''' | |||||
compound = 'linux:network:interface' | |||||
out = __salt__['saltutil.cmd']( tgt='I@' + compound, | |||||
tgt_type='compound', | |||||
fun='pillar.get', | |||||
arg=[compound], | |||||
timeout=10 | |||||
) or None | |||||
servers = [] | |||||
for minion in minion_list(): | |||||
addresses = [] | |||||
if minion in out: | |||||
ifaces = out[minion]['ret'] | |||||
for iface in ifaces: | |||||
ifobj = ifaces[iface] | |||||
if ifobj['enabled'] and 'address' in ifobj: | |||||
if 'mesh' in ifobj: | |||||
mesh = ifobj['mesh'] | |||||
else: | |||||
mesh = 'default' | |||||
addresses.append([mesh, ifobj['address']]) | |||||
servers.append([minion,addresses]) | |||||
return servers | |||||
def get_mesh(): | |||||
''' Build addresses mesh ''' | |||||
full_mesh = {} | |||||
nodes = nodes_addresses() | |||||
for node, nodeobj in nodes: | |||||
for item in nodeobj: | |||||
mesh = item[0] | |||||
addr = item[1] | |||||
if not mesh in full_mesh: | |||||
full_mesh[mesh] = [] | |||||
full_mesh[mesh].append(addr) | |||||
for node, nodeobj in nodes: | |||||
for item in nodeobj: | |||||
mesh = item[0] | |||||
tgts = full_mesh[mesh] | |||||
item.append(tgts) | |||||
return nodes | |||||
def ping_check(): | |||||
''' Ping addresses in a mesh ''' | |||||
mesh = get_mesh() | |||||
out = __salt__['saltutil.cmd']( tgt='*', | |||||
tgt_type='glob', | |||||
fun='net_checks.mesh_ping', | |||||
arg=[mesh], | |||||
timeout=10 | |||||
) or None | |||||
failed = [] | |||||
if out: | |||||
for minion in out: | |||||
ret = out[minion]['ret'] | |||||
if ret: | |||||
failed.append(ret) | |||||
else: | |||||
failed = ["No response from minions"] | |||||
if failed: | |||||
logger.error("FAILED") | |||||
logger.error('\n'.join(str(x) for x in failed)) | |||||
return False | |||||
else: | |||||
logger.setLevel(logging.INFO) | |||||
logger.info(["PASSED"]) | |||||
return True | |||||
def get_nics_csv(delim=","): | |||||
''' List nics in csv format | |||||
:param delim: Delimiter char. Type: str | |||||
''' | |||||
header = "server,nic_name,ip_addr,mac_addr,link,chassis_id,chassis_name,port_mac,port_descr\n" | |||||
io = "" | |||||
# Try to reuse lldp output if possible | |||||
try: | |||||
lldp_info = Popen("lldpcli -f keyvalue s n s", shell=True, stdout=PIPE).communicate()[0] | |||||
except: | |||||
lldp_info = "" | |||||
for nic in get_nics(): | |||||
lldp = "" | |||||
nic_name = nic[0] | |||||
if research('(one|ten|fourty)[0-9]+', nic_name): | |||||
# Check if we can fetch lldp data for that nic | |||||
for line in lldp_info.splitlines(): | |||||
chassis = 'lldp.' + nic[0] + '.chassis' | |||||
port = 'lldp.' + nic[0] + '.port' | |||||
if chassis in line or port in line: | |||||
lldp += delim + line.split('=')[1] | |||||
if not lldp: | |||||
lldp = delim + delim + delim + delim | |||||
io += __salt__['config.get']('id') + \ | |||||
delim + nic_name + \ | |||||
delim + str(nic[1]).strip() + \ | |||||
delim + str(nic[2]).strip() + \ | |||||
delim + str(nic[3]).strip() + \ | |||||
delim + str(nic[4]).strip() + \ | |||||
lldp + "\n" | |||||
return header + io |
# -*- coding: utf-8 -*- | |||||
''' | |||||
Support for Open vSwitch database configuration. | |||||
''' | |||||
from __future__ import absolute_import | |||||
import logging | |||||
import salt.utils | |||||
log = logging.getLogger(__name__) | |||||
def __virtual__(): | |||||
''' | |||||
Only load the module if Open vSwitch is installed | |||||
''' | |||||
if salt.utils.which('ovs-vsctl'): | |||||
return 'ovs_config' | |||||
return False | |||||
def _retcode_to_bool(retcode): | |||||
''' | |||||
Evaulates ovs-vsctl command`s retcode value. | |||||
Args: | |||||
retcode: Value of retcode field from response. | |||||
''' | |||||
return True if retcode == 0 else False | |||||
def set(cfg, value, wait=True): | |||||
''' | |||||
Updates a specified configuration entry. | |||||
Args: | |||||
cfg/value: a config entry to update | |||||
wait: wait or not for ovs-vswitchd to reconfigure itself before it exits. | |||||
CLI Example: | |||||
.. code-block:: bash | |||||
salt '*' ovs_config.set other_config:dpdk-init true | |||||
''' | |||||
wait = '' if wait else '--no-wait ' | |||||
cmd = 'ovs-vsctl {0}set Open_vSwitch . {1}="{2}"'.format(wait, cfg, str(value).lower()) | |||||
result = __salt__['cmd.run_all'](cmd) | |||||
return _retcode_to_bool(result['retcode']) | |||||
def remove(cfg): | |||||
''' | |||||
Removes a specified configuration entry. | |||||
Args: | |||||
cfg: a config entry to remove | |||||
CLI Example: | |||||
.. code-block:: bash | |||||
salt '*' ovs_config.remove other_config | |||||
''' | |||||
if ':' in cfg: | |||||
section, key = cfg.split(':') | |||||
cmd = 'ovs-vsctl remove Open_vSwitch . {} {}'.format(section, key) | |||||
else: | |||||
cmd = 'ovs-vsctl clear Open_vSwitch . ' + cfg | |||||
result = __salt__['cmd.run_all'](cmd) | |||||
return _retcode_to_bool(result['retcode']) | |||||
def list(): | |||||
''' | |||||
Return a current config of Open vSwitch | |||||
CLI Example: | |||||
.. code-block:: bash | |||||
salt '*' ovs_config.list | |||||
''' | |||||
cmd = 'ovs-vsctl list Open_vSwitch .' | |||||
result = __salt__['cmd.run_all'](cmd) | |||||
if result['retcode'] == 0: | |||||
config = {} | |||||
for l in result['stdout'].splitlines(): | |||||
cfg, value = map((lambda x: x.strip()), l.split(' : ')) | |||||
if value.startswith('{') and len(value) > 2: | |||||
for i in value[1:-1].replace('"', '').split(', '): | |||||
_k, _v = i.split('=') | |||||
config['{}:{}'.format(cfg,_k)] = _v | |||||
else: | |||||
config[cfg] = value | |||||
return config | |||||
else: | |||||
return False |
# -*- coding: utf-8 -*- | |||||
''' | |||||
Management of Open vSwitch configuration | |||||
======================================== | |||||
The OVS config can be managed with the ovs_config state module: | |||||
.. code-block:: yaml | |||||
other_config:dpdk-init: | |||||
ovs_config.present: | |||||
- value: True | |||||
other_config:dpdk-extra: | |||||
ovs_config.present: | |||||
- value: -n 12 --vhost-owner libvirt-qemu:kvm --vhost-perm 0664 | |||||
external_ids: | |||||
ovs_config.absent | |||||
''' | |||||
def __virtual__(): | |||||
''' | |||||
Only make these states available if Open vSwitch is installed. | |||||
''' | |||||
return 'ovs_config.list' in __salt__ | |||||
def present(name, value, wait=True): | |||||
''' | |||||
Ensures that the named config exists, eventually creates it. | |||||
Args: | |||||
name/value: The name/value of the config entry. | |||||
wait: Whether wait for ovs-vswitchd to reconfigure itself according to the modified database. | |||||
''' | |||||
ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''} | |||||
ovs_config = __salt__['ovs_config.list']() | |||||
if name in ovs_config and ovs_config[name] == str(value).lower(): | |||||
ret['result'] = True | |||||
ret['comment'] = '{0} is already set to {1}.'.format(name, value) | |||||
else: | |||||
config_updated = __salt__['ovs_config.set'](name, value, wait) | |||||
if config_updated: | |||||
ret['result'] = True | |||||
ret['comment'] = '{0} is updated.'.format(name) | |||||
ret['changes'] = { name: 'Updated to {0}'.format(value) } | |||||
else: | |||||
ret['result'] = False | |||||
ret['comment'] = 'Unable to update config of {0}.'.format(name) | |||||
return ret | |||||
def absent(name): | |||||
''' | |||||
Ensures that the named config does not exist, eventually deletes it. | |||||
Args: | |||||
name: The name of the config entry. | |||||
''' | |||||
ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''} | |||||
ovs_config = __salt__['ovs_config.list']() | |||||
if ':' in name and name not in ovs_config: | |||||
ret['result'] = True | |||||
ret['comment'] = '{0} does not exist.'.format(name) | |||||
else: | |||||
config_removed = __salt__['ovs_config.remove'](name) | |||||
if config_removed: | |||||
ret['result'] = True | |||||
ret['comment'] = '{0} is removed.'.format(name) | |||||
ret['changes'] = { name: '{0} removed'.format(name) } | |||||
else: | |||||
ret['result'] = False | |||||
ret['comment'] = 'Unable to delete config of {0}.'.format(name) | |||||
return ret |
{%- from "linux/map.jinja" import network with context %} | {%- from "linux/map.jinja" import network with context %} | ||||
Acquire::http::proxy "http://{{ network.proxy.host }}:{{ network.proxy.port }}/"; | Acquire::http::proxy "http://{{ network.proxy.host }}:{{ network.proxy.port }}/"; | ||||
Acquire::ftp::proxy "ftp://{{ network.proxy.host }}:{{ network.proxy.port }}/"; | Acquire::ftp::proxy "ftp://{{ network.proxy.host }}:{{ network.proxy.port }}/"; | ||||
Acquire::https::proxy "https://{{ network.proxy.host }}:{{ network.proxy.port }}/"; | |||||
Acquire::https::proxy "http://{{ network.proxy.host }}:{{ network.proxy.port }}/"; |
# 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 #} |
{% raw %} | |||||
{ | |||||
"annotations": { | |||||
"list": [] | |||||
}, | |||||
"editable": true, | |||||
"gnetId": null, | |||||
"graphTooltip": 0, | |||||
"hideControls": false, | |||||
"id": null, | |||||
"links": [], | |||||
"rows": [ | |||||
{ | |||||
"collapse": false, | |||||
"height": 333, | |||||
"panels": [ | |||||
{ | |||||
"aliasColors": {}, | |||||
"bars": false, | |||||
"dashLength": 10, | |||||
"dashes": false, | |||||
"datasource": "prometheus", | |||||
"decimals": 0, | |||||
"fill": 1, | |||||
"id": 1, | |||||
"legend": { | |||||
"avg": false, | |||||
"current": true, | |||||
"max": false, | |||||
"min": false, | |||||
"show": true, | |||||
"total": false, | |||||
"values": true | |||||
}, | |||||
"lines": true, | |||||
"linewidth": 1, | |||||
"links": [], | |||||
"nullPointMode": "null", | |||||
"percentage": false, | |||||
"pointradius": 5, | |||||
"points": false, | |||||
"renderer": "flot", | |||||
"seriesOverrides": [], | |||||
"spaceLength": 10, | |||||
"span": 6, | |||||
"stack": false, | |||||
"steppedLine": false, | |||||
"targets": [ | |||||
{ | |||||
"expr": "bond_slave_failures{host=\"$host\"}", | |||||
"format": "time_series", | |||||
"intervalFactor": 2, | |||||
"legendFormat": "{{ bond}}: {{ interface }}", | |||||
"refId": "A", | |||||
"step": 2 | |||||
} | |||||
], | |||||
"thresholds": [], | |||||
"timeFrom": null, | |||||
"timeShift": null, | |||||
"title": "Bond slave failures count", | |||||
"tooltip": { | |||||
"shared": true, | |||||
"sort": 0, | |||||
"value_type": "individual" | |||||
}, | |||||
"transparent": false, | |||||
"type": "graph", | |||||
"xaxis": { | |||||
"buckets": null, | |||||
"mode": "time", | |||||
"name": null, | |||||
"show": true, | |||||
"values": [] | |||||
}, | |||||
"yaxes": [ | |||||
{ | |||||
"decimals": 0, | |||||
"format": "short", | |||||
"label": null, | |||||
"logBase": 1, | |||||
"max": null, | |||||
"min": null, | |||||
"show": true | |||||
}, | |||||
{ | |||||
"decimals": null, | |||||
"format": "short", | |||||
"label": null, | |||||
"logBase": 1, | |||||
"max": null, | |||||
"min": null, | |||||
"show": true | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
"aliasColors": {}, | |||||
"bars": false, | |||||
"dashLength": 10, | |||||
"dashes": false, | |||||
"datasource": "prometheus", | |||||
"decimals": 0, | |||||
"fill": 1, | |||||
"id": 2, | |||||
"legend": { | |||||
"alignAsTable": false, | |||||
"avg": false, | |||||
"current": true, | |||||
"max": false, | |||||
"min": false, | |||||
"show": true, | |||||
"total": false, | |||||
"values": true | |||||
}, | |||||
"lines": true, | |||||
"linewidth": 1, | |||||
"links": [], | |||||
"nullPointMode": "null", | |||||
"percentage": false, | |||||
"pointradius": 5, | |||||
"points": false, | |||||
"renderer": "flot", | |||||
"seriesOverrides": [], | |||||
"spaceLength": 10, | |||||
"span": 6, | |||||
"stack": false, | |||||
"steppedLine": false, | |||||
"targets": [ | |||||
{ | |||||
"expr": "bond_status{host=\"$host\"}", | |||||
"format": "time_series", | |||||
"intervalFactor": 2, | |||||
"legendFormat": "{{ bond }}", | |||||
"refId": "A", | |||||
"step": 2 | |||||
} | |||||
], | |||||
"thresholds": [], | |||||
"timeFrom": null, | |||||
"timeShift": null, | |||||
"title": "Bond status", | |||||
"tooltip": { | |||||
"shared": true, | |||||
"sort": 0, | |||||
"value_type": "individual" | |||||
}, | |||||
"type": "graph", | |||||
"xaxis": { | |||||
"buckets": null, | |||||
"mode": "time", | |||||
"name": null, | |||||
"show": true, | |||||
"values": [] | |||||
}, | |||||
"yaxes": [ | |||||
{ | |||||
"decimals": 0, | |||||
"format": "none", | |||||
"label": null, | |||||
"logBase": 1, | |||||
"max": null, | |||||
"min": null, | |||||
"show": true | |||||
}, | |||||
{ | |||||
"format": "short", | |||||
"label": null, | |||||
"logBase": 1, | |||||
"max": null, | |||||
"min": null, | |||||
"show": true | |||||
} | |||||
] | |||||
} | |||||
], | |||||
"repeat": null, | |||||
"repeatIteration": null, | |||||
"repeatRowId": null, | |||||
"showTitle": false, | |||||
"title": "Dashboard Row", | |||||
"titleSize": "h6" | |||||
}, | |||||
{ | |||||
"collapse": false, | |||||
"height": 447, | |||||
"panels": [ | |||||
{ | |||||
"columns": [], | |||||
"datasource": "prometheus", | |||||
"fontSize": "100%", | |||||
"hideTimeOverride": false, | |||||
"id": 4, | |||||
"links": [], | |||||
"pageSize": null, | |||||
"scroll": true, | |||||
"showHeader": true, | |||||
"sort": { | |||||
"col": 0, | |||||
"desc": true | |||||
}, | |||||
"span": 12, | |||||
"styles": [ | |||||
{ | |||||
"alias": "Time", | |||||
"dateFormat": "YYYY-MM-DD HH:mm:ss", | |||||
"pattern": "Time", | |||||
"type": "date" | |||||
}, | |||||
{ | |||||
"alias": "", | |||||
"colorMode": null, | |||||
"colors": [ | |||||
"rgba(245, 54, 54, 0.9)", | |||||
"rgba(237, 129, 40, 0.89)", | |||||
"rgba(50, 172, 45, 0.97)" | |||||
], | |||||
"dateFormat": "YYYY-MM-DD HH:mm:ss", | |||||
"decimals": 2, | |||||
"pattern": "__name__", | |||||
"thresholds": [], | |||||
"type": "hidden", | |||||
"unit": "short" | |||||
}, | |||||
{ | |||||
"alias": "", | |||||
"colorMode": "row", | |||||
"colors": [ | |||||
"rgba(245, 54, 54, 0.9)", | |||||
"rgba(26, 161, 12, 0.89)", | |||||
"rgba(50, 172, 45, 0.97)" | |||||
], | |||||
"dateFormat": "YYYY-MM-DD HH:mm:ss", | |||||
"decimals": 0, | |||||
"pattern": "Value", | |||||
"thresholds": [ | |||||
"1" | |||||
], | |||||
"type": "number", | |||||
"unit": "none" | |||||
}, | |||||
{ | |||||
"alias": "", | |||||
"colorMode": null, | |||||
"colors": [ | |||||
"rgba(245, 54, 54, 0.9)", | |||||
"rgba(237, 129, 40, 0.89)", | |||||
"rgba(50, 172, 45, 0.97)" | |||||
], | |||||
"dateFormat": "YYYY-MM-DD HH:mm:ss", | |||||
"decimals": 2, | |||||
"pattern": "job", | |||||
"thresholds": [], | |||||
"type": "hidden", | |||||
"unit": "short" | |||||
}, | |||||
{ | |||||
"alias": "", | |||||
"colorMode": null, | |||||
"colors": [ | |||||
"rgba(245, 54, 54, 0.9)", | |||||
"rgba(237, 129, 40, 0.89)", | |||||
"rgba(50, 172, 45, 0.97)" | |||||
], | |||||
"decimals": 0, | |||||
"pattern": "/.*/", | |||||
"thresholds": [ | |||||
"" | |||||
], | |||||
"type": "number", | |||||
"unit": "none" | |||||
} | |||||
], | |||||
"targets": [ | |||||
{ | |||||
"expr": "bond_slave_status{host=\"$host\"}", | |||||
"format": "table", | |||||
"intervalFactor": 2, | |||||
"legendFormat": "", | |||||
"refId": "A", | |||||
"step": 2 | |||||
} | |||||
], | |||||
"timeFrom": "1s", | |||||
"timeShift": null, | |||||
"title": "Bond slave status", | |||||
"transform": "table", | |||||
"transparent": false, | |||||
"type": "table" | |||||
} | |||||
], | |||||
"repeat": null, | |||||
"repeatIteration": null, | |||||
"repeatRowId": null, | |||||
"showTitle": false, | |||||
"title": "Dashboard Row", | |||||
"titleSize": "h6" | |||||
} | |||||
], | |||||
"schemaVersion": 14, | |||||
"style": "dark", | |||||
"tags": [], | |||||
"templating": { | |||||
"list": [ | |||||
{ | |||||
"allValue": null, | |||||
"current": {}, | |||||
"datasource": "prometheus", | |||||
"hide": 0, | |||||
"includeAll": false, | |||||
"label": null, | |||||
"multi": false, | |||||
"name": "host", | |||||
"options": [], | |||||
"query": "label_values(bond_status,host)", | |||||
"refresh": 1, | |||||
"regex": "", | |||||
"sort": 1, | |||||
"tagValuesQuery": "", | |||||
"tags": [], | |||||
"tagsQuery": "", | |||||
"type": "query", | |||||
"useTags": false | |||||
} | |||||
] | |||||
}, | |||||
"time": { | |||||
"from": "now-5m", | |||||
"to": "now" | |||||
}, | |||||
"timepicker": { | |||||
"refresh_intervals": [ | |||||
"5s", | |||||
"10s", | |||||
"30s", | |||||
"1m", | |||||
"5m", | |||||
"15m", | |||||
"30m", | |||||
"1h", | |||||
"2h", | |||||
"1d" | |||||
], | |||||
"time_options": [ | |||||
"5m", | |||||
"15m", | |||||
"1h", | |||||
"6h", | |||||
"12h", | |||||
"24h", | |||||
"2d", | |||||
"7d", | |||||
"30d" | |||||
] | |||||
}, | |||||
"timezone": "", | |||||
"title": "Bond", | |||||
"version": 25 | |||||
} | |||||
{% endraw %} |
{%- from "linux/map.jinja" import login_defs with context -%} | |||||
# This file is managed by Salt, do not edit | |||||
{%- set allowed_options = [ | |||||
'CHFN_RESTRICT', | |||||
'CONSOLE_GROUPS', | |||||
'CREATE_HOME', | |||||
'DEFAULT_HOME', | |||||
'ENCRYPT_METHOD', | |||||
'ENV_HZ', | |||||
'ENV_PATH', | |||||
'ENV_SUPATH', | |||||
'ERASECHAR', | |||||
'FAIL_DELAY', | |||||
'FAKE_SHELL', | |||||
'GID_MAX', | |||||
'GID_MIN', | |||||
'HUSHLOGIN_FILE', | |||||
'KILLCHAR', | |||||
'LOG_OK_LOGINS', | |||||
'LOG_UNKFAIL_ENAB', | |||||
'LOGIN_RETRIES', | |||||
'LOGIN_TIMEOUT', | |||||
'MAIL_DIR', | |||||
'MAIL_FILE', | |||||
'MAX_MEMBERS_PER_GROUP', | |||||
'MD5_CRYPT_ENAB', | |||||
'PASS_MAX_DAYS', | |||||
'PASS_MIN_DAYS', | |||||
'PASS_WARN_AGE', | |||||
'SHA_CRYPT_MIN_ROUNDS', | |||||
'SHA_CRYPT_MAX_ROUNDS', | |||||
'SULOG_FILE', | |||||
'SU_NAME', | |||||
'SUB_GID_MIN', | |||||
'SUB_GID_MAX', | |||||
'SUB_GID_COUNT', | |||||
'SUB_UID_MIN', | |||||
'SUB_UID_MAX', | |||||
'SUB_UID_COUNT', | |||||
'SYS_GID_MAX', | |||||
'SYS_GID_MIN', | |||||
'SYS_UID_MAX', | |||||
'SYS_UID_MIN', | |||||
'SYSLOG_SG_ENAB', | |||||
'SYSLOG_SU_ENAB', | |||||
'TTYGROUP', | |||||
'TTYPERM', | |||||
'TTYTYPE_FILE', | |||||
'UID_MAX', | |||||
'UID_MIN', | |||||
'UMASK', | |||||
'USERDEL_CMD', | |||||
'USERGROUPS_ENAB' | |||||
] %} | |||||
{%- for opt_name in allowed_options %} | |||||
{%- if opt_name in login_defs %} | |||||
{%- set opt_params = login_defs.get(opt_name) %} | |||||
{%- if opt_params.get('enabled', true) %} | |||||
{{ opt_name.ljust(20) }} {{ opt_params.value }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endfor %} |
{%- from "linux/map.jinja" import auth with context %} | |||||
[duo] | |||||
ikey = {{ auth.duo.duo_ikey }} | |||||
skey = {{ auth.duo.duo_skey }} | |||||
host = {{ auth.duo.duo_host }} | |||||
pushinfo = yes | |||||
failmode = secure | |||||
{%- from "linux/map.jinja" import system with context %} | |||||
{%- set mcelog = system.mcelog %} | |||||
# | |||||
# Example config file for mcelog | |||||
# mcelog is the user space backend that decodes and process machine check events | |||||
# (cpu hardware errors) reported by the CPU to the kernel | |||||
# | |||||
# general format | |||||
#optionname = value | |||||
# white space is not allowed in value currently, except at the end where it is dropped | |||||
# | |||||
# In general all command line options that are not commands work here. | |||||
# See man mcelog or mcelog --help for a list. | |||||
# e.g. to enable the --no-syslog option use | |||||
#no-syslog = yes (or no to disable) | |||||
# when the option has a argument | |||||
#logfile = /tmp/logfile | |||||
# below are the options which are not command line options. | |||||
# Set CPU type for which mcelog decodes events: | |||||
#cpu = type | |||||
# For valid values for type please see mcelog --help. | |||||
# If this value is set incorrectly the decoded output will be likely incorrect. | |||||
# By default when this parameter is not set mcelog uses the CPU it is running on | |||||
# on very new kernels the mcelog events reported by the kernel also carry | |||||
# the CPU type which is used too when available and not overriden. | |||||
# Enable daemon mode: | |||||
#daemon = yes | |||||
# By default mcelog just processes the currently pending events and exits. | |||||
# In daemon mode it will keep running as a daemon in the background and poll | |||||
# the kernel for events and then decode them. | |||||
# Filter out known broken events by default. | |||||
filter = yes | |||||
# Don't log memory errors individually. | |||||
# They still get accounted if that is enabled. | |||||
#filter-memory-errors = yes | |||||
# output in undecoded raw format to be easier machine readable | |||||
# (default is decoded). | |||||
#raw = yes | |||||
# Set CPU Mhz to decode uptime from time stamp counter (output | |||||
# unreliable, not needed on new kernels which report the event time | |||||
# directly. A lot of systems don't have a linear time stamp clock | |||||
# and the output is wrong then. | |||||
# Normally mcelog tries to figure out if it the TSC is reliable | |||||
# and only uses the current frequency then. | |||||
# Setting a frequency forces timestamp decoding. | |||||
# This setting is obsolete with modern kernels which report the time | |||||
# directly. | |||||
#cpumhz = 1800.00 | |||||
# log output options | |||||
# Log decoded machine checks in syslog (default stdout or syslog for daemon) | |||||
#syslog = yes | |||||
# Log decoded machine checks in syslog with error level | |||||
#syslog-error = yes | |||||
# Never log anything to syslog | |||||
#no-syslog = yes | |||||
# Append log output to logfile instead of stdout. Only when no syslog logging is active | |||||
#logfile = filename | |||||
{%- if mcelog.logging is defined %} | |||||
{%- if mcelog.logging.syslog is defined %} | |||||
syslog = {{ 'yes' if mcelog.logging.syslog else 'no' }} | |||||
{%- endif %} | |||||
{%- if mcelog.logging.syslog_error is defined %} | |||||
syslog-error = {{ 'yes' if mcelog.logging.syslog_error else 'no' }} | |||||
{%- endif %} | |||||
{%- if mcelog.logging.no_syslog is defined %} | |||||
no-syslog = {{ 'yes' if mcelog.logging.no_syslog else 'no' }} | |||||
{%- endif %} | |||||
{%- if mcelog.logging.logfile is defined %} | |||||
logfile = {{ mcelog.logging.logfile }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
# Use SMBIOS information to decode DIMMs (needs root). | |||||
# This function is not recommended to use right now and generally not needed. | |||||
# The exception is memdb prepopulation, which is configured separately below. | |||||
#dmi = no | |||||
# When in daemon mode run as this user after set up. | |||||
# Note that the triggers will run as this user too. | |||||
# Setting this to non root will mean that triggers cannot take some corrective | |||||
# action, like offlining objects. | |||||
#run-credentials-user = root | |||||
# group to run as daemon with | |||||
# default to the group of the run-credentials-user | |||||
#run-credentials-group = nobody | |||||
[server] | |||||
# user allowed to access client socket. | |||||
# when set to * match any | |||||
# root is always allowed to access. | |||||
# default: root only | |||||
client-user = root | |||||
# group allowed to access mcelog | |||||
# When no group is configured any group matches (but still user checking). | |||||
# when set to * match any | |||||
#client-group = root | |||||
# Path to the unix socket for client<->server communication. | |||||
# When no socket-path is configured the server will not start | |||||
#socket-path = /var/run/mcelog-client | |||||
# When mcelog starts it checks if a server is already running. This configures the timeout | |||||
# for this check. | |||||
#initial-ping-timeout = 2 | |||||
# | |||||
[dimm] | |||||
# Is the in memory DIMM error tracking enabled? | |||||
# Only works on systems with integrated memory controller and | |||||
# which are supported. | |||||
# Only takes effect in daemon mode. | |||||
dimm-tracking-enabled = yes | |||||
# Use DMI information from the BIOS to prepopulate DIMM database. | |||||
# Note this might not work with all BIOS and requires mcelog to run as root. | |||||
# Alternative is to let mcelog create DIMM objects on demand. | |||||
dmi-prepopulate = yes | |||||
# | |||||
# Execute these triggers when the rate of corrected or uncorrected | |||||
# Errors per DIMM exceeds the threshold. | |||||
# Note when the hardware does not report DIMMs this might also | |||||
# be per channel. | |||||
# The default of 10/24h is reasonable for server quality | |||||
# DDR3 DIMMs as of 2009/10. | |||||
#uc-error-trigger = dimm-error-trigger | |||||
uc-error-threshold = 1 / 24h | |||||
#ce-error-trigger = dimm-error-trigger | |||||
ce-error-threshold = 10 / 24h | |||||
[socket] | |||||
# Enable memory error accounting per socket. | |||||
socket-tracking-enabled = yes | |||||
# Threshold and trigger for uncorrected memory errors on a socket. | |||||
# mem-uc-error-trigger = socket-memory-error-trigger | |||||
mem-uc-error-threshold = 100 / 24h | |||||
# Trigger script for corrected memory errors on a socket. | |||||
mem-ce-error-trigger = socket-memory-error-trigger | |||||
# Threshold on when to trigger a correct error for the socket. | |||||
mem-ce-error-threshold = 100 / 24h | |||||
# Log socket error threshold explicitely? | |||||
mem-ce-error-log = yes | |||||
# Trigger script for uncorrected bus error events | |||||
bus-uc-threshold-trigger = bus-error-trigger | |||||
# Trigger script for uncorrected IOMCA erors | |||||
iomca-threshold-trigger = iomca-error-trigger | |||||
# Trigger script for other uncategorized errors | |||||
unknown-threshold-trigger = unknown-error-trigger | |||||
[cache] | |||||
# Processing of cache error thresholds reported by Intel CPUs. | |||||
cache-threshold-trigger = cache-error-trigger | |||||
# Should cache threshold events be logged explicitely? | |||||
cache-threshold-log = yes | |||||
[page] | |||||
# Memory error accouting per 4K memory page. | |||||
# Threshold for the correct memory errors trigger script. | |||||
memory-ce-threshold = 10 / 24h | |||||
# Trigger script for corrected errors. | |||||
# memory-ce-trigger = page-error-trigger | |||||
# Should page threshold events be logged explicitely? | |||||
memory-ce-log = yes | |||||
# specify the internal action in mcelog to exceeding a page error threshold | |||||
# this is done in addition to executing the trigger script if available | |||||
# off no action | |||||
# account only account errors | |||||
# soft try to soft-offline page without killing any processes | |||||
# This requires an uptodate kernel. Might not be successfull. | |||||
# hard try to hard-offline page by killing processes | |||||
# Requires an uptodate kernel. Might not be successfull. | |||||
# soft-then-hard First try to soft offline, then try hard offlining | |||||
#memory-ce-action = off|account|soft|hard|soft-then-hard | |||||
memory-ce-action = soft | |||||
[trigger] | |||||
# Maximum number of running triggers | |||||
children-max = 2 | |||||
# execute triggers in this directory | |||||
directory = /etc/mcelog |
{%- from "linux/map.jinja" import auth with context %} | |||||
Name: Create home directory during login | Name: Create home directory during login | ||||
Default: yes | Default: yes | ||||
Priority: 0 | Priority: 0 | ||||
Session-Type: Additional | Session-Type: Additional | ||||
Session-Final: | Session-Final: | ||||
required pam_mkhomedir.so skel=/etc/skel umask=0022 silent | |||||
required pam_mkhomedir.so skel=/etc/skel umask={{ auth.mkhomedir.get('umask', '0022') }} silent |
{% if module_content.get('blacklist', false) -%} | |||||
{%- from "linux/map.jinja" import system with context -%} | |||||
# This file is managed by Salt, do not edit. | |||||
{%- set module_content = system.kernel.module.get(module_name) %} | |||||
{%- if module_content.get('blacklist', false) %} | |||||
blacklist {{ module_name }} | blacklist {{ module_name }} | ||||
{%- else -%} | |||||
{%- for option, value in module_content.get('option', {}) | dictsort -%} | |||||
options {{ module_name }} {{ option }}={{ value }} | |||||
{%- endif %} | |||||
{%- for alias, params in module_content.get('alias', {}) | dictsort %} | |||||
{%- if params.get('enabled', true) %} | |||||
alias {{ alias }} {{ module_name }} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- set options = [] %} | |||||
{%- for option, params in module_content.get('option', {}) | dictsort %} | |||||
{%- if params is mapping %} | |||||
{%- if params.get('enabled', true) and params.value is defined %} | |||||
{%- do options.append(option ~ '=' ~ params.value) %} | |||||
{%- endif %} | |||||
{%- else %} | |||||
{%- do options.append(option ~ '=' ~ params) %} | |||||
{%- endif %} | |||||
{%- endfor %} | {%- endfor %} | ||||
{%- if options | length > 0 %} | |||||
options {{ module_name }} {{ options | join(' ')}} | |||||
{%- endif %} | |||||
{%- if module_content.install is defined %} | |||||
{%- if module_content.install.get('enabled', true) and module_content.install.command is defined %} | |||||
install {{ module_name }} {{ module_content.install.command }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if module_content.remove is defined %} | |||||
{%- if module_content.remove.get('enabled', true) and module_content.remove.command is defined %} | |||||
remove {{ module_name }} {{ module_content.remove.command }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if module_content.softdep is defined %} | |||||
{%- set pre = [] %} | |||||
{%- set post = [] %} | |||||
{%- for pos, params in module_content.softdep.get('pre', {}) | dictsort %} | |||||
{%- if params.get('enabled', true) and params.value is defined %} | |||||
{%- do pre.append(params.value) %} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- for pos, params in module_content.softdep.get('post', {}) | dictsort %} | |||||
{%- if params.get('enabled', true) and params.value is defined %} | |||||
{%- do post.append(params.value) %} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- if pre | length + post | length > 0 %} | |||||
softdep {{ module_name }}{% if pre | length > 0 %} pre: {{ pre | join(' ') }}{% endif %}{% if post | length > 0 %} post: {{ post | join(' ') }}{% endif %} | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} |
{%- from "linux/map.jinja" import network with context %} | |||||
{%- set openvswitch = network.openvswitch %} | |||||
# This is a POSIX shell fragment -*- sh -*- | |||||
# FORCE_COREFILES: If 'yes' then core files will be enabled. | |||||
# FORCE_COREFILES=yes | |||||
# OVS_CTL_OPTS: Extra options to pass to ovs-ctl. This is, for example, | |||||
# a suitable place to specify --ovs-vswitchd-wrapper=valgrind. | |||||
# OVS_CTL_OPTS= | |||||
# OVS_VSWITCHD_OPTS: Extra options to pass to ovs-ctl. | |||||
# Options to start Open vSwitch daemon with. | |||||
# Example: '-vconsole:dbg -vsyslog:dbg -vfile:dbg -vFACILITY:clock2' | |||||
# OVS_VSWITCHD_OPTS= | |||||
{%- if openvswitch.get('logging', {}).vswitchd is defined %} | |||||
{%- set _vswitchd_opts = [] %} | |||||
{%- for opt in ['console', 'file', 'syslog'] %} | |||||
{%- if openvswitch.logging.vswitchd.get(opt) %} | |||||
{%- do _vswitchd_opts.append("-v"+ opt + ":" + openvswitch.logging.vswitchd.get(opt)) %} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- if openvswitch.logging.vswitchd.facility is defined %} | |||||
{%- do _vswitchd_opts.append("-vFACILITY:" + openvswitch.logging.vswitchd.facility) %} | |||||
{%- endif %} | |||||
OVS_VSWITCHD_OPTS="{{ ' '.join(_vswitchd_opts) }}" | |||||
{%- endif %} | |||||
# OVSDB_OPTS: Extra options to pass to ovs-ctl. | |||||
# Options to start Open vSwitch DB daemon with. | |||||
# Example: '-vconsole:dbg -vsyslog:dbg -vfile:dbg -vFACILITY:clock2' | |||||
# OVSDB_OPTS= | |||||
{%- if openvswitch.get('logging', {}).ovsdb is defined %} | |||||
{%- set _ovsdb_opts = [] %} | |||||
{%- for opt in ['console', 'file', 'syslog'] %} | |||||
{%- if openvswitch.logging.ovsdb.get(opt) %} | |||||
{%- do _ovsdb_opts.append("-v" + opt + ":" + openvswitch.logging.ovsdb.get(opt)) %} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- if openvswitch.logging.ovsdb.facility is defined %} | |||||
{%- do _ovsdb_opts.append("-vFACILITY:" + openvswitch.logging.ovsdb.facility) %} | |||||
{%- endif %} | |||||
OVSDB_OPTS="{{ ' '.join(_ovsdb_opts) }}" | |||||
{%- endif %} |
[Unit] | |||||
Description=Open vSwitch | |||||
Before=network.target | |||||
After=network-pre.target ovsdb-server.service ovs-vswitchd.service | |||||
PartOf=network.target | |||||
Requires=ovsdb-server.service | |||||
Requires=ovs-vswitchd.service | |||||
[Service] | |||||
Type=oneshot | |||||
ExecStart=/usr/bin/ovs-vsctl set open . external-ids:hostname=%H | |||||
ExecReload=/bin/true | |||||
ExecStop=/bin/true | |||||
RemainAfterExit=yes | |||||
[Install] | |||||
WantedBy=multi-user.target | |||||
auto {{ bridge_name }} | |||||
iface {{ bridge_name }} inet {{ bridge.get('proto', 'static' if bridge.address is defined else 'manual') }} | |||||
ovs_type {{ bridge.get('ovs_bridge_type', 'OVSBridge') }} | |||||
mtu {{ bridge.get('mtu', '1500') }} | |||||
{%- if bridge.address is defined %} | |||||
address {{ bridge.address }} | |||||
netmask {{ bridge.netmask }} | |||||
{%- endif %} | |||||
{%- if bridge.gateway is defined %} | |||||
gateway {{ bridge.gateway }} | |||||
{%- endif %} | |||||
{%- if bridge.ovs_options is defined %} | |||||
ovs_options {{ bridge.ovs_options }} | |||||
{%- endif %} |
{%- from "linux/map.jinja" import auth with context %} | |||||
# PAM configuration for the Secure Shell service | |||||
{%- if auth.duo.enabled %} | |||||
auth required /lib64/security/pam_duo.so | |||||
account required pam_nologin.so | |||||
# Standard Un*x authentication. | |||||
#@include common-auth | |||||
{%- else %} | |||||
# Standard Un*x authentication. | |||||
@include common-auth | |||||
{%- endif %} | |||||
# Disallow non-root logins when /etc/nologin exists. | |||||
account required pam_nologin.so | |||||
# Uncomment and edit /etc/security/access.conf if you need to set complex | |||||
# access limits that are hard to express in sshd_config. | |||||
# account required pam_access.so | |||||
# Standard Un*x authorization. | |||||
@include common-account | |||||
# SELinux needs to be the first session rule. This ensures that any | |||||
# lingering context has been cleared. Without this it is possible that a | |||||
# module could execute code in the wrong domain. | |||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close | |||||
# Set the loginuid process attribute. | |||||
session required pam_loginuid.so | |||||
# Create a new session keyring. | |||||
session optional pam_keyinit.so force revoke | |||||
# Standard Un*x session setup and teardown. | |||||
@include common-session | |||||
# Print the message of the day upon successful login. | |||||
# This includes a dynamically generated part from /run/motd.dynamic | |||||
# and a static (admin-editable) part from /etc/motd. | |||||
session optional pam_motd.so motd=/run/motd.dynamic | |||||
session optional pam_motd.so noupdate | |||||
# Print the status of the user's mailbox upon successful login. | |||||
session optional pam_mail.so standard noenv # [1] | |||||
# Set up user limits from /etc/security/limits.conf. | |||||
session required pam_limits.so | |||||
# Read environment variables from /etc/environment and | |||||
# /etc/security/pam_env.conf. | |||||
session required pam_env.so # [1] | |||||
# In Debian 4.0 (etch), locale-related environment variables were moved to | |||||
# /etc/default/locale, so read that as well. | |||||
session required pam_env.so user_readenv=1 envfile=/etc/default/locale | |||||
# SELinux needs to intervene at login time to ensure that the process starts | |||||
# in the proper default security context. Only sessions which are intended | |||||
# to run in the user's context should be run after this. | |||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open | |||||
# Standard Un*x password updating. | |||||
@include common-password | |||||
{%- from "linux/map.jinja" import system with context %} | |||||
{%- set repo = system.repo[repo_name] %} | |||||
{%- for pin in repo.pin %} | |||||
{%- set package = pin.get('package', '*') %} | |||||
{%- from "linux/map.jinja" import system with context -%} | |||||
{%- set repo = system.repo[repo_name] -%} | |||||
{%- if repo.pinning is defined -%} | |||||
{%- for id,pin in repo.pinning|dictsort -%} | |||||
{% if pin.get('enabled', False) %} | |||||
Package: {{ pin.get('package','*') }} | |||||
Pin: {{ pin.pin }} | |||||
Pin-Priority: {{ pin.priority }} | |||||
{%- endif %} | |||||
{%- endfor -%} | |||||
{%- elif repo.pin is defined -%} | |||||
{%- for pin in repo.pin -%} | |||||
{%- set package = pin.get('package', '*') %} | |||||
Package: {{ package }} | Package: {{ package }} | ||||
Pin: {{ pin.pin }} | Pin: {{ pin.pin }} | ||||
Pin-Priority: {{ pin.priority }} | Pin-Priority: {{ pin.priority }} | ||||
{% endfor %} | |||||
{%- endfor %} | |||||
{%- endif -%} |
description "Setup {{ device_name }} device" | description "Setup {{ device_name }} device" | ||||
start on filesystem | start on filesystem | ||||
task | |||||
pre-start script | |||||
if /sbin/losetup {{ device_name }}; then | |||||
stop ; exit 0 | |||||
fi | |||||
end script | |||||
pre-start exec losetup {{ device_name }} {{ file }} | |||||
post-stop exec losetup -d {{ device_name }} | |||||
exec losetup {{ device_name }} {{ file }} | |||||
script | |||||
while losetup {{ device_name }} ; do sleep 60 ; done | |||||
end script |
# Sysfs file for {{ name }} managed by salt-minion(1) | # Sysfs file for {{ name }} managed by salt-minion(1) | ||||
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN | # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN | ||||
{%- for key, value in sysfs.items() %} | |||||
{%- if sysfs is mapping %} | |||||
{%- set sysfs_list = [sysfs] %} | |||||
{%- else %} | |||||
{%- set sysfs_list = sysfs %} | |||||
{%- endif %} | |||||
{%- for item in sysfs_list %} | |||||
{%- for key, value in item.items() %} | |||||
{%- if key in ["mode", "owner"] %} | {%- if key in ["mode", "owner"] %} | ||||
{%- for attr, val in value.items() %} | {%- for attr, val in value.items() %} | ||||
mode {{ attr }} = {{ val }} | mode {{ attr }} = {{ val }} | ||||
{{ key }} = {{ value }} | {{ key }} = {{ value }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- endfor %} | {%- endfor %} | ||||
{%- endfor %} | |||||
{#- | {#- | ||||
vim: syntax=jinja | vim: syntax=jinja |
[[inputs.bond]] | |||||
{%- include 'telegraf/files/input/_common.conf' %} | |||||
{%- if values.bond_interfaces is defined %} | |||||
bond_interfaces = {{ values.bond_interfaces | json }} | |||||
{%- endif %} | |||||
{%- if values.host_proc is defined %} | |||||
host_proc = "{{ values.host_proc | json }}" | |||||
{%- endif %} | |||||
{%- include 'telegraf/files/input/_filters.conf' %} |
'logpath': '/var/log/atop', | 'logpath': '/var/log/atop', | ||||
'outfile': '/var/log/atop/daily.log' | 'outfile': '/var/log/atop/daily.log' | ||||
}, | }, | ||||
'at': { | |||||
'pkgs': [], | |||||
'services': [] | |||||
}, | |||||
'cron': { | |||||
'pkgs': [], | |||||
'services': [] | |||||
}, | |||||
}, | }, | ||||
'Debian': { | 'Debian': { | ||||
'pkgs': ['python-apt', 'apt-transport-https', 'libmnl0'], | 'pkgs': ['python-apt', 'apt-transport-https', 'libmnl0'], | ||||
'logpath': '/var/log/atop', | 'logpath': '/var/log/atop', | ||||
'outfile': '/var/log/atop/daily.log' | 'outfile': '/var/log/atop/daily.log' | ||||
}, | }, | ||||
'at': { | |||||
'pkgs': ['at'], | |||||
'services': ['atd'], | |||||
'user': {} | |||||
}, | |||||
'cron': { | |||||
'pkgs': ['cron'], | |||||
'services': ['cron'], | |||||
'user': {} | |||||
}, | |||||
}, | }, | ||||
'RedHat': { | 'RedHat': { | ||||
'pkgs': ['policycoreutils', 'policycoreutils-python', 'telnet', 'wget'], | 'pkgs': ['policycoreutils', 'policycoreutils-python', 'telnet', 'wget'], | ||||
'logpath': '/var/log/atop', | 'logpath': '/var/log/atop', | ||||
'outfile': '/var/log/atop/daily.log' | 'outfile': '/var/log/atop/daily.log' | ||||
}, | }, | ||||
'at': { | |||||
'pkgs': [], | |||||
'services': [] | |||||
}, | |||||
'cron': { | |||||
'pkgs': [], | |||||
'services': [] | |||||
}, | |||||
}, | }, | ||||
}, grain='os_family', merge=salt['pillar.get']('linux:system')) %} | }, grain='os_family', merge=salt['pillar.get']('linux:system')) %} | ||||
{% set banner = salt['grains.filter_by']({ | |||||
'BaseDefaults': { | |||||
'enabled': false, | |||||
}, | |||||
}, grain='os_family', merge=salt['pillar.get']('linux:system:banner'), base='BaseDefaults') %} | |||||
{% set auth = salt['grains.filter_by']({ | {% set auth = salt['grains.filter_by']({ | ||||
'Arch': { | 'Arch': { | ||||
'enabled': false, | 'enabled': false, | ||||
'duo': { | |||||
'enabled': false, | |||||
'duo_host': 'localhost', | |||||
'duo_ikey': '', | |||||
'duo_skey': '' | |||||
} | |||||
}, | }, | ||||
'RedHat': { | 'RedHat': { | ||||
'enabled': false, | 'enabled': false, | ||||
'duo': { | |||||
'enabled': false, | |||||
'duo_host': 'localhost', | |||||
'duo_ikey': '', | |||||
'duo_skey': '' | |||||
} | |||||
}, | }, | ||||
'Debian': { | 'Debian': { | ||||
'enabled': false, | 'enabled': false, | ||||
'duo': { | |||||
'enabled': false, | |||||
'duo_host': 'localhost', | |||||
'duo_ikey': '', | |||||
'duo_skey': '' | |||||
} | |||||
}, | }, | ||||
}, grain='os_family', merge=salt['pillar.get']('linux:system:auth')) %} | }, grain='os_family', merge=salt['pillar.get']('linux:system:auth')) %} | ||||
{% set ldap = salt['grains.filter_by']({ | {% set ldap = salt['grains.filter_by']({ | ||||
'RedHat': { | 'RedHat': { | ||||
'enabled': false, | 'enabled': false, | ||||
'pkgs': ['openldap-clients', 'nss-pam-ldapd', 'authconfig'], | |||||
'pkgs': ['openldap-clients', 'nss-pam-ldapd', 'authconfig', 'nscd'], | |||||
'version': '3', | 'version': '3', | ||||
'scope': 'sub', | 'scope': 'sub', | ||||
'uid': 'nslcd', | 'uid': 'nslcd', | ||||
}, | }, | ||||
'Debian': { | 'Debian': { | ||||
'enabled': false, | 'enabled': false, | ||||
'pkgs': ['libnss-ldapd', 'libpam-ldapd'], | |||||
'pkgs': ['libnss-ldapd', 'libpam-ldapd', 'nscd'], | |||||
'version': '3', | 'version': '3', | ||||
'scope': 'sub', | 'scope': 'sub', | ||||
'uid': 'nslcd', | 'uid': 'nslcd', | ||||
}, | }, | ||||
}, grain='os_family', merge=salt['pillar.get']('linux:system:auth:ldap')) %} | }, grain='os_family', merge=salt['pillar.get']('linux:system:auth:ldap')) %} | ||||
{%- load_yaml as login_defs_defaults %} | |||||
Debian: | |||||
CHFN_RESTRICT: | |||||
value: 'rwh' | |||||
DEFAULT_HOME: | |||||
value: 'yes' | |||||
ENCRYPT_METHOD: | |||||
value: 'SHA512' | |||||
ENV_PATH: | |||||
value: 'PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games' | |||||
ENV_SUPATH: | |||||
value: 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' | |||||
ERASECHAR: | |||||
value: '0177' | |||||
FAILLOG_ENAB: | |||||
value: 'yes' | |||||
FTMP_FILE: | |||||
value: '/var/log/btmp' | |||||
GID_MAX: | |||||
value: '60000' | |||||
GID_MIN: | |||||
value: '1000' | |||||
HUSHLOGIN_FILE: | |||||
value: '.hushlogin' | |||||
KILLCHAR: | |||||
value: '025' | |||||
LOGIN_RETRIES: | |||||
value: '5' | |||||
LOGIN_TIMEOUT: | |||||
value: '60' | |||||
LOG_OK_LOGINS: | |||||
value: 'no' | |||||
LOG_UNKFAIL_ENAB: | |||||
value: 'no' | |||||
MAIL_DIR: | |||||
value: '/var/mail' | |||||
PASS_MAX_DAYS: | |||||
value: '99999' | |||||
PASS_MIN_DAYS: | |||||
value: '0' | |||||
PASS_WARN_AGE: | |||||
value: '7' | |||||
SU_NAME: | |||||
value: 'su' | |||||
SYSLOG_SG_ENAB: | |||||
value: 'yes' | |||||
SYSLOG_SU_ENAB: | |||||
value: 'yes' | |||||
TTYGROUP: | |||||
value: 'tty' | |||||
TTYPERM: | |||||
value: '0600' | |||||
UID_MAX: | |||||
value: '60000' | |||||
UID_MIN: | |||||
value: '1000' | |||||
UMASK: | |||||
value: '022' | |||||
USERGROUPS_ENAB: | |||||
value: 'yes' | |||||
{%- endload %} | |||||
{%- set login_defs = salt['grains.filter_by'](login_defs_defaults, | |||||
grain='os_family', merge=salt['pillar.get']('linux:system:login_defs')) %} | |||||
{# 'network_name', #} | {# 'network_name', #} | ||||
{% set interface_params = [ | {% set interface_params = [ | ||||
'maxwait', | 'maxwait', | ||||
'stp', | 'stp', | ||||
'gro', | 'gro', | ||||
'rx', | |||||
'tx', | |||||
'sg', | |||||
'tso', | |||||
'ufo', | |||||
'gso', | |||||
'lro', | |||||
'lacp_rate', | 'lacp_rate', | ||||
'ad_select', | 'ad_select', | ||||
'downdelay', | 'downdelay', | ||||
'arp_ip_target', | 'arp_ip_target', | ||||
'primary', | 'primary', | ||||
] %} | ] %} | ||||
{% set debian_headers = "linux-headers-" + grains.get('kernelrelease')|string %} | |||||
{% set network = salt['grains.filter_by']({ | {% set network = salt['grains.filter_by']({ | ||||
'Arch': { | 'Arch': { | ||||
'pkgs': ['wpa_supplicant', 'dhclient', 'wireless_tools', 'ifenslave'], | 'pkgs': ['wpa_supplicant', 'dhclient', 'wireless_tools', 'ifenslave'], | ||||
'bridge_pkgs': ['bridge-utils'], | |||||
'ovs_pkgs': ['openvswitch-switch'], | |||||
'bridge_pkgs': ['bridge-utils', 'vlan'], | |||||
'ovs_pkgs': ['openvswitch-switch', 'vlan'], | |||||
'hostname_file': '/etc/hostname', | 'hostname_file': '/etc/hostname', | ||||
'network_manager': False, | 'network_manager': False, | ||||
'systemd': {}, | 'systemd': {}, | ||||
'host': {}, | 'host': {}, | ||||
'mine_dns_records': False, | 'mine_dns_records': False, | ||||
'dhclient_config': '/etc/dhcp/dhclient.conf', | 'dhclient_config': '/etc/dhcp/dhclient.conf', | ||||
'ovs_nowait': False, | |||||
}, | }, | ||||
'Debian': { | 'Debian': { | ||||
'pkgs': ['ifenslave'], | 'pkgs': ['ifenslave'], | ||||
'hostname_file': '/etc/hostname', | 'hostname_file': '/etc/hostname', | ||||
'bridge_pkgs': ['bridge-utils'], | |||||
'ovs_pkgs': ['openvswitch-switch', 'bridge-utils'], | |||||
'dpdk_pkgs': ['dpdk', 'dpdk-dev', 'dpdk-igb-uio-dkms', 'dpdk-rte-kni-dkms'], | |||||
'bridge_pkgs': ['bridge-utils', 'vlan'], | |||||
'ovs_pkgs': ['openvswitch-switch', 'bridge-utils', 'vlan'], | |||||
'dpdk_pkgs': ['dpdk', 'dpdk-dev', 'dpdk-igb-uio-dkms', 'dpdk-rte-kni-dkms', debian_headers.encode('utf8') ], | |||||
'network_manager': False, | 'network_manager': False, | ||||
'systemd': {}, | 'systemd': {}, | ||||
'interface': {}, | 'interface': {}, | ||||
'host': {}, | 'host': {}, | ||||
'mine_dns_records': False, | 'mine_dns_records': False, | ||||
'dhclient_config': '/etc/dhcp/dhclient.conf', | 'dhclient_config': '/etc/dhcp/dhclient.conf', | ||||
'ovs_nowait': False, | |||||
}, | }, | ||||
'RedHat': { | 'RedHat': { | ||||
'pkgs': ['iputils'], | 'pkgs': ['iputils'], | ||||
'bridge_pkgs': ['bridge-utils'], | |||||
'ovs_pkgs': ['openvswitch-switch', 'bridge-utils'], | |||||
'bridge_pkgs': ['bridge-utils', 'vlan'], | |||||
'ovs_pkgs': ['openvswitch-switch', 'bridge-utils', 'vlan'], | |||||
'hostname_file': '/etc/sysconfig/network', | 'hostname_file': '/etc/sysconfig/network', | ||||
'network_manager': False, | 'network_manager': False, | ||||
'systemd': {}, | 'systemd': {}, | ||||
'host': {}, | 'host': {}, | ||||
'mine_dns_records': False, | 'mine_dns_records': False, | ||||
'dhclient_config': '/etc/dhcp/dhclient.conf', | 'dhclient_config': '/etc/dhcp/dhclient.conf', | ||||
'ovs_nowait': False, | |||||
}, | }, | ||||
}, grain='os_family', merge=salt['pillar.get']('linux:network')) %} | }, grain='os_family', merge=salt['pillar.get']('linux:network')) %} | ||||
'service': 'multipath' | 'service': 'multipath' | ||||
}, | }, | ||||
}, | }, | ||||
}, grain='os_family', merge=salt['pillar.get']('linux:storage')) %} | |||||
}, merge=salt['grains.filter_by']({ | |||||
'trusty': { | |||||
'lvm_services': ['udev'], | |||||
}, | |||||
}, grain='oscodename', merge=salt['pillar.get']('linux:storage'))) %} | |||||
{% set monitoring = salt['grains.filter_by']({ | {% set monitoring = salt['grains.filter_by']({ | ||||
'default': { | 'default': { | ||||
'bond_status': { | |||||
'interfaces': False | |||||
}, | |||||
'zombie': { | 'zombie': { | ||||
'warn': 3, | 'warn': 3, | ||||
'crit': 7, | 'crit': 7, | ||||
'interface_regex': '^[a-z0-9]+$', | 'interface_regex': '^[a-z0-9]+$', | ||||
'ignore_selected': False, | 'ignore_selected': False, | ||||
}, | }, | ||||
'bond_status': { | |||||
'interfaces': False | |||||
'cpu_usage_percentage': { | |||||
'warn': 90.0, | |||||
}, | |||||
'memory_usage_percentage': { | |||||
'warn': 90.0, | |||||
'major': 95.0, | |||||
}, | |||||
'disk_usage_percentage': { | |||||
'warn': 85.0, | |||||
'major': 95.0, | |||||
}, | }, | ||||
'cpu_idle_percentage': { | |||||
'warn': 10.0, | |||||
'swap_usage_percentage': { | |||||
'warn': 50.0, | |||||
'minor': 90.0, | |||||
}, | }, | ||||
'free_memory_percentage': { | |||||
'warn': 10.0, | |||||
'crit': 5.0, | |||||
'inodes_usage_percentage': { | |||||
'warn': 85.0, | |||||
'major': 95.0, | |||||
}, | }, | ||||
'load_5': { | |||||
'warn': 3, | |||||
'system_load_threshold': { | |||||
'warn': 1, | |||||
'crit': 2, | |||||
}, | }, | ||||
'rx_packets_dropped_rate': { | |||||
'warn': 100, | |||||
'rx_packets_dropped_threshold': { | |||||
'warn': 100, | |||||
}, | }, | ||||
'tx_packets_dropped_rate': { | |||||
'warn': 100, | |||||
'tx_packets_dropped_threshold': { | |||||
'warn': 100, | |||||
}, | }, | ||||
'swap_in_rate': { | 'swap_in_rate': { | ||||
'warn': 1024 * 1024, | |||||
'warn': 1024 * 1024, | |||||
}, | }, | ||||
'swap_out_rate': { | 'swap_out_rate': { | ||||
'warn': 1024 * 1024, | |||||
'warn': 1024 * 1024, | |||||
}, | }, | ||||
'failed_auths_threshold': { | |||||
'warn': 5, | |||||
}, | |||||
'net_rx_action_per_cpu_threshold': { | |||||
'warning': '500', | |||||
'minor': '5000' | |||||
}, | |||||
'packets_dropped_per_cpu_threshold': { | |||||
'minor': '0', | |||||
'major': '100' | |||||
} | |||||
}, | }, | ||||
}, grain='os_family', merge=salt['pillar.get']('linux:monitoring')) %} | }, grain='os_family', merge=salt['pillar.get']('linux:monitoring')) %} | ||||
{%- if pillar.get('fluentd', {}).get('agent', {}).get('enabled', False) %} | |||||
{%- set positiondb = pillar.fluentd.agent.dir.positiondb %} | |||||
{%- if grains.get('init') == 'systemd' %} | {%- if grains.get('init') == 'systemd' %} | ||||
agent: | agent: | ||||
plugin: | plugin: | ||||
fluent-plugin-systemd: | fluent-plugin-systemd: | ||||
gem: ['fluent-plugin-systemd'] | |||||
deb: ['td-agent-additional-plugins'] | |||||
config: | config: | ||||
label: | label: | ||||
default_metric: | default_metric: | ||||
type: systemd | type: systemd | ||||
tag: systemd.source | tag: systemd.source | ||||
path: /run/log/journal | path: /run/log/journal | ||||
pos_file: {{ pillar.fluentd.agent.dir.positiondb }}/systemd.source.pos | |||||
pos_file: {{ positiondb }}/systemd.source.pos | |||||
entry: | entry: | ||||
field_map: | field_map: | ||||
MESSAGE: 'Payload' | MESSAGE: 'Payload' | ||||
record: | record: | ||||
- name: severity_label | - name: severity_label | ||||
value: '${ {"TRACE"=>8,"DEBUG"=>7,"INFO"=>6,"NOTICE"=>5,"WARNING"=>4,"ERROR"=>3,"CRITICAL"=>2,"ALERT"=>1,"EMERGENCY"=>0}.key(record["Severity"].to_i) }' | value: '${ {"TRACE"=>8,"DEBUG"=>7,"INFO"=>6,"NOTICE"=>5,"WARNING"=>4,"ERROR"=>3,"CRITICAL"=>2,"ALERT"=>1,"EMERGENCY"=>0}.key(record["Severity"].to_i) }' | ||||
- name: source | |||||
value: systemd | |||||
match: | match: | ||||
rewrite_tag: | rewrite_tag: | ||||
tag: systemd.source | tag: systemd.source | ||||
rule: | rule: | ||||
- name: ident | - name: ident | ||||
regexp: '^(.*)$' | regexp: '^(.*)$' | ||||
result: __TAG__.$1 | |||||
result: $1.systemd | |||||
push_to_default: | push_to_default: | ||||
tag: 'systemd.source.*' | |||||
tag: '*.systemd' | |||||
type: copy | type: copy | ||||
store: | store: | ||||
- type: relabel | - type: relabel | ||||
tag: 'metric.**' | tag: 'metric.**' | ||||
type: relabel | type: relabel | ||||
label: default_metric | label: default_metric | ||||
{%- else %} | |||||
agent: | |||||
config: | |||||
label: | |||||
default_metric: | |||||
filter: | |||||
metric_hdd_errors_parse: | |||||
tag: metric.hdd_errors | |||||
type: parser | |||||
key_name: Payload | |||||
parser: | |||||
type: regexp | |||||
format: '/(?<device>[sv]d[a-z]+\d*)/' | |||||
metric_hdd_errors: | |||||
tag: metric.hdd_errors | |||||
require: | |||||
- metric_hdd_errors_parse | |||||
type: prometheus | |||||
metric: | |||||
- name: hdd_errors_total | |||||
type: counter | |||||
desc: The total number of hdd errors. | |||||
label: | |||||
- name: host | |||||
value: ${Hostname} | |||||
- name: device | |||||
value: ${device} | |||||
syslog: | |||||
input: | |||||
syslog_file: | |||||
type: tail | |||||
tag: linux.syslog | |||||
path: /var/log/syslog | |||||
pos_file: {{ positiondb }}/linux_syslog.pos | |||||
suppress_parse_error_log: true | |||||
parser: | |||||
type: regexp | |||||
format: >- | |||||
'/(?<Payload>.*(?<device>[sv]d[a-z]{1,2}\d{0,3}).*)/' | |||||
match: | |||||
push_to_default: | |||||
tag: 'linux.**' | |||||
type: copy | |||||
store: | |||||
- type: relabel | |||||
label: default_output | |||||
- type: rewrite_tag_filter | |||||
rule: | |||||
- name: Payload | |||||
regexp: >- | |||||
'error.*\b[sv]d[a-z]{1,2}\d{0,3}\b.*' | |||||
result: metric.hdd_errors | |||||
- name: Payload | |||||
regexp: >- | |||||
'\b[sv]d[a-z]{1,2}\d{0,3}\b.*error' | |||||
result: metric.hdd_errors | |||||
push_to_metric: | |||||
tag: 'metric.**' | |||||
type: relabel | |||||
label: default_metric | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} |
{%- from "linux/map.jinja" import monitoring with context %} | |||||
dashboard: | dashboard: | ||||
linux_prometheus: | |||||
linux_overview_prometheus: | |||||
datasource: prometheus | datasource: prometheus | ||||
format: json | format: json | ||||
template: linux/files/grafana_dashboards/system_prometheus.json | |||||
template: linux/files/grafana_dashboards/system_overview_prometheus.json | |||||
linux_disk_prometheus: | |||||
datasource: prometheus | |||||
format: json | |||||
template: linux/files/grafana_dashboards/system_disk_prometheus.json | |||||
linux_network_prometheus: | |||||
datasource: prometheus | |||||
format: json | |||||
template: linux/files/grafana_dashboards/system_network_prometheus.json | |||||
linux_influxdb: | linux_influxdb: | ||||
datasource: influxdb | datasource: influxdb | ||||
format: json | format: json | ||||
template: linux/files/grafana_dashboards/system_influxdb.json | template: linux/files/grafana_dashboards/system_influxdb.json | ||||
{%- if monitoring.bond_status.interfaces is defined and monitoring.bond_status.interfaces %} | |||||
linux_bond: | |||||
datasource: prometheus | |||||
format: json | |||||
template: linux/files/grafana_dashboards/bond_prometheus.json | |||||
{%- endif %} |
{%- from "linux/map.jinja" import monitoring with context %} | {%- from "linux/map.jinja" import monitoring with context %} | ||||
server: | server: | ||||
alert: | alert: | ||||
SystemCpuIdleTooLow: | |||||
{%- set cpu_idle_threshold = monitoring.cpu_idle_percentage.warn|float %} | |||||
if: avg_over_time(cpu_usage_idle{cpu="cpu-total"}[5m]) < {{ cpu_idle_threshold }} | |||||
SystemCpuFullWarning: | |||||
{%- set cpu_usage_threshold = monitoring.cpu_usage_percentage.warn|float %} | |||||
if: >- | |||||
100 - avg_over_time(cpu_usage_idle{cpu="cpu-total"}[5m]) > {{ cpu_usage_threshold }} | |||||
{% raw %} | {% raw %} | ||||
for: 2m | |||||
labels: | labels: | ||||
severity: warning | severity: warning | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Idle CPU usage too low on {{ $labels.host }}' | |||||
description: 'The average idle CPU usage is too low on node {{ $labels.host }} (current value={{ $value }}%, threshold={% endraw %}{{ cpu_idle_threshold}}%).' | |||||
SystemDiskSpaceTooLow: | |||||
if: 'predict_linear(disk_free[1h], 8*3600) < 0' | |||||
{% raw %} | |||||
for: 15m | |||||
summary: "{%- endraw %}{{ cpu_usage_threshold }}{%- raw %}% CPU usage" | |||||
description: "The average CPU usage on the {{ $labels.host }} node is {{ $value }}% for 2 minutes." | |||||
SystemLoadTooHighWarning: | |||||
{%- endraw %} | |||||
{%- set load_threshold = monitoring.system_load_threshold.warn|float %} | |||||
if: >- | |||||
system_load5 / system_n_cpus > {{ load_threshold }} | |||||
{%- raw %} | |||||
for: 5m | |||||
labels: | labels: | ||||
severity: warning | severity: warning | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Free space for {{ $labels.path }} too low on {{ $labels.host }}' | |||||
description: 'The disk partition ({{ $labels.path }}) will be full in less than 8 hours on {{ $labels.host }}.' | |||||
{% endraw %} | |||||
SystemFreeOpenFilesTooLow: | |||||
if: 'predict_linear(linux_sysctl_fs_file_nr[1h], 8*3600) > linux_sysctl_fs_file_max' | |||||
{% raw %} | |||||
summary: "System load is {%- endraw %}{{ load_threshold }}{%- raw %}" | |||||
description: "The system load per CPU on the {{ $labels.host }} node is {{ $value }} for 5 minutes." | |||||
SystemLoadTooHighCritical: | |||||
{%- endraw %} | |||||
{%- set load_threshold = monitoring.system_load_threshold.crit|float %} | |||||
if: >- | |||||
system_load5 / system_n_cpus > {{ load_threshold }} | |||||
{%- raw %} | |||||
for: 5m | |||||
labels: | labels: | ||||
severity: warning | severity: warning | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Free open files for {{ $labels.path }} too low on {{ $labels.host }}' | |||||
description: 'Host {{ $labels.host }}) will run out of free open files in less than 8 hours.' | |||||
{% endraw %} | |||||
SystemDiskErrors: | |||||
if: 'increase(hdd_errors_total[5m]) > 0' | |||||
{% raw %} | |||||
summary: "System load is {%- endraw %}{{ load_threshold }}{%- raw %}" | |||||
description: "The system load per CPU on the {{ $labels.host }} node is {{ $value }} for 5 minutes." | |||||
SystemDiskFullWarning: | |||||
{%- endraw %} | |||||
{%- set disk_threshold = monitoring.disk_usage_percentage.warn|float %} | |||||
if: >- | |||||
disk_used_percent >= {{ disk_threshold }} | |||||
{%- raw %} | |||||
for: 2m | |||||
labels: | labels: | ||||
severity: critical | |||||
severity: warning | |||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Disk {{ $labels.device }} is failing' | |||||
description: 'The disk ({{ $labels.device }}) is reporting errors on {{ $labels.host }}.' | |||||
{% endraw %} | |||||
SystemDiskSpaceFull: | |||||
if: 'disk_used_percent >= 99 and disk_inodes_total > 0' | |||||
{% raw %} | |||||
summary: "Disk partition {{ $labels.path }} is {%- endraw %} {{ disk_threshold }}{%- raw %}% full" | |||||
description: "The disk partition ({{ $labels.path }}) on the {{ $labels.host }} node is {{ $value }}% full for 2 minutes." | |||||
SystemDiskFullMajor: | |||||
{%- endraw %} | |||||
{%- set disk_threshold = monitoring.disk_usage_percentage.major|float %} | |||||
if: >- | |||||
disk_used_percent >= {{ disk_threshold }} | |||||
{%- raw %} | |||||
for: 2m | |||||
labels: | labels: | ||||
severity: critical | |||||
severity: major | |||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Disk partition {{ $labels.path }} full on {{ $labels.host }}' | |||||
description: 'The disk partition ({{ $labels.path }}) is used at {{ $value }}% on {{ $labels.host }}.' | |||||
{% endraw %} | |||||
SystemDiskInodesTooLow: | |||||
if: 'predict_linear(disk_inodes_free[1h], 8*3600) < 0' | |||||
{% raw %} | |||||
for: 15m | |||||
summary: "Disk partition {{ $labels.path }} is {%- endraw %} {{ disk_threshold }}{%- raw %}% full" | |||||
description: "The disk partition ({{ $labels.path }}) on the {{ $labels.host }} node is {{ $value }}% full for 2 minutes." | |||||
SystemDiskInodesFullWarning: | |||||
{%- endraw %} | |||||
{%- set inodes_threshold = monitoring.inodes_usage_percentage.warn|float %} | |||||
if: >- | |||||
100 * disk_inodes_used / disk_inodes_total >= {{ inodes_threshold }} | |||||
for: 2m | |||||
labels: | labels: | ||||
severity: warning | severity: warning | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Free inodes for {{ $labels.path }} too low on {{ $labels.host }}' | |||||
description: 'The disk inodes ({{ $labels.path }}) will be full in less than 8 hours on {{ $labels.host }}.' | |||||
{% endraw %} | |||||
SystemDiskInodesFull: | |||||
if: 'disk_inodes_used / disk_inodes_total >= 0.99' | |||||
{% raw %} | |||||
summary: "{{ inodes_threshold }}{%- raw %}% of inodes for {{ $labels.path }} are used" | |||||
description: "The {{ $labels.host }} node uses {{ $value }}% of disk inodes in the {{ $labels.path }} volume for 2 minutes." | |||||
SystemDiskInodesFullMajor: | |||||
{%- endraw %} | |||||
{%- set inodes_threshold = monitoring.inodes_usage_percentage.major|float %} | |||||
if: >- | |||||
100 * disk_inodes_used / disk_inodes_total >= {{ inodes_threshold }} | |||||
for: 2m | |||||
labels: | labels: | ||||
severity: critical | |||||
severity: major | |||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Inodes for {{ $labels.path }} full on {{ $labels.host }}' | |||||
description: 'The disk inodes ({{ $labels.path }}) are used at {{ $value }}% on {{ $labels.host }}.' | |||||
{% endraw %} | |||||
SystemMemoryAvailableLow: | |||||
{%- set mem_avail_warn_threshold = monitoring.free_memory_percentage.warn|float %} | |||||
if: avg_over_time(mem_available_percent[5m]) < {{ mem_avail_warn_threshold }} | |||||
{% raw %} | |||||
summary: "{{ inodes_threshold }}{%- raw %}% of inodes for {{ $labels.path }} are used" | |||||
description: "The {{ $labels.host }} node uses {{ $value }}% of disk inodes in the {{ $labels.path }} volume for 2 minutes." | |||||
SystemDiskErrorsTooHigh: | |||||
if: >- | |||||
increase(hdd_errors_total[1m]) > 0 | |||||
for: 5m | |||||
labels: | labels: | ||||
severity: warning | severity: warning | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Free memory low on {{ $labels.host }}' | |||||
description: 'The percentage of free memory is low on node {{ $labels.host }} (current value={{ $value }}%, threshold={% endraw %}{{ mem_avail_warn_threshold }}%).' | |||||
SystemMemoryAvailableTooLow: | |||||
{%- set mem_avail_crit_threshold = monitoring.free_memory_percentage.crit|float %} | |||||
if: avg_over_time(mem_available_percent[5m]) < {{ mem_avail_crit_threshold }} | |||||
{% raw %} | |||||
summary: "Disk {{ $labels.device }} is failing" | |||||
description: "The {{ $labels.device }} disk on the {{ $labels.host }} node is reporting errors for 5 minutes." | |||||
SystemMemoryFullWarning: | |||||
{%- endraw %} | |||||
{%- set mem_threshold = monitoring.memory_usage_percentage.warn|float %} | |||||
if: >- | |||||
mem_used_percent >= {{ mem_threshold }} | |||||
for: 2m | |||||
labels: | labels: | ||||
severity: critical | |||||
severity: warning | |||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Free memory too low on {{ $labels.host }}' | |||||
description: 'The percentage of free memory is too low on node {{ $labels.host }} (current value={{ $value }}%, threshold={% endraw %}{{ mem_avail_crit_threshold }}%).' | |||||
SystemLoad5TooHigh: | |||||
if: system_load5 / system_n_cpus > {{ monitoring.load_5.warn }} | |||||
{% raw %} | |||||
summary: "{{ mem_threshold }}{%- raw %}% of memory is used" | |||||
description: "The {{ $labels.host }} node uses {{ $value }}% of memory for 2 minutes." | |||||
SystemMemoryFullMajor: | |||||
{%- endraw %} | |||||
{%- set mem_threshold = monitoring.memory_usage_percentage.major|float %} | |||||
if: >- | |||||
mem_used_percent >= {{ mem_threshold }} | |||||
for: 2m | |||||
labels: | |||||
severity: major | |||||
service: system | |||||
annotations: | |||||
summary: "{{ mem_threshold }}{%- raw %}% of memory is used" | |||||
description: "The {{ $labels.host }} node uses {{ $value }}% of memory for 2 minutes." | |||||
SystemSwapFullWarning: | |||||
{%- endraw %} | |||||
{%- set swap_threshold = monitoring.swap_usage_percentage.warn|float %} | |||||
if: >- | |||||
swap_used_percent >= {{ swap_threshold }} | |||||
for: 2m | |||||
labels: | labels: | ||||
severity: warning | severity: warning | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'High system load (5m) on {{ $labels.host }}' | |||||
description: 'The 5-minutes system load is too high on node {{ $labels.host }} (current value={{ $value }}, threshold={% endraw %}{{ monitoring.load_5.warn }}).' | |||||
summary: "{{ swap_threshold }}{%- raw %}% of swap is used" | |||||
description: "The swap on the {{ $labels.host }} node is {{ $value }}% used for 2 minutes." | |||||
SystemSwapFullMinor: | |||||
{%- endraw %} | |||||
{%- set swap_threshold = monitoring.swap_usage_percentage.minor|float %} | |||||
if: >- | |||||
swap_used_percent >= {{ swap_threshold }} | |||||
for: 2m | |||||
labels: | |||||
severity: minor | |||||
service: system | |||||
annotations: | |||||
summary: "{{ swap_threshold }}{%- raw %}% of swap is used" | |||||
description: "The swap on the {{ $labels.host }} node is {{ $value }}% used for 2 minutes." | |||||
SystemRxPacketsDroppedTooHigh: | SystemRxPacketsDroppedTooHigh: | ||||
{%- set net_rx_dropped_threshold = monitoring.rx_packets_dropped_rate.warn %} | |||||
if: rate(net_drop_in[1m]) > {{ net_rx_dropped_threshold }} | |||||
{% raw %} | |||||
{%- endraw %} | |||||
{%- set net_rx_dropped_threshold = monitoring.rx_packets_dropped_threshold.warn %} | |||||
if: >- | |||||
increase(net_drop_in[1m]) > {{ net_rx_dropped_threshold }} | |||||
labels: | labels: | ||||
severity: critical | |||||
severity: warning | |||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Too many received packets dropped on {{ $labels.host }} for interface {{ $labels.interface }}' | |||||
description: 'The rate of received packets which are dropped is too high on node {{ $labels.host }} for interface {{ $labels.interface }} (current value={{ $value }}/sec, threshold={% endraw %}{{ net_rx_dropped_threshold }}/sec)' | |||||
summary: "{{ net_rx_dropped_threshold }}{%- raw %} received packets were dropped" | |||||
description: "{{ $value }} packets received by the {{ $labels.interface }} interface on the {{ $labels.host }} node were dropped during the last minute." | |||||
SystemRxPacketsDroppedLongTermTooHigh: | |||||
if: >- | |||||
increase(net_drop_in[1m]) > 0 | |||||
for: 10m | |||||
labels: | |||||
severity: major | |||||
service: system | |||||
annotations: | |||||
summary: "Received packets long term dropping" | |||||
description: "{{ $value }} packets received by the {{ $labels.interface }} interface on the {{ $labels.host }} node were dropped during the last 10 minutes." | |||||
SystemTxPacketsDroppedTooHigh: | SystemTxPacketsDroppedTooHigh: | ||||
{%- set net_tx_dropped_threshold = monitoring.tx_packets_dropped_rate.warn %} | |||||
if: rate(net_drop_out[1m]) > {{ net_tx_dropped_threshold }} | |||||
{% raw %} | |||||
{%- endraw %} | |||||
{%- set net_tx_dropped_threshold = monitoring.tx_packets_dropped_threshold.warn %} | |||||
if: >- | |||||
increase(net_drop_out[1m]) > {{ net_tx_dropped_threshold }} | |||||
labels: | |||||
severity: warning | |||||
service: system | |||||
annotations: | |||||
summary: "{{ net_tx_dropped_threshold }}{%- raw %} transmitted packets were dropped" | |||||
description: "{{ $value }} packets transmitted by the {{ $labels.interface }} interface on the {{ $labels.host }} node were dropped during the last minute." | |||||
CronProcessDown: | |||||
if: >- | |||||
procstat_running{process_name="cron"} == 0 | |||||
labels: | labels: | ||||
severity: critical | severity: critical | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Too many transmitted packets dropped on {{ $labels.host }} for interface {{ $labels.interface }}' | |||||
description: 'The rate of transmitted packets which are dropped is too high on node {{ $labels.host }} for interface {{ $labels.interface }} (current value={{ $value }}/sec, threshold={% endraw %}{{ net_tx_dropped_threshold }}/sec)' | |||||
SystemSwapIn: | |||||
{%- set swap_in_threshold = monitoring.swap_in_rate.warn %} | |||||
if: rate(swap_in[2m]) > {{ swap_in_threshold }} | |||||
{% raw %} | |||||
summary: "Cron process is down" | |||||
description: "The cron process on the {{ $labels.host }} node is down." | |||||
SshdProcessDown: | |||||
if: >- | |||||
procstat_running{process_name="sshd"} == 0 | |||||
labels: | |||||
severity: critical | |||||
service: system | |||||
annotations: | |||||
summary: "SSH process is down" | |||||
description: "The SSH process on the {{ $labels.host }} node is down." | |||||
SshFailedLoginsTooHigh: | |||||
{%- endraw %} | |||||
{%- set threshold = monitoring.failed_auths_threshold.warn %} | |||||
if: >- | |||||
increase(failed_logins_total[5m]) > {{ threshold }} | |||||
labels: | labels: | ||||
severity: warning | severity: warning | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Swap input throughput too high on {{ $labels.host }}' | |||||
description: 'The rate of swap input bytes is too high on node {{ $labels.host }} (current value={{ $value }}b/s, threshold={% endraw %}{{ swap_in_threshold }}b/s).' | |||||
SystemSwapOut: | |||||
{%- set swap_out_threshold = monitoring.swap_out_rate.warn %} | |||||
if: rate(swap_out[2m]) > {{ swap_out_threshold }} | |||||
{% raw %} | |||||
summary: "{{ threshold }}{%- raw %} failed SSH logins" | |||||
description: "{{ $value }} failed SSH login attempts on the {{ $labels.host }} node during the last 5 minutes." | |||||
PacketsDroppedByCpuMinor: | |||||
{%- endraw %} | |||||
{%- set packets_dropped_minor_threshold = monitoring.packets_dropped_per_cpu_threshold.minor %} | |||||
if: >- | |||||
floor(increase(nstat_packet_drop[24h])) > {{ packets_dropped_minor_threshold }} | |||||
labels: | |||||
severity: minor | |||||
service: system | |||||
annotations: | |||||
summary: "CPU dropped {{ packets_dropped_minor_threshold }}{%- raw %} packets" | |||||
description: "The {{ $labels.cpu }} CPU on the {{ $labels.host }} node dropped {{ $value }} packets during the last 24 hours." | |||||
PacketsDroppedByCpuMajor: | |||||
{%- endraw %} | |||||
{%- set packets_dropped_major_threshold = monitoring.packets_dropped_per_cpu_threshold.major %} | |||||
if: >- | |||||
floor(increase(nstat_packet_drop[24h])) > {{ packets_dropped_major_threshold }} | |||||
labels: | |||||
severity: major | |||||
service: system | |||||
annotations: | |||||
summary: "CPU dropped {{ packets_dropped_major_threshold }}{%- raw %} packets" | |||||
description: "The {{ $labels.cpu }} CPU on the {{ $labels.host }} node dropped {{ $value }} packets during the last 24 hours." | |||||
NetRxActionByCpuWarning: | |||||
{%- endraw %} | |||||
{%- set net_rx_action_warning_threshold = monitoring.net_rx_action_per_cpu_threshold.warning %} | |||||
if: >- | |||||
floor(increase(nstat_time_squeeze[1d])) > {{ net_rx_action_warning_threshold }} | |||||
labels: | labels: | ||||
severity: warning | severity: warning | ||||
service: system | service: system | ||||
annotations: | annotations: | ||||
summary: 'Swap output throughput too high on {{ $labels.host }}' | |||||
description: 'The rate of swap output bytes is too high on node {{ $labels.host }} (current value={{ $value }}b/s, threshold={% endraw %}{{ swap_out_threshold }}b/s).' | |||||
summary: "CPU terminated {{ net_rx_action_warning_threshold }}{%- raw %} net_rx_action loops" | |||||
description: "The {{ $labels.cpu }} CPU on the {{ $labels.host }} node terminated {{ $value }} net_rx_action loops during the last 24 hours. Modify the net.core.netdev_budget kernel parameter." | |||||
NetRxActionByCpuMinor: | |||||
{%- endraw %} | |||||
{%- set net_rx_action_minor_threshold = monitoring.net_rx_action_per_cpu_threshold.minor %} | |||||
if: >- | |||||
floor(increase(nstat_time_squeeze[1d])) > {{ net_rx_action_minor_threshold }} | |||||
labels: | |||||
severity: minor | |||||
service: system | |||||
annotations: | |||||
summary: "CPU terminated {{ net_rx_action_minor_threshold }}{%- raw %} net_rx_action loops" | |||||
description: "The {{ $labels.cpu }} CPU on the {{ $labels.host }} node terminated {{ $value }} net_rx_action loops during the last 24 hours. Modify the net.core.netdev_budget kernel parameter." | |||||
{%- endraw %} | |||||
{%- if monitoring.bond_status.interfaces is defined and monitoring.bond_status.interfaces %} | |||||
{%- raw %} | |||||
BondInterfaceDown: | |||||
if: >- | |||||
bond_status < 1 | |||||
labels: | |||||
severity: critical | |||||
service: system | |||||
annotations: | |||||
summary: "{{ $labels.bond }} bond interface is down" | |||||
description: "The {{ $labels.bond }} bond interface on the {{ $labels.host }} node has all ifaces down." | |||||
BondInterfaceSlaveDown: | |||||
if: >- | |||||
bond_slave_status < 1 | |||||
labels: | |||||
severity: warning | |||||
service: system | |||||
annotations: | |||||
summary: "{{ $labels.bond }} bond interface slave {{ $labels.interface }} is down" | |||||
description: "The {{ $labels.bond }} bond interface slave {{ $labels.interface }} on the {{ $labels.host }} node is down." | |||||
BondInterfaceSlaveDownMajor: | |||||
if: >- | |||||
sum(bond_slave_status) by (bond,host) <= on (bond,host) 0.5 * count(bond_slave_status) | |||||
labels: | |||||
severity: major | |||||
service: system | |||||
annotations: | |||||
summary: "50% of bond interface slaves {{ $labels.bond }} are down" | |||||
description: "{{ $value }} {{ $labels.bond }} bond interface slaves on the {{ $labels.host }} node are down." | |||||
{% endraw %} | |||||
{%- endif %} |
{%- from "linux/map.jinja" import monitoring with context %} | |||||
agent: | agent: | ||||
input: | input: | ||||
cpu: | cpu: | ||||
kernel: | kernel: | ||||
net: | net: | ||||
mem: | mem: | ||||
nstat: | |||||
fieldpass: | |||||
- packet_drop | |||||
- time_squeeze | |||||
processes: | processes: | ||||
swap: | swap: | ||||
system: | system: | ||||
procstat: | |||||
process: | |||||
sshd: | |||||
exe: sshd | |||||
cron: | |||||
exe: cron | |||||
linux_sysctl_fs: | linux_sysctl_fs: | ||||
{%- if monitoring.bond_status.interfaces is defined and monitoring.bond_status.interfaces %} | |||||
bond: | |||||
template: linux/files/telegraf.conf | |||||
{%- if monitoring.bond_status.interfaces is list %} | |||||
bond_interfaces: {{ monitoring.bond_status.interfaces }} | |||||
{%- endif %} | |||||
{%- if monitoring.bond_status.host_proc is defined %} | |||||
host_proc: {{ monitoring.bond_status.host_proc }} | |||||
{%- endif %} | |||||
{%- endif %} |
linux_dpdk_pkgs: | linux_dpdk_pkgs: | ||||
pkg.installed: | pkg.installed: | ||||
- pkgs: {{ network.dpdk_pkgs }} | |||||
- pkgs: {{ network.dpdk_pkgs | json }} | |||||
linux_dpdk_kernel_module: | linux_dpdk_kernel_module: | ||||
kmod.present: | kmod.present: | ||||
linux_network_dpdk_ovs_option_{{ option }}: | linux_network_dpdk_ovs_option_{{ option }}: | ||||
cmd.run: | cmd.run: | ||||
- name: 'ovs-vsctl set Open_vSwitch . other_config:{{ option }}' | |||||
- name: 'ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set Open_vSwitch . other_config:{{ option }}' | |||||
- watch_in: | - watch_in: | ||||
- service: service_openvswitch | - service: service_openvswitch | ||||
- require: | - require: | ||||
{%- do bond_interfaces.update({iface_name: iface}) %} | {%- do bond_interfaces.update({iface_name: iface}) %} | ||||
{%- endfor %} | {%- endfor %} | ||||
linux_network_dpdk_bond_interface_{{ interface_name }}: | linux_network_dpdk_bond_interface_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: "ovs-vsctl add-bond {{ interface.bridge }} {{ interface_name }} {{ bond_interfaces.keys()|join(' ') }} {% for iface_name, iface in bond_interfaces.items() %}-- set Interface {{ iface_name }} type=dpdk options:dpdk-devargs={{ iface.pci }} {% endfor %}" | |||||
- unless: "ovs-vsctl show | grep {{ interface_name }}" | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} add-bond {{ interface.bridge }} {{ interface_name }} {{ bond_interfaces.keys()|join(' ') }}" | |||||
- unless: "ovs-vsctl list-ports {{ interface.bridge }} | grep -w {{ interface_name }}" | |||||
- require: | - require: | ||||
- cmd: linux_network_dpdk_bridge_interface_{{ interface.bridge }} | |||||
- cmd: linux_network_dpdk_bridge_interface_{{ interface.bridge }} | |||||
{% for iface_name, iface in bond_interfaces.items() %} | |||||
linux_network_dpdk_bond_interface_{{ iface_name }}_activate: | |||||
cmd.run: | |||||
- name: "timeout 5 /bin/sh -c -- 'while true; do ovs-vsctl get Interface {{ iface_name }} name 1>/dev/null 2>&1 && break || sleep 1; done'" | |||||
- unless: "ovs-vsctl get Interface {{ iface_name }} name 1>/dev/null 2>&1" | |||||
linux_network_dpdk_bond_interface_{{ iface_name }}_type: | |||||
cmd.run: | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set Interface {{ iface_name }} type=dpdk" | |||||
- unless: "ovs-vsctl get interface {{ iface_name }} type | grep -w dpdk" | |||||
- require: | |||||
- cmd: linux_network_dpdk_bond_interface_{{ iface_name }}_activate | |||||
linux_network_dpdk_bond_interface_{{ iface_name }}_options: | |||||
cmd.run: | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set Interface {{ iface_name }} options:dpdk-devargs={{ iface.pci }}" | |||||
- unless: "ovs-vsctl get interface {{ iface_name }} options:dpdk-devargs | grep -w {{ iface.pci }}" | |||||
- require: | |||||
- cmd: linux_network_dpdk_bond_interface_{{ iface_name }}_activate | |||||
{% endfor %} | |||||
linux_network_dpdk_bond_mode_{{ interface_name }}: | linux_network_dpdk_bond_mode_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: "ovs-vsctl set port {{ interface_name }} bond_mode={{ interface.mode }}" | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set port {{ interface_name }} bond_mode={{ interface.mode }}{%- if interface.mode == 'balance-slb' %} lacp=active{%- endif %}" | |||||
- unless: "ovs-appctl bond/show {{ interface_name }} | grep {{ interface.mode }}" | - unless: "ovs-appctl bond/show {{ interface_name }} | grep {{ interface.mode }}" | ||||
- require: | - require: | ||||
- cmd: linux_network_dpdk_bond_interface_{{ interface_name }} | - cmd: linux_network_dpdk_bond_interface_{{ interface_name }} | ||||
linux_network_dpdk_bridge_interface_{{ interface_name }}: | linux_network_dpdk_bridge_interface_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: "ovs-vsctl add-br {{ interface_name }} -- set bridge {{ interface_name }} datapath_type=netdev{% if interface.tag is defined %} -- set port {{ interface_name }} tag={{ interface.tag }}{% endif %}" | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} add-br {{ interface_name }} -- set bridge {{ interface_name }} datapath_type=netdev{% if interface.tag is defined %} -- set port {{ interface_name }} tag={{ interface.tag }}{% endif %}" | |||||
- unless: "ovs-vsctl show | grep {{ interface_name }}" | - unless: "ovs-vsctl show | grep {{ interface_name }}" | ||||
{# OVS dpdk needs ip address for vxlan termination on bridge br-prv #} | |||||
{%- if interface.address is defined %} | |||||
{# create override for openvswitch dependency for dpdk br-prv #} | |||||
/etc/systemd/system/ifup@{{ interface_name }}.service.d/override.conf: | |||||
file.managed: | |||||
- makedirs: true | |||||
- require: | |||||
- cmd: linux_network_dpdk_bridge_interface_{{ interface_name }} | |||||
- contents: | | |||||
[Unit] | |||||
Requires=openvswitch-switch.service | |||||
After=openvswitch-switch.service | |||||
{# enforce ip address and mtu for ovs dpdk br-prv #} | |||||
/etc/network/interfaces.d/ifcfg-{{ interface_name }}: | |||||
file.managed: | |||||
- contents: | | |||||
auto {{ interface_name }} | |||||
iface {{ interface_name }} inet static | |||||
address {{ interface.address }} | |||||
netmask {{ interface.netmask }} | |||||
{%- if interface.mtu is defined %} | |||||
mtu {{ interface.mtu }} | |||||
{%- endif %} | |||||
- require: | |||||
- file: /etc/systemd/system/ifup@{{ interface_name }}.service.d/override.conf | |||||
{%- endif %} | |||||
{%- elif interface.type == 'dpdk_ovs_port' and interface.bridge is defined %} | {%- elif interface.type == 'dpdk_ovs_port' and interface.bridge is defined %} | ||||
linux_network_dpdk_bridge_port_interface_{{ interface_name }}: | linux_network_dpdk_bridge_port_interface_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: "ovs-vsctl add-port {{ interface.bridge }} dpdk0 -- set Interface dpdk0 type=dpdk options:dpdk-devargs={{ interface.pci }}" | |||||
- unless: "ovs-vsctl show | grep dpdk0" | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} add-port {{ interface.bridge }} {{ interface_name }} -- set Interface {{ interface_name }} type=dpdk options:dpdk-devargs={{ interface.pci }}" | |||||
- unless: "ovs-vsctl list-ports {{ interface.bridge }} | grep -w {{ interface_name }}" | |||||
- require: | - require: | ||||
- cmd: linux_network_dpdk_bridge_interface_{{ interface.bridge }} | - cmd: linux_network_dpdk_bridge_interface_{{ interface.bridge }} | ||||
{# Multiqueue n_rxq, pmd_rxq_affinity and mtu setup on interfaces #} | {# Multiqueue n_rxq, pmd_rxq_affinity and mtu setup on interfaces #} | ||||
{%- if interface.type == 'dpdk_ovs_port' %} | {%- if interface.type == 'dpdk_ovs_port' %} | ||||
{%- if interface.n_rxq is defined %} | |||||
{%- if interface.n_rxq is defined %} | |||||
linux_network_dpdk_bridge_port_interface_n_rxq_{{ interface_name }}: | linux_network_dpdk_bridge_port_interface_n_rxq_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: "ovs-vsctl set Interface {{ interface_name }} options:n_rxq={{ interface.n_rxq }} " | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set Interface {{ interface_name }} options:n_rxq={{ interface.n_rxq }} " | |||||
- unless: | | - unless: | | ||||
ovs-vsctl get Interface {{ interface_name }} options | grep 'n_rxq="{{ interface.n_rxq }}"' | ovs-vsctl get Interface {{ interface_name }} options | grep 'n_rxq="{{ interface.n_rxq }}"' | ||||
{%- if interface.get("bond", "") != "" %} | |||||
- require: | |||||
- cmd: linux_network_dpdk_bond_interface_{{ interface.get("bond", "") }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if interface.pmd_rxq_affinity is defined %} | |||||
{%- if interface.pmd_rxq_affinity is defined %} | |||||
linux_network_dpdk_bridge_port_interface_pmd_rxq_affinity_{{ interface_name }}: | linux_network_dpdk_bridge_port_interface_pmd_rxq_affinity_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: "ovs-vsctl set Interface {{ interface_name }} other_config:pmd-rxq-affinity={{ interface.pmd_rxq_affinity }} " | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set Interface {{ interface_name }} other_config:pmd-rxq-affinity={{ interface.pmd_rxq_affinity }} " | |||||
- unless: | | - unless: | | ||||
ovs-vsctl get Interface {{ interface_name }} other_config | grep 'pmd-rxq-affinity="{{ interface.pmd_rxq_affinity }}"' | ovs-vsctl get Interface {{ interface_name }} other_config | grep 'pmd-rxq-affinity="{{ interface.pmd_rxq_affinity }}"' | ||||
{%- if interface.get("bond", "") != "" %} | |||||
- require: | |||||
- cmd: linux_network_dpdk_bond_interface_{{ interface.get("bond", "") }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if interface.mtu is defined %} | |||||
{%- if interface.mtu is defined %} | |||||
{# MTU ovs dpdk setup on interfaces #} | {# MTU ovs dpdk setup on interfaces #} | ||||
linux_network_dpdk_bridge_port_interface_mtu_{{ interface_name }}: | linux_network_dpdk_bridge_port_interface_mtu_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: "ovs-vsctl set Interface {{ interface_name }} mtu_request={{ interface.mtu }} " | |||||
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set Interface {{ interface_name }} mtu_request={{ interface.mtu }} " | |||||
- unless: "ovs-vsctl get Interface {{ interface_name }} mtu_request | grep {{ interface.mtu }}" | - unless: "ovs-vsctl get Interface {{ interface_name }} mtu_request | grep {{ interface.mtu }}" | ||||
{%- if interface.get("bond", "") != "" %} | |||||
- require: | |||||
- cmd: linux_network_dpdk_bond_interface_{{ interface.get("bond", "") }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | {%- endif %} | ||||
{# Change state to proper one, after releasing patch: | |||||
https://github.com/saltstack/salt/pull/45748/files/74599bbdfcf99f45d3a31296887097fade31cbf1 | |||||
linux_enforce_hostname: | linux_enforce_hostname: | ||||
cmd.wait: | |||||
network.system: | |||||
- enabled: True | |||||
- hostname: {{ network.hostname }} | |||||
- apply_hostname: True | |||||
- retain_settings: True | |||||
#} | |||||
linux_enforce_hostname: | |||||
cmd.run: | |||||
- name: hostname {{ network.hostname }} | - name: hostname {{ network.hostname }} | ||||
- unless: test "$(hostname)" = "{{ network.hostname }}" | - unless: test "$(hostname)" = "{{ network.hostname }}" | ||||
{# | |||||
linux_hostname_hosts: | |||||
host.present: | |||||
- ip: {{ grains.ip4_interfaces[network.get('default_interface', 'eth0')][0] }} | |||||
- names: | |||||
- {{ network.fqdn }} | |||||
- {{ network.hostname }} | |||||
#} | |||||
{%- if grains.get('noservices') %} | |||||
- onlyif: /bin/false | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} |
{%- from "linux/map.jinja" import network with context %} | {%- from "linux/map.jinja" import network with context %} | ||||
include: | include: | ||||
{%- if network.hostname is defined %} | |||||
- linux.network.hostname | - linux.network.hostname | ||||
{%- endif %} | |||||
{%- if network.host|length > 0 or network.get('purge_hosts', True) %} | {%- if network.host|length > 0 or network.get('purge_hosts', True) %} | ||||
- linux.network.host | - linux.network.host | ||||
{%- endif %} | {%- endif %} | ||||
{%- if network.systemd|length > 0 %} | {%- if network.systemd|length > 0 %} | ||||
- linux.network.systemd | - linux.network.systemd | ||||
{%- endif %} | {%- endif %} | ||||
{%- if network.openvswitch is defined %} | |||||
- linux.network.openvswitch | |||||
{%- endif %} | |||||
{%- if network.interface|length > 0 %} | {%- if network.interface|length > 0 %} | ||||
- linux.network.interface | - linux.network.interface | ||||
{%- endif %} | {%- endif %} |
{%- from "linux/map.jinja" import system with context %} | {%- from "linux/map.jinja" import system with context %} | ||||
{%- if network.enabled %} | {%- if network.enabled %} | ||||
{%- set dpdk_enabled = network.get('dpdk', {}).get('enabled', False) %} | |||||
{%- if dpdk_enabled %} | |||||
include: | |||||
- linux.network.dpdk | |||||
{%- endif %} | |||||
{%- macro set_param(param_name, param_dict) -%} | {%- macro set_param(param_name, param_dict) -%} | ||||
{%- if param_dict.get(param_name, False) -%} | {%- if param_dict.get(param_name, False) -%} | ||||
- {{ param_name }}: {{ param_dict[param_name] }} | - {{ param_name }}: {{ param_dict[param_name] }} | ||||
linux_network_bridge_pkgs: | linux_network_bridge_pkgs: | ||||
pkg.installed: | pkg.installed: | ||||
{%- if network.bridge == 'openvswitch' %} | {%- if network.bridge == 'openvswitch' %} | ||||
- pkgs: {{ network.ovs_pkgs }} | |||||
- pkgs: {{ network.ovs_pkgs | json }} | |||||
{%- else %} | {%- else %} | ||||
- pkgs: {{ network.bridge_pkgs }} | |||||
- pkgs: {{ network.bridge_pkgs | json }} | |||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | {%- endif %} | ||||
{%- set interface_name = interface.get('name', interface_name) %} | {%- set interface_name = interface.get('name', interface_name) %} | ||||
{# add linux network interface into OVS dpdk bridge #} | |||||
{%- if interface.type == 'dpdk_ovs_bridge' %} | |||||
{%- for int_name, int in network.interface.items() %} | |||||
{%- set int_name = int.get('name', int_name) %} | |||||
{%- if int.ovs_bridge is defined and interface_name == int.ovs_bridge %} | |||||
add_int_{{ int_name }}_to_ovs_dpdk_bridge_{{ interface_name }}: | |||||
cmd.run: | |||||
- unless: ovs-vsctl show | grep -w {{ int_name }} | |||||
- name: ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} add-port {{ interface_name }} {{ int_name }} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
linux_interfaces_include_{{ interface_name }}: | |||||
file.prepend: | |||||
- name: /etc/network/interfaces | |||||
- text: | | |||||
source /etc/network/interfaces.d/* | |||||
# Workaround for Upstream-Bug: https://github.com/saltstack/salt/issues/40262 | |||||
source /etc/network/interfaces.u/* | |||||
{# create override for openvswitch dependency for dpdk br-prv #} | |||||
/etc/systemd/system/ifup@{{ interface_name }}.service.d/override.conf: | |||||
file.managed: | |||||
- makedirs: true | |||||
- require: | |||||
- cmd: linux_network_dpdk_bridge_interface_{{ interface_name }} | |||||
- contents: | | |||||
[Unit] | |||||
Requires=openvswitch-switch.service | |||||
After=openvswitch-switch.service | |||||
dpdk_ovs_bridge_{{ interface_name }}: | |||||
file.managed: | |||||
- name: /etc/network/interfaces.u/ifcfg-{{ interface_name }} | |||||
- makedirs: True | |||||
- source: salt://linux/files/ovs_bridge | |||||
- defaults: | |||||
bridge: {{ interface|yaml }} | |||||
bridge_name: {{ interface_name }} | |||||
- template: jinja | |||||
dpdk_ovs_bridge_up_{{ interface_name }}: | |||||
cmd.run: | |||||
- name: ifup {{ interface_name }} | |||||
- require: | |||||
- file: dpdk_ovs_bridge_{{ interface_name }} | |||||
- file: linux_interfaces_final_include | |||||
{%- endif %} | |||||
{# it is not used for any interface with type preffix dpdk,eg. dpdk_ovs_port #} | {# it is not used for any interface with type preffix dpdk,eg. dpdk_ovs_port #} | ||||
{%- if interface.get('managed', True) and not 'dpdk' in interface.type %} | {%- if interface.get('managed', True) and not 'dpdk' in interface.type %} | ||||
{%- if interface.type == 'ovs_bridge' %} | {%- if interface.type == 'ovs_bridge' %} | ||||
ovs_bridge_{{ interface_name }}: | |||||
ovs_bridge_{{ interface_name }}_present: | |||||
openvswitch_bridge.present: | openvswitch_bridge.present: | ||||
- name: {{ interface_name }} | - name: {{ interface_name }} | ||||
add_int_{{ int_name }}_to_ovs_bridge_{{ interface_name }}: | add_int_{{ int_name }}_to_ovs_bridge_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- unless: ovs-vsctl show | grep {{ int_name }} | - unless: ovs-vsctl show | grep {{ int_name }} | ||||
- name: ovs-vsctl add-port {{ interface_name }} {{ int_name }} | |||||
- name: ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} add-port {{ interface_name }} {{ int_name }} | |||||
{%- endif %} | {%- endif %} | ||||
{%- endfor %} | {%- endfor %} | ||||
linux_interfaces_include_{{ interface_name }}: | |||||
file.prepend: | |||||
- name: /etc/network/interfaces | |||||
- text: | | |||||
source /etc/network/interfaces.d/* | |||||
# Workaround for Upstream-Bug: https://github.com/saltstack/salt/issues/40262 | |||||
source /etc/network/interfaces.u/* | |||||
ovs_bridge_{{ interface_name }}: | |||||
file.managed: | |||||
- name: /etc/network/interfaces.u/ifcfg-{{ interface_name }} | |||||
- makedirs: True | |||||
- source: salt://linux/files/ovs_bridge | |||||
- defaults: | |||||
bridge: {{ interface|yaml }} | |||||
bridge_name: {{ interface_name }} | |||||
- template: jinja | |||||
ovs_bridge_up_{{ interface_name }}: | |||||
cmd.run: | |||||
- name: ifup {{ interface_name }} | |||||
- require: | |||||
- file: ovs_bridge_{{ interface_name }} | |||||
- file: linux_interfaces_final_include | |||||
{%- elif interface.type == 'ovs_bond' %} | |||||
ovs_bond_{{ interface_name }}: | |||||
cmd.run: | |||||
- name: ovs-vsctl add-bond {{ interface.bridge }} {{ interface_name }} {{ interface.slaves }} bond_mode={{ interface.mode }} | |||||
- unless: ovs-vsctl show | grep -A 2 'Port.*{{ interface_name }}.' | |||||
- require: | |||||
- ovs_bridge_{{ interface.bridge }}_present | |||||
{%- elif interface.type == 'ovs_port' %} | {%- elif interface.type == 'ovs_port' %} | ||||
{%- if interface.get('port_type','internal') == 'patch' %} | {%- if interface.get('port_type','internal') == 'patch' %} | ||||
ovs_port_{{ interface_name }}: | |||||
ovs_port_{{ interface_name }}_present: | |||||
openvswitch_port.present: | openvswitch_port.present: | ||||
- name: {{ interface_name }} | - name: {{ interface_name }} | ||||
- bridge: {{ interface.bridge }} | - bridge: {{ interface.bridge }} | ||||
- require: | - require: | ||||
- openvswitch_bridge: ovs_bridge_{{ interface.bridge }} | |||||
{%- if dpdk_enabled and network.interface.get(interface.bridge, {}).get('type', 'ovs_bridge') == 'dpdk_ovs_bridge' %} | |||||
- cmd: linux_network_dpdk_bridge_interface_{{ interface.bridge }} | |||||
{%- else %} | |||||
- openvswitch_bridge: ovs_bridge_{{ interface.bridge }}_present | |||||
{%- endif %} | |||||
ovs_port_set_type_{{ interface_name }}: | ovs_port_set_type_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: ovs-vsctl set interface {{ interface_name }} type=patch | |||||
- name: ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set interface {{ interface_name }} type=patch | |||||
- unless: ovs-vsctl show | grep -A 1 'Interface {{ interface_name }}' | grep patch | - unless: ovs-vsctl show | grep -A 1 'Interface {{ interface_name }}' | grep patch | ||||
ovs_port_set_peer_{{ interface_name }}: | ovs_port_set_peer_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: ovs-vsctl set interface {{ interface_name }} options:peer={{ interface.peer }} | |||||
- name: ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set interface {{ interface_name }} options:peer={{ interface.peer }} | |||||
- unless: ovs-vsctl show | grep -A 2 'Interface {{ interface_name }}' | grep {{ interface.peer }} | - unless: ovs-vsctl show | grep -A 2 'Interface {{ interface_name }}' | grep {{ interface.peer }} | ||||
{% if interface.tag is defined %} | |||||
ovs_port_set_tag_{{ interface_name }}: | |||||
cmd.run: | |||||
- name: ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} set port {{ interface_name }} tag={{ interface.tag }} | |||||
- unless: ovs-vsctl get Port {{ interface_name }} tag | grep -Fx {{ interface.tag }} | |||||
{%- endif %} | |||||
{%- else %} | {%- else %} | ||||
linux_interfaces_include_{{ interface_name }}: | linux_interfaces_include_{{ interface_name }}: | ||||
- defaults: | - defaults: | ||||
port: {{ interface|yaml }} | port: {{ interface|yaml }} | ||||
port_name: {{ interface_name }} | port_name: {{ interface_name }} | ||||
auto: "" | |||||
iface_inet: "" | |||||
- template: jinja | - template: jinja | ||||
ovs_port_{{ interface_name }}_line1: | |||||
file.replace: | |||||
- name: /etc/network/interfaces | |||||
- pattern: auto {{ interface_name }}$ | |||||
- repl: "" | |||||
ovs_port_{{ interface_name }}_line2: | |||||
file.replace: | |||||
- name: /etc/network/interfaces | |||||
- pattern: 'iface {{ interface_name }} inet .*' | |||||
- repl: "" | |||||
ovs_port_up_{{ interface_name }}: | ovs_port_up_{{ interface_name }}: | ||||
cmd.run: | cmd.run: | ||||
- name: ifup {{ interface_name }} | - name: ifup {{ interface_name }} | ||||
- require: | - require: | ||||
- file: ovs_port_{{ interface_name }} | - file: ovs_port_{{ interface_name }} | ||||
- file: ovs_port_{{ interface_name }}_line1 | |||||
- file: ovs_port_{{ interface_name }}_line2 | |||||
- openvswitch_bridge: ovs_bridge_{{ interface.bridge }} | |||||
- openvswitch_bridge: ovs_bridge_{{ interface.bridge }}_present | |||||
- file: linux_interfaces_final_include | - file: linux_interfaces_final_include | ||||
{%- endif %} | {%- endif %} | ||||
- wireless-psk: {{ interface.wireless.key }} | - wireless-psk: {{ interface.wireless.key }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if pillar.linux.network.noifupdown is defined %} | |||||
- noifupdown: {{ pillar.linux.network.noifupdown }} | |||||
{%- endif %} | |||||
{%- for param in network.interface_params %} | {%- for param in network.interface_params %} | ||||
{{ set_param(param, interface) }} | {{ set_param(param, interface) }} | ||||
{%- endfor %} | {%- endfor %} | ||||
- mode: {{ interface.mode }} | - mode: {{ interface.mode }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if interface.get('ipflush_onchange', False) %} | |||||
linux_interface_ipflush_onchange_{{ interface_name }}: | |||||
cmd.run: | |||||
- name: "/sbin/ip address flush dev {{ interface_name }}" | |||||
- onchanges: | |||||
- network: linux_interface_{{ interface_name }} | |||||
{%- if interface.get('restart_on_ipflush', False) %} | |||||
linux_interface_restart_on_ipflush_{{ interface_name }}: | |||||
cmd.run: | |||||
- name: "ifdown {{ interface_name }}; ifup {{ interface_name }};" | |||||
- onchanges: | |||||
- cmd: linux_interface_ipflush_onchange_{{ interface_name }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if salt['grains.get']('saltversion') < '2017.7' %} | {%- if salt['grains.get']('saltversion') < '2017.7' %} | ||||
# TODO(ddmitriev): Remove this 'if .. endif' block completely when | # TODO(ddmitriev): Remove this 'if .. endif' block completely when | ||||
linux_network_packages: | linux_network_packages: | ||||
pkg.installed: | pkg.installed: | ||||
- pkgs: {{ network.pkgs }} | |||||
- pkgs: {{ network.pkgs | json }} | |||||
/etc/netctl/network_{{ interface.wireless.essid }}: | /etc/netctl/network_{{ interface.wireless.essid }}: | ||||
file.managed: | file.managed: | ||||
gateway: {{ route.gateway }} | gateway: {{ route.gateway }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- endfor %} | {%- endfor %} | ||||
{%- if interface.noifupdown is defined %} | |||||
- require_reboot: {{ interface.noifupdown }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if interface.type in ('eth','ovs_port') %} | |||||
{%- if interface.get('ipflush_onchange', False) %} | |||||
linux_interface_ipflush_onchange_{{ interface_name }}: | |||||
cmd.run: | |||||
- name: "/sbin/ip address flush dev {{ interface_name }}" | |||||
{%- if interface.type == 'eth' %} | |||||
- onchanges: | |||||
- network: linux_interface_{{ interface_name }} | |||||
{%- elif interface.type == 'ovs_port' %} | |||||
- onchanges: | |||||
- file: ovs_port_{{ interface_name }} | |||||
{%- endif %} | |||||
{%- if interface.get('restart_on_ipflush', False) %} | |||||
linux_interface_restart_on_ipflush_{{ interface_name }}: | |||||
cmd.run: | |||||
- name: "ifdown {{ interface_name }}; ifup {{ interface_name }};" | |||||
- onchanges: | |||||
- cmd: linux_interface_ipflush_onchange_{{ interface_name }} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} | ||||
{%- from "linux/map.jinja" import network with context %} | |||||
{%- if network.get('openvswitch', {}).get('enabled', False) %} | |||||
openvswitch_pkgs: | |||||
pkg.installed: | |||||
- pkgs: {{ network.ovs_pkgs | json }} | |||||
/etc/default/openvswitch-switch: | |||||
file.managed: | |||||
- source: salt://linux/files/openvswitch-switch.default | |||||
- template: jinja | |||||
- require: | |||||
- pkg: openvswitch_pkgs | |||||
/etc/systemd/system/openvswitch-switch.service: | |||||
file.managed: | |||||
- source: salt://linux/files/openvswitch-switch.systemd | |||||
- template: jinja | |||||
- require: | |||||
- pkg: openvswitch_pkgs | |||||
module.run: | |||||
- name: service.systemctl_reload | |||||
- onchanges: | |||||
- file: /etc/systemd/system/openvswitch-switch.service | |||||
openvswitch_switch_service: | |||||
service.running: | |||||
- name: openvswitch-switch | |||||
- enable: true | |||||
{%- if grains.get('noservices') %} | |||||
- onlyif: /bin/false | |||||
{%- endif %} | |||||
- watch: | |||||
- file: /etc/default/openvswitch-switch | |||||
{%- endif %} |
linux_lvm_pkgs: | linux_lvm_pkgs: | ||||
pkg.installed: | pkg.installed: | ||||
- pkgs: {{ storage.lvm_pkgs }} | |||||
- pkgs: {{ storage.lvm_pkgs | json }} | |||||
/etc/lvm/lvm.conf: | /etc/lvm/lvm.conf: | ||||
lvm_{{ vg.get('name', vgname) }}_lv_{{ volume.get('name', lvname) }}: | lvm_{{ vg.get('name', vgname) }}_lv_{{ volume.get('name', lvname) }}: | ||||
lvm.lv_present: | lvm.lv_present: | ||||
- order: 1 | |||||
- name: {{ volume.get('name', lvname) }} | - name: {{ volume.get('name', lvname) }} | ||||
- vgname: {{ vg.get('name', vgname) }} | - vgname: {{ vg.get('name', vgname) }} | ||||
- size: {{ volume.size }} | - size: {{ volume.size }} | ||||
- force: true | |||||
- require: | - require: | ||||
- lvm: lvm_vg_{{ vg.get('name', vgname) }} | - lvm: lvm_vg_{{ vg.get('name', vgname) }} | ||||
{%- if volume.mount is defined %} | {%- if volume.mount is defined %} |
{%- if mount.file_system == 'nfs' %} | {%- if mount.file_system == 'nfs' %} | ||||
linux_storage_nfs_packages: | linux_storage_nfs_packages: | ||||
pkg.installed: | pkg.installed: | ||||
- pkgs: {{ storage.nfs.pkgs }} | |||||
- pkgs: {{ storage.nfs.pkgs | json }} | |||||
{%- endif %} | {%- endif %} | ||||
{{ mount.path }}: | {{ mount.path }}: | ||||
mount.mounted: | mount.mounted: | ||||
- order: 1 | |||||
- device: {{ mount.device }} | - device: {{ mount.device }} | ||||
- fstype: {{ mount.file_system }} | - fstype: {{ mount.file_system }} | ||||
- mkmnt: True | - mkmnt: True |
linux_storage_multipath_packages: | linux_storage_multipath_packages: | ||||
pkg.installed: | pkg.installed: | ||||
- pkgs: {{ storage.multipath.pkgs }} | |||||
- pkgs: {{ storage.multipath.pkgs | json }} | |||||
linux_storage_multipath_config: | linux_storage_multipath_config: | ||||
file.managed: | file.managed: |
{%- endif %} | {%- endif %} | ||||
{%- else %} | |||||
{{ swap.device }}: | |||||
module.run: | |||||
- name: mount.rm_fstab | |||||
- m_name: none | |||||
- device: {{ swap.device }} | |||||
- onlyif: grep -q {{ swap.device }} /etc/fstab | |||||
linux_disable_swap_{{ swap.engine }}_{{ swap.device }}: | |||||
cmd.run: | |||||
{%- if swap.engine == 'partition' %} | |||||
- name: 'swapoff {{ swap.device }}' | |||||
{%- elif swap.engine == 'file' %} | |||||
- name: 'swapoff {{ swap.device }} && rm -f {{ swap.device }}' | |||||
{%- endif %} | |||||
- onlyif: file -L -s {{ swap.device }} | grep -q 'swap file' | |||||
{%- endif %} | {%- endif %} | ||||
{%- endfor %} | {%- endfor %} |
{%- from "linux/map.jinja" import system with context %} | |||||
{%- if system.at.enabled is defined and system.at.enabled %} | |||||
at_packages: | |||||
pkg.installed: | |||||
- names: {{ system.at.pkgs }} | |||||
at_services: | |||||
service.running: | |||||
- enable: true | |||||
- names: {{ system.at.services }} | |||||
- require: | |||||
- pkg: at_packages | |||||
{%- if grains.get('noservices') %} | |||||
- onlyif: /bin/false | |||||
{%- endif %} | |||||
{%- set allow_users = [] %} | |||||
{%- for user_name, user_params in system.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: daemon | |||||
- mode: 0640 | |||||
- 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 %} |
{%- from "linux/map.jinja" import auth with context %} | {%- from "linux/map.jinja" import auth with context %} | ||||
{%- if auth.enabled %} | {%- if auth.enabled %} | ||||
{%- if auth.duo.enabled %} | |||||
include: | |||||
- linux.system.auth.duo | |||||
{%- else %} | |||||
{%- set pam_modules_enable = "" %} | |||||
{%- set pam_modules_disable = "" %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
linux_auth_pam_packages: | |||||
pkg.installed: | |||||
- pkgs: [ 'libpam-runtime' ] | |||||
linux_auth_pam_add_profile: | |||||
file.managed: | |||||
- name: /usr/local/bin/pam-add-profile | |||||
- source: salt://linux/files/pam-add-profile | |||||
- mode: 755 | |||||
- require: | |||||
- pkg: linux_auth_pam_packages | |||||
{%- endif %} | |||||
{%- if auth.get('mkhomedir', {}).get('enabled', False) %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
{%- set pam_modules_enable = pam_modules_enable + ' mkhomedir' %} | |||||
linux_auth_mkhomedir_debconf_package: | |||||
pkg.installed: | |||||
- pkgs: [ 'debconf-utils' ] | |||||
linux_auth_mkhomedir_config: | |||||
file.managed: | |||||
- name: /usr/share/pam-configs/mkhomedir | |||||
- source: salt://linux/files/mkhomedir | |||||
- template: jinja | |||||
{%- endif %} | |||||
{%- else %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
{%- set pam_modules_disable = pam_modules_disable + ' mkhomedir' %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if auth.get('ldap', {}).get('enabled', False) %} | |||||
{%- from "linux/map.jinja" import ldap with context %} | |||||
{%- if auth.get('ldap', {}).get('enabled', False) %} | |||||
{%- from "linux/map.jinja" import ldap with context %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
{%- set pam_modules_enable = pam_modules_enable + ' ldap' %} | |||||
linux_auth_ldap_debconf_package: | |||||
pkg.installed: | |||||
- pkgs: [ 'debconf-utils' ] | |||||
linux_auth_debconf_libnss-ldapd: | linux_auth_debconf_libnss-ldapd: | ||||
debconf.set: | debconf.set: | ||||
value: 'false' | value: 'false' | ||||
- require_in: | - require_in: | ||||
- pkg: linux_auth_ldap_packages | - pkg: linux_auth_ldap_packages | ||||
- require: | |||||
- pkg: linux_auth_ldap_debconf_package | |||||
linux_auth_debconf_libpam-ldapd: | linux_auth_debconf_libpam-ldapd: | ||||
debconf.set: | debconf.set: | ||||
libpam-ldapd/enable_shadow: | libpam-ldapd/enable_shadow: | ||||
type: 'boolean' | type: 'boolean' | ||||
value: 'true' | value: 'true' | ||||
{#- Setup mkhomedir and ldap PAM profiles #} | |||||
linux_auth_mkhomedir_config: | |||||
file.managed: | |||||
- name: /usr/share/pam-configs/mkhomedir | |||||
- source: salt://linux/files/mkhomedir | |||||
- require: | |||||
- pkg: linux_auth_ldap_packages | |||||
linux_auth_pam_add_profile: | |||||
file.managed: | |||||
- name: /usr/local/bin/pam-add-profile | |||||
- source: salt://linux/files/pam-add-profile | |||||
- mode: 755 | |||||
linux_auth_pam_add_profiles: | |||||
{%- endif %} | |||||
{%- else %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
{%- set pam_modules_disable = pam_modules_disable + ' ldap' %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{#- Setup PAM profiles #} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
{%- if auth.get('mkhomedir', {}).get('enabled', False) %} | |||||
linux_auth_pam_add_profiles_mkhomedir_enable: | |||||
cmd.run: | cmd.run: | ||||
- name: /usr/local/bin/pam-add-profile ldap mkhomedir | |||||
- unless: "debconf-get-selections | grep libpam-runtime/profiles | grep mkhomedir | grep ldap" | |||||
- name: /usr/local/bin/pam-add-profile {{ pam_modules_enable }} | |||||
- unless: "[[ `grep -c pam_mkhomedir.so /etc/pam.d/common-session` -ne 0 ]]" | |||||
- require: | |||||
- file: linux_auth_pam_add_profile | |||||
linux_auth_pam_add_profiles_mkhomedir_update: | |||||
cmd.wait: | |||||
- name: /usr/local/bin/pam-add-profile {{ pam_modules_enable }} | |||||
- watch: | - watch: | ||||
- file: linux_auth_mkhomedir_config | - file: linux_auth_mkhomedir_config | ||||
- require: | - require: | ||||
- file: linux_auth_pam_add_profile | - file: linux_auth_pam_add_profile | ||||
{%- if auth.get('ldap', {}).get('enabled', False) %} | |||||
- pkg: linux_auth_ldap_packages | - pkg: linux_auth_ldap_packages | ||||
{%- endif %} | |||||
{%- else %} | |||||
linux_auth_pam_remove_profiles_mkhomedir: | |||||
cmd.run: | |||||
- name: /usr/sbin/pam-auth-update --remove {{ pam_modules_disable }} | |||||
- onlyif: "[[ `grep -c pam_mkhomedir.so /etc/pam.d/common-session` -ne 0 ]]" | |||||
- require: | |||||
- pkg: linux_auth_pam_packages | |||||
{%- endif %} | |||||
{%- elif grains.os_family == 'RedHat' %} | |||||
{%- if auth.get('ldap', {}).get('enabled', False) %} | |||||
linux_auth_pam_add_profiles_ldap: | |||||
cmd.run: | |||||
- name: /usr/local/bin/pam-add-profile {{ pam_modules_enable }} | |||||
- unless: "[[ `debconf-get-selections | grep libpam-runtime/profiles | grep -c ldap` -ne 0 ]]" | |||||
- require: | |||||
- file: linux_auth_pam_add_profile | |||||
- pkg: linux_auth_ldap_packages | |||||
{%- else %} | |||||
linux_auth_pam_remove_profiles_ldap: | |||||
cmd.run: | |||||
- name: /usr/sbin/pam-auth-update --remove {{ pam_modules_disable }} | |||||
- onlyif: "[[ `debconf-get-selections | grep libpam-runtime/profiles | grep -c ldap` -ne 0 ]]" | |||||
- require: | |||||
- pkg: linux_auth_pam_packages | |||||
{%- endif %} | |||||
linux_auth_config: | |||||
{%- elif grains.os_family == 'RedHat' %} | |||||
{%- if auth.get('mkhomedir', {}).get('enabled', False) %} | |||||
linux_auth_config_enable_mkhomedir: | |||||
cmd.run: | |||||
- name: "authconfig --enablemkhomedir --update" | |||||
- require: | |||||
{%- if auth.get('ldap', {}).get('enabled', False) %} | |||||
- pkg: linux_auth_ldap_packages | |||||
{%- endif %} | |||||
{%- else %} | |||||
linux_auth_config_disable_mkhomedir: | |||||
cmd.run: | |||||
- name: "authconfig --disablemkhomedir --update" | |||||
- require: | |||||
- pkg: linux_auth_ldap_packages | |||||
{%- endif %} | |||||
{%- if auth.get('ldap', {}).get('enabled', False) %} | |||||
linux_auth_config_enable_ldap: | |||||
cmd.run: | cmd.run: | ||||
- name: "authconfig --enableldap --enableldapauth --enablemkhomedir --update" | |||||
- name: "authconfig --enableldap --enableldapauth --update" | |||||
- require: | - require: | ||||
{%- if auth.get('ldap', {}).get('enabled', False) %} | |||||
- pkg: linux_auth_ldap_packages | - pkg: linux_auth_ldap_packages | ||||
{%- endif %} | |||||
{%- else %} | |||||
linux_auth_config_disable_ldap: | |||||
cmd.run: | |||||
- name: "authconfig --disableldap --disableldapauth --update" | |||||
- require: | |||||
- pkg: linux_auth_ldap_packages | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- else %} | |||||
{%- if auth.get('ldap', {}).get('enabled', False) %} | |||||
linux_auth_nsswitch_config_file: | linux_auth_nsswitch_config_file: | ||||
file.managed: | file.managed: | ||||
- name: /etc/nsswitch.conf | |||||
- name: /etc/nsswitch.conf | |||||
- source: salt://linux/files/nsswitch.conf | - source: salt://linux/files/nsswitch.conf | ||||
- template: jinja | - template: jinja | ||||
- mode: 644 | - mode: 644 | ||||
- watch_in: | - watch_in: | ||||
- service: linux_auth_nslcd_service | - service: linux_auth_nslcd_service | ||||
{%- endif %} | |||||
linux_auth_ldap_packages: | linux_auth_ldap_packages: | ||||
pkg.installed: | pkg.installed: | ||||
- pkgs: {{ ldap.pkgs }} | |||||
- pkgs: {{ ldap.pkgs | json }} | |||||
linux_auth_nslcd_config_file: | linux_auth_nslcd_config_file: | ||||
file.managed: | file.managed: | ||||
- enable: true | - enable: true | ||||
- name: nslcd | - name: nslcd | ||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} |
{%- if grains['os'] == 'Ubuntu' %} | |||||
package_duo: | |||||
pkg.installed: | |||||
- name: duo-unix | |||||
login_duo: | |||||
file.managed: | |||||
- name: /etc/duo/login_duo.conf | |||||
- source: salt://linux/files/login_duo.conf | |||||
- template: jinja | |||||
- user: 'root' | |||||
- group: 'root' | |||||
- mode: '0600' | |||||
pam_duo: | |||||
file.managed: | |||||
- name: /etc/duo/pam_duo.conf | |||||
- source: salt://linux/files/login_duo.conf | |||||
- template: jinja | |||||
- user: 'root' | |||||
- group: 'root' | |||||
- mode: '0600' | |||||
pam-sshd_config: | |||||
file.managed: | |||||
- name: /etc/pam.d/sshd | |||||
- user: root | |||||
- group: root | |||||
- source: salt://linux/files/pam-sshd | |||||
- mode: 600 | |||||
- template: jinja | |||||
{%- endif %} | |||||
{%- if system.autoupdates.pkgs %} | {%- if system.autoupdates.pkgs %} | ||||
linux_autoupdates_packages: | linux_autoupdates_packages: | ||||
pkg.installed: | pkg.installed: | ||||
- pkgs: {{ system.autoupdates.pkgs }} | |||||
- pkgs: {{ system.autoupdates.pkgs | json }} | |||||
{%- endif %} | {%- endif %} | ||||
{%- if grains.os_family == 'Debian' %} | {%- if grains.os_family == 'Debian' %} |
{%- from "linux/map.jinja" import banner with context %} | |||||
{%- if banner.get('enabled', False) %} | |||||
/etc/issue: | |||||
file.managed: | |||||
- user: root | |||||
- group: root | |||||
- mode: 644 | |||||
- contents_pillar: linux:system:banner:contents | |||||
{%- endif %} |
{%- from "linux/map.jinja" import system with context %} | |||||
{%- if system.cron.enabled is defined and system.cron.enabled %} | |||||
cron_packages: | |||||
pkg.installed: | |||||
- names: {{ system.cron.pkgs }} | |||||
cron_services: | |||||
service.running: | |||||
- enable: true | |||||
- names: {{ system.cron.services }} | |||||
- require: | |||||
- pkg: cron_packages | |||||
{%- if grains.get('noservices') %} | |||||
- onlyif: /bin/false | |||||
{%- endif %} | |||||
{%- set allow_users = [] %} | |||||
{%- for user_name, user_params in system.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: crontab | |||||
- mode: 0640 | |||||
- 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 %} |
{%- for file_name, file in system.file.items() %} | {%- for file_name, file in system.file.items() %} | ||||
linux_file_{{ file_name }}: | linux_file_{{ file_name }}: | ||||
{%- if file.serialize is defined %} | |||||
file.serialize: | |||||
- formatter: {{ file.serialize }} | |||||
{%- if file.contents is defined %} | |||||
- dataset: {{ file.contents|json }} | |||||
{%- elif file.contents_pillar is defined %} | |||||
- dataset_pillar: {{ file.contents_pillar }} | |||||
{%- endif %} | |||||
{%- else %} | |||||
file.managed: | file.managed: | ||||
{%- if file.name is defined %} | |||||
- name: {{ file.name }} | |||||
{%- else %} | |||||
- name: {{ file_name }} | |||||
{%- endif %} | |||||
{%- if file.source is defined %} | {%- if file.source is defined %} | ||||
- source: {{ file.source }} | - source: {{ file.source }} | ||||
{%- if file.hash is defined %} | {%- if file.hash is defined %} | ||||
{%- else %} | {%- else %} | ||||
- skip_verify: True | - skip_verify: True | ||||
{%- endif %} | {%- endif %} | ||||
{%- if file.template is defined %} | |||||
- template: {{ file.template }} | |||||
{%- endif %} | |||||
{%- elif file.contents is defined %} | {%- elif file.contents is defined %} | ||||
- contents: {{ file.contents|yaml }} | |||||
- contents: {{ file.contents|json }} | |||||
{%- elif file.contents_pillar is defined %} | {%- elif file.contents_pillar is defined %} | ||||
- contents_pillar: {{ file.contents_pillar }} | - contents_pillar: {{ file.contents_pillar }} | ||||
{%- elif file.contents_grains is defined %} | {%- elif file.contents_grains is defined %} | ||||
- contents_grains: {{ file.contents_grains }} | - contents_grains: {{ file.contents_grains }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | |||||
{%- if file.name is defined %} | |||||
- name: {{ file.name }} | |||||
{%- else %} | |||||
- name: {{ file_name }} | |||||
{%- endif %} | |||||
- makedirs: {{ file.get('makedirs', 'True') }} | - makedirs: {{ file.get('makedirs', 'True') }} | ||||
- user: {{ file.get('user', 'root') }} | - user: {{ file.get('user', 'root') }} | ||||
- group: {{ file.get('group', 'root') }} | - group: {{ file.get('group', 'root') }} |
- makedirs: True | - makedirs: True | ||||
{%- if grains['os_family'] == 'RedHat' %} | {%- if grains['os_family'] == 'RedHat' %} | ||||
{%- set boot_grub_cfg = '/boot/grub2/grub.cfg' %} | |||||
/etc/default/grub: | /etc/default/grub: | ||||
file.append: | file.append: | ||||
- text: | - text: | ||||
grub_update: | grub_update: | ||||
cmd.wait: | cmd.wait: | ||||
- name: grub2-mkconfig -o /boot/grub2/grub.cfg | |||||
- name: grub2-mkconfig -o {{ boot_grub_cfg }} | |||||
{%- else %} | {%- else %} | ||||
{%- set boot_grub_cfg = '/boot/grub/grub.cfg' %} | |||||
{%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %} | |||||
grub_update: | grub_update: | ||||
cmd.wait: | cmd.wait: | ||||
- name: update-grub | - name: update-grub | ||||
{%- endif %} | |||||
{%- if grains.get('virtual_subtype') in ['Docker', 'LXC'] %} | |||||
- onlyif: /bin/false | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} | ||||
grub_cfg_permissions: | |||||
file.managed: | |||||
- name: {{ boot_grub_cfg }} | |||||
- user: 'root' | |||||
- owner: 'root' | |||||
- mode: '400' | |||||
- replace: false | |||||
- onlyif: test -f {{ boot_grub_cfg }} | |||||
- require: | |||||
- cmd: grub_update |
{%- for hugepages_type, hugepages in system.kernel.hugepages.items() %} | {%- for hugepages_type, hugepages in system.kernel.hugepages.items() %} | ||||
{%- if hugepages.get('mount', False) or hugepages.get('default', False) %} | |||||
hugepages_mount_{{ hugepages_type }}: | hugepages_mount_{{ hugepages_type }}: | ||||
mount.mounted: | mount.mounted: | ||||
- name: {{ hugepages.mount_point }} | - name: {{ hugepages.mount_point }} | ||||
- device: Hugetlbfs-kvm | |||||
- device: Hugetlbfs-kvm-{{ hugepages.size|lower }} | |||||
- fstype: hugetlbfs | - fstype: hugetlbfs | ||||
- mkmnt: true | - mkmnt: true | ||||
- opts: mode=775,pagesize={{ hugepages.size }} | - opts: mode=775,pagesize={{ hugepages.size }} | ||||
- mount: {{ hugepages.mount|default('true') }} | |||||
# Make hugepages available right away with a temporary systctl write | # Make hugepages available right away with a temporary systctl write | ||||
# This will be handled via krn args after reboot, so don't use `sysctl.present` | # This will be handled via krn args after reboot, so don't use `sysctl.present` | ||||
{%- if hugepages.get('default', False) %} | |||||
hugepages_sysctl_vm_nr_hugepages: | hugepages_sysctl_vm_nr_hugepages: | ||||
cmd.run: | cmd.run: | ||||
- name: "sysctl vm.nr_hugepages={{ hugepages.count }}" | - name: "sysctl vm.nr_hugepages={{ hugepages.count }}" | ||||
- unless: "sysctl vm.nr_hugepages | grep -qE '{{ hugepages.count }}'" | - unless: "sysctl vm.nr_hugepages | grep -qE '{{ hugepages.count }}'" | ||||
{%- endif %} | {%- endif %} | ||||
{%- endfor %} | {%- endfor %} | ||||
{%- endif %} | {%- endif %} | ||||
# systemd always creates default mount point at /dev/hugepages | |||||
# we have to disable it, as we configure our own mount point for DPDK. | |||||
mask_dev_hugepages: | |||||
cmd.run: | |||||
- name: "systemctl mask dev-hugepages.mount" |
include: | include: | ||||
- linux.system.env | - linux.system.env | ||||
- linux.system.profile | - linux.system.profile | ||||
- linux.system.shell | |||||
{%- if system.login_defs is defined %} | |||||
- linux.system.login_defs | |||||
{%- endif %} | |||||
{%- if system.at is defined %} | |||||
- linux.system.at | |||||
{%- endif %} | |||||
{%- if system.cron is defined %} | |||||
- linux.system.cron | |||||
{%- endif %} | |||||
{%- if system.repo|length > 0 %} | {%- if system.repo|length > 0 %} | ||||
- linux.system.repo | - linux.system.repo | ||||
{%- endif %} | {%- endif %} | ||||
{%- if system.auth is defined %} | {%- if system.auth is defined %} | ||||
- linux.system.auth | - linux.system.auth | ||||
{%- endif %} | {%- endif %} | ||||
{%- if system.banner is defined %} | |||||
- linux.system.banner | |||||
{%- endif %} | |||||
{%- if system.mcelog is defined %} | |||||
- linux.system.mcelog | |||||
{%- endif %} |
include: | include: | ||||
- linux.system.user | - 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 }}: | linux_job_{{ job.command }}: | ||||
{%- if job.enabled|default(True) %} | |||||
{%- if job.get('enabled', True) %} | |||||
cron.present: | cron.present: | ||||
- name: > | - name: > | ||||
{{ job.command }} | {{ job.command }} | ||||
{%- if job.get('identifier', True) %} | |||||
{%- if job.get('identifier', True) %} | |||||
- identifier: {{ job.get('identifier', job.get('name', name)) }} | - 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 }}' | - minute: '{{ job.minute }}' | ||||
{%- endif %} | |||||
{%- if job.hour is defined %} | |||||
{%- endif %} | |||||
{%- if job.hour is defined %} | |||||
- hour: '{{ job.hour }}' | - hour: '{{ job.hour }}' | ||||
{%- endif %} | |||||
{%- if job.daymonth is defined %} | |||||
{%- endif %} | |||||
{%- if job.daymonth is defined %} | |||||
- daymonth: '{{ job.daymonth }}' | - daymonth: '{{ job.daymonth }}' | ||||
{%- endif %} | |||||
{%- if job.month is defined %} | |||||
{%- endif %} | |||||
{%- if job.month is defined %} | |||||
- month: '{{ job.month }}' | - month: '{{ job.month }}' | ||||
{%- endif %} | |||||
{%- if job.dayweek is defined %} | |||||
{%- endif %} | |||||
{%- if job.dayweek is defined %} | |||||
- dayweek: '{{ job.dayweek }}' | - dayweek: '{{ job.dayweek }}' | ||||
{%- endif %} | |||||
{%- if job.user|default("root") in system.get('user', {}).keys() %} | |||||
{%- endif %} | |||||
- require: | - 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: | cron.absent: | ||||
- name: {{ job.command }} | - name: {{ job.command }} | ||||
{%- if job.get('identifier', True) %} | |||||
{%- if job.get('identifier', True) %} | |||||
- identifier: {{ job.get('identifier', job.get('name', name)) }} | - identifier: {{ job.get('identifier', job.get('name', name)) }} | ||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- endfor %} | |||||
{%- endif %} | {%- endif %} |
{%- set kernel_boot_opts = [] %} | {%- set kernel_boot_opts = [] %} | ||||
{%- do kernel_boot_opts.append('isolcpus=' ~ system.kernel.isolcpu) if system.kernel.isolcpu is defined %} | {%- do kernel_boot_opts.append('isolcpus=' ~ system.kernel.isolcpu) if system.kernel.isolcpu is defined %} | ||||
{%- do kernel_boot_opts.append('elevator=' ~ system.kernel.elevator) if system.kernel.elevator is defined %} | {%- do kernel_boot_opts.append('elevator=' ~ system.kernel.elevator) if system.kernel.elevator is defined %} | ||||
{%- do kernel_boot_opts.append('transparent_hugepage=' ~ system.kernel.transparent_hugepage) if system.kernel.transparent_hugepage is defined %} | |||||
{%- do kernel_boot_opts.extend(system.kernel.boot_options) if system.kernel.boot_options is defined %} | {%- do kernel_boot_opts.extend(system.kernel.boot_options) if system.kernel.boot_options is defined %} | ||||
{%- if kernel_boot_opts %} | |||||
include: | include: | ||||
- linux.system.grub | - linux.system.grub | ||||
{%- if kernel_boot_opts %} | |||||
/etc/default/grub.d/99-custom-settings.cfg: | /etc/default/grub.d/99-custom-settings.cfg: | ||||
file.managed: | file.managed: | ||||
- contents: 'GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT {{ kernel_boot_opts|join(' ') }}"' | - contents: 'GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT {{ kernel_boot_opts|join(' ') }}"' | ||||
{%- endfor %} | {%- endfor %} | ||||
{%- for module_name, module_content in system.kernel.get('module', {}).items() %} | |||||
{%- if system.kernel.module is defined %} | |||||
modprobe_d_directory: | |||||
file.directory: | |||||
- name: /etc/modprobe.d | |||||
- user: root | |||||
- group: root | |||||
- mode: 755 | |||||
{%- for module_name in system.kernel.module %} | |||||
/etc/modprobe.d/{{ module_name }}.conf: | /etc/modprobe.d/{{ module_name }}.conf: | ||||
file.managed: | file.managed: | ||||
- template: jinja | - template: jinja | ||||
- source: salt://linux/files/modprobe.conf.jinja | - source: salt://linux/files/modprobe.conf.jinja | ||||
- defaults: | - defaults: | ||||
module_content: {{ module_content }} | |||||
module_name: {{ module_name }} | module_name: {{ module_name }} | ||||
- require: | |||||
- file: modprobe_d_directory | |||||
{%- endfor %} | |||||
{%- endfor %} | |||||
{%- endif %} | |||||
{%- for sysctl_name, sysctl_value in system.kernel.get('sysctl', {}).items() %} | {%- for sysctl_name, sysctl_value in system.kernel.get('sysctl', {}).items() %} | ||||
{%- from "linux/map.jinja" import system with context %} | |||||
{%- if system.enabled %} | |||||
{%- if system.login_defs is defined %} | |||||
login_defs: | |||||
file.managed: | |||||
- name: /etc/login.defs | |||||
- source: salt://linux/files/login.defs.jinja | |||||
- template: jinja | |||||
- user: root | |||||
- group: root | |||||
- mode: 644 | |||||
{%- endif %} | |||||
{%- endif %} |
{%- from "linux/map.jinja" import system with context %} | |||||
{%- if system.enabled %} | |||||
{%- if system.get('mcelog',{}).get('enabled', False) %} | |||||
mcelog_packages: | |||||
pkg.installed: | |||||
- name: mcelog | |||||
mcelog_conf: | |||||
file.managed: | |||||
- name: /etc/mcelog/mcelog.conf | |||||
- source: salt://linux/files/mcelog.conf | |||||
- template: jinja | |||||
- user: root | |||||
- group: root | |||||
- mode: 644 | |||||
- require: | |||||
- pkg: mcelog_packages | |||||
mce_service: | |||||
service.running: | |||||
- name: mcelog | |||||
- enable: true | |||||
- require: | |||||
- pkg: mcelog_packages | |||||
- watch: | |||||
- file: mcelog_conf | |||||
{%- endif %} | |||||
{%- endif %} |
{%- from "linux/map.jinja" import system with context %} | {%- from "linux/map.jinja" import system with context %} | ||||
{%- if system.enabled %} | |||||
{%- if system.enabled and system.motd|length > 0 %} | |||||
{%- if grains.os_family == 'RedHat' %} | |||||
/etc/update-motd.d: | |||||
file.directory: | |||||
- clean: true | |||||
{#- update-motd is not available in RedHat, so support only static motd #} | |||||
{%- if system.motd is string %} | |||||
{#- Set static motd only #} | |||||
/etc/motd: | /etc/motd: | ||||
file.managed: | file.managed: | ||||
- contents_pillar: linux:system:motd | - contents_pillar: linux:system:motd | ||||
{%- else %} | {%- else %} | ||||
{%- if grains.os == 'Ubuntu' %} | |||||
package_update_motd: | |||||
pkg.installed: | |||||
- name: update-motd | |||||
- require_in: | |||||
- file: /etc/update-motd.d | |||||
{%- endif %} | |||||
/etc/update-motd.d: | |||||
file.directory: | |||||
- clean: true | |||||
{%- if grains.oscodename == "jessie" %} | {%- if grains.oscodename == "jessie" %} | ||||
motd_fix_pam_sshd: | motd_fix_pam_sshd: | ||||
file.replace: | file.replace: |
{%- if pkgs %} | {%- if pkgs %} | ||||
linux_extra_packages_{{ pkgs_group }}: | linux_extra_packages_{{ pkgs_group }}: | ||||
pkg.{{ pkgs_group }}: | pkg.{{ pkgs_group }}: | ||||
- pkgs: {{ pkgs }} | |||||
- pkgs: {{ pkgs | json }} | |||||
{%- endif %} | {%- endif %} | ||||
{%- endfor %} | {%- endfor %} | ||||
- defaults: | - defaults: | ||||
script: {{ script|yaml }} | script: {{ script|yaml }} | ||||
- require_in: | - require_in: | ||||
- service: profile.d_clean | |||||
- file: profile.d_clean | |||||
{% endfor %} | {% endfor %} | ||||
{%- endif %} | {%- endif %} |
{%- from "linux/map.jinja" import system with context %} | {%- from "linux/map.jinja" import system with context %} | ||||
{%- if system.enabled %} | {%- if system.enabled %} | ||||
{% if system.pkgs %} | |||||
linux_repo_prereq_pkgs: | linux_repo_prereq_pkgs: | ||||
pkg.installed: | pkg.installed: | ||||
- pkgs: {{ system.pkgs }} | |||||
# global proxy setup | |||||
{%- if system.proxy.get('pkg', {}).get('enabled', False) %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
- pkgs: {{ system.pkgs | json }} | |||||
{%- endif %} | |||||
# global proxy setup | |||||
{%- if grains.os_family == 'Debian' %} | |||||
{%- if system.proxy.get('pkg', {}).get('enabled', False) %} | |||||
/etc/apt/apt.conf.d/99proxies-salt: | /etc/apt/apt.conf.d/99proxies-salt: | ||||
file.managed: | file.managed: | ||||
- template: jinja | - template: jinja | ||||
https: {{ system.proxy.get('pkg', {}).get('https', None) | default(system.proxy.get('https', None), true) }} | https: {{ system.proxy.get('pkg', {}).get('https', None) | default(system.proxy.get('https', None), true) }} | ||||
http: {{ system.proxy.get('pkg', {}).get('http', None) | default(system.proxy.get('http', None), true) }} | http: {{ system.proxy.get('pkg', {}).get('http', None) | default(system.proxy.get('http', None), true) }} | ||||
ftp: {{ system.proxy.get('pkg', {}).get('ftp', None) | default(system.proxy.get('ftp', None), true) }} | ftp: {{ system.proxy.get('pkg', {}).get('ftp', None) | default(system.proxy.get('ftp', None), true) }} | ||||
{%- else %} | |||||
{%- else %} | |||||
/etc/apt/apt.conf.d/99proxies-salt: | /etc/apt/apt.conf.d/99proxies-salt: | ||||
file.absent | file.absent | ||||
{%- endif %} | |||||
{%- else %} | |||||
# Implement grobal proxy configiration for non-debian OS. | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{% set default_repos = {} %} | |||||
{%- if system.purge_repos|default(False) %} | |||||
{% set default_repos = {} %} | |||||
{%- if system.purge_repos|default(False) %} | |||||
purge_sources_list_d_repos: | purge_sources_list_d_repos: | ||||
file.directory: | |||||
- name: /etc/apt/sources.list.d/ | |||||
- clean: True | |||||
{%- endif %} | |||||
file.directory: | |||||
- name: /etc/apt/sources.list.d/ | |||||
- clean: True | |||||
{%- endif %} | |||||
{%- for name, repo in system.repo.items() %} | |||||
{%- set name=repo.get('name', name) %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
{%- for name, repo in system.repo.items() %} | |||||
{%- set name=repo.get('name', name) %} | |||||
{%- if grains.os_family == 'Debian' %} | |||||
# per repository proxy setup | # per repository proxy setup | ||||
{%- if repo.get('proxy', {}).get('enabled', False) %} | |||||
{%- set external_host = repo.proxy.get('host', None) or repo.source.split('/')[2] %} | |||||
{%- if repo.get('proxy', {}).get('enabled', False) %} | |||||
{%- set external_host = repo.proxy.get('host', None) or repo.source.split('/')[2] %} | |||||
/etc/apt/apt.conf.d/99proxies-salt-{{ name }}: | /etc/apt/apt.conf.d/99proxies-salt-{{ name }}: | ||||
file.managed: | file.managed: | ||||
- template: jinja | - template: jinja | ||||
https: {{ repo.proxy.get('https', None) or system.proxy.get('pkg', {}).get('https', None) | default(system.proxy.get('https', None), True) }} | https: {{ repo.proxy.get('https', None) or system.proxy.get('pkg', {}).get('https', None) | default(system.proxy.get('https', None), True) }} | ||||
http: {{ repo.proxy.get('http', None) or system.proxy.get('pkg', {}).get('http', None) | default(system.proxy.get('http', None), True) }} | http: {{ repo.proxy.get('http', None) or system.proxy.get('pkg', {}).get('http', None) | default(system.proxy.get('http', None), True) }} | ||||
ftp: {{ repo.proxy.get('ftp', None) or system.proxy.get('pkg', {}).get('ftp', None) | default(system.proxy.get('ftp', None), True) }} | ftp: {{ repo.proxy.get('ftp', None) or system.proxy.get('pkg', {}).get('ftp', None) | default(system.proxy.get('ftp', None), True) }} | ||||
{%- else %} | |||||
{%- else %} | |||||
/etc/apt/apt.conf.d/99proxies-salt-{{ name }}: | /etc/apt/apt.conf.d/99proxies-salt-{{ name }}: | ||||
file.absent | file.absent | ||||
{%- endif %} | |||||
{%- if repo.pin is defined %} | |||||
{%- endif %} | |||||
{%- if repo.pin is defined or repo.pinning is defined %} | |||||
linux_repo_{{ name }}_pin: | linux_repo_{{ name }}_pin: | ||||
file.managed: | file.managed: | ||||
- name: /etc/apt/preferences.d/{{ name }} | - name: /etc/apt/preferences.d/{{ name }} | ||||
- template: jinja | - template: jinja | ||||
- defaults: | - defaults: | ||||
repo_name: {{ name }} | repo_name: {{ name }} | ||||
{%- else %} | |||||
{%- else %} | |||||
linux_repo_{{ name }}_pin: | linux_repo_{{ name }}_pin: | ||||
file.absent: | file.absent: | ||||
- name: /etc/apt/preferences.d/{{ name }} | - name: /etc/apt/preferences.d/{{ name }} | ||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if repo.get('default', False) %} | |||||
{%- do default_repos.update({name: repo}) %} | |||||
{%- if repo.get('key') %} | |||||
{%- if repo.get('key') %} | |||||
linux_repo_{{ name }}_key: | linux_repo_{{ name }}_key: | ||||
cmd.wait: | |||||
- name: "echo '{{ repo.key }}' | apt-key add -" | |||||
- watch: | |||||
{% set repo_key = salt['hashutil.base64_b64encode'](repo.key) %} | |||||
cmd.run: | |||||
- name: "echo '{{ repo_key }}' | base64 -d | apt-key add -" | |||||
- require_in: | |||||
{%- if repo.get('default', False) %} | |||||
- file: default_repo_list | - file: default_repo_list | ||||
{%- elif repo.key_url|default(False) %} | |||||
{% else %} | |||||
- pkgrepo: linux_repo_{{ name }} | |||||
{% endif %} | |||||
{# key_url fetch by curl when salt <2017.7, higher version of salt has | |||||
fixed bug for using a proxy_host/port specified at minion.conf | |||||
NOTE: curl/cmd.run usage to fetch gpg key has limited functionality behind proxy. | |||||
Environments with salt >= 2017.7 should use key_url specified at | |||||
pkgrepo.manage state (which uses properly configured http_host at | |||||
minion.conf). Older versions of salt require to have proxy set at | |||||
ENV and curl way to fetch gpg key here can have a sense for backward | |||||
compatibility. Be aware that as of salt 2018.3 no_proxy option is | |||||
not implemented at all. | |||||
#} | |||||
{%- elif repo.key_url|default(False) and grains['saltversioninfo'] < [2017, 7] and not repo.key_url.startswith('salt://') %} | |||||
linux_repo_{{ name }}_key: | linux_repo_{{ name }}_key: | ||||
cmd.wait: | |||||
- name: "curl -s {{ repo.key_url }} | apt-key add -" | |||||
- watch: | |||||
cmd.run: | |||||
- name: "curl -sL {{ repo.key_url }} | apt-key add -" | |||||
- require_in: | |||||
{%- if repo.get('default', False) %} | |||||
- file: default_repo_list | - file: default_repo_list | ||||
{% else %} | |||||
- pkgrepo: linux_repo_{{ name }} | |||||
{% endif %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- else %} | |||||
{%- if repo.get('enabled', True) %} | |||||
{%- if repo.get('default', False) %} | |||||
{%- do default_repos.update({name: repo}) %} | |||||
{%- else %} | |||||
{%- if repo.get('enabled', True) %} | |||||
linux_repo_{{ name }}: | linux_repo_{{ name }}: | ||||
pkgrepo.managed: | pkgrepo.managed: | ||||
{%- if repo.ppa is defined %} | |||||
- refresh_db: False | |||||
- require_in: | |||||
- refresh_db | |||||
{%- if repo.ppa is defined %} | |||||
- ppa: {{ repo.ppa }} | - ppa: {{ repo.ppa }} | ||||
{%- else %} | |||||
{%- else %} | |||||
- humanname: {{ name }} | - humanname: {{ name }} | ||||
- name: {{ repo.source }} | - name: {{ repo.source }} | ||||
{%- if repo.architectures is defined %} | |||||
{%- if repo.architectures is defined %} | |||||
- architectures: {{ repo.architectures }} | - architectures: {{ repo.architectures }} | ||||
{%- endif %} | |||||
{%- endif %} | |||||
- file: /etc/apt/sources.list.d/{{ name }}.list | - file: /etc/apt/sources.list.d/{{ name }}.list | ||||
- clean_file: {{ repo.clean|default(True) }} | |||||
{%- if repo.key_id is defined %} | |||||
- clean_file: {{ repo.get('clean_file', True) }} | |||||
{%- if repo.key_id is defined %} | |||||
- keyid: {{ repo.key_id }} | - keyid: {{ repo.key_id }} | ||||
{%- endif %} | |||||
{%- if repo.key_server is defined %} | |||||
{%- endif %} | |||||
{%- if repo.key_server is defined %} | |||||
- keyserver: {{ repo.key_server }} | - keyserver: {{ repo.key_server }} | ||||
{%- endif %} | |||||
{%- if repo.key_url is defined %} | |||||
{%- endif %} | |||||
{%- if repo.key_url is defined and (grains['saltversioninfo'] >= [2017, 7] or repo.key_url.startswith('salt://')) %} | |||||
- key_url: {{ repo.key_url }} | - key_url: {{ repo.key_url }} | ||||
{%- endif %} | |||||
{%- endif %} | |||||
- consolidate: {{ repo.get('consolidate', False) }} | - consolidate: {{ repo.get('consolidate', False) }} | ||||
- clean_file: {{ repo.get('clean_file', False) }} | |||||
- refresh_db: {{ repo.get('refresh_db', True) }} | |||||
- require: | - require: | ||||
- pkg: linux_repo_prereq_pkgs | |||||
{%- if repo.get('proxy', {}).get('enabled', False) %} | |||||
- file: /etc/apt/apt.conf.d/99proxies-salt-{{ name }} | - file: /etc/apt/apt.conf.d/99proxies-salt-{{ name }} | ||||
{%- endif %} | |||||
{%- if system.proxy.get('pkg', {}).get('enabled', False) %} | |||||
- file: /etc/apt/apt.conf.d/99proxies-salt | - file: /etc/apt/apt.conf.d/99proxies-salt | ||||
{%- endif %} | |||||
{%- if system.purge_repos|default(False) %} | |||||
{%- if system.purge_repos|default(False) %} | |||||
- file: purge_sources_list_d_repos | - file: purge_sources_list_d_repos | ||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- else %} | |||||
linux_repo_{{ name }}_absent: | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- else %} | |||||
linux_repo_{{ name }}: | |||||
pkgrepo.absent: | pkgrepo.absent: | ||||
{%- if repo.ppa is defined %} | |||||
- refresh_db: False | |||||
- require: | |||||
- file: /etc/apt/apt.conf.d/99proxies-salt-{{ name }} | |||||
- require_in: | |||||
- refresh_db | |||||
{%- if repo.ppa is defined %} | |||||
- ppa: {{ repo.ppa }} | - ppa: {{ repo.ppa }} | ||||
{%- if repo.key_id is defined %} | |||||
{%- if repo.key_id is defined %} | |||||
- keyid_ppa: {{ repo.keyid_ppa }} | - keyid_ppa: {{ repo.keyid_ppa }} | ||||
{%- endif %} | |||||
{%- else %} | |||||
{%- endif %} | |||||
{%- else %} | |||||
- file: /etc/apt/sources.list.d/{{ name }}.list | - file: /etc/apt/sources.list.d/{{ name }}.list | ||||
{%- if repo.key_id is defined %} | |||||
{%- if repo.key_id is defined %} | |||||
- keyid: {{ repo.key_id }} | - keyid: {{ repo.key_id }} | ||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | |||||
file.absent: | |||||
- name: /etc/apt/sources.list.d/{{ name }}.list | |||||
{%- endif %} | |||||
{%- if grains.os_family == "RedHat" %} | |||||
{%- endif %} | |||||
{#- os_family Debian #} | |||||
{%- endif %} | |||||
{%- if grains.os_family == "RedHat" %} | |||||
{%- if repo.get('enabled', True) %} | |||||
{%- if repo.get('proxy', {}).get('enabled', False) %} | |||||
{%- if repo.get('enabled', True) %} | |||||
{%- if repo.get('proxy', {}).get('enabled', False) %} | |||||
# PLACEHOLDER | # PLACEHOLDER | ||||
# TODO, implement per proxy configuration for Yum | # TODO, implement per proxy configuration for Yum | ||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- if not repo.get('default', False) %} | |||||
{%- if not repo.get('default', False) %} | |||||
linux_repo_{{ name }}: | linux_repo_{{ name }}: | ||||
pkgrepo.managed: | pkgrepo.managed: | ||||
- refresh_db: False | |||||
- require_in: | |||||
- refresh_db | |||||
- name: {{ name }} | - name: {{ name }} | ||||
- humanname: {{ repo.get('humanname', name) }} | - humanname: {{ repo.get('humanname', name) }} | ||||
{%- if repo.mirrorlist is defined %} | |||||
{%- if repo.mirrorlist is defined %} | |||||
- mirrorlist: {{ repo.mirrorlist }} | - mirrorlist: {{ repo.mirrorlist }} | ||||
{%- else %} | |||||
{%- else %} | |||||
- baseurl: {{ repo.source }} | - baseurl: {{ repo.source }} | ||||
{%- endif %} | |||||
{%- endif %} | |||||
- gpgcheck: {% if repo.get('gpgcheck', False) %}1{% else %}0{% endif %} | - gpgcheck: {% if repo.get('gpgcheck', False) %}1{% else %}0{% endif %} | ||||
{%- if repo.gpgkey is defined %} | |||||
{%- if repo.gpgkey is defined %} | |||||
- gpgkey: {{ repo.gpgkey }} | - gpgkey: {{ repo.gpgkey }} | ||||
{%- endif %} | |||||
- require: | |||||
- pkg: linux_repo_prereq_pkgs | |||||
{%- endif %} | |||||
{#- repo.enabled is false #} | |||||
{%- else %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- else %} | |||||
pkgrepo.absent: | pkgrepo.absent: | ||||
- refresh_db: False | |||||
- require_in: | |||||
- refresh_db | |||||
- name: {{ repo.source }} | - name: {{ repo.source }} | ||||
{%- endif %} | |||||
{#- os_family Redhat #} | |||||
{%- endif %} | |||||
{#- repo.items() loop #} | |||||
{%- endfor %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- if default_repos|length > 0 and grains.os_family == 'Debian' %} | |||||
{%- if default_repos|length > 0 and grains.os_family == 'Debian' %} | |||||
default_repo_list: | default_repo_list: | ||||
file.managed: | file.managed: | ||||
- user: root | - user: root | ||||
- group: root | - group: root | ||||
- mode: 0644 | - mode: 0644 | ||||
{%- if system.purge_repos|default(False) %} | |||||
{%- if system.purge_repos|default(False) %} | |||||
- replace: True | - replace: True | ||||
{%- endif %} | |||||
{%- endif %} | |||||
- defaults: | - defaults: | ||||
default_repos: {{ default_repos }} | default_repos: {{ default_repos }} | ||||
- require: | |||||
- pkg: linux_repo_prereq_pkgs | |||||
refresh_default_repo: | |||||
module.wait: | |||||
- name: pkg.refresh_db | |||||
- watch: | |||||
- file: default_repo_list | |||||
{%- endif %} | |||||
{%- endif %} | |||||
refresh_db: | |||||
{%- if system.get('refresh_repos_meta', True) %} | |||||
module.run: | |||||
- name: pkg.refresh_db | |||||
{%- else %} | |||||
test.succeed_without_changes | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} |
{%- from "linux/map.jinja" import system with context %} | |||||
{%- if system.enabled %} | |||||
{%- if system.shell is defined %} | |||||
{%- if system.shell.umask is defined %} | |||||
etc_bash_bashrc_umask: | |||||
file.blockreplace: | |||||
- name: /etc/bash.bashrc | |||||
- marker_start: "# BEGIN CIS 5.4.4 default user umask" | |||||
- marker_end: "# END CIS 5.4.4 default user umask" | |||||
- content: "umask {{ system.shell.umask }}" | |||||
- append_if_not_found: True | |||||
- onlyif: test -f /etc/bash.bashrc | |||||
etc_profile_umask: | |||||
file.blockreplace: | |||||
- name: /etc/profile | |||||
- marker_start: "# BEGIN CIS 5.4.4 default user umask" | |||||
- marker_end: "# END CIS 5.4.4 default user umask" | |||||
- content: "umask {{ system.shell.umask }}" | |||||
- append_if_not_found: True | |||||
- onlyif: test -f /etc/profile | |||||
{%- endif %} | |||||
{%- if system.shell.timeout is defined %} | |||||
etc_bash_bashrc_timeout: | |||||
file.blockreplace: | |||||
- name: /etc/bash.bashrc | |||||
- marker_start: "# BEGIN CIS 5.4.5 default user shell timeout" | |||||
- marker_end: "# END CIS 5.4.5 default user shell timeout" | |||||
- content: "TMOUT={{ system.shell.timeout }}" | |||||
- append_if_not_found: True | |||||
- onlyif: test -f /etc/bash.bashrc | |||||
etc_profile_timeout: | |||||
file.blockreplace: | |||||
- name: /etc/profile | |||||
- marker_start: "# BEGIN CIS 5.4.5 default user shell timeout" | |||||
- marker_end: "# END CIS 5.4.5 default user shell timeout" | |||||
- content: "TMOUT={{ system.shell.timeout }}" | |||||
- append_if_not_found: True | |||||
- onlyif: test -f /etc/profile | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} |
- require: | - require: | ||||
- pkg: linux_sysfs_package | - pkg: linux_sysfs_package | ||||
{% set apply = system.get('sysfs', {}).pop('enable_apply', True) %} | |||||
{%- for name, sysfs in system.get('sysfs', {}).items() %} | {%- for name, sysfs in system.get('sysfs', {}).items() %} | ||||
/etc/sysfs.d/{{ name }}.conf: | /etc/sysfs.d/{{ name }}.conf: | ||||
- require: | - require: | ||||
- file: /etc/sysfs.d | - file: /etc/sysfs.d | ||||
{%- for key, value in sysfs.items() %} | |||||
{%- if sysfs is mapping %} | |||||
{%- set sysfs_list = [sysfs] %} | |||||
{%- else %} | |||||
{%- set sysfs_list = sysfs %} | |||||
{%- endif %} | |||||
{%- if apply %} | |||||
{%- for item in sysfs_list %} | |||||
{%- set list_idx = loop.index %} | |||||
{%- for key, value in item.items() %} | |||||
{%- if key not in ["mode", "owner"] %} | {%- if key not in ["mode", "owner"] %} | ||||
{%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %} | {%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %} | ||||
{#- Sysfs cannot be set in docker, LXC, etc. #} | {#- Sysfs cannot be set in docker, LXC, etc. #} | ||||
linux_sysfs_write_{{ name }}_{{ key }}: | |||||
linux_sysfs_write_{{ list_idx }}_{{ name }}_{{ key }}: | |||||
module.run: | module.run: | ||||
- name: sysfs.write | - name: sysfs.write | ||||
- key: {{ key }} | - key: {{ key }} | ||||
{%- endfor %} | {%- endfor %} | ||||
{%- endfor %} | {%- endfor %} | ||||
{%- endif %} | |||||
{%- endfor %} |
{{ system.timezone }}: | {{ system.timezone }}: | ||||
timezone.system: | timezone.system: | ||||
{%- if grains.get('noservices') %} | |||||
- onlyif: /bin/false | |||||
{%- endif %} | |||||
- utc: {{ system.utc }} | - utc: {{ system.utc }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | |||||
{%- endif %} |
{%- endif %} | {%- endif %} | ||||
{%- endfor %} | {%- endfor %} | ||||
{%- if user.gid is not defined %} | |||||
system_group_{{ name }}: | |||||
group.present: | |||||
- name: {{ name }} | |||||
- require_in: | |||||
- user: system_user_{{ name }} | |||||
{%- endif %} | |||||
{%- if user.get('makedirs') %} | |||||
system_user_home_parentdir_{{ user.home }}: | |||||
file.directory: | |||||
- name: {{ user.home | path_join("..") }} | |||||
- makedirs: true | |||||
- require_in: | |||||
- user: system_user_{{ name }} | |||||
{%- endif %} | |||||
system_user_{{ name }}: | system_user_{{ name }}: | ||||
user.present: | user.present: | ||||
- name: {{ name }} | - name: {{ name }} | ||||
- password: {{ user.password }} | - password: {{ user.password }} | ||||
- hash_password: {{ user.get('hash_password', False) }} | - hash_password: {{ user.get('hash_password', False) }} | ||||
{% endif %} | {% endif %} | ||||
{%- if user.gid is defined and user.gid %} | |||||
- gid: {{ user.gid }} | |||||
{%- else %} | |||||
- gid_from_name: true | - gid_from_name: true | ||||
{%- endif %} | |||||
{%- if user.groups is defined %} | {%- if user.groups is defined %} | ||||
- groups: {{ user.groups }} | - groups: {{ user.groups }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if user.system is defined and user.system %} | {%- if user.system is defined and user.system %} | ||||
- system: True | - system: True | ||||
- shell: {{ user.get('shell', '/bin/false') }} | |||||
{%- else %} | {%- else %} | ||||
- shell: {{ user.get('shell', '/bin/bash') }} | - shell: {{ user.get('shell', '/bin/bash') }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if user.uid is defined and user.uid %} | {%- if user.uid is defined and user.uid %} | ||||
- uid: {{ user.uid }} | - uid: {{ user.uid }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if user.unique is defined %} | |||||
- unique: {{ user.unique }} | |||||
{%- endif %} | |||||
{%- if user.maxdays is defined %} | |||||
- maxdays: {{ user.maxdays }} | |||||
{%- endif %} | |||||
{%- if user.mindays is defined %} | |||||
- mindays: {{ user.mindays }} | |||||
{%- endif %} | |||||
{%- if user.warndays is defined %} | |||||
- warndays: {{ user.warndays }} | |||||
{%- endif %} | |||||
{%- if user.inactdays is defined %} | |||||
- inactdays: {{ user.inactdays }} | |||||
{%- endif %} | |||||
- require: {{ requires|yaml }} | - require: {{ requires|yaml }} | ||||
{%- if user.allow_uid_change is defined and user.allow_uid_change %} | {%- if user.allow_uid_change is defined and user.allow_uid_change %} | ||||
- allow_uid_change: true | - allow_uid_change: true | ||||
file.directory: | file.directory: | ||||
- name: {{ user.home }} | - name: {{ user.home }} | ||||
- user: {{ name }} | - user: {{ name }} | ||||
- mode: 700 | |||||
- mode: {{ user.get('home_dir_mode', 700) }} | |||||
- makedirs: true | - makedirs: true | ||||
- require: | - require: | ||||
- user: system_user_{{ name }} | - user: system_user_{{ name }} | ||||
/etc/sudoers.d/90-salt-user-{{ name|replace('.', '-') }}: | /etc/sudoers.d/90-salt-user-{{ name|replace('.', '-') }}: | ||||
file.absent | file.absent | ||||
{%- endif %} | {%- endif %} | ||||
{%- else %} | {%- else %} |
name: "linux" | name: "linux" | ||||
version: "2017.4.1" | version: "2017.4.1" | ||||
source: "https://github.com/tcpcloud/salt-formula-linux" | |||||
source: "https://github.com/salt-formulas/salt-formula-linux" |
# 1.1.1.1 Ensure mounting of cramfs filesystems is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The cramfs filesystem type is a compressed read-only Linux filesystem | |||||
# embedded in small footprint systems. A cramfs image can be used without | |||||
# having to first decompress the image. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Removing support for unneeded filesystem types reduces the local attack | |||||
# surface of the server. If this filesystem type is not needed, disable it. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v cramfs | |||||
# install /bin/true | |||||
# # lsmod | grep cramfs | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install cramfs /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
cramfs: | |||||
install: | |||||
command: /bin/true | |||||
# 1.1.1.2 Ensure mounting of freevxfs filesystems is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The freevxfs filesystem type is a free version of the Veritas type | |||||
# filesystem. This is the primary filesystem type for HP-UX operating systems. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Removing support for unneeded filesystem types reduces the local attack | |||||
# surface of the system. If this filesystem type is not needed, disable it. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v freevxfs | |||||
# install /bin/true | |||||
# # lsmod | grep freevxfs | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install freevxfs /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
freevxfs: | |||||
install: | |||||
command: /bin/true | |||||
# 1.1.1.3 Ensure mounting of jffs2 filesystems is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The jffs2 (journaling flash filesystem 2) filesystem type is a | |||||
# log-structured filesystem used in flash memory devices. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Removing support for unneeded filesystem types reduces the local attack | |||||
# surface of the system. If this filesystem type is not needed, disable it. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v jffs2 | |||||
# install /bin/true | |||||
# # lsmod | grep jffs2 | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install jffs2 /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
jffs2: | |||||
install: | |||||
command: /bin/true | |||||
# 1.1.1.4 Ensure mounting of hfs filesystems is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The hfs filesystem type is a hierarchical filesystem that allows | |||||
# you to mount Mac OS filesystems. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Removing support for unneeded filesystem types reduces the local attack | |||||
# surface of the system. If this filesystem type is not needed, disable it. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v hfs | |||||
# install /bin/true | |||||
# # lsmod | grep hfs | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install hfs /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
hfs: | |||||
install: | |||||
command: /bin/true | |||||
# 1.1.1.5 Ensure mounting of hfsplus filesystems is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The hfsplus filesystem type is a hierarchical filesystem designed to | |||||
# replace hfs that allows you to mount Mac OS filesystems. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Removing support for unneeded filesystem types reduces the local attack | |||||
# surface of the system. If this filesystem type is not needed, disable it. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v hfsplus | |||||
# install /bin/true | |||||
# # lsmod | grep hfsplus | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install hfsplus /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
hfsplus: | |||||
install: | |||||
command: /bin/true | |||||
# 1.1.1.6 Ensure mounting of squashfs filesystems is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The squashfs filesystem type is a compressed read-only Linux filesystem | |||||
# embedded in small footprint systems (similar to cramfs). A squashfs image | |||||
# can be used without having to first decompress the image. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Removing support for unneeded filesystem types reduces the local attack | |||||
# surface of the server. If this filesystem type is not needed, disable it. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v squashfs | |||||
# install /bin/true | |||||
# # lsmod | grep squashfs | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install squashfs /bin/true | |||||
# | |||||
# NOTE | |||||
# ==== | |||||
# In Ubuntu 16.04 squashfs is built into kernel, and 'install' command | |||||
# from modprobe.d dir has no effect. However, this is still checked by | |||||
# CIS-CAT in Ubuntu 16.04 benchmark v.1.0.0. This was removed in v.1.1.0. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
squashfs: | |||||
install: | |||||
command: /bin/true | |||||
# 1.1.1.7 Ensure mounting of udf filesystems is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The udf filesystem type is the universal disk format used to implement | |||||
# ISO/IEC 13346 and ECMA-167 specifications. This is an open vendor filesystem | |||||
# type for data storage on a broad range of media. This filesystem type is | |||||
# necessary to support writing DVDs and newer optical disc formats. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Removing support for unneeded filesystem types reduces the local attack | |||||
# surface of the server. If this filesystem type is not needed, disable it. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v udf | |||||
# install /bin/true | |||||
# # lsmod | grep udf | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install udf /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
udf: | |||||
install: | |||||
command: /bin/true | |||||
# 1.1.1.8 Ensure mounting of FAT filesystems is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The FAT filesystem format is primarily used on older windows systems and | |||||
# portable USB drives or flash modules. It comes in three types FAT12, FAT16, | |||||
# and FAT32 all of which are supported by the vfat kernel module. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Removing support for unneeded filesystem types reduces the local attack | |||||
# surface of the server. If this filesystem type is not needed, disable it. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v vfat | |||||
# install /bin/true | |||||
# # lsmod | grep vfat | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install vfat /bin/true | |||||
# | |||||
# Impact | |||||
# ====== | |||||
# FAT filesystems are often used on portable USB sticks and other flash | |||||
# media are commonly used to transfer files between workstations, removing | |||||
# VFAT support may prevent the ability to transfer files in this way. | |||||
# | |||||
# NOTE | |||||
# ==== | |||||
# In Ubuntu 16.04 vfat is built into kernel, and 'install' command | |||||
# from modprobe.d dir has no effect. However, this is still checked by | |||||
# CIS-CAT in Ubuntu 16.04 benchmark v.1.0.0. This was removed in v.1.1.0. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
vfat: | |||||
install: | |||||
command: /bin/true | |||||
# CIS 1.1.14 Ensure nodev option set on /dev/shm partition (Scored) | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The nodev mount option specifies that the filesystem cannot contain special | |||||
# devices. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Since the /run/shm filesystem is not intended to support devices, set this | |||||
# option to ensure that users cannot attempt to create special devices in | |||||
# /dev/shm partitions. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify that the nodev option is set on /dev/shm . | |||||
# | |||||
# # mount | grep /dev/shm | |||||
# shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime) | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Edit the /etc/fstab file and add nodev to the fourth field (mounting options) | |||||
# for the /dev/shm partition. See the fstab(5) manual page for more information. | |||||
# Run the following command to remount /dev/shm : | |||||
# | |||||
# # mount -o remount,nodev /dev/shm | |||||
# | |||||
# CIS 1.1.15 Ensure nosuid option set on /dev/shm partition (Scored) | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The nosuid mount option specifies that the filesystem cannot contain setuid | |||||
# files. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Setting this option on a file system prevents users from introducing | |||||
# privileged programs onto the system and allowing non-root users to execute them. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify that the no suid option is set on /dev/shm . | |||||
# | |||||
# # mount | grep /dev/shm | |||||
# shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime) | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit the /etc/fstab file and add nosuid to the fourth field (mounting options) | |||||
# for the /dev/shm partition. See the fstab(5) manual page for more information. | |||||
# Run the following command to remount /dev/shm : | |||||
# | |||||
# # mount -o remount,nosuid /dev/shm | |||||
# | |||||
# 1.1.16 Ensure noexec option set on /dev/shm partition (Scored) | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The noexec mount option specifies that the filesystem cannot contain | |||||
# executable binaries. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Setting this option on a file system prevents users from executing programs | |||||
# from shared memory. This deters users from introducing potentially malicious | |||||
# software on the system. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify that the noexec option is set on /run/shm . | |||||
# | |||||
# # mount | grep /dev/shm | |||||
# shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime) | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit the /etc/fstab file and add noexec to the fourth field (mounting options) | |||||
# for the /dev/shm partition. See the fstab(5) manual page for more information. | |||||
# Run the following command to remount /dev/shm : | |||||
# | |||||
# # mount -o remount,noexec /dev/shm | |||||
# | |||||
parameters: | |||||
linux: | |||||
storage: | |||||
mount: | |||||
ensure_dev_shm_mount_options: | |||||
enabled: true | |||||
file_system: tmpfs | |||||
device: shm | |||||
path: /dev/shm | |||||
opts: rw,nosuid,nodev,noexec,relatime | |||||
# CIS 1.1.21 Disable Automounting | |||||
# | |||||
# Description | |||||
# =========== | |||||
# autofs allows automatic mounting of devices, typically including CD/DVDs | |||||
# and USB drives. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# With automounting enabled anyone with physical access could attach a USB | |||||
# drive or disc and have its contents available in system even if they lacked | |||||
# permissions to mount it themselves. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command to verify autofs is not enabled: | |||||
# | |||||
# # systemctl is-enabled autofs | |||||
# disabled | |||||
# | |||||
# Verify result is not "enabled". | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Run the following command to disable autofs : | |||||
# | |||||
# # systemctl disable autofs | |||||
# | |||||
# Impact | |||||
# ====== | |||||
# The use portable hard drives is very common for workstation users. If your | |||||
# organization allows the use of portable storage or media on workstations | |||||
# and physical access controls to workstations is considered adequate there | |||||
# is little value add in turning off automounting. | |||||
# | |||||
# Notes | |||||
# ===== | |||||
# This control should align with the tolerance of the use of portable drives | |||||
# and optical media in the organization. On a server requiring an admin to | |||||
# manually mount media can be part of defense-in-depth to reduce the risk of | |||||
# unapproved software or information being introduced or proprietary software | |||||
# or information being exfiltrated. If admins commonly use flash drives and | |||||
# Server access has sufficient physical controls, requiring manual mounting | |||||
# may not increase security. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
service: | |||||
autofs: | |||||
status: disabled | |||||
# CIS 1.5.1 Ensure core dumps are restricted (Scored) | |||||
# | |||||
# Description | |||||
# =========== | |||||
# | |||||
# A core dump is the memory of an executable program. It is generally used to determine | |||||
# why a program aborted. It can also be used to glean confidential information from a core | |||||
# file. The system provides the ability to set a soft limit for core dumps, but this can be | |||||
# overridden by the user. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# | |||||
# Setting a hard limit on core dumps prevents users from overriding the soft variable. If core | |||||
# dumps are required, consider setting limits for user groups (see limits.conf(5) ). In | |||||
# addition, setting the fs.suid_dumpable variable to 0 will prevent setuid programs from | |||||
# dumping core. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # grep "hard core" /etc/security/limits.conf /etc/security/limits.d/* | |||||
# * hard core 0 | |||||
# # sysctl fs.suid_dumpable | |||||
# fs.suid_dumpable = 0 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Add the following line to the /etc/security/limits.conf file or a | |||||
# /etc/security/limits.d/* file: | |||||
# | |||||
# * hard core 0 | |||||
# | |||||
# Set the following parameter in the /etc/sysctl.conf file: | |||||
# | |||||
# fs.suid_dumpable = 0 | |||||
# | |||||
# Run the following command to set the active kernel parameter: | |||||
# | |||||
# # sysctl -w fs.suid_dumpable=0 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
limit: | |||||
cis: | |||||
enabled: true | |||||
domain: '*' | |||||
limits: | |||||
- type: 'hard' | |||||
item: 'core' | |||||
value: 0 | |||||
kernel: | |||||
sysctl: | |||||
fs.suid_dumpable: 0 | |||||
# 1.5.3 Ensure address space layout randomization (ASLR) is enabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# | |||||
# Address space layout randomization (ASLR) is an exploit mitigation technique which | |||||
# randomly arranges the address space of key data areas of a process. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# | |||||
# Randomly placing virtual memory regions will make it difficult to write memory page | |||||
# exploits as the memory placement will be consistently shifting. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following command and verify output matches: | |||||
# | |||||
# # sysctl kernel.randomize_va_space | |||||
# kernel.randomize_va_space = 2 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameter in the /etc/sysctl.conf file: | |||||
# | |||||
# kernel.randomize_va_space = 2 | |||||
# | |||||
# Run the following command to set the active kernel parameter: | |||||
# | |||||
# # sysctl -w kernel.randomize_va_space=2 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
kernel.randomize_va_space: 2 | |||||
# CIS 1.5.4 Ensure prelink is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# prelink is a program that modifies ELF shared libraries and ELF dynamically | |||||
# linked binaries in such a way that the time needed for the dynamic linker to | |||||
# perform relocations at startup significantly decreases. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# The prelinking feature can interfere with the operation of AIDE, because it | |||||
# changes binaries. Prelinking can also increase the vulnerability of the system | |||||
# if a malicious user is able to compromise a common library such as libc. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify prelink is not installed: | |||||
# | |||||
# # dpkg -s prelink | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Run the following command to restore binaries to normal: | |||||
# | |||||
# # prelink -ua | |||||
# | |||||
# Run the following command to uninstall prelink : | |||||
# | |||||
# # apt-get remove prelink | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
package: | |||||
prelink: | |||||
version: removed | |||||
# 2.3.1 Ensure NIS Client is not installed | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The Network Information Service (NIS), formerly known as Yellow Pages, | |||||
# is a client-server directory service protocol used to distribute system | |||||
# configuration files. The NIS client ( ypbind ) was used to bind a machine | |||||
# to an NIS server and receive the distributed configuration files. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# The NIS service is inherently an insecure system that has been vulnerable | |||||
# to DOS attacks, buffer overflows and has poor authentication for querying | |||||
# NIS maps. NIS generally has been replaced by such protocols as Lightweight | |||||
# Directory Access Protocol (LDAP). It is recommended that the service be | |||||
# removed. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify nis is not installed: | |||||
# | |||||
# dpkg -s nis | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Run the following command to uninstall nis: | |||||
# | |||||
# apt-get remove nis | |||||
# | |||||
# Impact | |||||
# ====== | |||||
# Many insecure service clients are used as troubleshooting tools and in | |||||
# testing environments. Uninstalling them can inhibit capability to test | |||||
# and troubleshoot. If they are required it is advisable to remove the clients | |||||
# after use to prevent accidental or intentional misuse. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
package: | |||||
nis: | |||||
version: removed | |||||
# 2.3.2 Ensure rsh client is not installed | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The rsh package contains the client commands for the rsh services. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# These legacy clients contain numerous security exposures and have been | |||||
# replaced with the more secure SSH package. Even if the server is removed, | |||||
# it is best to ensure the clients are also removed to prevent users from | |||||
# inadvertently attempting to use these commands and therefore exposing | |||||
# their credentials. Note that removing the rsh package removes the | |||||
# clients for rsh , rcp and rlogin . | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify rsh is not installed: | |||||
# | |||||
# dpkg -s rsh-client | |||||
# dpkg -s rsh-redone-client | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Run the following command to uninstall rsh : | |||||
# | |||||
# apt-get remove rsh-client rsh-redone-client | |||||
# | |||||
# Impact | |||||
# ====== | |||||
# Many insecure service clients are used as troubleshooting tools and in | |||||
# testing environments. Uninstalling them can inhibit capability to test | |||||
# and troubleshoot. If they are required it is advisable to remove the | |||||
# clients after use to prevent accidental or intentional misuse. | |||||
# | |||||
# NOTE | |||||
# ==== | |||||
# It is not possible to remove rsh-client by means of SaltStack because | |||||
# of the way SaltStack checks that package was really removed. 'rsh-client' | |||||
# is "provided" by openssh-client package, and SaltStack thinks that | |||||
# it is the same as 'rsh-client is installed'. So each time we try to | |||||
# remove 'rsh-client' on a system where 'openssh-client' is installed | |||||
# (that's almost every system), we got state failure. | |||||
# This was fixed in upstream SaltStack in 2018, not sure where we start using | |||||
# this version. Until that moment 'rsh-client' should remain unmanaged. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
package: | |||||
# rsh-client: | |||||
# version: removed | |||||
rsh-redone-client: | |||||
version: removed | |||||
# 2.3.3 Ensure talk client is not installed | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The talk software makes it possible for users to send and receive messages | |||||
# across systems through a terminal session. The talk client, which allows | |||||
# initialization of talk sessions, is installed by default. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# The software presents a security risk as it uses unencrypted protocols | |||||
# for communication. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify talk is not installed: | |||||
# | |||||
# dpkg -s talk | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Run the following command to uninstall talk : | |||||
# | |||||
# apt-get remove talk | |||||
# | |||||
# Impact | |||||
# ====== | |||||
# Many insecure service clients are used as troubleshooting tools and in | |||||
# testing environments. Uninstalling them can inhibit capability to test | |||||
# and troubleshoot. If they are required it is advisable to remove the clients | |||||
# after use to prevent accidental or intentional misuse. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
package: | |||||
talk: | |||||
version: removed | |||||
# 2.3.4 Ensure telnet client is not installed | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The telnet package contains the telnet client, which allows users to start | |||||
# connections to other systems via the telnet protocol. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# The telnet protocol is insecure and unencrypted. The use of an unencrypted | |||||
# transmission medium could allow an unauthorized user to steal credentials. | |||||
# The ssh package provides an encrypted session and stronger security and is | |||||
# included in most Linux distributions. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify telnet is not installed: | |||||
# | |||||
# # dpkg -s telnet | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Run the following command to uninstall telnet : | |||||
# | |||||
# # apt-get remove telnet | |||||
# | |||||
# Impact | |||||
# ====== | |||||
# Many insecure service clients are used as troubleshooting tools and in | |||||
# testing environments. Uninstalling them can inhibit capability to test and | |||||
# troubleshoot. If they are required it is advisable to remove the clients | |||||
# after use to prevent accidental or intentional misuse. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
package: | |||||
telnet: | |||||
version: removed | |||||
# 3.1.2 Ensure packet redirect sending is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# ICMP Redirects are used to send routing information to other hosts. As a host | |||||
# itself does not act as a router (in a host only configuration), there is | |||||
# no need to send redirects. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# An attacker could use a compromised host to send invalid ICMP redirects to | |||||
# other router devices in an attempt to corrupt routing and have users access | |||||
# a system set up by the attacker as opposed to a valid system. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.conf.all.send_redirects | |||||
# net.ipv4.conf.all.send_redirects = 0 | |||||
# # sysctl net.ipv4.conf.default.send_redirects | |||||
# net.ipv4.conf.default.send_redirects = 0 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameters in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.conf.all.send_redirects = 0 | |||||
# net.ipv4.conf.default.send_redirects = 0 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.conf.all.send_redirects=0 | |||||
# # sysctl -w net.ipv4.conf.default.send_red | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.conf.all.send_redirects: 0 | |||||
net.ipv4.conf.default.send_redirects: 0 |
# 3.2.1 Ensure source routed packets are not accepted | |||||
# | |||||
# Description | |||||
# =========== | |||||
# In networking, source routing allows a sender to partially or fully specify | |||||
# the route packets take through a network. In contrast, non-source routed | |||||
# packets travel a path determined by routers in the network. In some cases, | |||||
# systems may not be routable or reachable from some locations (e.g. private | |||||
# addresses vs. Internet routable), and so source routed packets would need | |||||
# to be used. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Setting `net.ipv4.conf.all.accept_source_route` and | |||||
# `net.ipv4.conf.default.accept_source_route` to 0 disables the system from | |||||
# accepting source routed packets. Assume this system was capable of routing | |||||
# packets to Internet routable addresses on one interface and private addresses | |||||
# on another interface. Assume that the private addresses were not routable to | |||||
# the Internet routable addresses and vice versa. Under normal routing | |||||
# circumstances, an attacker from the Internet routable addresses could not use | |||||
# the system as a way to reach the private address systems. If, however, source | |||||
# routed packets were allowed, they could be used to gain access to the private | |||||
# address systems as the route could be specified, rather than rely on routing | |||||
# protocols that did not allow this routing. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.conf.all.accept_source_route | |||||
# net.ipv4.conf.all.accept_source_route = 0 | |||||
# # sysctl net.ipv4.conf.default.accept_source_route | |||||
# net.ipv4.conf.default.accept_source_route = 0 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameters in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.conf.all.accept_source_route = 0 | |||||
# net.ipv4.conf.default.accept_source_route = 0 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.conf.all.accept_source_route=0 | |||||
# # sysctl -w net.ipv4.conf.default.accept_source_route=0 | |||||
# # sysctl -w net.ipv4.route.flush=1 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.conf.all.accept_source_route: 0 | |||||
net.ipv4.conf.default.accept_source_route: 0 |
# 3.2.2 Ensure ICMP redirects are not accepted | |||||
# | |||||
# Description | |||||
# =========== | |||||
# ICMP redirect messages are packets that convey routing information and tell | |||||
# your host (acting as a router) to send packets via an alternate path. It is | |||||
# a way of allowing an outside routing device to update your system routing | |||||
# tables. By setting net.ipv4.conf.all.accept_redirects to 0, the system will | |||||
# not accept any ICMP redirect messages, and therefore, won't allow outsiders | |||||
# to update the system's routing tables. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Attackers could use bogus ICMP redirect messages to maliciously alter the | |||||
# system routing tables and get them to send packets to incorrect networks and | |||||
# allow your system packets to be captured. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.conf.all.accept_redirects | |||||
# net.ipv4.conf.all.accept_redirects = 0 | |||||
# # sysctl net.ipv4.conf.default.accept_redirects | |||||
# net.ipv4.conf.default.accept_redirects = 0 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameters in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.conf.all.accept_redirects = 0 | |||||
# net.ipv4.conf.default.accept_redirects = 0 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.conf.all.accept_redirects=0 | |||||
# # sysctl -w net.ipv4.conf.default.accept_redirects=0 | |||||
# # sysctl -w net.ipv4.route.flush=1 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.conf.all.accept_redirects: 0 | |||||
net.ipv4.conf.default.accept_redirects: 0 |
# 3.2.3 Ensure secure ICMP redirects are not accepted | |||||
# | |||||
# Description | |||||
# =========== | |||||
# Secure ICMP redirects are the same as ICMP redirects, except they come from | |||||
# gateways listed on the default gateway list. It is assumed that these | |||||
# gateways are known to your system, and that they are likely to be secure. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# It is still possible for even known gateways to be compromised. Setting | |||||
# net.ipv4.conf.all.secure_redirects to 0 protects the system from routing | |||||
# table updates by possibly compromised known gateways. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.conf.all.secure_redirects | |||||
# net.ipv4.conf.all.secure_redirects = 0 | |||||
# # sysctl net.ipv4.conf.default.secure_redirects | |||||
# net.ipv4.conf.default.secure_redirects = 0 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameters in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.conf.all.secure_redirects = 0 | |||||
# net.ipv4.conf.default.secure_redirects = 0 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.conf.all.secure_redirects=0 | |||||
# # sysctl -w net.ipv4.conf.default.secure_redirects=0 | |||||
# # sysctl -w net.ipv4.route.flush=1 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.conf.all.secure_redirects: 0 | |||||
net.ipv4.conf.default.secure_redirects: 0 |
# 3.2.4 Ensure suspicious packets are logged | |||||
# | |||||
# Description | |||||
# =========== | |||||
# When enabled, this feature logs packets with un-routable source | |||||
# addresses to the kernel log. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Enabling this feature and logging these packets allows an administrator | |||||
# to investigate the possibility that an attacker is sending spoofed | |||||
# packets to their system. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.conf.all.log_martians | |||||
# net.ipv4.conf.all.log_martians = 1 | |||||
# # sysctl net.ipv4.conf.default.log_martians | |||||
# net.ipv4.conf.default.log_martians = 1 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameters in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.conf.all.log_martians = 1 | |||||
# net.ipv4.conf.default.log_martians = 1 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.conf.all.log_martians=1 | |||||
# # sysctl -w net.ipv4.conf.default.log_martians=1 | |||||
# # sysctl -w net.ipv4.route.flush=1 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.conf.all.log_martians: 1 | |||||
net.ipv4.conf.default.log_martians: 1 |
# 3.2.5 Ensure broadcast ICMP requests are ignored | |||||
# | |||||
# Description | |||||
# =========== | |||||
# Setting net.ipv4.icmp_echo_ignore_broadcasts to 1 will cause the | |||||
# system to ignore all ICMP echo and timestamp requests to broadcast | |||||
# and multicast addresses. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Accepting ICMP echo and timestamp requests with broadcast or multicast | |||||
# destinations for your network could be used to trick your host into starting | |||||
# (or participating) in a Smurf attack. A Smurf attack relies on an attacker | |||||
# sending large amounts of ICMP broadcast messages with a spoofed source | |||||
# address. All hosts receiving this message and responding would send | |||||
# echo-reply messages back to the spoofed address, which is probably not | |||||
# routable. If many hosts respond to the packets, the amount of traffic on | |||||
# the network could be significantly multiplied. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.icmp_echo_ignore_broadcasts | |||||
# net.ipv4.icmp_echo_ignore_broadcasts = 1 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameter in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.icmp_echo_ignore_broadcasts = 1 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 | |||||
# # sysctl -w net.ipv4.route.flush=1 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.icmp_echo_ignore_broadcasts: 1 |
# 3.2.6 Ensure bogus ICMP responses are ignored | |||||
# | |||||
# Description | |||||
# =========== | |||||
# Setting icmp_ignore_bogus_error_responses to 1 prevents the kernel from | |||||
# logging bogus responses (RFC-1122 non-compliant) from broadcast reframes, | |||||
# keeping file systems from filling up with useless log messages. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Some routers (and some attackers) will send responses that violate RFC-1122 | |||||
# and attempt to fill up a log file system with many useless error messages. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.icmp_ignore_bogus_error_responses | |||||
# net.ipv4.icmp_ignore_bogus_error_responses = 1 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameter in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.icmp_ignore_bogus_error_responses = 1 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1 | |||||
# # sysctl -w net.ipv4.route.flush=1 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.icmp_ignore_bogus_error_responses: 1 |
# 3.2.7 Ensure Reverse Path Filtering is enabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# Setting net.ipv4.conf.all.rp_filter and net.ipv4.conf.default.rp_filter to 1 | |||||
# forces the Linux kernel to utilize reverse path filtering on a received | |||||
# packet to determine if the packet was valid. Essentially, with reverse path | |||||
# filtering, if the return packet does not go out the same interface that the | |||||
# corresponding source packet came from, the packet is dropped (and logged if | |||||
# log_martians is set). | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Setting these flags is a good way to deter attackers from sending your system | |||||
# bogus packets that cannot be responded to. One instance where this feature | |||||
# breaks down is if asymmetrical routing is employed. This would occur when | |||||
# using dynamic routing protocols (bgp, ospf, etc) on your system. If you are | |||||
# using asymmetrical routing on your system, you will not be able to enable | |||||
# this feature without breaking the routing. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.conf.all.rp_filter | |||||
# net.ipv4.conf.all.rp_filter = 1 | |||||
# # sysctl net.ipv4.conf.default.rp_filter | |||||
# net.ipv4.conf.default.rp_filter = 1 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameters in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.conf.all.rp_filter = 1 | |||||
# net.ipv4.conf.default.rp_filter = 1 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.conf.all.rp_filter=1 | |||||
# # sysctl -w net.ipv4.conf.default.rp_filter=1 | |||||
# # sysctl -w net.ipv4.route.flush=1 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.conf.all.rp_filter: 1 | |||||
net.ipv4.conf.default.rp_filter: 1 |
# 3.2.8 Ensure TCP SYN Cookies is enabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# When tcp_syncookies is set, the kernel will handle TCP SYN packets normally | |||||
# until the half-open connection queue is full, at which time, the SYN cookie | |||||
# functionality kicks in. SYN cookies work by not using the SYN queue at all. | |||||
# Instead, the kernel simply replies to the SYN with a SYN|ACK, but will | |||||
# include a specially crafted TCP sequence number that encodes the source and | |||||
# destination IP address and port number and the time the packet was sent. | |||||
# A legitimate connection would send the ACK packet of the three way handshake | |||||
# with the specially crafted sequence number. This allows the system to verify | |||||
# that it has received a valid response to a SYN cookie and allow the | |||||
# connection, even though there is no corresponding SYN in the queue. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Attackers use SYN flood attacks to perform a denial of service attacked on a | |||||
# system by sending many SYN packets without completing the three way handshake. | |||||
# This will quickly use up slots in the kernel's half-open connection queue and | |||||
# prevent legitimate connections from succeeding. SYN cookies allow the system | |||||
# to keep accepting valid connections, even if under a denial of service attack. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# | |||||
# Run the following commands and verify output matches: | |||||
# | |||||
# # sysctl net.ipv4.tcp_syncookies | |||||
# net.ipv4.tcp_syncookies = 1 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the following parameter in the /etc/sysctl.conf file: | |||||
# | |||||
# net.ipv4.tcp_syncookies = 1 | |||||
# | |||||
# Run the following commands to set the active kernel parameters: | |||||
# | |||||
# # sysctl -w net.ipv4.tcp_syncookies=1 | |||||
# # sysctl -w net.ipv4.route.flush=1 | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
sysctl: | |||||
net.ipv4.tcp_syncookies: 1 |
# CIS 3.3.3 Ensure IPv6 is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# Although IPv6 has many advantages over IPv4, few organizations have | |||||
# implemented IPv6. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# If IPv6 is not to be used, it is recommended that it be disabled to | |||||
# reduce the attack surface of the system. | |||||
# | |||||
# Audit | |||||
# ====== | |||||
# Run the following command and verify that each linux line has | |||||
# the 'ipv6.disable=1' parameter set: | |||||
# | |||||
# # grep "^\s*linux" /boot/grub/grub.cfg | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit /etc/default/grub and add 'ipv6.disable=1' to GRUB_CMDLINE_LINUX: | |||||
# | |||||
# GRUB_CMDLINE_LINUX="ipv6.disable=1" | |||||
# | |||||
# Run the following command to update the grub2 configuration: | |||||
# | |||||
# # update-grub | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
boot_options: | |||||
- ipv6.disable=1 |
# 3.5.2 Ensure DCCP is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The Datagram Congestion Control Protocol (DCCP) is a transport layer protocol | |||||
# that supports streaming media and telephony. DCCP provides a way to gain | |||||
# access to congestion control, without having to do it at the application | |||||
# layer, but does not provide in-sequence delivery. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# If the protocol is not required, it is recommended that the drivers not be | |||||
# installed to reduce the potential attack surface. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v dccp | |||||
# install /bin/true | |||||
# # lsmod | grep dccp | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install dccp /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
dccp: | |||||
install: | |||||
command: /bin/true | |||||
# 3.5.2 Ensure SCTP is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The Stream Control Transmission Protocol (SCTP) is a transport layer | |||||
# protocol used to support message oriented communication, with several | |||||
# streams of messages in one connection. It serves a similar function as | |||||
# TCP and UDP, incorporating features of both. It is message-oriented | |||||
# like UDP, and ensures reliable in-sequence transport of messages with | |||||
# congestion control like TCP. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# If the protocol is not being used, it is recommended that kernel module | |||||
# not be loaded, disabling the service to reduce the potential attack surface. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v sctp | |||||
# install /bin/true | |||||
# # lsmod | grep sctp | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install sctp /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
sctp: | |||||
install: | |||||
command: /bin/true | |||||
# 3.5.3 Ensure RDS is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The Reliable Datagram Sockets (RDS) protocol is a transport layer protocol | |||||
# designed to provide low-latency, high-bandwidth communications between | |||||
# cluster nodes. It was developed by the Oracle Corporation. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# If the protocol is not being used, it is recommended that kernel module | |||||
# not be loaded, disabling the service to reduce the potential attack surface. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v rds | |||||
# install /bin/true | |||||
# # lsmod | grep rds | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install rds /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
rds: | |||||
install: | |||||
command: /bin/true | |||||
# 3.5.4 Ensure TIPC is disabled | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The Transparent Inter-Process Communication (TIPC) protocol is designed | |||||
# to provide communication between cluster nodes. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# If the protocol is not being used, it is recommended that kernel module | |||||
# not be loaded, disabling the service to reduce the potential attack surface. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following commands and verify the output is as indicated: | |||||
# | |||||
# # modprobe -n -v tipc | |||||
# install /bin/true | |||||
# # lsmod | grep tipc | |||||
# <No output> | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: | |||||
# | |||||
# install tipc /bin/true | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
kernel: | |||||
module: | |||||
tipc: | |||||
install: | |||||
command: /bin/true | |||||
# CIS 5.4.1.1 Ensure password expiration is 90 days or less (Scored) | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The PASS_MAX_DAYS parameter in /etc/login.defs allows an administrator to | |||||
# force passwords to expire once they reach a defined age. It is recommended | |||||
# that the PASS_MAX_DAYS parameter be set to less than or equal to 90 days. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# The window of opportunity for an attacker to leverage compromised credentials | |||||
# or successfully compromise credentials via an online brute force attack is | |||||
# limited by the age of the password. Therefore, reducing the maximum age of a | |||||
# password also reduces an attacker's window of opportunity. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify PASS_MAX_DAYS is 90 or less: | |||||
# | |||||
# # grep PASS_MAX_DAYS /etc/login.defs | |||||
# PASS_MAX_DAYS 90 | |||||
# | |||||
# Verify all users with a password have their maximum days between password | |||||
# change set to 90 or less: | |||||
# | |||||
# # egrep ^[^:]+:[^\!*] /etc/shadow | cut -d: -f1 | |||||
# <list of users> | |||||
# # chage --list <user> | |||||
# Maximum number of days between password change: 90 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Set the PASS_MAX_DAYS parameter to 90 in /etc/login.defs : | |||||
# | |||||
# PASS_MAX_DAYS 90 | |||||
# | |||||
# Modify user parameters for all users with a password set to match: | |||||
# | |||||
# # chage --maxdays 90 <user> | |||||
# | |||||
# Notes | |||||
# ===== | |||||
# You can also check this setting in /etc/shadow directly. The 5th field | |||||
# should be 90 or less for all users with a password. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
login_defs: | |||||
PASS_MAX_DAYS: | |||||
value: 90 | |||||
# CIS 5.4.1.2 Ensure minimum days between password changes is 7 or more (Scored) | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The PASS_MIN_DAYS parameter in /etc/login.defs allows an administrator to | |||||
# prevent users from changing their password until a minimum number of days | |||||
# have passed since the last time the user changed their password. It is | |||||
# recommended that PASS_MIN_DAYS parameter be set to 7 or more days. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# By restricting the frequency of password changes, an administrator can | |||||
# prevent users from repeatedly changing their password in an attempt to | |||||
# circumvent password reuse controls. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify PASS_MIN_DAYS is 7 or more: | |||||
# | |||||
# # grep PASS_MIN_DAYS /etc/login.defs | |||||
# PASS_MIN_DAYS 7 | |||||
# | |||||
# Verify all users with a password have their minimum days between password | |||||
# change set to 7 or more: | |||||
# | |||||
# # egrep ^[^:]+:[^\!*] /etc/shadow | cut -d: -f1 | |||||
# <list of users> | |||||
# # chage --list <user> | |||||
# Minimum number of days between password change: 7 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# Set the PASS_MIN_DAYS parameter to 7 in /etc/login.defs : | |||||
# | |||||
# PASS_MIN_DAYS 7 | |||||
# | |||||
# Modify user parameters for all users with a password set to match: | |||||
# | |||||
# # chage --mindays 7 <user> | |||||
# | |||||
# Notes | |||||
# ===== | |||||
# You can also check this setting in /etc/shadow directly. The 5th field | |||||
# should be 7 or more for all users with a password. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
login_defs: | |||||
PASS_MIN_DAYS: | |||||
value: 7 | |||||
# CIS 5.4.1.3 Ensure password expiration warning days is 7 or more (Scored) | |||||
# | |||||
# Description | |||||
# =========== | |||||
# The PASS_WARN_AGE parameter in /etc/login.defs allows an administrator to | |||||
# notify users that their password will expire in a defined number of days. | |||||
# It is recommended that the PASS_WARN_AGE parameter be set to 7 or more days. | |||||
# | |||||
# Rationale | |||||
# ========= | |||||
# Providing an advance warning that a password will be expiring gives users | |||||
# time to think of a secure password. Users caught unaware may choose a simple | |||||
# password or write it down where it may be discovered. | |||||
# | |||||
# Audit | |||||
# ===== | |||||
# Run the following command and verify PASS_WARN_AGE is 7 or more: | |||||
# | |||||
# # grep PASS_WARN_AGE /etc/login.defs | |||||
# PASS_WARN_AGE 7 | |||||
# | |||||
# Verify all users with a password have their number of days of warning before | |||||
# password expires set to 7 or more: | |||||
# | |||||
# # egrep ^[^:]+:[^\!*] /etc/shadow | cut -d: -f1 | |||||
# <list of users> | |||||
# # chage --list <user> | |||||
# Number of days of warning before password expires: 7 | |||||
# | |||||
# Remediation | |||||
# =========== | |||||
# | |||||
# Set the PASS_WARN_AGE parameter to 7 in /etc/login.defs : | |||||
# | |||||
# PASS_WARN_AGE 7 | |||||
# | |||||
# Modify user parameters for all users with a password set to match: | |||||
# | |||||
# # chage --warndays 7 <user> | |||||
# | |||||
# Notes | |||||
# ===== | |||||
# You can also check this setting in /etc/shadow directly. The 6th field | |||||
# should be 7 or more for all users with a password. | |||||
# | |||||
parameters: | |||||
linux: | |||||
system: | |||||
login_defs: | |||||
PASS_WARN_AGE: | |||||
value: 7 | |||||