Merge "Fix obsolete parameter."
diff --git a/.gitignore b/.gitignore
index aa8e42a..cc3ab8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,8 @@
.kitchen
+.bundle
+bundle/
tests/build/
*.swp
*.pyc
.ropeproject
+Gemfile*
diff --git a/.kitchen.yml b/.kitchen.yml
index 51d6a26..dce7fe2 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -63,4 +63,17 @@
pillars-from-files:
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
diff --git a/.travis.yml b/.travis.yml
index 78246a5..dce83af 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,6 @@
+language: python
+python:
+- "2.7.13"
sudo: required
services:
- docker
@@ -17,7 +20,8 @@
gem 'test-kitchen'
gem 'kitchen-docker'
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'
- bundle install
@@ -28,6 +32,7 @@
- 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
diff --git a/README.rst b/README.rst
index 50e1b13..79b8b18 100644
--- a/README.rst
+++ b/README.rst
@@ -50,6 +50,7 @@
home: '/home/jdoe'
home_dir_mode: 755
email: 'jonh@doe.com'
+ unique: false
jsmith:
name: 'jsmith'
enabled: true
@@ -70,6 +71,30 @@
home: '/home/elizabeth'
password: "$6$nUI7QEz3$dFYjzQqK5cJ6HQ38KqG4gTWA9eJu3aKx6TRVDFh6BVJxJgFWg2akfAA7f1fCxcSUeOJ2arCO6EEI6XXnHXxG10"
+Configure password expiration parameters
+----------------------------------------
+The following login.defs parameters can be overridden per-user:
+
+* PASS_MAX_DAYS
+* PASS_MIN_DAYS
+* PASS_WARN_DAYS
+* INACTIVE
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ ...
+ user:
+ jdoe:
+ name: 'jdoe'
+ enabled: true
+ ...
+ maxdays: <PASS_MAX_DAYS>
+ mindays: <PASS_MIN_DAYS>
+ warndays: <PASS_WARN_DAYS>
+ inactdays: <INACTIVE>
+
Configure sudo for users and groups under ``/etc/sudoers.d/``.
This ways ``linux.system.sudo`` pillar map to actual sudo attributes:
@@ -442,6 +467,14 @@
name: /tmp/test.txt
source: http://example.com/test.txt
+ linux:
+ system:
+ file:
+ test2:
+ name: /tmp/test2.txt
+ source: http://example.com/test2.jinja
+ template: jinja
+
Ensure presence of file by specifying its contents:
.. code-block:: yaml
@@ -805,6 +838,22 @@
power/state: "root:power"
- devices/system/cpu/cpu0/cpufreq/scaling_governor: powersave
+Sysfs definition with disabled automatic write. Attributes are saved
+to configuration, but are not applied during the run.
+Thay will be applied automatically after the reboot.
+
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ sysfs:
+ enable_apply: false
+ scheduler:
+ block/sda/queue/scheduler: deadline
+
+.. note:: The `enable_apply` parameter defaults to `True` if not defined.
+
Huge Pages
~~~~~~~~~~~~
@@ -902,6 +951,31 @@
priority: 900
package: '*'
+If you need to add multiple pin rules for one repo, please use new,ordered definition format
+('pinning' definition will be in priotity to use):
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ repo:
+ mcp_saltstack:
+ source: "deb [arch=amd64] http://repo.saltstack.com/apt/ubuntu/16.04/amd64/2017.7/ xenial main"
+ architectures: amd64
+ clean_file: true
+ pinning:
+ 10:
+ enabled: true
+ pin: 'release o=SaltStack'
+ priority: 50
+ package: 'libsodium18'
+ 20:
+ enabled: true
+ pin: 'release o=SaltStack'
+ priority: 1100
+ package: '*'
+
+
.. note:: For old Ubuntu releases (<xenial)
extra packages for apt transport, like ``apt-transport-https``
may be required to be installed manually.
@@ -1218,6 +1292,13 @@
enabled: true
network_manager: true
+Execute linux.network.interface state without ifupdown activity:
+
+.. code-block:: bash
+
+ salt-call linux.network.interface pillar='{"linux":{"network":{"noifupdown":True}}}'
+
+
Linux with default static network interfaces, default gateway
interface and DNS servers:
@@ -1629,6 +1710,23 @@
export FTP_PROXY=ftp://127.0.3.3:2121
export NO_PROXY='.local'
+
+Configure login.defs parameters
+-------------------------------
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ login_defs:
+ <opt_name>:
+ enabled: true
+ value: <opt_value>
+
+<opt_name> is a configurational option defined in 'man login.defs'.
+<opt_name> is case sensitive, should be UPPERCASE only!
+
+
Linux with hosts
Parameter ``purge_hosts`` will enforce whole ``/etc/hosts file``,
@@ -2077,6 +2175,31 @@
shadow: (&(&(objectClass=person)(uidNumber=*))(unixHomeDirectory=*))
group: (&(objectClass=group)(gidNumber=*))
+PAM duo 2FA integration
+
+.. code-block:: yaml
+
+ parameters:
+ linux:
+ system:
+ auth:
+ enabled: true
+ duo:
+ enabled: true
+ duo_host: localhost
+ duo_ikey: DUO-INTEGRATION-KEY
+ duo_skey: DUO-SECRET-KEY
+
+duo package version may be specified (optional)
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ package:
+ duo-unix:
+ version: 1.10.1-0
+
Disabled multipath (the default setup):
.. code-block:: yaml
@@ -2153,6 +2276,240 @@
interface: bond0
mac: "ff:ff:ff:ff:ff:ff" (optional)
+Check network params on the environment
+---------------------------------------
+
+Grab nics and nics states
+
+.. code-block:: bash
+
+ salt osd001\* net_checks.get_nics
+
+**Example of system output:**
+
+.. code-block:: bash
+
+ osd001.domain.com:
+ |_
+ - bond0
+ - None
+ - 1e:c8:64:42:23:b9
+ - 0
+ - 1500
+ |_
+ - bond1
+ - None
+ - 3c:fd:fe:27:3b:00
+ - 1
+ - 9100
+ |_
+ - fourty1
+ - None
+ - 3c:fd:fe:27:3b:00
+ - 1
+ - 9100
+ |_
+ - fourty2
+ - None
+ - 3c:fd:fe:27:3b:02
+ - 1
+ - 9100
+
+Grab 10G nics PCI addresses for hugepages setup
+
+.. code-block:: bash
+
+ salt cmp001\* net_checks.get_ten_pci
+
+**Example of system output:**
+
+.. code-block:: bash
+
+ cmp001.domain.com:
+ |_
+ - ten1
+ - 0000:19:00.0
+ |_
+ - ten2
+ - 0000:19:00.1
+ |_
+ - ten3
+ - 0000:19:00.2
+ |_
+ - ten4
+ - 0000:19:00.3
+
+Grab ip address for an interface
+
+.. code-block:: bash
+
+ salt cmp001\* net_checks.get_ip iface=one4
+
+**Example of system output:**
+
+.. code-block:: bash
+
+ cmp001.domain.com:
+ 10.200.177.101
+
+Grab ip addresses map
+
+.. code-block:: bash
+
+ salt-call net_checks.nodes_addresses
+
+**Example of system output:**
+
+.. code-block:: bash
+
+ local:
+ |_
+ - cid01.domain.com
+ |_
+ |_
+ - pxe
+ - 10.200.177.91
+ |_
+ - control
+ - 10.200.178.91
+ |_
+ - cmn02.domain.com
+ |_
+ |_
+ - storage_access
+ - 10.200.181.67
+ |_
+ - pxe
+ - 10.200.177.67
+ |_
+ - control
+ - 10.200.178.67
+ |_
+ - cmp010.domain.com
+ |_
+ |_
+ - pxe
+ - 10.200.177.110
+ |_
+ - storage_access
+ - 10.200.181.110
+ |_
+ - control
+ - 10.200.178.110
+ |_
+ - vxlan
+ - 10.200.179.110
+
+Verify full mesh connectivity
+
+.. code-block:: bash
+
+ salt-call net_checks.ping_check
+
+**Example of positive system output:**
+
+.. code-block:: bash
+
+ ['PASSED']
+ [INFO ] ['PASSED']
+ local:
+ True
+
+**Example of system output in case of failure:**
+
+.. code-block:: bash
+
+ FAILED
+ [ERROR ] FAILED
+ ['control: 10.0.1.92 -> 10.0.1.224: Failed']
+ ['control: 10.0.1.93 -> 10.0.1.224: Failed']
+ ['control: 10.0.1.51 -> 10.0.1.224: Failed']
+ ['control: 10.0.1.102 -> 10.0.1.224: Failed']
+ ['control: 10.0.1.13 -> 10.0.1.224: Failed']
+ ['control: 10.0.1.81 -> 10.0.1.224: Failed']
+ local:
+ False
+
+For this feature to work, please mark addresses with some role.
+Otherwise 'default' role is assumed and mesh would consist of all
+addresses on the environment.
+
+Mesh mark is needed only for interfaces which are enabled and have
+ip address assigned.
+
+Checking dhcp pxe network meaningless, as it is used for salt
+master vs minion communications, therefore treated as checked.
+
+.. code-block:: yaml
+
+ parameters:
+ linux:
+ network:
+ interface:
+ ens3:
+ enabled: true
+ type: eth
+ proto: static
+ address: ${_param:deploy_address}
+ netmask: ${_param:deploy_network_netmask}
+ gateway: ${_param:deploy_network_gateway}
+ mesh: pxe
+
+Check pillars for ip address duplicates
+
+.. code-block:: bash
+
+ salt-call net_checks.verify_addresses
+
+**Example of positive system output:**
+
+.. code-block:: bash
+
+ ['PASSED']
+ [INFO ] ['PASSED']
+ local:
+ True
+
+**Example of system output in case of failure:**
+
+.. code-block:: bash
+
+ FAILED. Duplicates found
+ [ERROR ] FAILED. Duplicates found
+ ['gtw01.domain.com', 'gtw02.domain.com', '10.0.1.224']
+ [ERROR ] ['gtw01.domain.com', 'gtw02.domain.com', '10.0.1.224']
+ local:
+ False
+
+Generate csv report for the env
+
+.. code-block:: bash
+
+ salt -C 'kvm* or cmp* or osd*' net_checks.get_nics_csv \
+ | grep '^\ ' | sed 's/\ *//g' | grep -Ev ^server \
+ | sed '1 i\server,nic_name,ip_addr,mac_addr,link,mtu,chassis_id,chassis_name,port_mac,port_descr'
+
+**Example of system output:**
+
+.. code-block:: bash
+
+ server,nic_name,ip_addr,mac_addr,link,mtu,chassis_id,chassis_name,port_mac,port_descr
+ cmp010.domain.com,bond0,None,b4:96:91:10:5b:3a,1,1500,,,,
+ cmp010.domain.com,bond0.21,10.200.178.110,b4:96:91:10:5b:3a,1,1500,,,,
+ cmp010.domain.com,bond0.22,10.200.179.110,b4:96:91:10:5b:3a,1,1500,,,,
+ cmp010.domain.com,bond1,None,3c:fd:fe:34:ad:22,0,1500,,,,
+ cmp010.domain.com,bond1.24,10.200.181.110,3c:fd:fe:34:ad:22,0,1500,,,,
+ cmp010.domain.com,fourty5,None,3c:fd:fe:34:ad:20,0,9000,,,,
+ cmp010.domain.com,fourty6,None,3c:fd:fe:34:ad:22,0,9000,,,,
+ cmp010.domain.com,one1,None,b4:96:91:10:5b:38,0,1500,,,,
+ cmp010.domain.com,one2,None,b4:96:91:10:5b:39,1,1500,f0:4b:3a:8f:75:40,exnfvaa18-20,548,ge-0/0/22
+ cmp010.domain.com,one3,None,b4:96:91:10:5b:3a,1,1500,f0:4b:3a:8f:75:40,exnfvaa18-20,547,ge-0/0/21
+ cmp010.domain.com,one4,10.200.177.110,b4:96:91:10:5b:3b,1,1500,f0:4b:3a:8f:75:40,exnfvaa18-20,546,ge-0/0/20
+ cmp011.domain.com,bond0,None,b4:96:91:13:6c:aa,1,1500,,,,
+ cmp011.domain.com,bond0.21,10.200.178.111,b4:96:91:13:6c:aa,1,1500,,,,
+ cmp011.domain.com,bond0.22,10.200.179.111,b4:96:91:13:6c:aa,1,1500,,,,
+ ...
+
Usage
=====
diff --git a/_modules/net_checks.py b/_modules/net_checks.py
new file mode 100644
index 0000000..cb0f4fc
--- /dev/null
+++ b/_modules/net_checks.py
@@ -0,0 +1,279 @@
+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
diff --git a/_modules/ovs_config.py b/_modules/ovs_config.py
new file mode 100644
index 0000000..3122f71
--- /dev/null
+++ b/_modules/ovs_config.py
@@ -0,0 +1,101 @@
+# -*- 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
diff --git a/_states/ovs_config.py b/_states/ovs_config.py
new file mode 100644
index 0000000..bcc8ad6
--- /dev/null
+++ b/_states/ovs_config.py
@@ -0,0 +1,81 @@
+# -*- 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
diff --git a/linux/files/login.defs.jinja b/linux/files/login.defs.jinja
new file mode 100644
index 0000000..572c558
--- /dev/null
+++ b/linux/files/login.defs.jinja
@@ -0,0 +1,62 @@
+{%- 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 %}
diff --git a/linux/files/login_duo.conf b/linux/files/login_duo.conf
new file mode 100644
index 0000000..914ce8a
--- /dev/null
+++ b/linux/files/login_duo.conf
@@ -0,0 +1,8 @@
+{%- 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
+
diff --git a/linux/files/ovs_bridge b/linux/files/ovs_bridge
new file mode 100644
index 0000000..bf9b74f
--- /dev/null
+++ b/linux/files/ovs_bridge
@@ -0,0 +1,14 @@
+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 %}
diff --git a/linux/files/pam-sshd b/linux/files/pam-sshd
new file mode 100644
index 0000000..1aeb502
--- /dev/null
+++ b/linux/files/pam-sshd
@@ -0,0 +1,67 @@
+{%- 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
+
diff --git a/linux/files/preferences_repo b/linux/files/preferences_repo
index 603d313..91e9f9b 100644
--- a/linux/files/preferences_repo
+++ b/linux/files/preferences_repo
@@ -1,8 +1,19 @@
-{%- 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 }}
Pin: {{ pin.pin }}
Pin-Priority: {{ pin.priority }}
-{% endfor %}
+ {%- endfor %}
+{%- endif -%}
diff --git a/linux/map.jinja b/linux/map.jinja
index 52d0e70..667a2dd 100644
--- a/linux/map.jinja
+++ b/linux/map.jinja
@@ -112,12 +112,30 @@
{% set auth = salt['grains.filter_by']({
'Arch': {
'enabled': false,
+ 'duo': {
+ 'enabled': false,
+ 'duo_host': 'localhost',
+ 'duo_ikey': '',
+ 'duo_skey': ''
+ }
},
'RedHat': {
'enabled': false,
+ 'duo': {
+ 'enabled': false,
+ 'duo_host': 'localhost',
+ 'duo_ikey': '',
+ 'duo_skey': ''
+ }
},
'Debian': {
'enabled': false,
+ 'duo': {
+ 'enabled': false,
+ 'duo_host': 'localhost',
+ 'duo_ikey': '',
+ 'duo_skey': ''
+ }
},
}, grain='os_family', merge=salt['pillar.get']('linux:system:auth')) %}
@@ -140,6 +158,70 @@
},
}, 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', #}
{% set interface_params = [
@@ -367,8 +449,8 @@
'warn': 5,
},
'net_rx_action_per_cpu_threshold': {
- 'warning': '0',
- 'minor': '100'
+ 'warning': '500',
+ 'minor': '5000'
},
'packets_dropped_per_cpu_threshold': {
'minor': '0',
@@ -376,3 +458,4 @@
}
},
}, grain='os_family', merge=salt['pillar.get']('linux:monitoring')) %}
+
diff --git a/linux/meta/fluentd.yml b/linux/meta/fluentd.yml
index a6f9cc4..f6d6720 100644
--- a/linux/meta/fluentd.yml
+++ b/linux/meta/fluentd.yml
@@ -77,6 +77,8 @@
record:
- 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) }'
+ - name: source
+ value: systemd
match:
rewrite_tag:
tag: systemd.source
@@ -84,9 +86,9 @@
rule:
- name: ident
regexp: '^(.*)$'
- result: __TAG__.$1
+ result: $1.systemd
push_to_default:
- tag: 'systemd.source.*'
+ tag: '*.systemd'
type: copy
store:
- type: relabel
diff --git a/linux/meta/prometheus.yml b/linux/meta/prometheus.yml
index 3ca2b26..5a3ca05 100644
--- a/linux/meta/prometheus.yml
+++ b/linux/meta/prometheus.yml
@@ -234,24 +234,24 @@
{%- endraw %}
{%- set net_rx_action_warning_threshold = monitoring.net_rx_action_per_cpu_threshold.warning %}
if: >-
- floor(increase(nstat_time_squeeze[24h])) > {{ net_rx_action_warning_threshold }}
+ floor(increase(nstat_time_squeeze[1d])) > {{ net_rx_action_warning_threshold }}
labels:
severity: warning
service: system
annotations:
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."
+ 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[24h])) > {{ net_rx_action_minor_threshold }}
+ 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."
+ 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 %}
diff --git a/linux/network/dpdk.sls b/linux/network/dpdk.sls
index 2c7dcb9..7cc4102 100644
--- a/linux/network/dpdk.sls
+++ b/linux/network/dpdk.sls
@@ -106,7 +106,7 @@
linux_network_dpdk_bond_interface_{{ interface_name }}:
cmd.run:
- name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} add-bond {{ interface.bridge }} {{ interface_name }} {{ bond_interfaces.keys()|join(' ') }}"
- - unless: "ovs-vsctl show | grep {{ interface_name }}"
+ - unless: "ovs-vsctl list-ports {{ interface.bridge }} | grep -w {{ interface_name }}"
- require:
- cmd: linux_network_dpdk_bridge_interface_{{ interface.bridge }}
@@ -143,43 +143,12 @@
- 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 }}"
- {# 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.u/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 %}
- - makedirs: True
- - require:
- - file: /etc/systemd/system/ifup@{{ interface_name }}.service.d/override.conf
-
- {%- endif %}
-
{%- elif interface.type == 'dpdk_ovs_port' and interface.bridge is defined %}
linux_network_dpdk_bridge_port_interface_{{ interface_name }}:
cmd.run:
- - name: "ovs-vsctl{%- if network.ovs_nowait %} --no-wait{%- endif %} 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:
- cmd: linux_network_dpdk_bridge_interface_{{ interface.bridge }}
diff --git a/linux/network/interface.sls b/linux/network/interface.sls
index c2d2a23..6086957 100644
--- a/linux/network/interface.sls
+++ b/linux/network/interface.sls
@@ -2,7 +2,8 @@
{%- from "linux/map.jinja" import system with context %}
{%- if network.enabled %}
-{%- if network.get('dpdk', {}).get('enabled', False) %}
+{%- set dpdk_enabled = network.get('dpdk', {}).get('enabled', False) %}
+{%- if dpdk_enabled %}
include:
- linux.network.dpdk
{%- endif %}
@@ -76,9 +77,45 @@
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 #}
@@ -88,7 +125,7 @@
{%- if interface.type == 'ovs_bridge' %}
-ovs_bridge_{{ interface_name }}:
+ovs_bridge_{{ interface_name }}_present:
openvswitch_bridge.present:
- name: {{ interface_name }}
@@ -103,24 +140,49 @@
cmd.run:
- unless: ovs-vsctl show | grep {{ 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/*
+
+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_port' %}
{%- if interface.get('port_type','internal') == 'patch' %}
-ovs_port_{{ interface_name }}:
+ovs_port_{{ interface_name }}_present:
openvswitch_port.present:
- name: {{ interface_name }}
- bridge: {{ interface.bridge }}
- require:
- {%- if network.interface.get(interface.bridge, {}).get('type', 'ovs_bridge') == 'dpdk_ovs_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 }}
+ - openvswitch_bridge: ovs_bridge_{{ interface.bridge }}_present
{%- endif %}
ovs_port_set_type_{{ interface_name }}:
@@ -158,28 +220,16 @@
- defaults:
port: {{ interface|yaml }}
port_name: {{ interface_name }}
+ auto: ""
+ iface_inet: ""
- 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 }}:
cmd.run:
- name: ifup {{ interface_name }}
- require:
- 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
{%- endif %}
@@ -222,6 +272,9 @@
- wireless-psk: {{ interface.wireless.key }}
{%- endif %}
{%- endif %}
+ {%- if pillar.linux.network.noifupdown is defined %}
+ - noifupdown: {{ pillar.linux.network.noifupdown }}
+ {%- endif %}
{%- for param in network.interface_params %}
{{ set_param(param, interface) }}
{%- endfor %}
diff --git a/linux/storage/swap.sls b/linux/storage/swap.sls
index 7b8d82e..3b3fd80 100644
--- a/linux/storage/swap.sls
+++ b/linux/storage/swap.sls
@@ -53,6 +53,24 @@
{%- 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 %}
{%- endfor %}
diff --git a/linux/system/at.sls b/linux/system/at.sls
index a441d1a..864ae0c 100644
--- a/linux/system/at.sls
+++ b/linux/system/at.sls
@@ -33,8 +33,8 @@
- template: jinja
- source: salt://linux/files/cron_users.jinja
- user: root
- - group: root
- - mode: 0600
+ - group: daemon
+ - mode: 0640
- defaults:
users: {{ allow_users | yaml }}
- require:
diff --git a/linux/system/auth.sls b/linux/system/auth.sls
index 2de2f6c..690ec04 100644
--- a/linux/system/auth.sls
+++ b/linux/system/auth.sls
@@ -1,9 +1,13 @@
{%- from "linux/map.jinja" import auth with context %}
{%- if auth.enabled %}
- {%- set pam_modules_enable = "" %}
- {%- set pam_modules_disable = "" %}
- {%- if grains.os_family == 'Debian' %}
+ {%- 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' ]
@@ -15,11 +19,11 @@
- mode: 755
- require:
- pkg: linux_auth_pam_packages
- {%- endif %}
+ {%- endif %}
- {%- if auth.get('mkhomedir', {}).get('enabled', False) %}
- {%- if grains.os_family == 'Debian' %}
- {%- set pam_modules_enable = pam_modules_enable + ' mkhomedir' %}
+ {%- 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' ]
@@ -30,18 +34,18 @@
- source: salt://linux/files/mkhomedir
- template: jinja
+ {%- endif %}
+ {%- else %}
+ {%- if grains.os_family == 'Debian' %}
+ {%- set pam_modules_disable = pam_modules_disable + ' mkhomedir' %}
+ {%- endif %}
{%- 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' %}
- {%- set pam_modules_enable = pam_modules_enable + ' ldap' %}
+ {%- if grains.os_family == 'Debian' %}
+ {%- set pam_modules_enable = pam_modules_enable + ' ldap' %}
linux_auth_ldap_debconf_package:
pkg.installed:
@@ -69,16 +73,16 @@
libpam-ldapd/enable_shadow:
type: 'boolean'
value: 'true'
+ {%- endif %}
+ {%- else %}
+ {%- if grains.os_family == 'Debian' %}
+ {%- set pam_modules_disable = pam_modules_disable + ' ldap' %}
+ {%- endif %}
{%- 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) %}
+ {%- if grains.os_family == 'Debian' %}
+ {%- if auth.get('mkhomedir', {}).get('enabled', False) %}
linux_auth_pam_add_profiles_mkhomedir_enable:
cmd.run:
- name: /usr/local/bin/pam-add-profile {{ pam_modules_enable }}
@@ -92,19 +96,19 @@
- file: linux_auth_mkhomedir_config
- require:
- file: linux_auth_pam_add_profile
- {%- if auth.get('ldap', {}).get('enabled', False) %}
+ {%- if auth.get('ldap', {}).get('enabled', False) %}
- pkg: linux_auth_ldap_packages
- {%- endif %}
- {%- else %}
+ {%- 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 %}
+ {%- endif %}
- {%- if auth.get('ldap', {}).get('enabled', False) %}
+ {%- 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 }}
@@ -112,49 +116,49 @@
- require:
- file: linux_auth_pam_add_profile
- pkg: linux_auth_ldap_packages
- {%- else %}
+ {%- 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 %}
+ {%- endif %}
- {%- elif grains.os_family == 'RedHat' %}
- {%- if auth.get('mkhomedir', {}).get('enabled', False) %}
+ {%- 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) %}
+ {%- if auth.get('ldap', {}).get('enabled', False) %}
- pkg: linux_auth_ldap_packages
- {%- endif %}
- {%- else %}
+ {%- 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) %}
+ {%- endif %}
+ {%- if auth.get('ldap', {}).get('enabled', False) %}
linux_auth_config_enable_ldap:
cmd.run:
- name: "authconfig --enableldap --enableldapauth --update"
- require:
- {%- if auth.get('ldap', {}).get('enabled', False) %}
+ {%- if auth.get('ldap', {}).get('enabled', False) %}
- pkg: linux_auth_ldap_packages
- {%- endif %}
- {%- else %}
+ {%- endif %}
+ {%- else %}
linux_auth_config_disable_ldap:
cmd.run:
- name: "authconfig --disableldap --disableldapauth --update"
- require:
- pkg: linux_auth_ldap_packages
+ {%- endif %}
{%- endif %}
- {%- endif %}
- {%- if auth.get('ldap', {}).get('enabled', False) %}
+ {%- if auth.get('ldap', {}).get('enabled', False) %}
linux_auth_nsswitch_config_file:
file.managed:
@@ -187,6 +191,6 @@
- enable: true
- name: nslcd
+ {%- endif %}
{%- endif %}
-
{%- endif %}
diff --git a/linux/system/auth/duo.sls b/linux/system/auth/duo.sls
new file mode 100644
index 0000000..5270d8d
--- /dev/null
+++ b/linux/system/auth/duo.sls
@@ -0,0 +1,36 @@
+{%- 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 %}
+
diff --git a/linux/system/cron.sls b/linux/system/cron.sls
index 7f7ae0e..a5f57a4 100644
--- a/linux/system/cron.sls
+++ b/linux/system/cron.sls
@@ -33,8 +33,8 @@
- template: jinja
- source: salt://linux/files/cron_users.jinja
- user: root
- - group: root
- - mode: 0600
+ - group: crontab
+ - mode: 0640
- defaults:
users: {{ allow_users | yaml }}
- require:
diff --git a/linux/system/file.sls b/linux/system/file.sls
index ffc1d76..e8a6d52 100644
--- a/linux/system/file.sls
+++ b/linux/system/file.sls
@@ -21,6 +21,9 @@
{%- else %}
- skip_verify: True
{%- endif %}
+ {%- if file.template is defined %}
+ - template: {{ file.template }}
+ {%- endif %}
{%- elif file.contents is defined %}
- contents: {{ file.contents|yaml }}
{%- elif file.contents_pillar is defined %}
@@ -28,6 +31,7 @@
{%- elif file.contents_grains is defined %}
- contents_grains: {{ file.contents_grains }}
{%- endif %}
+
{%- endif %}
{%- if file.name is defined %}
- name: {{ file.name }}
diff --git a/linux/system/grub.sls b/linux/system/grub.sls
index 74ea553..49277ff 100644
--- a/linux/system/grub.sls
+++ b/linux/system/grub.sls
@@ -7,6 +7,7 @@
- makedirs: True
{%- if grains['os_family'] == 'RedHat' %}
+ {%- set boot_grub_cfg = '/boot/grub2/grub.cfg' %}
/etc/default/grub:
file.append:
- text:
@@ -14,14 +15,26 @@
grub_update:
cmd.wait:
- - name: grub2-mkconfig -o /boot/grub2/grub.cfg
+ - name: grub2-mkconfig -o {{ boot_grub_cfg }}
{%- else %}
+ {%- set boot_grub_cfg = '/boot/grub/grub.cfg' %}
-{%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %}
grub_update:
cmd.wait:
- name: update-grub
-{%- endif %}
+ {%- if grains.get('virtual_subtype') in ['Docker', 'LXC'] %}
+ - onlyif: /bin/false
+ {%- endif %}
{%- endif %}
+
+grub_cfg_permissions:
+ file.managed:
+ - name: {{ boot_grub_cfg }}
+ - user: 'root'
+ - owner: 'root'
+ - mode: '400'
+ - onlyif: test -f {{ boot_grub_cfg }}
+ - require:
+ - cmd: grub_update
diff --git a/linux/system/init.sls b/linux/system/init.sls
index 4f97fa0..20d39d9 100644
--- a/linux/system/init.sls
+++ b/linux/system/init.sls
@@ -3,6 +3,10 @@
include:
- linux.system.env
- linux.system.profile
+- linux.system.shell
+{%- if system.login_defs is defined %}
+- linux.system.login_defs
+{%- endif %}
- linux.system.at
- linux.system.cron
{%- if system.repo|length > 0 %}
diff --git a/linux/system/kernel.sls b/linux/system/kernel.sls
index e6111c5..3dc3046 100644
--- a/linux/system/kernel.sls
+++ b/linux/system/kernel.sls
@@ -8,10 +8,10 @@
{%- do kernel_boot_opts.append('elevator=' ~ system.kernel.elevator) if system.kernel.elevator is defined %}
{%- do kernel_boot_opts.extend(system.kernel.boot_options) if system.kernel.boot_options is defined %}
-{%- if kernel_boot_opts %}
include:
- linux.system.grub
+{%- if kernel_boot_opts %}
/etc/default/grub.d/99-custom-settings.cfg:
file.managed:
- contents: 'GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT {{ kernel_boot_opts|join(' ') }}"'
diff --git a/linux/system/login_defs.sls b/linux/system/login_defs.sls
new file mode 100644
index 0000000..f94348a
--- /dev/null
+++ b/linux/system/login_defs.sls
@@ -0,0 +1,13 @@
+{%- 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 %}
diff --git a/linux/system/repo.sls b/linux/system/repo.sls
index d000f50..03bb72d 100644
--- a/linux/system/repo.sls
+++ b/linux/system/repo.sls
@@ -62,7 +62,7 @@
file.absent
{%- endif %}
- {%- if repo.pin is defined %}
+ {%- if repo.pin is defined or repo.pinning is defined %}
linux_repo_{{ name }}_pin:
file.managed:
- name: /etc/apt/preferences.d/{{ name }}
diff --git a/linux/system/shell.sls b/linux/system/shell.sls
new file mode 100644
index 0000000..29fc1dc
--- /dev/null
+++ b/linux/system/shell.sls
@@ -0,0 +1,45 @@
+{%- 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 %}
diff --git a/linux/system/sysfs.sls b/linux/system/sysfs.sls
index 8440384..a4e28bf 100644
--- a/linux/system/sysfs.sls
+++ b/linux/system/sysfs.sls
@@ -11,6 +11,8 @@
- require:
- pkg: linux_sysfs_package
+{% set apply = system.get('sysfs', {}).pop('enable_apply', True) %}
+
{%- for name, sysfs in system.get('sysfs', {}).items() %}
/etc/sysfs.d/{{ name }}.conf:
@@ -32,6 +34,8 @@
{%- set sysfs_list = sysfs %}
{%- endif %}
+{%- if apply %}
+
{%- for item in sysfs_list %}
{%- set list_idx = loop.index %}
{%- for key, value in item.items() %}
@@ -48,4 +52,7 @@
{%- endfor %}
{%- endfor %}
+
+{%- endif %}
+
{%- endfor %}
diff --git a/linux/system/timezone.sls b/linux/system/timezone.sls
index 6b8e778..f7076c5 100644
--- a/linux/system/timezone.sls
+++ b/linux/system/timezone.sls
@@ -5,8 +5,11 @@
{{ system.timezone }}:
timezone.system:
+ {%- if grains.get('noservices') %}
+ - onlyif: /bin/false
+ {%- endif %}
- utc: {{ system.utc }}
{%- endif %}
-{%- endif %}
\ No newline at end of file
+{%- endif %}
diff --git a/linux/system/user.sls b/linux/system/user.sls
index 7a0c98b..42086d5 100644
--- a/linux/system/user.sls
+++ b/linux/system/user.sls
@@ -37,7 +37,11 @@
- password: {{ user.password }}
- hash_password: {{ user.get('hash_password', False) }}
{% endif %}
+ {%- if user.gid is defined and user.gid %}
+ - gid: {{ user.gid }}
+ {%- else %}
- gid_from_name: true
+ {%- endif %}
{%- if user.groups is defined %}
- groups: {{ user.groups }}
{%- endif %}
@@ -50,6 +54,21 @@
{%- if user.uid is defined and user.uid %}
- uid: {{ user.uid }}
{%- 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 }}
system_user_home_{{ user.home }}:
diff --git a/metadata/service/system/cis/cis-1-1-1-1.yml b/metadata/service/system/cis/cis-1-1-1-1.yml
new file mode 100644
index 0000000..2331a54
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-1-1.yml
@@ -0,0 +1,37 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-1-2.yml b/metadata/service/system/cis/cis-1-1-1-2.yml
new file mode 100644
index 0000000..f84b56f
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-1-2.yml
@@ -0,0 +1,36 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-1-3.yml b/metadata/service/system/cis/cis-1-1-1-3.yml
new file mode 100644
index 0000000..91390b5
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-1-3.yml
@@ -0,0 +1,36 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-1-4.yml b/metadata/service/system/cis/cis-1-1-1-4.yml
new file mode 100644
index 0000000..c246ad2
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-1-4.yml
@@ -0,0 +1,36 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-1-5.yml b/metadata/service/system/cis/cis-1-1-1-5.yml
new file mode 100644
index 0000000..e258052
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-1-5.yml
@@ -0,0 +1,36 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-1-6.yml b/metadata/service/system/cis/cis-1-1-1-6.yml
new file mode 100644
index 0000000..59da5db
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-1-6.yml
@@ -0,0 +1,43 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-1-7.yml b/metadata/service/system/cis/cis-1-1-1-7.yml
new file mode 100644
index 0000000..0102220
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-1-7.yml
@@ -0,0 +1,38 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-1-8.yml b/metadata/service/system/cis/cis-1-1-1-8.yml
new file mode 100644
index 0000000..7c06c8e
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-1-8.yml
@@ -0,0 +1,50 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-14_15_16.yml b/metadata/service/system/cis/cis-1-1-14_15_16.yml
new file mode 100644
index 0000000..d9c7e72
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-14_15_16.yml
@@ -0,0 +1,95 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-1-21.yml b/metadata/service/system/cis/cis-1-1-21.yml
new file mode 100644
index 0000000..da84f49
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-1-21.yml
@@ -0,0 +1,53 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-1-5-4.yml b/metadata/service/system/cis/cis-1-5-4.yml
new file mode 100644
index 0000000..5583d80
--- /dev/null
+++ b/metadata/service/system/cis/cis-1-5-4.yml
@@ -0,0 +1,37 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-2-3-1.yml b/metadata/service/system/cis/cis-2-3-1.yml
new file mode 100644
index 0000000..6116f36
--- /dev/null
+++ b/metadata/service/system/cis/cis-2-3-1.yml
@@ -0,0 +1,43 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-2-3-2.yml b/metadata/service/system/cis/cis-2-3-2.yml
new file mode 100644
index 0000000..ecbfa6a
--- /dev/null
+++ b/metadata/service/system/cis/cis-2-3-2.yml
@@ -0,0 +1,55 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-2-3-3.yml b/metadata/service/system/cis/cis-2-3-3.yml
new file mode 100644
index 0000000..859754b
--- /dev/null
+++ b/metadata/service/system/cis/cis-2-3-3.yml
@@ -0,0 +1,39 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-2-3-4.yml b/metadata/service/system/cis/cis-2-3-4.yml
new file mode 100644
index 0000000..34c8eb2
--- /dev/null
+++ b/metadata/service/system/cis/cis-2-3-4.yml
@@ -0,0 +1,40 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-3-5-1.yml b/metadata/service/system/cis/cis-3-5-1.yml
new file mode 100644
index 0000000..b232990
--- /dev/null
+++ b/metadata/service/system/cis/cis-3-5-1.yml
@@ -0,0 +1,38 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-3-5-2.yml b/metadata/service/system/cis/cis-3-5-2.yml
new file mode 100644
index 0000000..0207eb9
--- /dev/null
+++ b/metadata/service/system/cis/cis-3-5-2.yml
@@ -0,0 +1,41 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-3-5-3.yml b/metadata/service/system/cis/cis-3-5-3.yml
new file mode 100644
index 0000000..723de8b
--- /dev/null
+++ b/metadata/service/system/cis/cis-3-5-3.yml
@@ -0,0 +1,37 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-3-5-4.yml b/metadata/service/system/cis/cis-3-5-4.yml
new file mode 100644
index 0000000..6a4920c
--- /dev/null
+++ b/metadata/service/system/cis/cis-3-5-4.yml
@@ -0,0 +1,37 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-5-4-1-1.yml b/metadata/service/system/cis/cis-5-4-1-1.yml
new file mode 100644
index 0000000..8b82466
--- /dev/null
+++ b/metadata/service/system/cis/cis-5-4-1-1.yml
@@ -0,0 +1,52 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-5-4-1-2.yml b/metadata/service/system/cis/cis-5-4-1-2.yml
new file mode 100644
index 0000000..50543ca
--- /dev/null
+++ b/metadata/service/system/cis/cis-5-4-1-2.yml
@@ -0,0 +1,52 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-5-4-1-3.yml b/metadata/service/system/cis/cis-5-4-1-3.yml
new file mode 100644
index 0000000..3567f2a
--- /dev/null
+++ b/metadata/service/system/cis/cis-5-4-1-3.yml
@@ -0,0 +1,52 @@
+# 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
+
diff --git a/metadata/service/system/cis/cis-5-4-4.yml b/metadata/service/system/cis/cis-5-4-4.yml
new file mode 100644
index 0000000..639babc
--- /dev/null
+++ b/metadata/service/system/cis/cis-5-4-4.yml
@@ -0,0 +1,57 @@
+# CIS 5.4.4 Ensure default user umask is 027 or more restrictive (Scored)
+#
+# Description
+# ===========
+# The default umask determines the permissions of files created by users.
+# The user creating the file has the discretion of making their files and
+# directories readable by others via the chmod command. Users who wish to
+# allow their files and directories to be readable by others by default may
+# choose a different default umask by inserting the umask command into the
+# standard shell configuration files ( .profile , .bashrc , etc.) in their
+# home directories.
+#
+# Rationale
+# =========
+# Setting a very secure default value for umask ensures that users make a
+# conscious choice about their file permissions. A default umask setting of
+# 077 causes files and directories created by users to not be readable by
+# any other user on the system. A umask of 027 would make files and
+# directories readable by users in the same Unix group, while a umask of 022
+# would make files readable by every user on the system.
+#
+# Audit
+# =====
+# Run the following commands and verify all umask lines returned are 027 or
+# more restrictive.
+#
+# # grep "^umask" /etc/bash.bashrc
+# umask 027
+# # grep "^umask" /etc/profile
+# umask 027
+#
+# Remediation
+# ===========
+# Edit the /etc/bash.bashrc and /etc/profile files (and the appropriate files
+# for any other shell supported on your system) and add or edit any umask
+# parameters as follows:
+#
+# umask 027
+#
+# Notes
+# =====
+# The audit and remediation in this recommendation apply to bash and shell.
+# If other shells are supported on the system, it is recommended that their
+# configuration files also are checked.
+#
+# Other methods of setting a default user umask exist however the shell
+# configuration files are the last run and will override other settings if
+# they exist therefore our recommendation is to configure in the shell
+# configuration files. If other methods are in use in your environment they
+# should be audited and the shell configs should be verified to not override.
+#
+parameters:
+ linux:
+ system:
+ shell:
+ umask: "027"
+
diff --git a/metadata/service/system/cis/init.yml b/metadata/service/system/cis/init.yml
index 5c91125..0c2626d 100644
--- a/metadata/service/system/cis/init.yml
+++ b/metadata/service/system/cis/init.yml
@@ -1,6 +1,21 @@
classes:
+- service.linux.system.cis.cis-1-1-1-1
+- service.linux.system.cis.cis-1-1-1-2
+- service.linux.system.cis.cis-1-1-1-3
+- service.linux.system.cis.cis-1-1-1-4
+- service.linux.system.cis.cis-1-1-1-5
+- service.linux.system.cis.cis-1-1-1-6
+- service.linux.system.cis.cis-1-1-1-7
+- service.linux.system.cis.cis-1-1-1-8
+- service.linux.system.cis.cis-1-1-14_15_16
+- service.linux.system.cis.cis-1-1-21
- service.linux.system.cis.cis-1-5-1
- service.linux.system.cis.cis-1-5-3
+- service.linux.system.cis.cis-1-5-4
+- service.linux.system.cis.cis-2-3-1
+- service.linux.system.cis.cis-2-3-2
+- service.linux.system.cis.cis-2-3-3
+- service.linux.system.cis.cis-2-3-4
- service.linux.system.cis.cis-3-1-2
- service.linux.system.cis.cis-3-2-1
- service.linux.system.cis.cis-3-2-2
@@ -12,6 +27,14 @@
- service.linux.system.cis.cis-3-2-8
# Temp. disable PROD-22520
#- service.linux.system.cis.cis-3-3-3
+- service.linux.system.cis.cis-3-5-1
+- service.linux.system.cis.cis-3-5-2
+- service.linux.system.cis.cis-3-5-3
+- service.linux.system.cis.cis-3-5-4
+- service.linux.system.cis.cis-5-4-1-1
+- service.linux.system.cis.cis-5-4-1-2
+- service.linux.system.cis.cis-5-4-1-3
+- service.linux.system.cis.cis-5-4-4
- service.linux.system.cis.cis-6-1-2
- service.linux.system.cis.cis-6-1-3
- service.linux.system.cis.cis-6-1-4
diff --git a/tests/example/file_template.jinja b/tests/example/file_template.jinja
new file mode 100644
index 0000000..1779fcd
--- /dev/null
+++ b/tests/example/file_template.jinja
@@ -0,0 +1 @@
+foo{{ pillar["test"]["example"] }}
diff --git a/tests/pillar/system.sls b/tests/pillar/system.sls
index 0b792b6..de1da29 100644
--- a/tests/pillar/system.sls
+++ b/tests/pillar/system.sls
@@ -99,6 +99,7 @@
subjects:
- '@group1'
sysfs:
+ enable_apply: true
scheduler:
block/sda/queue/scheduler: deadline
power:
@@ -127,6 +128,7 @@
enabled: true
home: /root
name: root
+ maxdays: 365
testuser:
enabled: true
name: testuser
@@ -135,6 +137,7 @@
uid: 9999
full_name: Test User
home: /home/test
+ unique: false
groups:
- db-ops
- salt-ops
@@ -201,6 +204,22 @@
proxy:
enabled: true
https: https://127.0.5.1:443
+ saltstack:
+ source: "deb [arch=amd64] http://repo.saltstack.com/apt/ubuntu/16.04/amd64/2017.7/ xenial main"
+ key_url: "http://repo.saltstack.com/apt/ubuntu/16.04/amd64/2017.7/SALTSTACK-GPG-KEY.pub"
+ architectures: amd64
+ clean_file: true
+ pinning:
+ 10:
+ enabled: true
+ pin: 'release o=SaltStack'
+ priority: 50
+ package: 'libsodium18'
+ 20:
+ enabled: true
+ pin: 'release o=SaltStack'
+ priority: 1100
+ package: '*'
opencontrail:
source: "deb http://ppa.launchpad.net/tcpcloud/contrail-3.0/ubuntu xenial main"
keyid: E79EE90C
@@ -407,6 +426,12 @@
- .local
LANG: C
LC_ALL: C
+ login_defs:
+ PASS_MAX_DAYS:
+ value: 99
+ shell:
+ umask: '027'
+ timeout: 900
profile:
vi_flavors.sh: |
export PAGER=view
diff --git a/tests/pillar/system_duo.sls b/tests/pillar/system_duo.sls
new file mode 100644
index 0000000..114324e
--- /dev/null
+++ b/tests/pillar/system_duo.sls
@@ -0,0 +1,212 @@
+linux:
+ network:
+ enabled: false
+ hostname: linux
+ fqdn: linux.ci.local
+ system:
+ enabled: true
+ at:
+ enabled: false
+ user:
+ root:
+ enabled: true
+ testuser:
+ enabled: true
+ cron:
+ enabled: false
+ user:
+ root:
+ enabled: false
+ cluster: default
+ name: linux
+ domain: ci.local
+ environment: prd
+ purge_repos: true
+ directory:
+ /tmp/test:
+ makedirs: true
+ apparmor:
+ enabled: false
+ haveged:
+ enabled: true
+ prompt:
+ default: "linux.ci.local$"
+ package:
+ htop:
+ version: latest
+ repo:
+ disabled_repo:
+ source: "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
+ enabled: false
+ disabled_repo_left_proxy:
+ source: "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
+ enabled: false
+ proxy:
+ enabled: true
+ https: https://127.0.5.1:443
+ saltstack:
+ source: "deb [arch=amd64] http://repo.saltstack.com/apt/ubuntu/16.04/amd64/2017.7/ xenial main"
+ key_url: "http://repo.saltstack.com/apt/ubuntu/16.04/amd64/2017.7/SALTSTACK-GPG-KEY.pub"
+ architectures: amd64
+ clean_file: true
+ pinning:
+ 10:
+ enabled: true
+ pin: 'release o=SaltStack'
+ priority: 50
+ package: 'libsodium18'
+ 20:
+ enabled: true
+ pin: 'release o=SaltStack'
+ priority: 1100
+ package: '*'
+ apt-salt:
+ source: "deb http://apt.mirantis.com/xenial stable salt"
+ #key_url: http://apt.mirantis.com/public.gpg
+ # pub 4096R/A76882D3 2015-06-17
+ key: |
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
+ Version: GnuPG v1
+
+ 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
+ jtcwJrHue5Xn8UPSLkE=
+ =SWiA
+ -----END PGP PUBLIC KEY BLOCK-----
+ architectures: amd64
+ proxy:
+ enabled: true
+ apt-salt-nightly:
+ source: "deb http://apt.mirantis.com/xenial nightly salt"
+ key_url: http://apt.mirantis.com/public.gpg
+ architectures: amd64
+ proxy:
+ enabled: false
+ apt-extra-nightly:
+ source: "deb http://apt.mirantis.com/xenial nightly extra"
+ key_url: http://apt.mirantis.com/public.gpg
+ architectures: amd64
+ duo:
+ key: |
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
+ Version: GnuPG v2.0.22 (GNU/Linux)
+
+ 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
+ WbTIiN63dr6gdz7hoZJ7PFmJ
+ =t1j7
+ -----END PGP PUBLIC KEY BLOCK-----
+ source: "deb [arch=amd64] http://pkg.duosecurity.com/Ubuntu xenial main"
+ architectures: amd64
+ locale:
+ en_US:
+ enabled: true
+ default: true
+ cs_CZ:
+ enabled: true
+ autoupdates:
+ enabled: true
+ sudo:
+ enabled: false
+ env:
+ BOB_VARIABLE: Alice
+ LANG: C
+ LC_ALL: C
+ login_defs:
+ PASS_MAX_DAYS:
+ value: 99
+ shell:
+ umask: '027'
+ timeout: 900
+ profile:
+ vi_flavors.sh: |
+ export PAGER=view
+ alias vi=vim
+ locales: |
+ export LANG=en_US
+ export LC_ALL=en_US.UTF-8
+ auth:
+ enabled: true
+ duo:
+ enabled: true
+ duo_host: localhost
+ duo_ikey: DUO-INTEGRATION-KEY
+ duo_skey: DUO-SECRET-KEY
+
diff --git a/tests/pillar/system_file.sls b/tests/pillar/system_file.sls
index 0769b18..09900af 100644
--- a/tests/pillar/system_file.sls
+++ b/tests/pillar/system_file.sls
@@ -23,4 +23,10 @@
mode: 700
dir_mode: 700
encoding: utf-8
- makedirs: true
\ No newline at end of file
+ makedirs: true
+ test3:
+ name: /tmp/test3.txt
+ source: salt://linux/files/test/file_template.jinja
+ template: jinja
+test:
+ example: "bar"