├── .gitignore ├── .travis.yml ├── CONTRIBUTORS ├── Dockerfile ├── LICENSE ├── README.md ├── Vagrantfile ├── defaults └── main.yml ├── docs ├── CIS_Ubuntu.md ├── contacts.md ├── index.md └── tests.md ├── handlers └── main.yml ├── meta └── main.yml ├── mkdocs.yml ├── tasks ├── check_requirements.yml ├── main.yml ├── section_01.yml ├── section_01_level1.yml ├── section_02.yml ├── section_02_level1.yml ├── section_02_level2.yml ├── section_03.yml ├── section_03_level1.yml ├── section_04.yml ├── section_04_level1.yml ├── section_04_level2.yml ├── section_05.yml ├── section_05_level1.yml ├── section_06.yml ├── section_06_level1.yml ├── section_06_level1_05.yml ├── section_07.yml ├── section_07_level1.yml ├── section_08.yml ├── section_08_level1.yml ├── section_08_level2.yml ├── section_09.yml ├── section_09_level1.yml ├── section_09_level1_03.yml ├── section_10.yml ├── section_10_level1.yml ├── section_11.yml ├── section_11_level1.yml ├── section_12.yml ├── section_12_level1.yml ├── section_13.yml └── section_13_level1.yml ├── tests ├── callbacks │ └── log_plays.py ├── desktop_defaults.yml ├── docker_defaults.yml ├── docker_nofirewall_defaults.yml ├── inventory ├── main.yml ├── playbook.yml ├── setup-tests.sh └── travis_defaults.yml └── vars └── main.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | 56 | *~ 57 | *.swp 58 | site/ 59 | 60 | .idea -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | env: 6 | - ANSIBLE_VERSION=1.9.1 7 | - ANSIBLE_VERSION=2.0 8 | 9 | notifications: 10 | irc: "chat.freenode.net##cis-ansible" 11 | 12 | before_install: 13 | # Make sure everything's up to date. Not possible with sudo: false 14 | - sudo apt-get update -qq 15 | - sudo apt-get install aptitude 16 | # Create hard to quote file for issue #13 17 | - echo hello >> "hard'to\"quote$file" 18 | - sudo chown 1234:4321 "hard'to\"quote$file" 19 | # Copy specific configuration file to default/main/yml 20 | - cp tests/travis_defaults.yml vars/main.yml 21 | 22 | before_script: 23 | - sudo ./tests/setup-tests.sh 24 | 25 | install: 26 | # Install Ansible. 27 | - pip install ansible==$ANSIBLE_VERSION 28 | 29 | # Add ansible.cfg to pick up roles path. 30 | - "{ echo '[defaults]'; echo 'roles_path = ../'; echo 'callback_plugins = ./tests/callbacks/'; } >> ansible.cfg" 31 | 32 | script: 33 | # The -t level1 enable quicker verification, and the level2 enables postfix 34 | # when installing AIDE. Thus it is not idempotent on the second launch 35 | # (but ok on the third). It may be a good idea to invert the section order 36 | # in the future. 37 | - ansible-playbook -i tests/inventory tests/playbook.yml --syntax-check 38 | - ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 39 | - if [ ${ANSIBLE_VERSION} = "1.9.1" ]; then cp /tmp/coveralls /tmp/firstcover; fi 40 | - ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 > /tmp/idempotence 41 | - > 42 | cat /tmp/idempotence 43 | | grep -q 'changed=0.*failed=0' 44 | && (echo 'Idempotence test: pass' && exit 0) 45 | || (echo 'Idempotence test: fail' && cat /tmp/idempotence && exit 1) 46 | 47 | after_success: 48 | - if [ ${ANSIBLE_VERSION} = "1.9.1" ]; then COVERALLS_URL='https://coveralls.io/api/v1/jobs'; fi 49 | - if [ ${ANSIBLE_VERSION} = "1.9.1" ]; then curl -v -F 'json_file=@/tmp/firstcover' "$COVERALLS_URL"; fi 50 | - if [ ${ANSIBLE_VERSION} = "1.9.1" ]; then cat /tmp/firstcover; fi 51 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # cis-ubuntu-ansible 2 | # 3 | # VERSION 1.0 4 | FROM ubuntu:14.04 5 | MAINTAINER Paul Chaignon 6 | 7 | ADD . /cis-ubuntu-ansible 8 | WORKDIR /cis-ubuntu-ansible 9 | 10 | RUN apt-get update 11 | RUN apt-get -y install python-pip aptitude rsh-client rsh-redone-client talk avahi-daemon cups isc-dhcp-server ntp rpcbind nfs-kernel-server bind9 openssh-client openssh-server python-dev slapd nis libffi-dev libssl-dev 12 | RUN pip install --upgrade setuptools ansible 13 | RUN touch /etc/inetd.conf 14 | RUN echo 'shell.bla' > /tmp/inetd 15 | RUN cp /tmp/inetd /etc/inetd.conf 16 | RUN echo 'start on runlevel [2345]' > /tmp/runxinit 17 | RUN cp /tmp/runxinit /etc/init/xinetd.conf 18 | 19 | RUN echo hello >> "hard'to\"quote$file" 20 | RUN chown 1234:4321 "hard'to\"quote$file" 21 | RUN cp tests/docker_defaults.yml vars/main.yml 22 | RUN echo '[defaults]' > ansible.cfg 23 | RUN echo 'roles_path = ../' >> ansible.cfg 24 | 25 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --syntax-check 26 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 27 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 > results_indempotence.txt 28 | RUN cat results_indempotence.txt 29 | RUN cat results_indempotence.txt | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1) 30 | 31 | 32 | 33 | 34 | FROM ubuntu:12.04 35 | MAINTAINER Paul Chaignon 36 | 37 | ADD . /cis-ubuntu-ansible 38 | WORKDIR /cis-ubuntu-ansible 39 | 40 | RUN apt-get update 41 | RUN apt-get -y install python-pip aptitude rsh-client rsh-redone-client talk avahi-daemon cups isc-dhcp-server ntp rpcbind nfs-kernel-server bind9 openssh-client openssh-server python-dev slapd nis sudo libffi-dev 42 | RUN pip install ansible 43 | RUN touch /etc/inetd.conf 44 | RUN echo 'shell.bla' > /tmp/inetd 45 | RUN cp /tmp/inetd /etc/inetd.conf 46 | RUN echo 'start on runlevel [2345]' > /tmp/runxinit 47 | RUN cp /tmp/runxinit /etc/init/xinetd.conf 48 | 49 | RUN echo hello >> "hard'to\"quote$file" 50 | RUN chown 1234:4321 "hard'to\"quote$file" 51 | RUN cp tests/docker_defaults.yml vars/main.yml 52 | RUN echo '[defaults]' > ansible.cfg 53 | RUN echo 'roles_path = ../' >> ansible.cfg 54 | 55 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --syntax-check 56 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 57 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 > results_indempotence.txt 58 | RUN cat results_indempotence.txt 59 | RUN cat results_indempotence.txt | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1) 60 | 61 | 62 | 63 | 64 | 65 | FROM ubuntu:15.04 66 | MAINTAINER Paul Chaignon 67 | 68 | ADD . /cis-ubuntu-ansible 69 | WORKDIR /cis-ubuntu-ansible 70 | 71 | RUN apt-get update 72 | RUN apt-get -y install python-pip aptitude rsh-client rsh-redone-client talk avahi-daemon cups isc-dhcp-server ntp rpcbind nfs-kernel-server bind9 openssh-client openssh-server python-dev sudo libffi-dev libssl-dev 73 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y install slapd nis 74 | RUN pip install --upgrade setuptools ansible 75 | RUN touch /etc/inetd.conf 76 | RUN echo 'shell.bla' > /tmp/inetd 77 | RUN cp /tmp/inetd /etc/inetd.conf 78 | RUN echo 'start on runlevel [2345]' > /tmp/runxinit 79 | RUN cp /tmp/runxinit /etc/init/xinetd.conf 80 | 81 | RUN echo hello >> "hard'to\"quote$file" 82 | RUN chown 1234:4321 "hard'to\"quote$file" 83 | RUN cp tests/docker_nofirewall_defaults.yml vars/main.yml 84 | RUN echo '[defaults]' > ansible.cfg 85 | RUN echo 'roles_path = ../' >> ansible.cfg 86 | 87 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --syntax-check 88 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 89 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 > results_indempotence.txt 90 | RUN cat results_indempotence.txt 91 | RUN cat results_indempotence.txt | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1) 92 | 93 | 94 | 95 | 96 | 97 | FROM ubuntu:16.04 98 | MAINTAINER Paul Chaignon 99 | 100 | ADD . /cis-ubuntu-ansible 101 | WORKDIR /cis-ubuntu-ansible 102 | 103 | RUN apt-get update 104 | RUN apt-get -y install python-pip aptitude rsh-client rsh-redone-client talk avahi-daemon cups isc-dhcp-server ntp rpcbind nfs-kernel-server bind9 openssh-client openssh-server python-dev libffi-dev libssl-dev 105 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y install slapd nis 106 | RUN pip install ansible 107 | RUN touch /etc/inetd.conf 108 | RUN echo 'shell.bla' > /tmp/inetd 109 | RUN cp /tmp/inetd /etc/inetd.conf 110 | RUN echo 'start on runlevel [2345]' > /tmp/runxinit 111 | RUN cp /tmp/runxinit /etc/init/xinetd.conf 112 | 113 | RUN echo hello >> "hard'to\"quote$file" 114 | RUN chown 1234:4321 "hard'to\"quote$file" 115 | RUN cp tests/docker_nofirewall_defaults.yml vars/main.yml 116 | RUN echo '[defaults]' > ansible.cfg 117 | RUN echo 'roles_path = ../' >> ansible.cfg 118 | 119 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --syntax-check 120 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 121 | RUN ansible-playbook -i tests/inventory tests/playbook.yml --connection=local --sudo -e "pipelining=True" -t level1 > results_indempotence.txt 122 | RUN cat results_indempotence.txt 123 | RUN cat results_indempotence.txt | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1) 124 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CIS for Ubuntu 14.04 2 | 3 | [![Build Status](https://travis-ci.org/awailly/cis-ubuntu-ansible.svg?branch=master)](https://travis-ci.org/awailly/cis-ubuntu-ansible) 4 | [![Documentation Status](https://readthedocs.org/projects/cis-ubuntu-ansible/badge/?version=latest)](https://readthedocs.org/projects/cis-ubuntu-ansible/?badge=latest) 5 | [![Coverage Status](https://coveralls.io/repos/awailly/cis-ubuntu-ansible/badge.svg?branch=master)](https://coveralls.io/r/awailly/cis-ubuntu-ansible?branch=master) 6 | 7 | ## Prerequisites 8 | 9 | The role is focused on hardening an Ubuntu 14.04 system. However it has been successfully tested on other Debian based systems (Debian 8, Raspbian). The minimum requirements of the targeted system are `ssh`, `aptitude` and `python2`; `ansible>=1.9` is required on your local system. 10 | 11 | ## Usage 12 | 13 | ### One liner installation & execution 14 | 15 | The following will automatically install Ansible, download and run the playbook on your local system. 16 | ``` 17 | $ \curl -sSL http://git.io/vZw8S > /tmp/cis.sh && bash /tmp/cis.sh 18 | ``` 19 | To apply the playbook on a remote system: 20 | ``` 21 | $ IP=[remote host's IP] USER=[remote user] \curl -sSL http://git.io/vZw8S | bash 22 | ``` 23 | 24 | ### Manual installation 25 | 26 | Install dependencies on your host (on Ubuntu 14.04): 27 | 28 | ```bash 29 | $ sudo apt-get install python-pip git python-dev 30 | $ sudo pip install ansible markupsafe 31 | ``` 32 | 33 | Create a placeholder to describe your machine: 34 | 35 | ```bash 36 | $ mkdir -p ansible/roles-ubuntu/roles 37 | $ cd ansible/roles-ubuntu 38 | $ git clone https://github.com/awailly/cis-ubuntu-ansible.git roles/cis 39 | ``` 40 | 41 | Create a playbook in the _roles-ubuntu_ folder: 42 | 43 | ```bash 44 | $ cat >> playbook.yml << 'EOF' 45 | --- 46 | - hosts: all 47 | roles: 48 | - cis 49 | EOF 50 | ``` 51 | 52 | ### Tuning the environment 53 | 54 | You have to tune the environment to match your security requirements. The default is very restrictive and will perform strong modifications on the system. All requirements are enabled and may not work. For example the rsyslog server address have to be defined to respect the CIS rule. 55 | 56 | *Read `default/main.yml` file and set your variables in `vars/main.yml`* 57 | 58 | For the CI tests we only create specific files for the environment (see `tests/travis_defaults.yml`) in the `vars/` directory. 59 | 60 | ### Running the role 61 | 62 | Replace the target information (USER, IPADDRESS) and run the playbook with a version of ansible higher than 1.8: 63 | 64 | $ ansible-playbook -b -u USER -i 'IPADDRESS,' playbook.yml 65 | 66 | Note that this command will perform modifications on the target. Add the `-C` option to only check for modifications and audit the system. However, some tasks cannot be audited as they need to register a variable on the target and thus modify the system. 67 | 68 | If the user you are using is not privileged you have to use the `-b` (`become`) option to perform privilege escalation. The password required to become superuser can be specified with the `--ask-become-pass` option. 69 | 70 | ### Optimizations 71 | 72 | Ansible come with some great options that can improve your operations: 73 | 74 | - Add the `-e "pipelining=True"` option to the command line to speed up the hardening process. 75 | - Specify the private key to use with the `--private-key=~/.ssh/id_rsa` option. 76 | - The conventional method to specify hosts in ansible is to create an `inventory` file and feed it with a group of hosts to process. 77 | 78 | ## Documentation 79 | 80 | The details of each tasks operated on the target system is available in the [online documentation](http://cis-ubuntu-ansible.readthedocs.org/en/latest/). It is build on every commit based on the `docs/` repository content. 81 | 82 | ## Contributing 83 | 84 | We accept modifications through pull requests. Please note that CI tests and code coverage are being performed automatically. All tests have to pass before accepting the contribution. 85 | 86 | Issues are welcome too, and we expect reproductible steps to have efficient discussions. 87 | 88 | ## License 89 | 90 | This project is under [GPL license](LICENSE). 91 | 92 | ## Contact 93 | 94 | We have a dedicated IRC channel for the project on chat.freenode.net. Join us on ##cis-ansible or with the [direct link](https://kiwiirc.com/client/irc.freenode.net/?nick=GuestAnsib|?##cis-ansible). 95 | 96 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure(2) do |config| 5 | config.vm.box = "ubuntu/trusty64" 6 | config.nfs.functional = false 7 | 8 | config.vm.provider "virtualbox" do |vb| 9 | vb.memory = 1024 10 | vb.cpus = 1 11 | vb.gui = false 12 | end 13 | 14 | config.vm.provider :libvirt do |libvirt| 15 | libvirt.memory = 1024 16 | libvirt.cpus = 1 17 | libvirt.nic_model_type = "virtio" 18 | libvirt.random_hostname = true 19 | end 20 | 21 | config.vm.provision "prepare-installation", privileged: true, type: "shell", inline: <<-SHELL 22 | apt-get update 23 | apt-get install -y python-pip python-dev libffi-dev libssl-dev openssh-server 24 | pip install ansible markupsafe 25 | SHELL 26 | 27 | config.vm.provision "install", type: "shell", inline: <<-SHELL 28 | mkdir -p /home/vagrant/ansible/roles-ubuntu/roles 29 | cd /home/vagrant/ansible/roles-ubuntu 30 | cp -r /vagrant roles/cis 31 | cat >> playbook.yml << 'EOF' 32 | --- 33 | - hosts: 127.0.0.1 34 | connection: local 35 | roles: 36 | - cis 37 | EOF 38 | SHELL 39 | 40 | config.vm.provision "run", type: "shell", inline: <<-SHELL 41 | cd /home/vagrant/ansible/roles-ubuntu 42 | ansible-playbook -b -u vagrant -i '127.0.0.1,' playbook.yml 43 | SHELL 44 | end 45 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | # Please enter following parameters before system hardening 2 | 3 | 4 | 5 | # Section 01 6 | 7 | # The execution is faster without packages upgrade. 8 | apt_upgrade: True 9 | 10 | # Only update apt cache if older than this value (in seconds) 11 | apt_cache_valid_time: 3600 12 | 13 | 14 | # Section 02 15 | 16 | partitioning: False 17 | 18 | # True if run/shm is write-protected. 19 | run_shm_read_only: False 20 | 21 | 22 | # Section 03 23 | 24 | # Default root password: root 25 | root_password: $6$5Mklo2YKvXOM50Zj$E8w4oiykpG9WiElxwHLx85rFFFG0z/lu0vp0wiU0SAnMnw0CmYhmArxvLxBjWQ6XVHv88XQyfpTjX4CPH89hf1 26 | 27 | # Grub Bootloader PBKDF2 Password (use grub-mkpasswd-pbkdf2 to generate) 28 | root_password_grub: grub.pbkdf2.sha512.10000.529DB4AF052F170948C1DB2A754CEA8A286804DA2D9A4EB5A7CCE4B8636775C83EAF8A1093CBDBC256954BCE789A58EFB3B75D23DFC76583C703922D5DADB69E.4D5BD1EC6736057095CA2EBF55C2DA02DFB0B0784F2105A396F1CEF11FEB1483D5C420F412E2E817E2570DDFC22ABCC329C5FF44091A0ACDE67171FF72E96CFD 29 | 30 | # Section 04 31 | 32 | # Set this flag to use AppArmor. It is useful to disable it when the system does not support the kernel module. 33 | use_apparmor: True 34 | 35 | # Modify the kernel behavior to disallow dump of suid binaries. 36 | restrict_core_dumps: True 37 | 38 | # Set this flag to randomize virtual memory region placement. 39 | enable_aslr: True 40 | 41 | 42 | # Section 06 43 | 44 | # We focus a server installation, but we may be accept some desktops. 45 | remove_xserver: True 46 | 47 | # Default ntp server for when none-already exists. 48 | ntp_server: 0.fr.pool.ntp.org 49 | 50 | 51 | # Section 07 52 | 53 | # Set this flag if the kernel has TCP syncookies support. 54 | enable_tcp_syncookies: True 55 | 56 | # A Docker host will need this set to 1 in order to route container traffic. 57 | # (https://docs.docker.com/engine/userguide/networking/default_network/container-communication) 58 | net_ipv4_ip_forward: 0 59 | 60 | # Enable the activate_ufw variable with True to install and enable service on boot. 61 | # NOTE: If not properly configured it may result in incorrect services behavior. 62 | activate_ufw: True 63 | 64 | # Disable all ipv6 interfaces. Suggested if the protocol is not used. 65 | disable_ipv6: True 66 | 67 | 68 | # Section 08 69 | 70 | # Set auditd logs file size in /var/log/auditd 71 | max_log_file_auditd: 200 72 | 73 | # Set this flag if you have a remote rsyslog server to send logs. 74 | # WARNING: Update the IP address or rsyslog will hit 100% of the CPU usage. 75 | set_rsyslog_remote: False 76 | 77 | # Override to change the group and permissions of log files in 8.2.4 (eg, to 'adm' and 'g-wx,o-rwx' respectively) 78 | rsyslog_log_files_group: root 79 | rsyslog_log_files_permissions: og-rwx 80 | 81 | # Set rsyslog's logs remote server address to send logs. 82 | # WARNING: Update the IP address without localhost address or rsyslog will hit 100% of the CPU usage 83 | remote_logs_host_address: X.X.X.X 84 | 85 | # Set this flag to use AIDE. Disable when using another file integrity checker like OSSEC. 86 | use_aide: True 87 | 88 | 89 | 90 | # Section 09 91 | 92 | # This variable will install and setup the pam_cracklib module, enforcing strong passwords settings. 93 | use_pam_cracklib: True 94 | 95 | 96 | # Section 13 97 | 98 | # This variable defines if accounts without password have to be locked 99 | lock_shadow_accounts: False 100 | 101 | # The modification of user homes may lock users and set the system in an errored state. Set to false if one of the user is using / as home. 102 | modify_user_homes: True 103 | -------------------------------------------------------------------------------- /docs/CIS_Ubuntu.md: -------------------------------------------------------------------------------- 1 | # CIS Security Bencmarks for Ubuntu 2 | 3 | ## Recommendations 4 | 5 | This recommendations provide prescriptive guidance for system and application administrators who plan to develop, deploy, 6 | assess, or secure solutions that incorporate Ubuntu server. 7 | 8 | ### 1 - Patching and Software Updates 9 | 10 | Newer patches may contain security enhancements that would not be available through the latest full update. As a result, it is recommended that the latest software patches be used to 11 | take advantage of the latest functionality. 12 | 13 | ### 2 - Filesystem Configuration 14 | 15 | Directories that are used for system-wide functions can be further protected by placing them on separate partitions. This provides protection for resource exhaustion and enables the use of mounting options that are applicable to the directory's intended use. It is recommended to store user's data on separate partitions and have stricter mount options. 16 | 17 | According to the CIS rules, the partitioning scheme would be the following : 18 | 19 | ``` 20 | | Partition | Mount options | 21 | |-----------------|-------------------------------| 22 | | / | nodev, nosuid, noexec | 23 | | /home | nodev | 24 | | /tmp | bind mount /var/tmp to /tmp | 25 | | /var | | 26 | | /var/log | | 27 | | /var/log/audit | | 28 | ``` 29 | The section 2 is made to fulfill this particular scheme. If for any reason, you can not use this partitioning, then, you can disable partitioning checking by changing the file `default/main.yml` and set the value of `partitioning` to `False` 30 | 31 | ### 3 - Secure Boot Settings 32 | 33 | Malicious code try to start as early as possible during the boot process, so boot loader configuration files must be protected. Fixing permissions to read and write for root only prevents non-root users from seeing the boot parameters or changing them. Non-root users who read the boot parameters may be able to identify weaknesses in security upon boot and be able to exploit them. It is recommendated to protect boot loader with a boot password will prevent an unauthorized user from entering boot parameters or changing the boot partition. 34 | 35 | ### 4 - Process Hardening 36 | 37 | During execution the process offers a surface of vulnerability, this section aims to reduce the risk to exploit vulnerabilty: 38 | 39 | - Core dump can be used to glean confidential information and must be restricted. 40 | - Activating whenever possible processors function to prevent exploitation of buffer overflow vulnerabilities. 41 | - Make difficult to write memory page exploits using random placing virtual memory regions. 42 | - etc ... 43 | 44 | #### 4.5 - AppArmor Activation 45 | 46 | The apparmor installation enforce the new isolation profiles for known applications. A restart of the services is needed to completely setup the new policy. If the restart is not performed, the following error will appear: 47 | 48 | 1 processes are unconfined but have a profile defined. 49 | /usr/sbin/rsyslogd 50 | 51 | We already provide the [rsyslog restart](https://github.com/awailly/cis-ubuntu-ansible/issues/7#issuecomment-102357799), but it is not possible to do this for all services. Check if the `sudo service restart` command solve the issue, and else fill an issue. 52 | 53 | ### 5 - OS Services 54 | 55 | It order to prevent the exploitation of vulnerabilities, it is highly adviced to disable all services that are not required for normal system operation. If a service is not enabled, it cannot be exploited ! Therefore, legacy services (NIS, rsh client/server, telnet, ...) must be not active on the system. 56 | 57 | ### 6 - Special Purpose Services 58 | 59 | Some services that are installed on servers need to be specifically actived. If any of these services are not required, it is recommended that they be disabled or deleted from the system to reduce the potential attack surface. The X Window system that provides a Graphical User Interface (GUI) to users is typically used on desktops where users login, but not on servers. Remove it if your organization not specifically requires graphical login access via X Windows. For the same reason, it is recommended to disable Avahi, a free zeroconf service discovery protocol, if this service is not needed. 60 | 61 | At last, it is likely that a service that is installed on a server specifically need to run this service, uninstall or disable others services : DHCP server, CUPS (Common Unix Print System) protocol, HTTP Proxy server, Samba, IMAP and POP server, LDAP, NFS and RPC, DNS server, FTP server, etc ... . 62 | 63 | ### 7 - Network Configuration and Firewalls 64 | 65 | This section tests aim to secure network and firewall configuration. If the system has at least two interfaces, it can act as a router, but the system must be considered as host only and not as a router, so, network parameters must be set to avoid any routing functions and all IP functionalities used on a router must be disable. The IPv6 networking protocol is replacing Ipv4, but it must be disable if IPv6 is not used. In case of wireless network is present but not used, wireless devices can be disabled to reduce the potential attack surface. 66 | 67 | It is recommended to filter network access using TCP Wrapper: Hosts authorized and hosts not permitted to connect to the system must be specified. 68 | 69 | The Linux kernel modules support several network protocols that are not commonly used (ex: Datagram Congestion Control Protocol (DCCP), Stream Control Transmission Protocol (SCTP), etc...) . If these protocols are not needed, it is recommended that they be disabled in the kernel. 70 | 71 | Finally, it is encourage to activate the Firewall. IPtables is an application that allows a system administrator to configure the IPv4 tables, chains and rules provided by the Linux kernel firewall. 72 | 73 | ### 8 - Logging and Auditing 74 | 75 | Intrusions attempts and others suspicious system behavior must be monitor using log monitoring and auditing tools. It is recommended that rsyslog be used for logging and auditd be used for auditing. In addition to the local log files, it is also recommended that system collect copies of their system logs on a secure, centralized log server via an encrypted connection (*). Indeed, the attacker modifies the local log files on the affected system. 76 | 77 | Because it is often necessary to correlate log information from many different systems it is recommended that the time be synchronized among systems and devices connected to the local network. 78 | 79 | (*) Warning : Do not configure the IP address for remote logs server with the localhost address (127.0.0.1), if so, rsyslog will hit 100% of the CPU usage. 80 | 81 | 82 | ### 9 - System Access, Authentication and Authorization 83 | 84 | This section aims to reinforce system protection against the exploitation of software utilities or modules in Unix operating systems to gain elevated privileges. 85 | 86 | Cron is a time-based job scheduler used in Unix operating systems to set up and maintain software environments with scheduling jobs. Granting read or write access to cron configuration files could provide unprivileged users with the ability to elevate their privileges or gain insight on system jobs that run on the system. It is also a strategy to circumvent auditing controls. 87 | 88 | PAM (Pluggable Authentication Modules) is a service that implements modular authentication modules on UNIX systems. It must be carefully configured to secure system authentication. 89 | 90 | It is strongly recommended that sites abandon older clear-text protocols such as telnet, ftp, rlogin, rsh and rcp and use SSH to prevent session hijacking and sniffing of sensitive data off the network. If the ssh server is used, it must be carefully configured to prevent security issues. 91 | 92 | #### SSH fingerprint 93 | 94 | The section 9.13 affects SSH configuration. As a result of those configurations, the fingerprint of the SSH public key will be different on the next reboot of the system. This is normal behavior and you will be warned about the change of the fingerprint when you will try to connect to it again. 95 | 96 | To remove old fingerprint you can use the following command : 97 | `ssh-keygen -f "~/.ssh/known_hosts" -R {{ip_of_distant_system}}` 98 | 99 | #### Ignoring errors for 9.3.13 100 | 101 | The tasks 9.3.13.X check for allowed users and groups to connect on the system. We cannot define the allowed users without risking to lock the system. You can define the `AllowUsers`, `AllowGroups`, `DenyUsers` and `DenyGroups` to respect your current security rules. 102 | 103 | ### 10 - User Accounts and Environment 104 | 105 | Setting up a secure defaults password policies for system, user accounts and their environment is a key point to secure servers. It is recommended to : 106 | 107 | - be sure that any changes in /etc/login.defs file affect individual userIDs. 108 | - make sure that accounts provided with Ubuntu that are used to manage applications and not used by regular users are 109 | locked to prevent them from being used to provide an interactive shell. 110 | - use GID 0 for the root account helps prevent root-owned files from accidentally becoming accessible to non-privileged users. 111 | - set a very secure default value for umask. This ensures that users, who creating files, make a conscious choice about their 112 | files permissions. 113 | 114 | ### 11 - Warning Banners 115 | 116 | Warning messages inform users who are attempting to login to the system of their legal status regarding the system and must include the name of the organization that owns the system and any monitoring policies that are in place. 117 | Login banners also has the side effect of providing detailed system and patch level informations to attackers attempting to target specific exploits at a system. 118 | 119 | ### 12 - Verify System File Permissions 120 | 121 | This section specifically focus on critical configuration files for the servers security: /etc/passwd and /etc/shadow. 122 | 123 | The /etc/passwd file is a text-based database of information about users that may log in to the system or other operating system user identities that own running processes, this file typically has file system permissions that allow it to be readable by all users of the system (world-readable), although it may only be modified by the superuser. 124 | 125 | The /etc/shadow is used to increase the security level of passwords by restricting all but highly privileged users' access to hashed password data. Typically, that data is kept in files owned by and accessible only by the super user. 126 | 127 | ### 13 - Review User and Group Settings 128 | 129 | Users and groups are used on Linux to control access to the system's files, directories, and peripherals. Linux offers relatively simple access control mechanisms by default, it recommended to enforce permissions for user and group. 130 | 131 | ## List of hardening audit tests 132 | 133 | ### 134 | 1 - Patching and Software Updates 135 | 136 | - 1.1 Install Updates, Patches and Additional Security Software 137 | 138 | ### 139 | 2 - Filesystem Configuration 140 | 141 | - 2.1 Create Separate Partition for /tmp 142 | - 2.2 Set nodev option for /tmp Partition 143 | - 2.3 Set nosuid option for /tmp Partition 144 | - 2.4 Set noexec option for /tmp Partition 145 | - 2.5 Create Separate Partition for /var 146 | - 2.6 Bind Mount the /var/tmp directory to /tmp 147 | - 2.7 Create Separate Partition for /var/log 148 | - 2.8 Create Separate Partition for /var/log/audit 149 | - 2.9 Create Separate Partition for /home 150 | - 2.10 Add nodev Option to /home 151 | - 2.11 Add nodev Option to Removable Media Partitions 152 | - 2.12 Add noexec Option to Removable Media Partitions 153 | - 2.13 Add nosuid Option to Removable Media Partitions 154 | - 2.14 Add nodev Option to /run/shm Partition 155 | - 2.15 Add noexec Option to /run/shm Partition 156 | - 2.16 Add nosuid Option to /run/shm Partition 157 | - 2.17 Set Sticky Bit on All World-Writable Directories (preparation) 158 | - 2.18 Disable Mounting of cramfs Filesystems 159 | - 2.19 Disable Mounting of freevxfs Filesystems 160 | - 2.20 Disable Mounting of jffs2 Filesystems 161 | - 2.21 Disable Mounting of hfs Filesystems 162 | - 2.22 Disable Mounting of hfsplus Filesystems 163 | - 2.23 Disable Mounting of squashfs Filesystems 164 | - 2.24 Disable Mounting of udf Filesystems 165 | - 2.25 Disable Automounting 166 | 167 | ### 168 | 3 - Secure Boot Settings 169 | 170 | - 3 Check for /boot/grub/grub.cfg file 171 | - 3.1 Set User/Group Owner on bootloader config 172 | - 3.2 Set Permissions on bootloader config 173 | - 3.3.1 Set Boot Loader Superuser 174 | - 3.3.2 Set Boot Loader Password 175 | - 3.3.3 Disable password protection booting 176 | - 3.3.4 Update Grub configuration 177 | - 3.4 Require Authentication for Single-User Mode 178 | 179 | ### 180 | 4 - Process Hardening 181 | 182 | - 4.1 Restrict Core Dumps 183 | - 4.2 Enable XD/NX Support on 32-bit x86 Systems 184 | - 4.3 Enable Randomized Virtual Memory Region Placement 185 | - 4.4 Disable Prelink 186 | - 4.5 Activate AppArmor 187 | 188 | ### 189 | 5 - OS Services 190 | 191 | - 5.1 Ensure NIS is not installed 192 | - 5.2 Ensure rsh, rlogin, rexec, talk, telnet, chargen, daytime, echo, discard, time is not enabled 193 | - 5.3 Ensure rsh client is not installed 194 | - 5.4 Ensure talk server is not enabled 195 | - 5.5 Ensure talk client is not installed 196 | - 5.6 Ensure telnet server is not enabled 197 | - 5.7 Ensure tftp server is not enabled 198 | - 5.8 Ensure xinetd is not enabled 199 | 200 | ### 201 | 6 - Special Purpose Services 202 | 203 | - 6.1 Ensure the X Window system is not installed 204 | - 6.2 Ensure Avahi Server is not enabled 205 | - 6.3 Ensure print server is not enabled 206 | - 6.4 Ensure DHCP Server is not enabled 207 | - 6.5 Configure Network Time Protocol 208 | - 6.6 Ensure LDAP is not enabled 209 | - 6.7 Ensure NFS and RPC are not enabled 210 | - 6.8-14 Ensure DNS,FTP,HTTP,IMAP,POP,Samba,Proxy,SNMP Servers are not enabled 211 | - 6.15 Configure Mail Transfer Agent for Local-Only Mode 212 | - 6.16 Ensure rsync service is not enabled 213 | - 6.17 Ensure Biosdevname is not enabled 214 | 215 | ### 216 | 7 - Network Configuration and Firewalls 217 | 218 | - 7.1.1 Disable IP Forwarding 219 | - 7.1.2 Disable Send Packet Redirects 220 | - 7.2 Modify Network Parameters (Host and Router) 221 | - 7.2.1 Disable Source Routed Packet Acceptance 222 | - 7.2.2 Disable ICMP Redirect Acceptance 223 | - 7.2.3 Disable Secure ICMP Redirect Acceptance 224 | - 7.2.4 Log Suspicious Packets 225 | - 7.2.5 Enable Ignore Broadcast Requests 226 | - 7.2.6 Enable Bad Error Message Protection 227 | - 7.2.7 Enable RFC-recommended Source Route Validation 228 | - 7.2.8 Enable TCP SYN Cookies 229 | - 7.3 Configure IPv6 230 | - 7.3.1 Disable IPv6 Router Advertisements 231 | - 7.3.2 Disable IPv6 Redirect Acceptance 232 | - 7.3.3 Disable IPv6 233 | - 7.4.1 Install TCP Wrappers 234 | - 7.4.2 Create /etc/hosts.allow 235 | - 7.4.3 Verify Permissions on /etc/hosts.allow 236 | - 7.4.4 Create /etc/hosts.deny 237 | - 7.4.5 Verify Permissions on /etc/hosts.deny 238 | - 7.5.1-4 Disable DCCP, SCTP, RDS, TIPC 239 | - 7.6 Deactivate Wireless Interfaces 240 | - 7.7 Ensure Firewall is active 241 | 242 | ### 243 | 8 - Logging and Auditing 244 | 245 | - 8.1.1 Configure Data Retention 246 | - 8.1.2 Install and Enable auditd Service 247 | - 8.1.3 Enable Auditing for Processes That Start Prior to auditd 248 | - 8.1.4 Record Events That Modify Date and Time Information 249 | - 8.1.5 Record Events That Modify User/Group Information 250 | - 8.1.6 Record Events That Modify the System's Network Environment 251 | - 8.1.7 Record Events That Modify the System's Mandatory AccessControls 252 | - 8.1.8 Collect Login and Logout Events 253 | - 8.1.9 Collect Session Initiation Information 254 | - 8.1.10 Collect Discretionary Access Control Permission ModificationEvents 255 | - 8.1.11 Collect Unsuccessful Unauthorized Access Attempts to Files 256 | - 8.1.12 Collect Use of Privileged Commands 257 | - 8.1.13 Collect Successful File System Mounts 258 | - 8.1.14 Collect File Deletion Events by User 259 | - 8.1.15 Collect Changes to System Administration Scope (sudoers) 260 | - 8.1.16 Collect System Administrator Actions (sudolog) 261 | - 8.1.17 Collect Kernel Module Loading and Unloading 262 | - 8.1.18 Make the Audit Configuration Immutable 263 | - 8.2 Configure rsyslog 264 | - 8.2.1 Install the rsyslog package 265 | - 8.2.2 Ensure the rsyslog Service is activated 266 | - 8.2.3 Configure /etc/rsyslog.conf 267 | - 8.2.4 Create and Set Permissions on rsyslog Log Files 268 | - 8.2.5 Configure rsyslog to Send Logs to a Remote Log Host 269 | - 8.2.6 Accept Remote rsyslog Messages Only on Designated Log Hosts 270 | - 8.3.1 Install AIDE 271 | - 8.3.2 Implement Periodic Execution of File Integrity 272 | 273 | ### 274 | 9 - System Access, Authentication and Authorization 275 | 276 | - 9.1.1.1 Check that cron conf file exists (check) 277 | - 9.1.1.2 Enable cron Daemon 278 | - 9.1.2 Set User/Group Owner and Permission on /etc/crontab 279 | - 9.1.3 Set User/Group Owner and Permission on /etc/cron.hourly 280 | - 9.1.4 Set User/Group Owner and Permission on /etc/cron.daily 281 | - 9.1.5 Set User/Group Owner and Permission on /etc/cron.weekly 282 | - 9.1.6 Set User/Group Owner and Permission on /etc/cron.monthly 283 | - 9.1.7 Set User/Group Owner and Permission on /etc/cron.d 284 | - 9.1.8 Restrict at/cron to Authorized Users 285 | - 9.2.1 Set Password Creation Requirement Parameters Usingpam_cracklib 286 | - 9.2.2 Set Lockout for Failed Password Attempts 287 | - 9.2.3 Limit Password Reuse 288 | - 9.3 Check if ssh is installed 289 | - 9.3.1 Set SSH Protocol to 2 290 | - 9.3.2 Set LogLevel to INFO 291 | - 9.3.3 Set Permissions on /etc/ssh/sshd_config 292 | - 9.3.{4,7,8,9,10} Disable some SSH options 293 | - 9.3.5 Set SSH MaxAuthTries to 4 or Less 294 | - 9.3.6 Set SSH IgnoreRhosts to Yes 295 | - 9.3.11 Use Only Approved Cipher in Counter Mode 296 | - 9.3.12.1 Set Idle Timeout Interval for User Login 297 | - 9.3.13.1 Limit Access via SSH 298 | - 9.3.14 Set SSH Banner 299 | - 9.3.14 Set SSH Banner File 300 | - 9.4 Restrict root Login to System Console 301 | - 9.5 Restrict Access to the su Command 302 | 303 | ### 304 | 10 - User Accounts and Environment 305 | 306 | - 10.1.1 Set Password Expiration Days 307 | - 10.1.2 Set Password Change Minimum Number of Days 308 | - 10.1.3 Set Password Expiring Warning Days 309 | - 10.2 Disable System Accounts 310 | - 10.3 Set Default Group for root Account 311 | - 10.4 Set Default umask for Users 312 | - 10.5 Lock Inactive User Accounts 313 | 314 | ### 315 | 11 - Warning Banners 316 | 317 | - 11.1 Set Warning Banner for Standard Login Services 318 | - 11.2 Remove OS Information from Login Warning Banners 319 | - 11.3 Set Graphical Warning Banner 320 | 321 | ### 322 | 12 - Verify System File Permissions 323 | 324 | - 12.1 Verify Permissions on /etc/passwd 325 | - 12.2 Verify Permissions on /etc/shadow 326 | - 12.3 Verify Permissions on /etc/group 327 | - 12.4 Verify User/Group Ownership on /etc/passwd 328 | - 12.5 Verify User/Group Ownership on /etc/shadow 329 | - 12.6 Verify User/Group Ownership on /etc/group 330 | - 12.7 Find World Writable Files 331 | - 12.8 Find Un-owned Files and Directories 332 | - 12.9 Find Un-grouped Files and Directories 333 | - 12.10 Find SUID System Executables 334 | - 12.11 Find SGID System Executables 335 | 336 | ### 337 | 13 - Review User and Group Settings 338 | 339 | - 13.1 Ensure Password Fields are Not Empty 340 | - 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File 341 | - 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File 342 | - 13.4 Verify No Legacy "+" Entries Exist in /etc/group File 343 | - 13.5 Verify No UID 0 Accounts Exist Other Than root 344 | - 13.6 Ensure root PATH Integrity 345 | - 13.7 Check Permissions on User Home Directories 346 | - 13.8 Check User Dot File Permissions 347 | - 13.9 Check Permissions on User .netrc Files 348 | - 13.10 Check for Presence of User .rhosts Files 349 | - 13.11 Check Groups in /etc/passwd 350 | - 13.12 Check That Users Are Assigned Valid Home Directories 351 | - 13.13 Check User Home Directory Ownership 352 | - 13.14 Check for Duplicate UIDs 353 | - 13.15 Check for Duplicate GIDs 354 | - 13.16 Check for Duplicate User Names 355 | - 13.17 Check for Duplicate Group Names 356 | - 13.18 Check for Presence of User .netrc Files 357 | - 13.19 Check for Presence of User .forward Files 358 | - 13.20 Ensure shadow group is empty 359 | -------------------------------------------------------------------------------- /docs/contacts.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | If you need help, please contact: 11 | 12 | Aurélien WAILLY : aurélien.wailly@orange.com 13 | 14 | Pascal LEGOUGE : pascal.legouge@orange.com -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Welcome to Hardwatt documentation 2 | 3 | This documentation provides a description of the Hardwatt project. Hardwatt project provides a tool for establishing a secure configuration posture for server hosted in Openwatt infrastruture. 4 | 5 | The secure configuration recommandations are based on the 6 | CIS Security Benchmarks program which provides industry best practices to help organizations assess and improve their security. 7 | 8 | To obtain the latest version of the CIS Security Benchmarks please visit http://benchmarks.cisecurity.org. 9 | 10 | ## Contents 11 | 12 | * [Hardwatt homepage](www.hardwatt-project.orange.com) - Start the security hardening of a server. 13 | * [Secwatt library homepage](https://registry.hub.docker.com/u/awailly/cis-ubuntu-ansible/) - Download secure Docker instances. 14 | 15 | !! Caution !! 16 | 17 | The security hardening is highly recommended to be performed during initial system installation. If the system is already installed, it is recommended that a full backup be 18 | performed before hardening the system. 19 | 20 | 21 | * [CIS Security Benchmarks](http://benchmarks.cisecurity.org) - Security recommandations for hardening a server. 22 | 23 | >- [CIS Security Benchmarks for Ubuntu server](CIS_Ubuntu.md) 24 | 25 | ## Contacts 26 | 27 | If you need help, please contact: 28 | 29 | - Aurélien WAILLY : aurélien.wailly@orange.com 30 | - Pascal LEGOUGE : pascal.legouge@orange.com 31 | -------------------------------------------------------------------------------- /docs/tests.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | We provide a simple way to evaluate the effective code coverage of our tool ([see the issue](https://github.com/awailly/cis-ubuntu-ansible/issues/25)). 4 | 5 | ## Travis 6 | 7 | The travis-ci environment gives an isolated Ubuntu 12.04 to perform two run of cis-ubuntu-ansible. 8 | 9 | ## Drone.io 10 | 11 | The drone environment is close to travis, but provides Ubuntu 14.04 and the ability to export files. [@pchaigno](https://github.com/pchaigno) created the settings and the dynamic code coverage badge with [this PR](https://github.com/awailly/cis-ubuntu-ansible/pull/28). 12 | 13 | # Code coverage 14 | 15 | All sections cannot be tested given the strong impact on the testing systems, and our rights. Note that the current document focus on the drone.io build where the badge is generated. If you have a creative way to do the same on travis, contact us or open an issue. 16 | 17 | ## Section 01 - Patching and Sofware Updates 18 | 19 | The section tests for new packages and require a long time. Given our ephemeral travis and drone builds, we skip this step. 20 | 21 | [![Status: Skipped](https://img.shields.io/badge/Status-Skipped-red.svg)] 22 | 23 | ## Section 02 - Filesystem configuration 24 | 25 | This section deals with current filesystem mounts and we are not able to perform such modifications on the CI environments. 26 | 27 | [![Status: Skipped](https://img.shields.io/badge/Status-Skipped-red.svg)] 28 | 29 | ## Section 03 - Secure boot settings 30 | 31 | This section hardens the grub related files, which is not available on the testing system. 32 | 33 | [![Status: Skipped](https://img.shields.io/badge/Status-Skipped-red.svg)] 34 | 35 | ## Section 04 - Additional process hardening 36 | 37 | This section looks for potential leaks and fix them. The build environment prohibid us from modifying some variables (such as *fs.suid_dumpable*). 38 | 39 | [![Status: Partially Tested](https://img.shields.io/badge/Status-Partially tested-yellow.svg)] 40 | 41 | ## Section 05 - OS services 42 | 43 | This section disables unneeded services on the system to reduce the attack surface. There is no restriction here. 44 | 45 | [![Status: Tested](https://img.shields.io/badge/Status-Tested-brightgreen.svg)] 46 | 47 | ## Section 06 - Special purposes services 48 | 49 | This section extends section 05 with other services. 50 | 51 | [![Status: Partially Tested](https://img.shields.io/badge/Status-Partially tested-yellow.svg)] 52 | 53 | ## Section 07 54 | 55 | This section forces sysctl values to correctly setup network and IPv6. 56 | 57 | [![Status: Tested](https://img.shields.io/badge/Status-Tested-brightgreen.svg)] 58 | 59 | ## Section 08 60 | 61 | This section configures logs and rights. 62 | 63 | [![Status: Partially Tested](https://img.shields.io/badge/Status-Partially tested-yellow.svg)] 64 | 65 | ## Section 09 66 | 67 | [![Status: Skipped](https://img.shields.io/badge/Status-Skipped-red.svg)] 68 | 69 | ## Section 010 70 | 71 | [![Status: Skipped](https://img.shields.io/badge/Status-Skipped-red.svg)] 72 | 73 | ## Section 011 74 | 75 | [![Status: Skipped](https://img.shields.io/badge/Status-Skipped-red.svg)] 76 | 77 | ## Section 012 78 | 79 | [![Status: Skipped](https://img.shields.io/badge/Status-Skipped-red.svg)] 80 | 81 | ## Section 013 82 | 83 | [![Status: Skipped](https://img.shields.io/badge/Status-Skipped-red.svg)] 84 | 85 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart auditd 4 | service: name=auditd state=restarted 5 | changed_when: False 6 | ignore_errors: True 7 | 8 | - name: restart rsyslog 9 | service: name=rsyslog state=restarted 10 | changed_when: False 11 | ignore_errors: True 12 | 13 | - name: restart ssh 14 | service: name=ssh state=restarted 15 | changed_when: False 16 | ignore_errors: True 17 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | allow_duplicates: no 4 | 5 | 6 | galaxy_info: 7 | author: Aurélien Wailly 8 | description: Ansible role to meet CIS (Center for Internet Security) requirements on ubuntu 9 | license: GPLv2 10 | min_ansible_version: 1.9.0.1 11 | platforms: 12 | - name: Ubuntu 13 | versions: 14 | 14.04 15 | categories: 16 | #- cloud 17 | #- cloud:ec2 18 | #- cloud:gce 19 | #- cloud:rax 20 | #- clustering 21 | #- database 22 | #- database:nosql 23 | #- database:sql 24 | #- development 25 | - monitoring 26 | #- networking 27 | #- packaging 28 | - system 29 | #- web 30 | 31 | 32 | 33 | dependencies: [] 34 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: hardwatt 2 | pages: 3 | - [index.md, Home] 4 | - [CIS_Ubuntu.md] 5 | - [tests.md, Tests] 6 | - [contacts.md, Contacts] 7 | -------------------------------------------------------------------------------- /tasks/check_requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Check if OS is Debian-based (we do not support others) 4 | debug: msg="Check OS family" 5 | failed_when: ansible_os_family != "Debian" 6 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: check_requirements.yml 4 | 5 | - include: section_01.yml 6 | tags: section01 7 | 8 | - include: section_02.yml 9 | tags: section02 10 | 11 | - include: section_03.yml 12 | tags: section03 13 | 14 | - include: section_04.yml 15 | tags: section04 16 | 17 | - include: section_05.yml 18 | tags: section05 19 | 20 | - include: section_07.yml 21 | tags: section07 22 | 23 | - include: section_08.yml 24 | tags: section08 25 | 26 | - include: section_06.yml 27 | tags: section06 28 | 29 | - include: section_09.yml 30 | tags: section09 31 | 32 | - include: section_10.yml 33 | tags: section10 34 | 35 | - include: section_11.yml 36 | tags: section11 37 | 38 | - include: section_12.yml 39 | tags: section12 40 | 41 | - include: section_13.yml 42 | tags: section13 43 | 44 | -------------------------------------------------------------------------------- /tasks/section_01.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_01_level1.yml 4 | tags: 5 | - section01 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_01_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 1.1.1 Install Updates, Patches and Additional Security Software (Not Scored) 4 | apt: update_cache=yes cache_valid_time={{apt_cache_valid_time}} 5 | tags: 6 | - section1 7 | - section1.1 8 | - section1.1.1 9 | 10 | - name: 1.1.2 Install Updates, Patches and Additional Security Software (Not Scored) 11 | apt: upgrade=yes 12 | when: apt_upgrade == True 13 | tags: 14 | - section1 15 | - section1.1 16 | - section1.1.2 17 | -------------------------------------------------------------------------------- /tasks/section_02.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_02_level1.yml 4 | tags: 5 | - section02 6 | - level1 7 | 8 | - include: section_02_level2.yml 9 | tags: 10 | - section02 11 | - level2 -------------------------------------------------------------------------------- /tasks/section_02_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 2.1 Create Separate Partition for /tmp (Scored) 4 | command: grep '\s/tmp\s' /etc/fstab 5 | register: tmp_partition 6 | when: partitioning == True 7 | failed_when: tmp_partition.rc == 1 8 | changed_when: False 9 | ignore_errors: True 10 | tags: 11 | - section2 12 | - section2.1 13 | 14 | - name: 2.2 - 4 Set nodev, nosuid, noexec Options for /tmp Partition (Scored) 15 | mount: name="/tmp" src="/tmp" state="mounted" opts="defaults,nodev,nosuid,noexec" fstype=ext4 16 | when: partitioning == True 17 | tags: 18 | - section2 19 | - section2.2 20 | - section2.3 21 | - section2.4 22 | 23 | - name: 2.5 Create Separate Partition for /var (Scored) 24 | command: grep '\s/var\s' /etc/fstab 25 | when: partitioning == True 26 | register: var_partition 27 | failed_when: var_partition.rc == 1 28 | changed_when: False 29 | ignore_errors: True 30 | tags: 31 | - section2 32 | - section2.5 33 | 34 | - name: 2.6 Bind Mount the /var/tmp directory to /tmp (Scored) 35 | mount: name="/var/tmp" src="/tmp" opts=bind state=mounted fstype=ext4 36 | when: partitioning == True 37 | tags: 38 | - section2 39 | - section2.6 40 | 41 | - name: 2.7 Create Separate Partition for /var/log (Scored) 42 | command: grep '\s/var\/log\s' /etc/fstab 43 | when: partitioning == True 44 | register: var_log_partition 45 | failed_when: var_log_partition.rc == 1 46 | changed_when: False 47 | ignore_errors: True 48 | tags: 49 | - section2 50 | - section2.7 51 | 52 | - name: 2.8 Create Separate Partition for /var/log/audit (Scored) 53 | command: grep '\s/var\/log\/audit\s' /etc/fstab 54 | when: partitioning == True 55 | register: var_log_audit_partition 56 | failed_when: var_log_audit_partition.rc == 1 57 | changed_when: False 58 | ignore_errors: True 59 | tags: 60 | - section2 61 | - section2.8 62 | 63 | - name: 2.9 Create Separate Partition for /home (Scored) 64 | command: grep '\s/home\s' /etc/fstab 65 | when: partitioning == True 66 | register: home_partition 67 | failed_when: home_partition.rc == 1 68 | changed_when: False 69 | ignore_errors: True 70 | tags: 71 | - section2 72 | - section2.9 73 | 74 | - name: 2.10 Add nodev Option to /home (Scored) 75 | mount: name="/home" src="/home" state=mounted opts=defaults,nodev fstype="ext4" 76 | when: partitioning == True 77 | tags: 78 | - section2 79 | - section2.10 80 | 81 | - name: 2.11 Add nodev Option to Removable Media Partitions (Not Scored) 82 | debug: msg="/!\ Ensure removable partitions have nodev option" 83 | tags: 84 | - section2 85 | - section2.11 86 | 87 | - name: 2.12 Add noexec Option to Removable Media Partitions (Not Scored) 88 | debug: msg="/!\ Ensure removable partitions have noexec option" 89 | tags: 90 | - section2 91 | - section2.12 92 | 93 | - name: 2.13 Add nosuid Option to Removable Media Partitions (Not Scored) 94 | debug: msg="/!\ Ensure removable partitions have nosuid option" 95 | tags: 96 | - section2 97 | - section2.13 98 | 99 | - name: 2.14 - 16 Add nodev, nosuid, noexec Options to /run/shm Partition (Scored) 100 | mount: name="/run/shm" src="/run/shm" state="mounted" opts="defaults,nodev,nosuid,noexec" fstype="tmpfs" 101 | when: run_shm_read_only == False 102 | tags: 103 | - section2 104 | - section2.14 105 | - section2.15 106 | - section2.16 107 | 108 | - name: 2.17.1 Set Sticky Bit on All World-Writable Directories (check) (Scored) 109 | shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type d -perm -0002 -print 2>/dev/null 110 | failed_when: False 111 | changed_when: False 112 | always_run: True 113 | register: sticky_bit_dirs 114 | tags: 115 | - section2 116 | - section2.17 117 | 118 | - name: 2.17.2 Set Sticky Bit on All World-Writable Directories (Scored) 119 | file: 120 | path: "{{ item }}" 121 | mode: "a+t" 122 | with_items: "{{sticky_bit_dirs.stdout_lines}}" 123 | tags: 124 | - section2 125 | - section2.17 126 | 127 | - name: 2.25.1 Disable Automounting (check) (Scored) 128 | stat: > 129 | path=/etc/init/autofs.conf 130 | register: autofs_file 131 | tags: 132 | - section2 133 | - section2.25 134 | 135 | - name: 2.25.2 Disable Automounting (Scored) 136 | lineinfile: > 137 | dest=/etc/init/autofs.conf 138 | line='#start on runlevel [2345]' 139 | regexp='start on runlevel' 140 | state=present 141 | when: autofs_file.stat.exists == True 142 | tags: 143 | - section2 144 | - section2.25 145 | -------------------------------------------------------------------------------- /tasks/section_02_level2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 2.18 Disable Mounting of cramfs Filesystems (Not Scored) 4 | lineinfile: > 5 | dest=/etc/modprobe.d/CIS.conf 6 | line='install cramfs /bin/true' 7 | state=present 8 | create=yes 9 | tags: 10 | - section2 11 | - section2.18 12 | 13 | - name: 2.19 Disable Mounting of freevxfs Filesystems (Not Scored) 14 | lineinfile: > 15 | dest=/etc/modprobe.d/CIS.conf 16 | line='install freevxfs /bin/true' 17 | state=present 18 | create=yes 19 | tags: 20 | - section2 21 | - section2.19 22 | 23 | - name: 2.20 Disable Mounting of jffs2 Filesystems (Not Scored) 24 | lineinfile: > 25 | dest=/etc/modprobe.d/CIS.conf 26 | line='install jffs2 /bin/true' 27 | state=present 28 | create=yes 29 | tags: 30 | - section2 31 | - section2.20 32 | 33 | - name: 2.21 Disable Mounting of hfs Filesystems (Not Scored) 34 | lineinfile: > 35 | dest=/etc/modprobe.d/CIS.conf 36 | line='install hfs /bin/true' 37 | state=present 38 | create=yes 39 | tags: 40 | - section2 41 | - section2.21 42 | 43 | - name: 2.22 Disable Mounting of hfsplus Filesystems (Not Scored) 44 | lineinfile: > 45 | dest=/etc/modprobe.d/CIS.conf 46 | line='install hfsplus /bin/true' 47 | state=present 48 | create=yes 49 | tags: 50 | - section2 51 | - section2.22 52 | 53 | - name: 2.23 Disable Mounting of squashfs Filesystems (Not Scored) 54 | lineinfile: > 55 | dest=/etc/modprobe.d/CIS.conf 56 | line='install squashfs /bin/true' 57 | state=present 58 | create=yes 59 | tags: 60 | - section2 61 | - section2.23 62 | 63 | - name: 2.24 Disable Mounting of udf Filesystems (Not Scored) 64 | lineinfile: > 65 | dest=/etc/modprobe.d/CIS.conf 66 | line='install udf /bin/true' 67 | state=present 68 | create=yes 69 | tags: 70 | - section2 71 | - section2.24 72 | -------------------------------------------------------------------------------- /tasks/section_03.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_03_level1.yml 4 | tags: 5 | - section03 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_03_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | #sections 3.3 and 3.4 have to happen before as the latter overwrite 3.1 and 3.2 3 | 4 | - name: 3.0 Check for /boot/grub/grub.cfg file (Not Scored) 5 | stat: path=/boot/grub/grub.cfg 6 | register: grub_cfg_file 7 | tags: 8 | - section3 9 | 10 | - name: 3.3.1.1 Set Boot Loader Superuser (check) (Scored) 11 | command: grep "^set superusers" /boot/grub/grub.cfg 12 | register: boot_superusers 13 | when: grub_cfg_file.stat.exists == True 14 | changed_when: False 15 | failed_when: False 16 | always_run: True 17 | tags: 18 | - section3 19 | - section3.3 20 | - section3.3.1 21 | - section3.3.1.1 22 | 23 | - name: 3.3.1.2 Set Boot Loader Superuser (Scored) 24 | lineinfile: > 25 | dest='/etc/grub.d/40_custom' 26 | regexp='^set superusers' 27 | line='set superusers="root"' 28 | state=present 29 | create=yes 30 | when: grub_cfg_file.stat.exists == True and boot_superusers.rc == 1 31 | tags: 32 | - section3 33 | - section3.3 34 | - section3.3.1 35 | - section3.3.1.2 36 | 37 | - name: 3.3.2.1 Set Boot Loader Password (check) (Scored) 38 | command: grep "^password" /boot/grub/grub.cfg 39 | register: boot_password 40 | when: grub_cfg_file.stat.exists == True 41 | changed_when: False 42 | failed_when: False 43 | always_run: True 44 | tags: 45 | - section3 46 | - section3.3 47 | - section3.3.2 48 | - section3.3.2.1 49 | 50 | - name: 3.3.2.2 Set Boot Loader Password (Scored) 51 | lineinfile: > 52 | dest='/etc/grub.d/40_custom' 53 | regexp='^password' 54 | line="password_pbkdf2 root {{root_password_grub}}" 55 | state=present 56 | when: grub_cfg_file.stat.exists == True and boot_password.rc == 1 57 | tags: 58 | - section3 59 | - section3.3 60 | - section3.3.2 61 | - section3.3.2.2 62 | 63 | - name: 3.3.3 Disable password protection booting (Scored) 64 | lineinfile: > 65 | dest='/etc/grub.d/10_linux' 66 | create=yes 67 | regexp='^CLASS=' 68 | line='CLASS="--class gnu-linux --class gnu --class os --unrestricted"' 69 | state=present 70 | tags: 71 | - section3 72 | - section3.3 73 | - section3.3.3 74 | 75 | 76 | - name: 3.3.4 Update Grub configuration (Scored) 77 | command: update-grub 78 | when: grub_cfg_file.stat.exists == True and (boot_superusers.rc == 1 or boot_password.rc == 1) 79 | tags: 80 | - section3 81 | - section3.3 82 | - section3.3.4 83 | 84 | 85 | - name: 3.4.1 Require Authentication for Single-User Mode (check) (Scored) 86 | shell: 'grep "^root:[*\!]:" /etc/shadow' 87 | register: root_password_set 88 | changed_when: False 89 | failed_when: False 90 | always_run: True 91 | tags: 92 | - section3 93 | - section3.4 94 | - section3.4.1 95 | 96 | - name: 3.4.2 Require Authentication for Single-User Mode (Scored) 97 | user: name=root state=present password='{{ root_password }}' 98 | when: root_password_set.rc == 1 99 | tags: 100 | - section3 101 | - section3.4 102 | - section3.4.2 103 | 104 | - name: 3.1 Set User/Group Owner on bootloader config (Scored) 105 | file: path=/boot/grub/grub.cfg owner=root group=root 106 | when: grub_cfg_file.stat.exists == True 107 | tags: 108 | - section3 109 | - section3.1 110 | 111 | - name: 3.2 Set Permissions on bootloader config (Scored) 112 | file: path=/boot/grub/grub.cfg mode="o-rwx,g-rwx" 113 | when: grub_cfg_file.stat.exists == True 114 | become: yes 115 | tags: 116 | - section3 117 | - section3.2 118 | -------------------------------------------------------------------------------- /tasks/section_04.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_04_level1.yml 4 | tags: 5 | - section04 6 | - level1 7 | 8 | - include: section_04_level2.yml 9 | tags: 10 | - section04 11 | - level2 12 | -------------------------------------------------------------------------------- /tasks/section_04_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 4.1.1 Restrict Core Dumps (Scored) 4 | lineinfile: dest='/etc/security/limits.conf' line="* hard core 0" state=present insertbefore='^# End of file' 5 | tags: 6 | - section4 7 | - section4.1 8 | - section4.1.1 9 | 10 | - name: 4.1.2 Restrict Core Dumps (Scored) 11 | sysctl: > 12 | name=fs.suid_dumpable 13 | value=0 14 | state=present 15 | when: restrict_core_dumps == True 16 | tags: 17 | - section4 18 | - section4.1 19 | - section4.1.2 20 | 21 | - name: 4.1.4 Restrict Core Dumps (stat file) (Scored) 22 | stat: path='/etc/init/apport.conf' 23 | register: apport_present 24 | tags: 25 | - section4 26 | - section4.1 27 | - section4.1.4 28 | 29 | - name: 4.1.5 Restrict Core Dumps (Scored) 30 | lineinfile: > 31 | dest='/etc/init/apport.conf' 32 | line='#start on runlevel [2345]' 33 | state=present 34 | regexp='start on runlevel' 35 | when: apport_present.stat.exists == True 36 | tags: 37 | - section4 38 | - section4.1 39 | - section4.1.3 40 | 41 | - name: 4.1.6 Restrict Core Dumps (stat file) (Scored) 42 | stat: path='/etc/init/whoopsie.conf' 43 | register: whoopsie_present 44 | tags: 45 | - section4 46 | - section4.1 47 | - section4.1.4 48 | 49 | - name: 4.1.7 Restrict Core Dumps (Scored) 50 | lineinfile: > 51 | dest='/etc/init/whoopsie.conf' 52 | line='#start on runlevel [2345]' 53 | state=present 54 | regexp='start on runlevel' 55 | when: whoopsie_present.stat.exists == True 56 | tags: 57 | - section4 58 | - section4.1 59 | - section4.1.4 60 | 61 | - name: 4.2 Enable XD/NX Support on 32-bit x86 Systems (read dmesg) (Not Scored) 62 | shell: 'dmesg | grep NX' 63 | register: nx_result 64 | failed_when: nx_result.rc == 1 65 | changed_when: False 66 | ignore_errors: True 67 | tags: 68 | - section4 69 | - section4.2 70 | 71 | - name: 4.3 Enable Randomized Virtual Memory Region Placement (Scored) 72 | sysctl: > 73 | name=kernel.randomize_va_space 74 | value=2 75 | state=present 76 | when: enable_aslr 77 | tags: 78 | - section4 79 | - section4.3 80 | 81 | - name: 4.4.1 Disable Prelink (check) (Scored) 82 | stat: path=/usr/sbin/prelink 83 | register: prelink_rc 84 | tags: 85 | - section4 86 | - section4.4 87 | 88 | - name: 4.4.2 Disable Prelink (restore) (Scored) 89 | command: '/usr/sbin/prelink -ua' 90 | when: prelink_rc.stat.exists == True 91 | tags: 92 | - section4 93 | - section4.4 94 | 95 | - name: 4.4.3 Disable Prelink (remove) (Scored) 96 | apt: purge=yes name='prelink' state=absent 97 | when: prelink_rc.stat.exists == True 98 | tags: 99 | - section4 100 | - section4.4 101 | -------------------------------------------------------------------------------- /tasks/section_04_level2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 4.5.1 Check if the grub config file exists (Not Scored) 4 | stat: path=/etc/default/grub 5 | register: grub_cfg_file 6 | tags: 7 | - section4 8 | - section4.5 9 | 10 | - name: 4.5.2 Determines if AppArmor is set in grub config (Not Scored) 11 | command: "grep 'GRUB_CMDLINE_LINUX' /etc/default/grub" 12 | register: grub_apparmor 13 | changed_when: False 14 | when: grub_cfg_file.stat.exists 15 | always_run: True 16 | tags: 17 | - section4 18 | - section4.5 19 | 20 | - name: 4.5.3 Check if the extlinux config file exists (Not Scored) 21 | stat: path=/extlinux.conf 22 | register: extlinux_cfg_file 23 | tags: 24 | - section4 25 | - section4.5 26 | 27 | - name: 4.5.4 Determines if AppArmor is set in extlinux (Not Scored) 28 | command: "grep 'apparmor' /extlinux.conf" 29 | register: extlinux_apparmor 30 | changed_when: False 31 | when: extlinux_cfg_file.stat.exists 32 | always_run: True 33 | tags: 34 | - section4 35 | - section4.5 36 | 37 | - name: 4.5.5 Determines if AppArmor is already set in boot config (Not Scored) 38 | command: "grep CONFIG_DEFAULT_SECURITY_APPARMOR /boot/config-{{ ansible_kernel }}" 39 | register: boot_apparmor 40 | changed_when: False 41 | always_run: True 42 | tags: 43 | - section4 44 | - section4.5 45 | 46 | - name: 4.5.6 Activate AppArmor (install) (Scored) 47 | apt: > 48 | name=apparmor 49 | state=present 50 | when: use_apparmor == True 51 | tags: 52 | - section4 53 | - section4.5 54 | 55 | - name: 4.5.7 Activate AppArmor (Kernel LSM - grub) (Scored) 56 | lineinfile: > 57 | dest='/etc/default/grub' 58 | regexp='^GRUB_CMDLINE_LINUX=""' 59 | line='GRUB_CMDLINE_LINUX=apparmor="1 security=apparmor"' 60 | state=present 61 | when: "(use_apparmor == True) and grub_cfg_file.stat.exists and ('apparmor' not in grub_apparmor['stdout']) and ('not set' in boot_apparmor['stdout'])" 62 | tags: 63 | - section4 64 | - section4.5 65 | 66 | - name: 4.5.8 Activate AppArmor (Kernel LSM - extlinux) (Scored) 67 | lineinfile: > 68 | dest='/extlinux.conf' 69 | regexp="^append initrd=" 70 | line="append initrd={{ ansible_cmdline['initrd'] }} root={{ ansible_cmdline['root'] }} console=tty0 console={{ ansible_cmdline['console'] }} apparmor=1 security=apparmor ro quiet" 71 | when: "(use_apparmor == True) and extlinux_cfg_file.stat.exists and ('apparmor' not in extlinux_apparmor['stdout']) and ('not set' in boot_cfg_apparmor['stdout'])" 72 | tags: 73 | - section4 74 | - section4.5 75 | 76 | - name: 4.5.9 Activate AppArmor (start) (Scored) 77 | service: > 78 | name=apparmor 79 | state=started 80 | when: use_apparmor == True 81 | register: apparmor_status 82 | ignore_errors: True 83 | tags: 84 | - section4 85 | - section4.5 86 | 87 | - name: 4.5.10 Determine if AppArmor started without error (Not Scored) 88 | fail: msg="Apparmor can not be started. This is normal behavior if you run the playbook for the first time.\nPlease reboot the machine and run it again to proceed with the rest of the playbook." 89 | when: apparmor_status.failed is defined 90 | 91 | - name: 4.5.11 Fix rsyslog /run/utmp permissions (Not Scored) 92 | lineinfile: > 93 | dest="/etc/apparmor.d/usr.sbin.rsyslogd" 94 | line=" /run/utmp rk," 95 | insertbefore=" /var/spool/rsyslog/ r," 96 | state=present 97 | when: use_apparmor == True 98 | tags: 99 | - section4 100 | - section4.5 101 | 102 | - name: 4.5.12 Activate AppArmor (fix profiles) (Scored) 103 | service: > 104 | name=rsyslog 105 | state=restarted 106 | changed_when: False 107 | when: use_apparmor == True 108 | tags: 109 | - section4 110 | - section4.5 111 | 112 | - name: 4.5.13 Activate AppArmor (Scored) 113 | command: apparmor_status 114 | register: aa_status_lines 115 | failed_when: '"0 profiles are loaded" in aa_status_lines.stdout_lines or "0 processes are in complain mode." not in aa_status_lines.stdout_lines or "0 processes are unconfined but have a profile defined." not in aa_status_lines.stdout_lines' 116 | # - '"0 processes are unconfined but have a profile defined." not in aa_status_lines.stdout_lines' 117 | changed_when: False 118 | when: use_apparmor == True 119 | tags: 120 | - section4 121 | - section4.5 122 | 123 | - name: 4.5.14 Activate AppArmor (enforce install) (Scored) 124 | apt: > 125 | name=apparmor-utils 126 | state=present 127 | when: use_apparmor == True 128 | tags: 129 | - section4 130 | - section4.5 131 | 132 | - name: 4.5.15 Activate AppArmor (enforce) (Scored) 133 | #shell: 'aa-enforce /etc/apparmor.d/*' 134 | shell: for profile in /etc/apparmor.d/*; do aa-enforce $profile; done 135 | register: aaenforce_rc 136 | failed_when: aaenforce_rc.rc == 1 137 | changed_when: False 138 | when: use_apparmor == True 139 | tags: 140 | - section4 141 | - section4.5 142 | -------------------------------------------------------------------------------- /tasks/section_05.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_05_level1.yml 4 | tags: 5 | - section05 6 | - level1 7 | 8 | 9 | -------------------------------------------------------------------------------- /tasks/section_05_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 5.1.1 Ensure NIS is not installed (Scored) 4 | apt: name=nis state=absent purge=yes 5 | tags: 6 | - section5 7 | - section5.1 8 | - section5.1.1 9 | 10 | - name: 5.1.2.1 Ensure rsh, rlogin, rexec, talk, telnet, chargen, daytime, echo, discard, time is not enabled (stat inetd) (Scored) 11 | stat: path=/etc/inetd.conf 12 | register: inetd_path 13 | tags: 14 | - section5 15 | - section5.1 16 | - section5.1.2 17 | 18 | - name: 5.1.2.2 Ensure rsh, rlogin, rexec, talk, telnet, chargen, daytime, echo, discard, time is not enabled (Scored) 19 | lineinfile: > 20 | dest=/etc/inetd.conf 21 | regexp='^({{ item }}.*)' 22 | line='#\1' 23 | state=present 24 | backrefs=yes 25 | backup=yes 26 | with_items: 27 | - shell 28 | - login 29 | - exec 30 | - talk 31 | - ntalk 32 | - telnet 33 | - chargen 34 | - daytime 35 | - echo 36 | - discard 37 | - time 38 | when: inetd_path.stat.exists == True 39 | tags: 40 | - section5 41 | - section5.1 42 | - section5.1.2 43 | 44 | - name: 5.1.3.1 Ensure rsh client is not installed (Scored) 45 | apt: name=rsh-client state=absent purge=yes 46 | tags: 47 | - section5 48 | - section5.1 49 | - section5.1.3 50 | 51 | - name: 5.1.3.2 Ensure rsh client is not installed (Scored) 52 | apt: name=rsh-redone-client state=absent purge=yes 53 | tags: 54 | - section5 55 | - section5.1 56 | - section5.1.3 57 | 58 | - name: 5.1.5 Ensure talk client is not installed (Scored) 59 | apt: name=talk state=absent purge=yes 60 | tags: 61 | - section5 62 | - section5.1 63 | - section5.1.5 64 | 65 | - name: 5.1.8.1 Ensure xinetd is not enabled (stat xinetd) (Scored) 66 | stat: path=/etc/init/xinetd.conf 67 | register: xinetd_path 68 | tags: 69 | - section5 70 | - section5.1 71 | - section5.1.8 72 | 73 | - name: 5.1.8.2 Ensure xinetd is not enabled (Scored) 74 | lineinfile: > 75 | dest=/etc/init/xinetd.conf 76 | regexp='start on runlevel' 77 | state=present 78 | line='#start on runlevel [2345]' 79 | when: xinetd_path.stat.exists == True 80 | tags: 81 | - section5 82 | - section5.1 83 | - section5.1.8 84 | -------------------------------------------------------------------------------- /tasks/section_06.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_06_level1.yml 4 | tags: 5 | - section06 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_06_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 6.1 Ensure the X Window system is not installed (Scored) 4 | apt: name=xserver-xorg-core* purge=yes state=absent 5 | when: remove_xserver == True 6 | tags: 7 | - section6 8 | - section6.1 9 | 10 | - name: 6.2.1 Ensure Avahi Server is not enabled (check) (Scored) 11 | stat: path='/etc/init/avahi-daemon.conf' 12 | register: avahi_stat 13 | tags: 14 | - section6 15 | - section6.2 16 | 17 | - name: 6.2.2 Ensure Avahi Server is not enabled (Scored) 18 | lineinfile: > 19 | line='#start on (filesystem' 20 | state=present 21 | regexp='start on \(filesystem' 22 | dest=/etc/init/avahi-daemon.conf 23 | when: avahi_stat.stat.exists == True 24 | tags: 25 | - section6 26 | - section6.2 27 | 28 | - name: 6.3.1 Ensure print server is not enabled (check) (Not Scored) 29 | stat: path='/etc/init/cups.conf' 30 | register: cups_stat 31 | tags: 32 | - section6 33 | - section6.3 34 | 35 | - name: 6.3.2 Ensure print server is not enabled (Not Scored) 36 | lineinfile: > 37 | line='#start on (filesystem' 38 | state=present 39 | regexp='start on \(filesystem' 40 | dest=/etc/init/cups.conf 41 | when: cups_stat.stat.exists == True 42 | tags: 43 | - section6 44 | - section6.3 45 | 46 | - name: 6.4.1.1 Ensure DHCP Server is not enabled (check) (Scored) 47 | stat: path='/etc/init/isc-dhcp-server.conf' 48 | register: dhcp_stat 49 | tags: 50 | - section6 51 | - section6.4 52 | - section6.4.1 53 | 54 | - name: 6.4.1.2 Ensure DHCP Server is not enabled (Scored) 55 | lineinfile: > 56 | line='#start on runlevel [2345]' 57 | state=present 58 | regexp='start on runlevel' 59 | dest=/etc/init/isc-dhcp-server.conf 60 | when: dhcp_stat.stat.exists == True 61 | tags: 62 | - section6 63 | - section6.4 64 | - section6.4.1 65 | 66 | - name: 6.4.2.1 Ensure DHCP Server is not enabled (check) (Scored) 67 | stat: path='/etc/init/isc-dhcp-server6.conf' 68 | register: dhcp6_stat 69 | tags: 70 | - section6 71 | - section6.4 72 | - section6.4.2 73 | 74 | - name: 6.4.2.2 Ensure DHCP Server is not enabled (Scored) 75 | lineinfile: > 76 | line='#start on runlevel [2345]' 77 | state=present 78 | regexp='start on runlevel' 79 | dest=/etc/init/isc-dhcp-server6.conf 80 | when: dhcp6_stat.stat.exists == True 81 | tags: 82 | - section6 83 | - section6.4 84 | - section6.4.2 85 | 86 | - name: 6.5.1.1 Configure Network Time Protocol (install) (NTP) (Scored) 87 | apt: name=ntp state=present 88 | tags: 89 | - section6 90 | - section6.5 91 | - section6.5.1 92 | 93 | - name: 6.5.1.2 Check if /etc/ntp.conf file exists (stat) 94 | stat: 95 | path: /etc/ntp.conf 96 | register: ntp_conf_file 97 | tags: 98 | - section6 99 | - section6.5 100 | - section6.5.1 101 | 102 | - include: section_06_level1_05.yml 103 | when: ntp_conf_file.stat.exists == True 104 | 105 | - name: 6.6 Ensure LDAP is not enabled (Not Scored) 106 | apt: name=slapd purge=yes state=absent 107 | tags: 108 | - section6 109 | - section6.6 110 | 111 | - name: 6.7.1 Ensure NFS and RPC are not enabled (stat) (Not Scored) 112 | stat: path=/etc/init/rpcbind-boot.conf 113 | register: nfs_rpc_rc 114 | tags: 115 | - section6 116 | - section6.7 117 | - section6.7.1 118 | 119 | - name: 6.7.2.1 Ensure NFS and RPC are not enabled (Not Scored) 120 | lineinfile: > 121 | dest=/etc/init/rpcbind-boot.conf 122 | line='#start on virtual-filesystems and net-device-up IFACE=lo' 123 | state=present 124 | regexp='start on virtual-filesystems and net' 125 | when: nfs_rpc_rc.stat.exists == True 126 | tags: 127 | - section6 128 | - section6.7 129 | - section6.7.2 130 | 131 | - name: 6.7.2.2 Ensure NFS and RPC are not enabled (check) (Not Scored) 132 | command: dpkg -S nfs-kernel-server 133 | changed_when: False 134 | failed_when: False 135 | always_run: True 136 | register: nfs_present 137 | tags: 138 | - section6 139 | - section6.7 140 | - section6.7.2 141 | 142 | - name: 6.7.2.3 Ensure NFS and RPC are not enabled (rc.d) (Not Scored) 143 | service: > 144 | name=nfs-kernel-server 145 | enabled=no 146 | when: nfs_present is defined and nfs_present.rc == 0 147 | register: nfs_service_result 148 | failed_when: "nfs_service_result|failed and 'service not found' not in nfs_service_result.msg" 149 | tags: 150 | - section6 151 | - section6.7 152 | - section6.7.2 153 | 154 | - name: 6.8-14 Ensure DNS,FTP,HTTP,IMAP,POP,Samba,Proxy,SNMP Servers are not enabled (Not Scored) 155 | service: > 156 | name={{ item }} 157 | enabled=no 158 | with_items: 159 | - bind9 160 | - vsftpd 161 | - apache2 162 | - dovecot 163 | - smbd 164 | - squid3 165 | - snmpd 166 | failed_when: False 167 | tags: 168 | - section6 169 | - section6.8 170 | - section6.9 171 | - section6.10 172 | - section6.11 173 | - section6.12 174 | - section6.13 175 | - section6.14 176 | 177 | - name: 6.15.1 Configure Mail Transfer Agent for Local-Only Mode (check) (Scored) 178 | stat: path=/etc/postfix/main.cf 179 | register: postfix_main_cf 180 | tags: 181 | - section6 182 | - section6.15 183 | 184 | - name: 6.15.2 Configure Mail Transfer Agent for Local-Only Mode (Scored) 185 | lineinfile: > 186 | dest=/etc/postfix/main.cf 187 | regexp='^inet_interfaces =' 188 | line='inet_interfaces = localhost' 189 | state=present 190 | when: postfix_main_cf.stat.exists == True 191 | tags: 192 | - section6 193 | - section6.15 194 | 195 | - name: 6.15.3 Configure Mail Transfer Agent for Local-Only Mode (Scored) 196 | lineinfile: > 197 | dest=/etc/postfix/main.cf 198 | regexp='^inet_protocols =' 199 | line='inet_protocols = ipv4' 200 | state=present 201 | when: postfix_main_cf.stat.exists == True and disable_ipv6 == True 202 | tags: 203 | - section6 204 | - section6.15 205 | 206 | - name: 6.16.1 Ensure rsync service is not enabled (check) (Scored) 207 | stat: path=/etc/default/rsync 208 | register: default_rsync 209 | tags: 210 | - section6 211 | - section6.16 212 | 213 | - name: 6.16.2 Ensure rsync service is not enabled (Scored) 214 | lineinfile: > 215 | dest='/etc/default/rsync' 216 | regexp='^RSYNC_ENABLE' 217 | line='RSYNC_ENABLE=false' 218 | when: default_rsync.stat.exists == True 219 | tags: 220 | - section6 221 | - section6.16 222 | 223 | - name: 6.17 Ensure Biosdevname is not enabled (Scored) 224 | apt: name=biosdevname purge=yes state=absent 225 | tags: 226 | - section6 227 | - section6.17 228 | -------------------------------------------------------------------------------- /tasks/section_06_level1_05.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 6.5.2 Configure Network Time Protocol (restrict4) (NTP) (Scored) 4 | lineinfile: > 5 | dest='/etc/ntp.conf' 6 | line='restrict -4 default kod nomodify notrap nopeer noquery' 7 | regexp='^restrict -4 default' 8 | state=present 9 | tags: 10 | - section6 11 | - section6.5 12 | - section6.5.2 13 | 14 | - name: 6.5.3 Configure Network Time Protocol (restrict6) (NTP) (Scored) 15 | lineinfile: > 16 | dest='/etc/ntp.conf' 17 | line='restrict -6 default kod nomodify notrap nopeer noquery' 18 | regexp='^restrict -6 default' 19 | state=present 20 | tags: 21 | - section6 22 | - section6.5 23 | - section6.5.3 24 | 25 | - name: 6.5.4.1 Configure Network Time Protocol (server check) (NTP) (Scored) 26 | command: 'grep "^server" /etc/ntp.conf' 27 | register: ntp_server_rc 28 | changed_when: False 29 | always_run: True 30 | ignore_errors: True 31 | tags: 32 | - section6 33 | - section6.5 34 | - section6.5.4 35 | 36 | - name: 6.5.4.2 Configure Network Time Protocol (server add) (NTP) (Scored) 37 | lineinfile: > 38 | dest='/etc/ntp.conf' 39 | line='server {{ ntp_server }}' 40 | state=present 41 | when: ntp_server_rc.rc == 1 42 | tags: 43 | - section6 44 | - section6.5 45 | - section6.5.4 46 | -------------------------------------------------------------------------------- /tasks/section_07.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_07_level1.yml 4 | tags: 5 | - section07 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_07_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 7.1.1 Disable IP Forwarding (Scored) 4 | sysctl: > 5 | name=net.ipv4.ip_forward 6 | value={{net_ipv4_ip_forward}} 7 | state=present 8 | tags: 9 | - section7 10 | - section7.1 11 | - section7.1.1 12 | 13 | - name: 7.1.2.1 Disable Send Packet Redirects (Scored) 14 | sysctl: > 15 | name=net.ipv4.conf.all.send_redirects 16 | value=0 17 | state=present 18 | tags: 19 | - section7 20 | - section7.1 21 | - section7.1.2 22 | 23 | - name: 7.1.2.2 Disable Send Packet Redirects (Scored) 24 | sysctl: > 25 | name=net.ipv4.conf.default.send_redirects 26 | value=0 27 | state=present 28 | tags: 29 | - section7 30 | - section7.1 31 | - section7.1.2 32 | 33 | - name: 7.2.1.1 Disable Source Routed Packet Acceptance (Scored) 34 | sysctl: > 35 | name=net.ipv4.conf.all.accept_source_route 36 | value=0 37 | state=present 38 | tags: 39 | - section7 40 | - section7.2 41 | - section7.2.1 42 | 43 | - name: 7.2.1.2 Disable Source Routed Packet Acceptance (Scored) 44 | sysctl: > 45 | name=net.ipv4.conf.default.accept_source_route 46 | value=0 47 | state=present 48 | tags: 49 | - section7 50 | - section7.2 51 | - section7.2.1 52 | 53 | - name: 7.2.2.1 Disable ICMP Redirect Acceptance (Scored) 54 | sysctl: > 55 | name=net.ipv4.conf.all.accept_redirects 56 | value=0 57 | state=present 58 | tags: 59 | - section7 60 | - section7.2 61 | - section7.2.2 62 | 63 | - name: 7.2.2.2 Disable ICMP Redirect Acceptance (Scored) 64 | sysctl: > 65 | name=net.ipv4.conf.default.accept_redirects 66 | value=0 67 | state=present 68 | tags: 69 | - section7 70 | - section7.2 71 | - section7.2.2 72 | 73 | - name: 7.2.3.1 Disable Secure ICMP Redirect Acceptance (Scored) 74 | sysctl: > 75 | name=net.ipv4.conf.all.secure_redirects 76 | value=0 77 | state=present 78 | tags: 79 | - section7 80 | - section7.2 81 | - section7.2.3 82 | 83 | - name: 7.2.3.2 Disable Secure ICMP Redirect Acceptance (Scored) 84 | sysctl: > 85 | name=net.ipv4.conf.default.secure_redirects 86 | value=0 87 | state=present 88 | tags: 89 | - section7 90 | - section7.2 91 | - section7.2.3 92 | 93 | - name: 7.2.4.1 Log Suspicious Packets (Scored) 94 | sysctl: > 95 | name=net.ipv4.conf.all.log_martians 96 | value=1 97 | state=present 98 | tags: 99 | - section7 100 | - section7.2 101 | - section7.2.4 102 | 103 | - name: 7.2.4.2 Log Suspicious Packets (Scored) 104 | sysctl: > 105 | name=net.ipv4.conf.default.log_martians 106 | value=1 107 | state=present 108 | tags: 109 | - section7 110 | - section7.2 111 | - section7.2.4 112 | 113 | - name: 7.2.4.3 Log Suspicious Packets (flushing tables) (Scored) 114 | sysctl: > 115 | name=net.ipv4.route.flush 116 | value=1 117 | state=present 118 | tags: 119 | - section7 120 | - section7.2 121 | - section7.2.4 122 | 123 | - name: 7.2.5 Enable Ignore Broadcast Requests (Scored) 124 | sysctl: > 125 | name=net.ipv4.icmp_echo_ignore_broadcasts 126 | value=1 127 | state=present 128 | tags: 129 | - section7 130 | - section7.2 131 | - section7.2.5 132 | 133 | - name: 7.2.6 Enable Bad Error Message Protection (Scored) 134 | sysctl: > 135 | name=net.ipv4.icmp_ignore_bogus_error_responses 136 | value=1 137 | state=present 138 | tags: 139 | - section7 140 | - section7.2 141 | - section7.2.6 142 | 143 | - name: 7.2.7.1 Enable RFC-recommended Source Route Validation (Scored) 144 | sysctl: > 145 | name=net.ipv4.conf.all.rp_filter 146 | value=1 147 | state=present 148 | tags: 149 | - section7 150 | - section7.2 151 | - section7.2.7 152 | 153 | - name: 7.2.7.2 Enable RFC-recommended Source Route Validation (Scored) 154 | sysctl: > 155 | name=net.ipv4.conf.default.rp_filter 156 | value=1 157 | state=present 158 | tags: 159 | - section7 160 | - section7.2 161 | - section7.2.7 162 | 163 | - name: 7.2.8 Enable TCP SYN Cookies (Scored) 164 | sysctl: > 165 | name=net.ipv4.tcp_syncookies 166 | value=1 167 | state=present 168 | when: enable_tcp_syncookies 169 | tags: 170 | - section7 171 | - section7.2 172 | - section7.2.8 173 | 174 | - name: 7.3.1.1 Disable IPv6 Router Advertisements (Not Scored) 175 | sysctl: > 176 | name=net.ipv6.conf.all.accept_ra 177 | value=0 178 | state=present 179 | tags: 180 | - section7 181 | - section7.3 182 | - section7.3.1 183 | 184 | - name: 7.3.1.2 Disable IPv6 Router Advertisements (Not Scored) 185 | sysctl: > 186 | name=net.ipv6.conf.default.accept_ra 187 | value=0 188 | state=present 189 | tags: 190 | - section7 191 | - section7.3 192 | - section7.3.1 193 | 194 | - name: 7.3.2.1 Disable IPv6 Redirect Acceptance (Not Scored) 195 | sysctl: > 196 | name=net.ipv6.conf.all.accept_redirects 197 | value=0 198 | state=present 199 | tags: 200 | - section7 201 | - section7.3 202 | - section7.3.2 203 | 204 | - name: 7.3.2.2 Disable IPv6 Redirect Acceptance (Not Scored) 205 | sysctl: > 206 | name=net.ipv6.conf.default.accept_redirects 207 | value=0 208 | state=present 209 | tags: 210 | - section7 211 | - section7.3 212 | - section7.3.2 213 | 214 | - name: 7.3.3 Disable IPv6 (Not Scored) 215 | sysctl: > 216 | name={{ item }} 217 | value=1 218 | state=present 219 | with_items: 220 | - net.ipv6.conf.all.disable_ipv6 221 | - net.ipv6.conf.default.disable_ipv6 222 | - net.ipv6.conf.lo.disable_ipv6 223 | when: disable_ipv6 == True 224 | tags: 225 | - section7 226 | - section7.3 227 | - section7.3.3 228 | 229 | - name: 7.4.1 Install TCP Wrappers (Scored) 230 | apt: name=tcpd state=present 231 | tags: 232 | - section7 233 | - section7.4 234 | - section7.4.1 235 | 236 | - name: 7.4.2 Create /etc/hosts.allow (Not Scored) 237 | debug: msg="*** Verify /etc/hosts.allow ***" 238 | tags: 239 | - section7 240 | - section7.4 241 | - section7.4.2 242 | 243 | - name: 7.4.3 Verify Permissions on /etc/hosts.allow (Scored) 244 | file: > 245 | path=/etc/hosts.allow 246 | owner=root 247 | group=root 248 | mode=0644 249 | tags: 250 | - section7 251 | - section7.4 252 | - section7.4.3 253 | 254 | - name: 7.4.4 Create /etc/hosts.deny (Not Scored) 255 | debug: msg='*** Verify /etc/hosts.deny ***' 256 | tags: 257 | - section7 258 | - section7.4 259 | - section7.4.4 260 | 261 | - name: 7.4.5 Verify Permissions on /etc/hosts.deny (Scored) 262 | file: > 263 | path=/etc/hosts.deny 264 | owner=root 265 | group=root 266 | mode=0644 267 | tags: 268 | - section7 269 | - section7.4 270 | - section7.4.5 271 | 272 | - name: 7.5.0 Ensures /etc/modprobe.d/ exists (Not Scored) 273 | file: > 274 | path=/etc/modprobe.d 275 | state=directory 276 | register: cis_conf_file 277 | tags: 278 | - section7 279 | - section7.5 280 | 281 | - name: 7.5.1-4 Disable DCCP, SCTP, RDS, TIPC (Not Scored) 282 | lineinfile: > 283 | dest=/etc/modprobe.d/CIS.conf 284 | line='install {{ item }} /bin/true' 285 | state=present 286 | create=True 287 | with_items: 288 | - dccp 289 | - sctp 290 | - rds 291 | - tipc 292 | tags: 293 | - section7 294 | - section7.5 295 | - section7.5.1 296 | - section7.5.2 297 | - section7.5.3 298 | - section7.5.4 299 | 300 | - name: 7.6 Deactivate Wireless Interfaces (Not Scored) 301 | shell: 'lspci -k | grep -i wifi' 302 | changed_when: False 303 | register: lspci_wifi 304 | failed_when: lspci_wifi.rc == 0 305 | tags: 306 | - section7 307 | - section7.6 308 | 309 | - name: 7.7.1 Ensure Firewall is active (install) (Scored) 310 | apt: > 311 | name=ufw 312 | state=present 313 | when: activate_ufw 314 | tags: 315 | - section7 316 | - section7.7 317 | 318 | - name: 7.7.2 Ensure Firewall is active (started) (Scored) 319 | service: > 320 | name=ufw 321 | state=started 322 | when: activate_ufw 323 | tags: 324 | - section7 325 | - section7.7 326 | 327 | - name: 7.7.3 Ensure Firewall is active (enabled) (Scored) 328 | lineinfile: > 329 | dest=/etc/ufw/ufw.conf 330 | regexp='ENABLED=' 331 | line='ENABLED=yes' 332 | state=present 333 | create=yes 334 | when: activate_ufw 335 | tags: 336 | - section7 337 | - section7.7 338 | -------------------------------------------------------------------------------- /tasks/section_08.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_08_level1.yml 4 | tags: 5 | - section08 6 | - level1 7 | 8 | 9 | - include: section_08_level2.yml 10 | tags: 11 | - section08 12 | - level2 13 | 14 | -------------------------------------------------------------------------------- /tasks/section_08_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # - name: 8.2 Configure rsyslog 4 | # The rsyslog software is recommended as a replacement for the default syslogd daemon and 5 | # provides improvements over syslogd, such as connection-oriented (i.e. TCP) transmission 6 | # of logs, the option to log to database formats, and the encryption of log data en route to a 7 | # central logging server. 8 | # tags: 9 | # - section8 10 | # - section8.2 11 | 12 | 13 | - name: 8.2.1 Install the rsyslog package (Scored) 14 | apt: name=rsyslog state=present 15 | tags: 16 | - section8 17 | - section8.2 18 | - section8.2.1 19 | 20 | - name: 8.2.2.1 Ensure the rsyslog Service is activated (check) (Scored) 21 | command: grep 'start on filesystem' /etc/rsyslog.conf 22 | register: startonfilesystem 23 | changed_when: False 24 | failed_when: False 25 | always_run: True 26 | tags: 27 | - section8 28 | - section8.2 29 | - section8.2.2 30 | 31 | - name: 8.2.2.2 Ensure the rsyslog Service is activated (Scored) 32 | lineinfile: 33 | dest=/etc/rsyslog.conf 34 | line='start on filesystem' 35 | insertafter=EOF 36 | state=present 37 | when: startonfilesystem.rc == 1 38 | tags: 39 | - section8 40 | - section8.2 41 | - section8.2.2 42 | 43 | - name: 8.2.3 Configure /etc/rsyslog.conf (Not Scored) 44 | lineinfile: 45 | dest: /etc/rsyslog.conf 46 | line: "{{ item }}" 47 | insertafter: EOF 48 | with_items: 49 | - '*.emerg :omusrmsg:*' 50 | - 'mail.* -/var/log/mail' 51 | - 'mail.info -/var/log/mail.info' 52 | - 'mail.warning -/var/log/mail.warn' 53 | - 'mail.err /var/log/mail.err' 54 | - 'news.crit -/var/log/news/news.crit' 55 | - 'news.err -/var/log/news/news.err' 56 | - 'news.notice -/var/log/news/news.notice' 57 | - '*.=warning;*.=err -/var/log/warn' 58 | - '*.crit /var/log/warn' 59 | - '*.*;mail.none;news.none -/var/log/messages' 60 | - 'local0,local1.* -/var/log/localmessages' 61 | - 'local2,local3.* -/var/log/localmessages' 62 | - 'local4,local5.* -/var/log/localmessages' 63 | - 'local6,local7.* -/var/log/localmessages' 64 | changed_when: False 65 | notify: restart rsyslog 66 | tags: 67 | - section8 68 | - section8.2 69 | - section8.2.3 70 | 71 | - name: 8.2.4.1 Create and Set Permissions on rsyslog Log Files (check) (Scored) 72 | shell: awk '{ print $NF }' /etc/rsyslog.d/* /etc/rsyslog.conf | grep -oiP "/var/log/[\w\.-]+" 73 | register: result 74 | changed_when: False 75 | always_run: True 76 | tags: 77 | - section8 78 | - section8.2 79 | - section8.2.4 80 | 81 | - name: 8.2.4.2 Create and Set Permissions on rsyslog Log Files (Scored) 82 | shell: 'mkdir -p -- "$(dirname -- {{ item }})"; touch -- {{ item }}' 83 | with_items: "{{result.stdout_lines}}" 84 | changed_when: False 85 | register: rsyslog_files_created 86 | tags: 87 | - section8 88 | - section8.2 89 | - section8.2.4 90 | 91 | - name: 8.2.4.3 Create and Set Permissions on rsyslog Log Files (Scored) 92 | file: 93 | path: "{{ item }}" 94 | owner: root 95 | group: "{{ rsyslog_log_files_group }}" 96 | mode: "{{ rsyslog_log_files_permissions }}" 97 | when: "(rsyslog_files_created.results|length > 0) and ('skipped' not in rsyslog_files_created.results[0])" 98 | with_items: "{{result.stdout_lines}}" 99 | notify: restart rsyslog 100 | tags: 101 | - section8 102 | - section8.2 103 | - section8.2.4 104 | 105 | - name: 8.2.5.1 Configure rsyslog to Send Logs to a Remote Log Host (Scored) 106 | command: grep "^*.*[^I][^I]*@" /etc/rsyslog.conf 107 | register: remoteloghost 108 | changed_when: False 109 | failed_when: False 110 | always_run: True 111 | tags: 112 | - section8 113 | - section8.2 114 | - section8.2.5 115 | 116 | - name: 8.2.5.2 Configure rsyslog to Send Logs to a Remote Log Host (Scored) 117 | lineinfile: 118 | dest: /etc/rsyslog.conf 119 | line: "*.* @@{{remote_logs_host_address}}" 120 | insertafter: EOF 121 | state: present 122 | when: set_rsyslog_remote == True and remoteloghost.rc == 1 123 | tags: 124 | - section8 125 | - section8.2 126 | - section8.2.5 127 | 128 | - name: 8.2.6.1 Accept Remote rsyslog Messages Only on Designated Log Hosts (check) (Not Scored) 129 | command: grep '^$ModLoad imtcp' /etc/rsyslog.conf 130 | register: moadloadpresent 131 | changed_when: False 132 | failed_when: False 133 | always_run: True 134 | tags: 135 | - section8 136 | - section8.2 137 | - section8.2.6 138 | 139 | - name: 8.2.6.2 Accept Remote rsyslog Messages Only on Designated Log Hosts (Not Scored) 140 | lineinfile: 141 | dest: /etc/rsyslog.conf 142 | regexp: "^#({{ item }})" 143 | line: "{{ item }}" 144 | state: present 145 | with_items: 146 | - '$ModLoad imtcp' 147 | - '$InputTCPServerRun 514' 148 | when: set_rsyslog_remote == True and moadloadpresent.rc == 1 149 | changed_when: False 150 | notify: restart rsyslog 151 | tags: 152 | - section8 153 | - section8.2 154 | - section8.2.6 155 | -------------------------------------------------------------------------------- /tasks/section_08_level2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Change order or the default auditd.conf file will not be created 4 | - name: 8.1.2 Install and Enable auditd Service (Scored) 5 | apt: name=auditd state=present 6 | tags: 7 | - section8 8 | - section8.1 9 | - section8.1.2 10 | - section8.1.2 11 | 12 | - name: 8.1.1-3.1 Check if the file auditd.conf exists (Not Scored) 13 | stat: > 14 | path=/etc/audit/auditd.conf 15 | register: auditd_file 16 | tags: 17 | - section8 18 | - section8.1 19 | - section8.1.1 20 | - section8.1.1.1 21 | - section8.1.1.2 22 | - section8.1.1.3 23 | 24 | - name: 8.1.1-3.2 Create the audit directory if it does not exists (Not Scored) 25 | file: > 26 | path=/etc/audit/ 27 | state=directory 28 | when: not auditd_file.stat.exists 29 | tags: 30 | - section8 31 | - section8.1 32 | - section8.1.1 33 | - section8.1.1.1 34 | - section8.1.1.2 35 | - section8.1.1.3 36 | 37 | - name: 8.1.1-3.3 Configure Data Retention (Not Scored) 38 | lineinfile: > 39 | dest=/etc/audit/auditd.conf 40 | regexp="{{ item.rxp }}" 41 | line="{{ item.line }}" 42 | state=present 43 | create=yes 44 | with_items: 45 | - { rxp: '^max_log_file ', line: 'max_log_file = {{ max_log_file_auditd }}' } 46 | - { rxp: '^space_left_action', line: 'space_left_action = email' } 47 | - { rxp: '^action_mail_acct', line: 'action_mail_acct = root' } 48 | - { rxp: '^admin_space_left_action', line: 'admin_space_left_action = halt' } 49 | - { rxp: '^max_log_file_action', line: 'max_log_file_action = keep_logs' } 50 | notify: restart auditd 51 | tags: 52 | - section8 53 | - section8.1 54 | - section8.1.1 55 | - section8.1.1.1 56 | - section8.1.1.2 57 | - section8.1.1.3 58 | 59 | - name: 8.1.3.1 Enable Auditing for Processes That Start Prior to auditd (Scored) 60 | stat: path=/etc/default/grub 61 | register: grubcfg_file 62 | tags: 63 | - section8 64 | - section8.1 65 | - section8.1.3 66 | 67 | - name: 8.1.3.2 Enable Auditing for Processes That Start Prior to auditd (Scored) 68 | file: > 69 | path=/etc/default/grub 70 | state=touch 71 | when: not grubcfg_file.stat.exists 72 | tags: 73 | - section8 74 | - section8.1 75 | - section8.1.3 76 | 77 | - name: 8.1.3.3 Enable Auditing for Processes That Start Prior to auditd (Scored) 78 | lineinfile: > 79 | dest=/etc/default/grub 80 | regexp='GRUB_CMDLINE_LINUX="' 81 | line='GRUB_CMDLINE_LINUX="audit=1"' 82 | state=present 83 | create=yes 84 | tags: 85 | - section8 86 | - section8.1 87 | - section8.1.3 88 | 89 | - name: 8.1.4.1 Record Events That Modify Date and Time Information (Scored) 90 | lineinfile: > 91 | dest=/etc/audit/audit.rules 92 | line='{{ item }}' 93 | state=present 94 | create=yes 95 | with_items: 96 | - '-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change' 97 | - '-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change' 98 | - '-a always,exit -F arch=b64 -S clock_settime -k time-change' 99 | - '-a always,exit -F arch=b32 -S clock_settime -k time-change' 100 | - '-w /etc/localtime -p wa -k time-change' 101 | notify: restart auditd 102 | when: ansible_userspace_bits == "64" 103 | tags: 104 | - section8 105 | - section8.1 106 | - section8.1.4 107 | 108 | - name: 8.1.4.2 Record Events That Modify Date and Time Information (Scored) 109 | lineinfile: > 110 | dest=/etc/audit/audit.rules 111 | line='{{ item }}' 112 | state=present 113 | create=yes 114 | with_items: 115 | - '-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change' 116 | - '-a always,exit -F arch=b32 -S clock_settime -k time-change' 117 | - '-w /etc/localtime -p wa -k time-change' 118 | notify: restart auditd 119 | when: ansible_userspace_bits == "32" 120 | tags: 121 | - section8 122 | - section8.1 123 | - section8.1.4 124 | 125 | - name: 8.1.5,7,8,9,15,16,17 Record Events That Modify User/Group Information (Scored) 126 | lineinfile: > 127 | dest=/etc/audit/audit.rules 128 | line='{{ item }}' 129 | state=present 130 | create=yes 131 | with_items: 132 | - '-w /etc/group -p wa -k identity' 133 | - '-w /etc/passwd -p wa -k identity' 134 | - '-w /etc/gshadow -p wa -k identity' 135 | - '-w /etc/shadow -p wa -k identity' 136 | - '-w /etc/security/opasswd -p wa -k identity' 137 | - '-w /var/log/faillog -p wa -k logins' 138 | - '-w /var/log/lastlog -p wa -k logins' 139 | - '-w /var/log/tallylog -p wa -k logins' 140 | - '-w /var/run/utmp -p wa -k session' 141 | - '-w /var/log/wtmp -p wa -k session' 142 | - '-w /var/log/btmp -p wa -k session' 143 | - '-w /etc/selinux/ -p wa -k MAC-policy' 144 | - '-w /etc/sudoers -p wa -k scope' 145 | - '-w /var/log/sudo.log -p wa -k actions' 146 | - '-w /sbin/insmod -p x -k modules' 147 | - '-w /sbin/rmmod -px -k modules' 148 | - '-w /sbin/modprobe -p x -k modules' 149 | notify: restart auditd 150 | tags: 151 | - section8 152 | - section8.1 153 | - section8.1.5 154 | - section8.1.7 155 | - section8.1.8 156 | - section8.1.9 157 | - section8.1.15 158 | - section8.1.16 159 | - section8.1.17 160 | 161 | - name: 8.1.6,10,11,13,14,17.1 Record Events That Modify the System's Network Environment (64b) (Scored) 162 | lineinfile: > 163 | dest=/etc/audit/audit.rules 164 | line='{{ item }}' 165 | state=present 166 | create=yes 167 | with_items: 168 | - '-a exit,always -F arch=b64 -S sethostname -S setdomainname -k system-locale' 169 | - '-a exit,always -F arch=b32 -S sethostname -S setdomainname -k system-locale' 170 | - '-w /etc/issue -p wa -k system-locale' 171 | - '-w /etc/issue.net -p wa -k system-locale' 172 | - '-w /etc/hosts -p wa -k system-locale' 173 | - '-w /etc/network -p wa -k system-locale' 174 | - '-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod' 175 | - '-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod' 176 | - '-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod' 177 | - '-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod' 178 | - '-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod' 179 | - '-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod' 180 | - '-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access' 181 | - '-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access' 182 | - '-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access' 183 | - '-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access' 184 | - '-a always,exit -F arch=b64 -S mount -F auid>=500 -F auid!=4294967295 -k mounts' 185 | - '-a always,exit -F arch=b32 -S mount -F auid>=500 -F auid!=4294967295 -k mounts' 186 | - '-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete' 187 | - '-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete' 188 | - '-a always,exit -F arch=b64 -S init_module -S delete_module -k modules' 189 | notify: restart auditd 190 | when: ansible_userspace_bits == "64" 191 | tags: 192 | - section8 193 | - section8.1 194 | - section8.1.6 195 | - section8.1.10 196 | - section8.1.11 197 | - section8.1.13 198 | - section8.1.14 199 | - section8.1.17 200 | 201 | - name: 8.1.6,10,11,13,14,17.2 Record Events That Modify the System's Network Environment (32b) (Scored) 202 | lineinfile: > 203 | dest=/etc/audit/audit.rules 204 | line='{{ item }}' 205 | state=present 206 | create=yes 207 | with_items: 208 | - '-a exit,always -F arch=b32 -S sethostname -S setdomainname -k system-locale' 209 | - '-w /etc/issue -p wa -k system-locale' 210 | - '-w /etc/issue.net -p wa -k system-locale' 211 | - '-w /etc/hosts -p wa -k system-locale' 212 | - '-w /etc/network -p wa -k system-locale' 213 | - '-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod' 214 | - '-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod' 215 | - '-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod' 216 | - '-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access' 217 | - '-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access' 218 | - '-a always,exit -F arch=b32 -S mount -F auid>=500 -F auid!=4294967295 -k mounts' 219 | - '-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete' 220 | - '-a always,exit -F arch=b32 -S init_module -S delete_module -k modules' 221 | notify: restart auditd 222 | when: ansible_userspace_bits == "32" 223 | tags: 224 | - section8 225 | - section8.1 226 | - section8.1.6 227 | - section8.1.10 228 | - section8.1.11 229 | - section8.1.13 230 | - section8.1.14 231 | - section8.1.17 232 | 233 | - name: 8.3.1.1 Install AIDE (Scored) 234 | apt: name=aide state=present 235 | register: aide_installed 236 | when: use_aide == True 237 | tags: 238 | - section8 239 | - section8.3 240 | - section8.3.1 241 | 242 | - name: 8.3.1.2 Install AIDE (init) (Scored) 243 | command: aideinit 244 | when: 245 | - use_aide == True 246 | - aide_installed.changed == True 247 | tags: 248 | - section8 249 | - section8.3 250 | - section8.3.1 251 | 252 | - name: 8.3.1.3 Install AIDE (Scored) 253 | stat: path=/var/lib/aide/aide.db.new 254 | register: aide_db_path 255 | when: 256 | - use_aide == True 257 | - aide_installed.changed == True 258 | tags: 259 | - section8 260 | - section8.3 261 | - section8.3.1 262 | 263 | - name: 8.3.1.4 Install AIDE (copy db) (Scored) 264 | command: mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db 265 | when: 266 | - use_aide == True 267 | - aide_installed.changed == True 268 | - aide_db_path.stat.exists == True 269 | tags: 270 | - section8 271 | - section8.3 272 | - section8.3.1 273 | 274 | - name: 8.3.2 Implement Periodic Execution of File Integrity (Scored) 275 | cron: name="Check files integrity" minute="0" hour="5" job="/usr/sbin/aide --check" 276 | when: use_aide == True 277 | tags: 278 | - section8 279 | - section8.3 280 | - section8.3.2 281 | 282 | # We have to run the check after AIDE installation as postfix create new matched binaries 283 | - name: 8.1.12.1 Collect Use of Privileged Commands (Scored) 284 | shell: find / -xdev \( -perm -4000 -o -perm -2000 \) -type f | awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged" }' 285 | register: audit_lines_for_find 286 | changed_when: False 287 | tags: 288 | - section8 289 | - section8.1 290 | - section8.1.12 291 | 292 | - name: 8.1.12.2 Collect Use of Privileged Commands (infos) (Scored) 293 | lineinfile: > 294 | dest=/etc/audit/audit.rules 295 | line='{{ item }}' 296 | state=present 297 | create=yes 298 | with_items: "{{ audit_lines_for_find.stdout_lines }}" 299 | tags: 300 | - section8 301 | - section8.1 302 | - section8.1.12 303 | 304 | - name: 8.1.18 Make the Audit Configuration Immutable (Scored) 305 | lineinfile: > 306 | dest='/etc/audit/audit.rules' 307 | line='-e 2' 308 | insertafter=EOF 309 | state=present 310 | create=yes 311 | tags: 312 | - section8 313 | - section8.1 314 | - section8.1.18 315 | -------------------------------------------------------------------------------- /tasks/section_09.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_09_level1.yml 4 | tags: 5 | - section09 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_09_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 9.1.1.1 Check that cron conf file exists (check) (Scored) 4 | stat: path=/etc/init/cron.conf 5 | register: cron_conf_stat 6 | tags: 7 | - section9 8 | - section9.1 9 | - section9.1.1 10 | - section9.1.1.1 11 | 12 | - name: 9.1.1.2 Enable cron Daemon (Scored) 13 | service: > 14 | name=cron 15 | state=started 16 | enabled=yes 17 | when: not cron_conf_stat.stat.exists 18 | tags: 19 | - section9 20 | - section9.1 21 | - section9.1.1 22 | - section9.1.1.2 23 | 24 | - name: 9.1.2 Set User/Group Owner and Permission on /etc/crontab (Scored) 25 | file: path='/etc/crontab' owner=root group=root mode="og-rwx" 26 | tags: 27 | - section9 28 | - section9.1 29 | - section9.1.2 30 | 31 | - name: 9.1.3 Set User/Group Owner and Permission on /etc/cron.hourly (Scored) 32 | file: path=/etc/cron.hourly owner=root group=root mode="og-rwx" 33 | tags: 34 | - section9 35 | - section9.1 36 | - section9.1.3 37 | 38 | - name: 9.1.4 Set User/Group Owner and Permission on /etc/cron.daily (Scored) 39 | file: path=/etc/cron.daily owner=root group=root mode="og-rwx" 40 | tags: 41 | - section9 42 | - section9.1 43 | - section9.1.4 44 | 45 | - name: 9.1.5 Set User/Group Owner and Permission on /etc/cron.weekly (Scored) 46 | file: path=/etc/cron.weekly owner=root group=root mode="og-rwx" 47 | tags: 48 | - section9 49 | - section9.1 50 | - section9.1.5 51 | 52 | - name: 9.1.6 Set User/Group Owner and Permission on /etc/cron.monthly (Scored) 53 | file: path=/etc/cron.monthly owner=root group=root mode="og-rwx" 54 | tags: 55 | - section9 56 | - section9.1 57 | - section9.1.6 58 | 59 | - name: 9.1.7 Set User/Group Owner and Permission on /etc/cron.d (Scored) 60 | file: path=/etc/cron.d owner=root group=root mode="og-rwx" 61 | tags: 62 | - section9 63 | - section9.1 64 | - section9.1.7 65 | 66 | - name: 9.1.8.1 Restrict at/cron to Authorized Users (remove deny) (Scored) 67 | file: path={{ item }} state=absent 68 | with_items: 69 | - /etc/cron.deny 70 | - /etc/at.deny 71 | tags: 72 | - section9 73 | - section9.1 74 | - section9.1.8 75 | 76 | - name: 9.1.8.2 Restrict at/cron to Authorized Users (create cron allow) (Scored) 77 | copy: 78 | dest: /etc/cron.allow 79 | owner: root 80 | group: root 81 | mode: "og-rwx" 82 | content: "" 83 | force: no 84 | tags: 85 | - section9 86 | - section9.1 87 | - section9.1.8 88 | 89 | - name: 9.1.8.3 Restrict at/cron to Authorized Users (create at allow) (Scored) 90 | copy: 91 | dest: /etc/at.allow 92 | owner: root 93 | group: root 94 | mode: "og-rwx" 95 | content: "" 96 | force: no 97 | tags: 98 | - section9 99 | - section9.1 100 | - section9.1.8 101 | 102 | - name: 9.2.1.1 Set Password Creation Requirement Parameters Using pam_cracklib (install) (Scored) 103 | apt: name=libpam-cracklib state=present 104 | when: use_pam_cracklib == True 105 | tags: 106 | - section9 107 | - section9.2 108 | - section9.2.1 109 | 110 | - name: 9.2.1.2 Set Password Creation Requirement Parameters Using pam_cracklib (Scored) 111 | lineinfile: > 112 | dest='/etc/pam.d/common-password' 113 | regexp="pam_cracklib.so" 114 | line="password required pam_cracklib.so retry=3 minlen=14 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1" 115 | state=present 116 | when: use_pam_cracklib == True 117 | tags: 118 | - section9 119 | - section9.2 120 | - section9.2.1 121 | 122 | #Note for section 9.2.2: 123 | #If a user has been locked out because they have reached the maximum consecutive failure count 124 | #defined by denied= in the pam_tally2.so module, the user can be unlocked by issuing the command 125 | #/sbin/pam_tally2 -u username --reset 126 | #This command sets the failed count to 0, effectively unlocking the user 127 | - name: 9.2.2 Set Lockout for Failed Password Attempts (Not Scored) 128 | lineinfile: > 129 | dest='/etc/pam.d/login' 130 | regexp='pam_tally2' 131 | line="auth required pam_tally2.so onerr=fail audit silent deny=5 unlock_time=900" 132 | state=present 133 | tags: 134 | - section9 135 | - section9.2 136 | - section9.2.2 137 | 138 | - name: 9.2.3 Limit Password Reuse (Scored) 139 | lineinfile: > 140 | dest='/etc/pam.d/common-password' 141 | regexp='remember=5' 142 | line="password sufficient pam_unix.so remember=5" 143 | state=present 144 | tags: 145 | - section9 146 | - section9.2 147 | - section9.2.3 148 | 149 | - name: 9.3 Check if ssh is installed (check) (Not Scored) 150 | stat: path='/etc/ssh/sshd_config' 151 | register: ssh_config_file 152 | tags: 153 | - section9 154 | - section9.3 155 | - section9.3.1 156 | 157 | - include: section_09_level1_03.yml 158 | when: ssh_config_file.stat.exists == True 159 | 160 | - name: 9.4.1 Restrict root Login to System Console (check) (Not Scored) 161 | stat: path=/etc/securetty 162 | register: securetty_file 163 | tags: 164 | - section9 165 | - section9.4 166 | 167 | - name: 9.4.2 Restrict root Login to System Console (Not Scored) 168 | debug: msg='*** Check /etc/securetty for console allowed for root access ***' 169 | when: securetty_file.stat.exists == True 170 | tags: 171 | - section9 172 | - section9.4 173 | 174 | - name: 9.5.1 Restrict Access to the su Command (Scored) 175 | lineinfile: > 176 | dest='/etc/pam.d/su' 177 | line='auth required pam_wheel.so use_uid' 178 | state=present 179 | tags: 180 | - section9 181 | - section9.5 182 | - section9.5.1 183 | -------------------------------------------------------------------------------- /tasks/section_09_level1_03.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 9.3.1 Set SSH Protocol to 2 (Scored) 4 | lineinfile: > 5 | dest='/etc/ssh/sshd_config' 6 | regexp='^Protocol' 7 | state=present 8 | line='Protocol 2' 9 | notify: restart ssh 10 | tags: 11 | - section9 12 | - section9.3 13 | - section9.3.1 14 | 15 | - name: 9.3.2 Set LogLevel to INFO (Scored) 16 | lineinfile: > 17 | dest='/etc/ssh/sshd_config' 18 | regexp='^LogLevel' 19 | state=present 20 | line='LogLevel INFO' 21 | notify: restart ssh 22 | tags: 23 | - section9 24 | - section9.3 25 | - section9.3.2 26 | 27 | - name: 9.3.3 Set Permissions on /etc/ssh/sshd_config (Scored) 28 | file: path='/etc/ssh/sshd_config' owner=root group=root mode=600 29 | notify: restart ssh 30 | tags: 31 | - section9 32 | - section9.3 33 | - section9.3.3 34 | 35 | #Regroups sections 9.3.4 9.3.7 9.3.8 9.3.9 9.3.10 36 | - name: 9.3.{4,7,8,9,10} Disable some SSH options (Scored) 37 | lineinfile: > 38 | dest='/etc/ssh/sshd_config' 39 | regexp='^{{ item }}' 40 | line='{{ item }} no' 41 | state=present 42 | with_items: 43 | - X11Forwarding 44 | - HostbasedAuthentication 45 | - PermitRootLogin 46 | - PermitEmptyPasswords 47 | - PermitUserEnvironment 48 | notify: restart ssh 49 | tags: 50 | - section9 51 | - section9.3 52 | - section9.3.4 53 | - section9.3.7 54 | - section9.3.8 55 | - section9.3.9 56 | - section9.3.10 57 | 58 | - name: 9.3.5 Set SSH MaxAuthTries to 4 or Less (Scored) 59 | lineinfile: > 60 | dest='/etc/ssh/sshd_config' 61 | regexp='^MaxAuthTries' 62 | line='MaxAuthTries 4' 63 | state=present 64 | notify: restart ssh 65 | tags: 66 | - section9 67 | - section9.3 68 | - section9.3.5 69 | 70 | - name: 9.3.6 Set SSH IgnoreRhosts to Yes (Scored) 71 | lineinfile: > 72 | dest='/etc/ssh/sshd_config' 73 | regexp='^IgnoreRhosts' 74 | line='IgnoreRhosts yes' 75 | state=present 76 | notify: restart ssh 77 | tags: 78 | - section9 79 | - section9.3 80 | - section9.3.6 81 | 82 | - name: 9.3.11 Use Only Approved Cipher in Counter Mode (Scored) 83 | lineinfile: > 84 | dest='/etc/ssh/sshd_config' 85 | regexp='^Ciphers' 86 | line='Ciphers aes128-ctr,aes192-ctr,aes256-ctr' 87 | state=present 88 | notify: restart ssh 89 | tags: 90 | - section9 91 | - section9.3 92 | - section9.3.11 93 | 94 | - name: 9.3.12.1 Set Idle Timeout Interval for User Login (Scored) 95 | lineinfile: > 96 | dest='/etc/ssh/sshd_config' 97 | regexp='^ClientAliveInterval' 98 | line='ClientAliveInterval 300' 99 | state=present 100 | tags: 101 | - section9 102 | - section9.3 103 | - section9.3.12 104 | - section9.3.12.1 105 | 106 | - name: 9.3.12.2 Set Idle Timeout Interval for User Login (Scored) 107 | lineinfile: > 108 | dest='/etc/ssh/sshd_config' 109 | regexp='^ClientAliveCountMax' 110 | line='ClientAliveCountMax 0' 111 | state=present 112 | notify: restart ssh 113 | tags: 114 | - section9 115 | - section9.3 116 | - section9.3.12 117 | - section9.3.12.2 118 | 119 | - name: 9.3.13.1 Limit Access via SSH (Scored) 120 | shell: grep AllowUsers /etc/ssh/sshd_config 121 | register: allow_rc 122 | failed_when: allow_rc.rc == 1 123 | changed_when: False 124 | always_run: True 125 | ignore_errors: True 126 | tags: 127 | - section9 128 | - section9.3 129 | - section9.3.13 130 | - section9.3.13.1 131 | 132 | - name: 9.3.13.2 Limit Access via SSH (Scored) 133 | shell: grep AllowGroups /etc/ssh/sshd_config 134 | register: allow_rc 135 | failed_when: allow_rc.rc == 1 136 | changed_when: False 137 | always_run: True 138 | ignore_errors: True 139 | tags: 140 | - section9 141 | - section9.3 142 | - section9.3.13 143 | - section9.3.13.2 144 | 145 | - name: 9.3.13.3 Limit Access via SSH (Scored) 146 | shell: grep DenyUsers /etc/ssh/sshd_config 147 | register: allow_rc 148 | failed_when: allow_rc.rc == 1 149 | changed_when: False 150 | always_run: True 151 | ignore_errors: True 152 | tags: 153 | - section9 154 | - section9.3 155 | - section9.3.13 156 | - section9.3.13.3 157 | 158 | - name: 9.3.13.4 Limit Access via SSH (Scored) 159 | shell: grep DenyGroups /etc/ssh/sshd_config 160 | register: allow_rc 161 | failed_when: allow_rc.rc == 1 162 | changed_when: False 163 | always_run: True 164 | ignore_errors: True 165 | notify: restart ssh 166 | tags: 167 | - section9 168 | - section9.3 169 | - section9.3.13 170 | - section9.3.13.4 171 | 172 | - name: 9.3.14 Set SSH Banner (Scored) 173 | lineinfile: > 174 | dest='/etc/ssh/sshd_config' 175 | regexp='^Banner' 176 | line='Banner /etc/issue.net' 177 | state=present 178 | notify: restart ssh 179 | tags: 180 | - section9 181 | - section9.3 182 | - section9.3.14 183 | 184 | -------------------------------------------------------------------------------- /tasks/section_10.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_10_level1.yml 4 | tags: 5 | - section10 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_10_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 10.1.1.1 Set Password Expiration Days (check) (Scored) 4 | command: grep -oP '(?<=^PASS_MAX_DAYS\s)[0-9]+' /etc/login.defs 5 | register: pass_max_days 6 | changed_when: False 7 | always_run: True 8 | tags: 9 | - section10 10 | - section10.1 11 | - section10.1.1 12 | 13 | - name: 10.1.1.2 Set Password Expiration Days (Scored) 14 | lineinfile: > 15 | dest='/etc/login.defs' 16 | line='PASS_MAX_DAYS 90' 17 | regexp='^PASS_MAX_DAYS' 18 | when: pass_max_days.stdout|int > 90 19 | tags: 20 | - section10 21 | - section10.1 22 | - section10.1.1 23 | 24 | - name: 10.1.2.1 Set Password Change Minimum Number of Days (check) (Scored) 25 | command: grep -oP '(?<=^PASS_MIN_DAYS\s)[0-9]+' /etc/login.defs 26 | register: pass_min_days 27 | changed_when: False 28 | always_run: True 29 | tags: 30 | - section10 31 | - section10.1 32 | - section10.1.2 33 | 34 | - name: 10.1.2.2 Set Password Change Minimum Number of Days (Scored) 35 | lineinfile: > 36 | dest='/etc/login.defs' 37 | line='PASS_MIN_DAYS 7' 38 | regexp='^PASS_MIN_DAYS' 39 | when: pass_min_days.stdout|int < 7 40 | tags: 41 | - section10 42 | - section10.1 43 | - section10.1.2 44 | 45 | - name: 10.1.3.1 Set Password Expiring Warning Days (check) (Scored) 46 | command: grep -oP '(?<=^PASS_WARN_AGE\s)[0-9]+' /etc/login.defs 47 | register: pass_warn_age 48 | changed_when: False 49 | always_run: True 50 | tags: 51 | - section10 52 | - section10.1 53 | - section10.1.3 54 | 55 | - name: 10.1.3.2 Set Password Expiring Warning Days (Scored) 56 | lineinfile: > 57 | dest='/etc/login.defs' 58 | line='PASS_WARN_AGE 7' 59 | regexp='^PASS_WARN_AGE' 60 | when: pass_warn_age.stdout|int < 7 61 | tags: 62 | - section10 63 | - section10.1 64 | - section10.1.3 65 | 66 | - name: 10.2.1.1 Disable System Accounts (check) (Scored) 67 | shell: awk -F':' '($1!="root" && $1!="sync" && $1!="shutdown" &&$1!="halt" && $3<500 && $7!="/usr/sbin/nologin" && $7!="/bin/false") {print $1}' /etc/passwd 68 | register: awk_etc_passwd 69 | changed_when: False 70 | always_run: True 71 | tags: 72 | - section10 73 | - section10.2 74 | 75 | - name: 10.2.2.2 Disable System Accounts (Scored) 76 | command: /usr/sbin/usermod -s /usr/sbin/nologin {{ item }} 77 | with_items: "{{awk_etc_passwd.stdout_lines}}" 78 | tags: 79 | - section10 80 | - section10.2 81 | 82 | - name: 10.3 Set Default Group for root Account (Scored) 83 | user: > 84 | name=root 85 | group=root 86 | tags: 87 | - section10 88 | - section10.3 89 | 90 | - name: 10.4 Set Default umask for Users (Scored) 91 | lineinfile: > 92 | dest=/etc/login.defs 93 | line='UMASK\t077' 94 | regexp='^UMASK' 95 | state=present 96 | tags: 97 | - section10 98 | - section10.4 99 | 100 | - name: 10.5.1 Lock Inactive User Accounts (check) (Scored) 101 | command: grep INACTIVE /etc/login.defs 102 | changed_when: False 103 | failed_when: False 104 | always_run: True 105 | register: lock_inactive_rc 106 | tags: 107 | - section10 108 | - section10.5 109 | 110 | - name: 10.5.2 Lock Inactive User Accounts (Scored) 111 | lineinfile: > 112 | dest=/etc/login.defs 113 | line='INACTIVE=35' 114 | state=present 115 | when: lock_inactive_rc.rc == 1 116 | tags: 117 | - section10 118 | - section10.5 119 | 120 | -------------------------------------------------------------------------------- /tasks/section_11.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_11_level1.yml 4 | tags: 5 | - section11 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_11_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 11.1 Set Warning Banner for Standard Login Services (Scored) 4 | lineinfile: > 5 | dest={{ item }} 6 | create=yes 7 | line='Authorized uses only. All activity may be monitored and reported.' 8 | state=present 9 | mode=644 10 | owner=root 11 | group=root 12 | with_items: 13 | - /etc/motd 14 | - /etc/issue 15 | - /etc/issue.net 16 | tags: 17 | - section11 18 | - section11.1 19 | 20 | - name: 11.2 Remove OS Information from Login Warning Banners (Scored) 21 | shell: egrep '(\\v|\\r|\\m|\\s)' {{ item }} 22 | register: egrep_os_infos 23 | failed_when: egrep_os_infos.rc == 0 24 | changed_when: False 25 | with_items: 26 | - /etc/motd 27 | - /etc/issue 28 | - /etc/issue.net 29 | tags: 30 | - section11 31 | - section11.2 32 | 33 | - name: 11.3 Set Graphical Warning Banner (Not Scored) 34 | debug: msg="*** Set a banner for the display manager ***" 35 | tags: 36 | - section11 37 | - section11.3 38 | -------------------------------------------------------------------------------- /tasks/section_12.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_12_level1.yml 4 | tags: 5 | - section12 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_12_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 12.1 Verify Permissions on /etc/passwd (Scored) 4 | file: path=/etc/passwd mode=0644 5 | tags: 6 | - section12 7 | - section12.1 8 | 9 | - name: 12.2 Verify Permissions on /etc/shadow (Scored) 10 | file: path=/etc/shadow mode='o-rwx,g-rw' 11 | tags: 12 | - section12 13 | - section12.2 14 | 15 | - name: 12.3 Verify Permissions on /etc/group (Scored) 16 | file: path=/etc/group mode=0644 17 | tags: 18 | - section12 19 | - section12.3 20 | 21 | - name: 12.4 Verify User/Group Ownership on /etc/passwd (Scored) 22 | file: path=/etc/passwd owner=root group=root 23 | tags: 24 | - section12 25 | - section12.4 26 | 27 | - name: 12.5 Verify User/Group Ownership on /etc/shadow (Scored) 28 | file: path=/etc/shadow owner=root group=shadow 29 | tags: 30 | - section12 31 | - section12.5 32 | 33 | - name: 12.6 Verify User/Group Ownership on /etc/group (Scored) 34 | file: path=/etc/group owner=root group=root 35 | tags: 36 | - section12 37 | - section12.6 38 | 39 | - name: 12.7.1 Find World Writable Files (check) (Not Scored) 40 | shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -0002 -print 41 | changed_when: False 42 | failed_when: False 43 | always_run: True 44 | register: world_files 45 | tags: 46 | - section12 47 | - section12.7 48 | 49 | - name: 12.7.2 Find World Writable Files (Not Scored) 50 | debug: msg="{{ item }}" 51 | with_items: "{{world_files.stdout_lines}}" 52 | tags: 53 | - section12 54 | - section12.7 55 | 56 | - name: 12.8.1 Find Un-owned Files and Directories (check) (Scored) 57 | shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -nouser -ls 58 | changed_when: False 59 | failed_when: False 60 | always_run: True 61 | register: unowned_files 62 | tags: 63 | - section12 64 | - section12.8 65 | 66 | - name: 12.8.2 Find Un-owned Files and Directories (Scored) 67 | debug: msg="{{ item }}" 68 | with_items: "{{unowned_files.stdout_lines}}" 69 | tags: 70 | - section12 71 | - section12.9 72 | 73 | - name: 12.9.1 Find Un-grouped Files and Directories (check) (Scored) 74 | shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -nogroup -ls 75 | changed_when: False 76 | failed_when: False 77 | always_run: True 78 | register: ungrouped_files 79 | tags: 80 | - section12 81 | - section12.9 82 | 83 | - name: 12.9.2 Find Un-grouped Files and Directories (Scored) 84 | debug: > 85 | msg="{{ item }}" 86 | with_items: "{{ungrouped_files.stdout_lines}}" 87 | tags: 88 | - section12 89 | - section12.9 90 | 91 | - name: 12.10.1 Find SUID System Executables (check) (Not Scored) 92 | shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000 -print 93 | changed_when: False 94 | failed_when: False 95 | always_run: True 96 | register: suid_files 97 | tags: 98 | - section12 99 | - section12.10 100 | 101 | - name: 12.10.2 Find SUID System Executables (Not Scored) 102 | debug: msg="{{ item }}" 103 | with_items: "{{suid_files.stdout_lines}}" 104 | tags: 105 | - section12 106 | - section12.10 107 | 108 | - name: 12.11.1 Find SGID System Executables (check) (Not Scored) 109 | shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -2000 -print 110 | changed_when: False 111 | failed_when: False 112 | always_run: True 113 | register: gsuid_files 114 | tags: 115 | - section12 116 | - section12.11 117 | 118 | - name: 12.11.2 Find SGID System Executables (Not Scored) 119 | debug: msg="{{ item }}" 120 | with_items: "{{gsuid_files.stdout_lines}}" 121 | tags: 122 | - section12 123 | - section12.10 124 | -------------------------------------------------------------------------------- /tasks/section_13.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - include: section_13_level1.yml 4 | tags: 5 | - section13 6 | - level1 7 | 8 | -------------------------------------------------------------------------------- /tasks/section_13_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: 13.1.1 Ensure Password Fields are Not Empty (check) (Scored) 4 | command: awk -F':' '($2 == "" ) { print $1 }' /etc/shadow 5 | register: awk_empty_shadow 6 | changed_when: False 7 | always_run: True 8 | failed_when: awk_empty_shadow.stdout != '' and lock_shadow_accounts == False 9 | tags: 10 | - section13 11 | - section13.1 12 | 13 | - name: 13.1.2 Ensure Password Fields are Not Empty (locking accounts) (Scored) 14 | command: passwd -l '{{ item }}' 15 | with_items: "{{awk_empty_shadow.stdout_lines}}" 16 | when: lock_shadow_accounts == True 17 | tags: 18 | - section13 19 | - section13.1 20 | 21 | - name: 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) 22 | command: grep '^+:' /etc/passwd 23 | register: plus_pass 24 | failed_when: plus_pass.rc == 0 25 | changed_when: plus_pass.rc == 0 26 | tags: 27 | - section13 28 | - section13.2 29 | 30 | - name: 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) 31 | command: grep '^+:' /etc/shadow 32 | register: plus_shadow 33 | failed_when: plus_shadow.rc == 0 34 | changed_when: plus_shadow.rc == 0 35 | tags: 36 | - section13 37 | - section13.3 38 | 39 | - name: 13.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) 40 | command: grep '^+:' /etc/group 41 | register: plus_group 42 | failed_when: plus_group.rc == 0 43 | changed_when: plus_group.rc == 0 44 | tags: 45 | - section13 46 | - section13.4 47 | 48 | - name: 13.5 Verify No UID 0 Accounts Exist Other Than root (Scored) 49 | command: awk -F':' '($3 == 0) { print $1 }' /etc/passwd 50 | register: uid_zero_root 51 | changed_when: False 52 | failed_when: uid_zero_root.stdout != 'root' 53 | tags: 54 | - section13 55 | - section13.5 56 | 57 | - name: 13.6.1 Ensure root PATH Integrity (empty value) (Scored) 58 | shell: 'echo $PATH | grep ::' 59 | register: path_colon 60 | changed_when: False 61 | always_run: True 62 | failed_when: path_colon.rc == 0 63 | tags: 64 | - section13 65 | - section13.6 66 | 67 | - name: 13.6.2 Ensure root PATH Integrity (colon end) (Scored) 68 | shell: 'echo $PATH | grep :$' 69 | register: path_colon_end 70 | changed_when: False 71 | always_run: True 72 | failed_when: path_colon_end.rc == 0 73 | tags: 74 | - section13 75 | - section13.6 76 | 77 | - name: 13.6.3 Ensure root PATH Integrity (dot in path) (Scored) 78 | shell: "/bin/bash --login -c 'env | grep ^PATH=' | sed -e 's/PATH=//' -e 's/::/:/' -e 's/:$//' -e 's/:/\\n/g'" 79 | become: yes 80 | register: dot_in_path 81 | changed_when: False 82 | always_run: True 83 | failed_when: '"." in dot_in_path.stdout_lines' 84 | tags: 85 | - section13 86 | - section13.6 87 | 88 | - name: 13.6.4 Ensure root PATH Integrity (Scored) 89 | file: > 90 | path='{{ item }}' 91 | follow=yes 92 | state=directory 93 | owner=root 94 | mode='o-w,g-w' 95 | with_items: "{{dot_in_path.stdout_lines}}" 96 | tags: 97 | - section13 98 | - section13.6 99 | 100 | - name: 13.7.1 Check Permissions on User Home Directories (gather users) (Scored) 101 | shell: /bin/egrep -v '(root|halt|sync|shutdown|false)' /etc/passwd | /usr/bin/awk -F':' '($7 != "/usr/sbin/nologin") { print $6 }' 102 | register: home_users 103 | changed_when: False 104 | failed_when: False 105 | always_run: True 106 | tags: 107 | - section13 108 | - section13.7 109 | 110 | - name: 13.7.2 Check Permissions on User Home Directories (Scored) 111 | file: > 112 | path='{{ item }}' 113 | mode='g-w,o-rwx' 114 | state=directory 115 | with_items: "{{home_users.stdout_lines}}" 116 | when: modify_user_homes == True 117 | tags: 118 | - section13 119 | - section13.7 120 | 121 | - name: 13.8.1 Check User Dot File Permissions (check) (Scored) 122 | shell: for pth in `/bin/egrep -v '(root|halt|sync|shutdown)' /etc/passwd | /usr/bin/awk -F':' '($7 != "/usr/sbin/nologin") { print $6 }'`; do ls -d -A -1 $pth/.* | egrep -v '[..]$'; done 123 | changed_when: False 124 | failed_when: False 125 | always_run: True 126 | register: home_dot_files 127 | tags: 128 | - section13 129 | - section13.8 130 | 131 | - name: 13.8.2 Check User Dot File Permissions (Scored) 132 | file: > 133 | path='{{ item }}' 134 | follow=yes 135 | mode='o-w,g-w' 136 | with_items: "{{home_dot_files.stdout_lines}}" 137 | tags: 138 | - section13 139 | - section13.8 140 | 141 | - name: 13.9 Check Permissions on User .netrc Files (Scored) 142 | file: > 143 | path='{{ item }}/.netrc' 144 | mode='g-rwx,o-rwx' 145 | recurse=yes 146 | state=directory 147 | with_items: "{{home_users.stdout_lines}}" 148 | tags: 149 | - section13 150 | - section13.9 151 | 152 | - name: 13.10 Check for Presence of User .rhosts Files (Scored) 153 | file: > 154 | state=absent 155 | path='{{ item }}/.rhosts' 156 | with_items: "{{home_users.stdout_lines}}" 157 | tags: 158 | - section13 159 | - section13.10 160 | 161 | - name: 13.11.1 Check Groups in /etc/passwd (check) (Scored) 162 | command: cut -s -d':' -f4 /etc/passwd 163 | register: groups_id_cut 164 | changed_when: False 165 | always_run: True 166 | tags: 167 | - section13 168 | - section13.11 169 | 170 | - name: 13.11.2 Check Groups in /etc/passwd (Scored) 171 | command: grep -q -P "^.*?:[^:]*:{{ item }}:" /etc/group 172 | with_items: "{{groups_id_cut.stdout_lines}}" 173 | register: groups_present 174 | changed_when: False 175 | always_run: True 176 | tags: 177 | - section13 178 | - section13.11 179 | 180 | - name: 13.12 Check That Users Are Assigned Valid Home Directories (Scored) 181 | stat: path='{{ item }}' 182 | with_items: "{{home_users.stdout_lines}}" 183 | register: rstat 184 | failed_when: rstat is defined and rstat.stat.isdir == False 185 | always_run: True 186 | tags: 187 | - section13 188 | - section13.12 189 | 190 | - name: 13.13 Check User Home Directory Ownership (Scored) 191 | debug: msg="*** Hardcore ***" 192 | tags: 193 | - section13 194 | - section13.13 195 | 196 | - name: 13.14 Check for Duplicate UIDs (Scored) 197 | shell: cut -f3 -d':' /etc/passwd | sort | uniq -d 198 | register: uids_list 199 | failed_when: uids_list.stdout != '' 200 | changed_when: False 201 | always_run: True 202 | tags: 203 | - section13 204 | - section13.14 205 | 206 | - name: 13.15 Check for Duplicate GIDs (Scored) 207 | shell: cut -f3 -d':' /etc/group | sort | uniq -d 208 | register: gids_list 209 | failed_when: gids_list.stdout != '' 210 | changed_when: False 211 | always_run: True 212 | tags: 213 | - section13 214 | - section13.15 215 | 216 | - name: 13.16 Check for Duplicate User Names (Scored) 217 | shell: cut -f1 -d':' /etc/passwd | sort | uniq -d 218 | register: uids_list 219 | failed_when: uids_list.stdout != '' 220 | changed_when: False 221 | always_run: True 222 | tags: 223 | - section13 224 | - section13.16 225 | 226 | - name: 13.17 Check for Duplicate Group Names (Scored) 227 | shell: cut -f1 -d':' /etc/group | sort | uniq -d 228 | register: uids_list 229 | failed_when: uids_list.stdout != '' 230 | changed_when: False 231 | always_run: True 232 | tags: 233 | - section13 234 | - section13.17 235 | 236 | - name: 13.18.1 Check for Presence of User .netrc Files (check) (Scored) 237 | stat: path='{{ item }}/.netrc' 238 | with_items: '{{ home_users.stdout_lines }}' 239 | always_run: True 240 | changed_when: False 241 | register: netrc_files 242 | tags: 243 | - section13 244 | - section13.18 245 | 246 | - name: 13.18.2 Check for Presence of User .netrc Files (Scored) 247 | debug: msg='Check if {{ item.stat.path}} is needed, and remove otherwise' 248 | when: item is defined and item.stat.exists == True 249 | with_items: '{{ netrc_files.results }}' 250 | tags: 251 | - section13 252 | - section13.18 253 | 254 | - name: 13.19 Check for Presence of User .forward Files (Scored) 255 | file: > 256 | path='{{ item }}/.forward' 257 | state=absent 258 | with_items: "{{home_users.stdout_lines}}" 259 | tags: 260 | - section13 261 | - section13.19 262 | 263 | - name: 13.20.1 Ensure shadow group is empty (check) (Scored) 264 | shell: grep '^shadow' /etc/group | cut -f4 -d':' 265 | register: shadow_group_empty 266 | failed_when: shadow_group_empty.stdout != '' 267 | changed_when: False 268 | always_run: True 269 | tags: 270 | - section13 271 | - section13.20 272 | - section13.20.1 273 | 274 | - name: 13.20.2 Ensure shadow group is empty (check) (Scored) 275 | shell: grep '^shadow' /etc/group | cut -f1 -d':' 276 | register: shadow_group_id 277 | failed_when: False 278 | changed_when: False 279 | always_run: True 280 | tags: 281 | - section13 282 | - section13.20 283 | - section13.20.1 284 | 285 | - name: 13.20.3 Ensure shadow group is empty (check) (Scored) 286 | shell: awk -F':' '($4 == "{{ item }}") { print }' /etc/passwd 287 | register: awk_passwd_shadow 288 | with_items: "{{shadow_group_id.stdout_lines}}" 289 | changed_when: False 290 | failed_when: awk_passwd_shadow.stdout != '' 291 | always_run: True 292 | tags: 293 | - section13 294 | - section13.20 295 | - section13.20.2 296 | -------------------------------------------------------------------------------- /tests/callbacks/log_plays.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | import os 17 | import time 18 | import json 19 | import hashlib 20 | import re 21 | 22 | ROLE_PATH = 'roles/cis' 23 | ROLE_PATH = '.' 24 | 25 | class TestBook(object): 26 | def __init__(self): 27 | self.tasks = {} 28 | 29 | def new(self, name): 30 | n = name.split('|')[1] 31 | self.tasks[n] = TestTask(n) 32 | return self.update(name.split('|')[1], 'FAIL') 33 | 34 | def update(self, name, status): 35 | self.tasks[name].update(status) 36 | return self.tasks[name] 37 | 38 | def jsonify(self): 39 | d = {} 40 | d['service_job_id'] = os.environ['TRAVIS_JOB_ID'] 41 | d['service_name'] = "travis-ci" 42 | d['source_files'] = [] 43 | 44 | s = {} 45 | for i in self.tasks: 46 | # Notifies 47 | if self.tasks[i].section == None: 48 | continue 49 | 50 | t = self.tasks[i] 51 | 52 | if t.sublevel != None: 53 | with open("%s/tasks/section_%s_level%s_%s.yml" % (ROLE_PATH, t.section, t.level, t.subsection)) as f: 54 | data = f.read() 55 | tname = "tasks/section_%s_level%s_%s.yml" % (t.section, t.level, t.subsection) 56 | else: 57 | with open("%s/tasks/section_%s_level%s.yml" % (ROLE_PATH, t.section, t.level)) as f: 58 | data = f.read() 59 | tname = "tasks/section_%s_level%s.yml" % (t.section, t.level) 60 | 61 | if not tname in s: 62 | s[tname] = {} 63 | s[tname]["name"] = tname 64 | s[tname]["source_digest"] = hashlib.md5(data).hexdigest() 65 | s[tname]["coverage"] = [0] * len(data.split('\n')) 66 | 67 | for n in range(t.line_start, t.line_start + t.line_size + 1): 68 | s[tname]["coverage"][n] = t.isalwaysok or int(t.status == 'CHANGED') 69 | 70 | n = 0 71 | for line in data.splitlines(): 72 | match = re.match(r'\s*(---|tags:|- section.*|- (include|name): .*)?$', line) 73 | if match: 74 | s[tname]["coverage"][n] = None 75 | n += 1 76 | 77 | for se in s: 78 | d['source_files'].append(s[se]) 79 | 80 | return json.dumps(d) 81 | 82 | class TestTask(object): 83 | def __init__(self, name): 84 | self.name = name 85 | self.status = 'null' 86 | self.level = None 87 | self.sublevel = None 88 | try: 89 | self.section = "%02d" % int(self.name.split('.')[0]) 90 | # Notifies are executed 91 | except ValueError: 92 | self.section = None 93 | 94 | try: 95 | self.subsection = "%02d" % int(self.name.split('.')[1]) 96 | # Notifies are executed 97 | except: 98 | self.subsection = None 99 | 100 | if self.section != None: 101 | try: 102 | with open("%s/tasks/section_%s_level1_%s.yml" % (ROLE_PATH, self.section, self.subsection)) as f: 103 | data = f.readlines() 104 | num = data.index([ n for n in data if self.name in n ][0]) 105 | self.level = 1 106 | self.sublevel = self.subsection 107 | except: 108 | try: 109 | with open("%s/tasks/section_%s_level1.yml" % (ROLE_PATH, self.section)) as f: 110 | data = f.readlines() 111 | num = data.index([ n for n in data if self.name in n ][0]) 112 | self.level = 1 113 | except: 114 | with open("%s/tasks/section_%s_level2.yml" % (ROLE_PATH, self.section)) as f: 115 | data = f.readlines() 116 | num = data.index([ n for n in data if self.name in n ][0]) 117 | self.level = 2 118 | 119 | self.line_start = num 120 | while num /tmp/inetd 10 | sudo cp /tmp/inetd /etc/inetd.conf 11 | echo 'start on runlevel [2345]' > /tmp/runxinit 12 | sudo cp /tmp/runxinit /etc/init/xinetd.conf 13 | 14 | #Prepare section 06 15 | sudo apt-get install avahi-daemon cups isc-dhcp-server slapd rpcbind nfs-kernel-server bind9 biosdevname 16 | sudo apt-get remove ntp 17 | sed -i '/server /d' /etc/ntp.conf 2>/dev/null 18 | sudo apt-get install vsftpd 19 | sed -i 's/^Protocol .*/Protocol 1/g' /etc/ssh/sshd_config 20 | sed -i 's/^IgnoreRhosts .*/IgnoreRhosts No/g' /etc/ssh/sshd_config 21 | 22 | #Prepare section 07 23 | sudo sysctl net.ipv4.ip_forward=1 24 | sudo sysctl net.ipv4.conf.all.send_redirects=1 25 | sudo sysctl net.ipv4.conf.default.send_redirects=1 26 | sudo sysctl net.ipv4.conf.all.accept_source_route=1 27 | sudo sysctl net.ipv4.conf.default.accept_source_route=1 28 | sudo sysctl net.ipv4.conf.all.accept_redirects=1 29 | sudo sysctl net.ipv4.conf.default.accept_redirects=1 30 | sudo sysctl net.ipv4.conf.all.secure_redirects=1 31 | sudo sysctl net.ipv4.conf.default.secure_redirects=1 32 | sudo sysctl net.ipv4.conf.all.log_martians=0 33 | sudo sysctl net.ipv4.conf.default.log_martians=0 34 | sudo sysctl net.ipv4.icmp_echo_ignore_broadcasts=0 35 | sudo sysctl net.ipv4.icmp_ignore_bogus_error_responses=0 36 | sudo sysctl net.ipv4.conf.all.rp_filter=0 37 | sudo sysctl net.ipv4.conf.default.rp_filter=0 38 | sudo sysctl net.ipv4.tcp_syncookies=0 39 | sudo sysctl net.ipv6.conf.all.accept_ra=1 40 | sudo sysctl net.ipv6.conf.default.accept_ra=1 41 | sudo sysctl net.ipv6.conf.all.accept_redirects=1 42 | sudo sysctl net.ipv6.conf.default.accept_redirects=1 43 | sudo chmod 777 /etc/hosts.allow 44 | sudo chmod 777 /etc/hosts.deny 45 | 46 | #Prepare section 08 47 | sudo chmod 777 /etc/rsyslog.conf 48 | cat >> /etc/rsyslog.d/30-marathon.conf << 'EOF' 49 | if $programname == 'marathon' then { 50 | action(type="omfile" asyncWriting="on" file="/var/log/marathon.log") 51 | stop 52 | } 53 | EOF 54 | 55 | #Prepare section 13 56 | #section13.1 57 | sudo adduser --system --shell /bin/bash --disabled-password --home /home/git nopassuser 58 | sudo passwd -d nopassuser 59 | #section13.6 60 | mkdir /tmp/wordwritabledir 61 | chmod 777 /tmp/wordwritabledir 62 | sudo sed -ri 's;^PATH="(.*)";PATH="\1:/tmp/wordwritabledir";' /etc/environment 63 | echo "export PATH=/tmp/wordwritabledir:\$PATH" >> ~/.bashrc 64 | echo "export PATH=/tmp/wordwritabledir:\$PATH" > /tmp/hackpath 65 | sudo cat /root/.bashrc /tmp/hackpath > /tmp/finalpath 66 | sudo cp /tmp/finalpath /root/.bashrc 67 | sudo sed -i.bak '/secure_path/d' /etc/sudoers 68 | #section13.8.2 69 | mkdir ~/.dotpermissive 70 | echo 'secr3t' > ~/.dotpermissive/secr3t 71 | chmod 777 ~/.dotpermissive 72 | #section13.10 73 | mkdir ~/.rhosts 74 | mkdir ~/.forward 75 | -------------------------------------------------------------------------------- /tests/travis_defaults.yml: -------------------------------------------------------------------------------- 1 | # Better coverage with automatic account locking 2 | lock_shadow_accounts: True 3 | 4 | # Set this flag to use AppArmor. It is useful to disable it when the system does not support the kernel module. 5 | use_apparmor: False 6 | 7 | # The execution is faster without packages upgrade. 8 | apt_upgrade: False 9 | 10 | # Modify the kernel behavior to disallow dump of suid binaries 11 | restrict_core_dumps: False 12 | 13 | # Disable all ipv6 interfaces. Suggested if the protocol is not used. 14 | disable_ipv6: True 15 | 16 | # Not loosing coverage. 17 | set_rsyslog_remote: True 18 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | # This file contains variables specific to your environment --------------------------------------------------------------------------------