├── AnsibleConfig ├── cis_playbook.yml ├── component-nginx.yml └── nginx_playbook.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Deployment ├── README_ec2.md ├── README_image_builder_nginx.md ├── README_infrastructure_ssm_params.md ├── README_launch_config.md ├── README_s3.md └── README_vpc.md ├── LICENSE ├── LinuxCis ├── .ansible-lint ├── .gitignore ├── .yamllint ├── LICENSE ├── README.md ├── ansible.cfg ├── defaults │ └── main.yml ├── files │ └── etc │ │ └── systemd │ │ └── system │ │ └── tmp.mount ├── handlers │ └── main.yml ├── library │ └── grub_crypt.py ├── requirements.txt ├── tasks │ ├── main.yml │ ├── post.yml │ ├── prelim.yml │ ├── section1.yml │ ├── section2.yml │ ├── section3.yml │ ├── section4.yml │ ├── section5.yml │ └── section6.yml └── templates │ ├── audit │ ├── rhel7cis_rule_4_1_10.rules.j2 │ ├── rhel7cis_rule_4_1_11.rules.j2 │ ├── rhel7cis_rule_4_1_12.rules.j2 │ ├── rhel7cis_rule_4_1_13.rules.j2 │ ├── rhel7cis_rule_4_1_14.rules.j2 │ ├── rhel7cis_rule_4_1_15.rules.j2 │ ├── rhel7cis_rule_4_1_16.rules.j2 │ ├── rhel7cis_rule_4_1_17.rules.j2 │ ├── rhel7cis_rule_4_1_18.rules.j2 │ ├── rhel7cis_rule_4_1_4.rules.j2 │ ├── rhel7cis_rule_4_1_5.rules.j2 │ ├── rhel7cis_rule_4_1_6.rules.j2 │ ├── rhel7cis_rule_4_1_7.rules.j2 │ ├── rhel7cis_rule_4_1_8.rules.j2 │ └── rhel7cis_rule_4_1_9.rules.j2 │ ├── chrony.conf.j2 │ ├── etc │ ├── issue.j2 │ ├── issue.net.j2 │ └── motd.j2 │ ├── hosts.allow.j2 │ └── ntp.conf.j2 ├── Nginx ├── .ansible-lint ├── .gitignore ├── .yamllint ├── LICENSE ├── README.md ├── defaults │ └── main.yml ├── files │ └── index.html ├── handlers │ └── main.yml ├── tasks │ ├── main.yml │ ├── setup-Debian.yml │ ├── setup-RedHat.yml │ ├── setup-Ubuntu.yml │ └── vhosts.yml ├── templates │ ├── nginx.conf.j2 │ └── vhost.j2 └── vars │ ├── Debian.yml │ └── RedHat.yml ├── Parameters ├── infrastructure-ssm-parameters.json ├── kms-params.json ├── nginx-config.json ├── nginx-image-builder-params.json ├── s3-iam-config.json ├── vpc-endpoint-params.json └── vpc-params.json ├── README.md └── Templates ├── infrastructure-ssm-params.yml ├── kms.yml ├── nginx-config.yml ├── nginx-image-builder.yml ├── s3-iam-config.yml └── vpc.yml /AnsibleConfig/cis_playbook.yml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | --- 4 | 5 | - name: Linux CIS Level 1 Harden Server 6 | hosts: 127.0.0.1 7 | gather_facts: true 8 | connection: local 9 | become: yes 10 | 11 | roles: 12 | - LinuxCis 13 | -------------------------------------------------------------------------------- /AnsibleConfig/component-nginx.yml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | name: 'Ansible Playbook Execution on Amazon Linux 2' 4 | description: 'This is a sample component that demonstrates how to download and execute an Ansible playbook against Amazon Linux 2.' 5 | schemaVersion: 1.0 6 | constants: 7 | - s3bucket: 8 | type: string 9 | value: # <-- REPLACE VALUE HERE WITH S3 BUCKET NAME 10 | phases: 11 | - name: build 12 | steps: 13 | - name: InstallAnsible 14 | action: ExecuteBash 15 | inputs: 16 | commands: 17 | - sudo amazon-linux-extras install -y ansible2 18 | - name: CreateDirectory 19 | action: ExecuteBash 20 | inputs: 21 | commands: 22 | - sudo mkdir -p /ansibleloc/roles 23 | - name: DownloadLinuxCis 24 | action: S3Download 25 | inputs: 26 | - source: 's3://{{ s3bucket }}/components/linux-cis.zip' 27 | destination: '/ansibleloc/linux-cis.zip' 28 | - name: UzipLinuxCis 29 | action: ExecuteBash 30 | inputs: 31 | commands: 32 | - unzip /ansibleloc/linux-cis.zip -d /ansibleloc/roles 33 | - echo "unzip linux-cis file" 34 | - name: DownloadCisPlaybook 35 | action: S3Download 36 | inputs: 37 | - source: 's3://{{ s3bucket }}/components/cis_playbook.yml' 38 | destination: '/ansibleloc/cis_playbook.yml' 39 | - name: InvokeCisAnsible 40 | action: ExecuteBinary 41 | inputs: 42 | path: ansible-playbook 43 | arguments: 44 | - '{{ build.DownloadCisPlaybook.inputs[0].destination }}' 45 | - '--tags=level1' 46 | - name: DeleteCisPlaybook 47 | action: ExecuteBash 48 | inputs: 49 | commands: 50 | - rm '{{ build.DownloadCisPlaybook.inputs[0].destination }}' 51 | - name: DownloadNginx 52 | action: S3Download 53 | inputs: 54 | - source: 's3://{{ s3bucket }}/components/nginx.zip' 55 | destination: '/ansibleloc/nginx.zip' 56 | - name: UzipNginx 57 | action: ExecuteBash 58 | inputs: 59 | commands: 60 | - unzip /ansibleloc/nginx.zip -d /ansibleloc/roles 61 | - echo "unzip Nginx file" 62 | - name: DownloadNginxPlaybook 63 | action: S3Download 64 | inputs: 65 | - source: 's3://{{ s3bucket }}/components/nginx_playbook.yml' 66 | destination: '/ansibleloc/nginx_playbook.yml' 67 | - name: InvokeNginxAnsible 68 | action: ExecuteBinary 69 | inputs: 70 | path: ansible-playbook 71 | arguments: 72 | - '{{ build.DownloadNginxPlaybook.inputs[0].destination }}' 73 | - name: DeleteNginxPlaybook 74 | action: ExecuteBash 75 | inputs: 76 | commands: 77 | - rm '{{ build.DownloadNginxPlaybook.inputs[0].destination }}' 78 | 79 | - name: validate 80 | steps: 81 | - name: ValidateDebug 82 | action: ExecuteBash 83 | inputs: 84 | commands: 85 | - sudo echo "ValidateDebug section" 86 | 87 | - name: test 88 | steps: 89 | - name: TestDebug 90 | action: ExecuteBash 91 | inputs: 92 | commands: 93 | - sudo echo "TestDebug section" 94 | - name: Download_Inspector_Test 95 | action: S3Download 96 | inputs: 97 | - source: 's3://ec2imagebuilder-managed-resources-us-east-1-prod/components/inspector-test-linux/1.0.1/InspectorTest' 98 | destination: '/workdir/InspectorTest' 99 | - name: Set_Executable_Permissions 100 | action: ExecuteBash 101 | inputs: 102 | commands: 103 | - sudo chmod +x /workdir/InspectorTest 104 | - name: ExecuteInspectorAssessment 105 | action: ExecuteBinary 106 | inputs: 107 | path: '/workdir/InspectorTest' 108 | -------------------------------------------------------------------------------- /AnsibleConfig/nginx_playbook.yml: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | --- 4 | 5 | - name: Linux CIS Level 1 Nginx 6 | hosts: 127.0.0.1 7 | gather_facts: true 8 | connection: local 9 | become: yes 10 | 11 | roles: 12 | - Nginx 13 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /Deployment/README_ec2.md: -------------------------------------------------------------------------------- 1 | #### USAGE: 2 | ``` 3 | Provisions an EC2 Instance, a Security Group, and Systems Manager Session Manager Permissions. This CloudFormation Template deploys an Instance Profile to enable Session Manager to connect to the instance. 4 | 5 | The purpose of using Session Manager is to allow users to connect to EC2 Instances without have to traverse the internet. Additionally, using Session Manager allows users to not have to open any ports to connect to their instances. 6 | ``` 7 | 8 | #### EDIT: vpc-params.json 9 | - InstanceType 10 | - NetworkStackName 11 | - SGGroupName 12 | - EnvironmentName 13 | - EC2InstanceName 14 | - SessionManagerRoleName 15 | - SessionManagerPolicyName 16 | 17 | #### RUN: deploy vpc 18 | 19 | ``` 20 | aws cloudformation create-stack --stack-name --template-body file:///ec2-instance-template.yml --parameters file://vpc-private-params.json --capabilities CAPABILITY_IAM -—region 21 | ``` 22 | 23 | **Example** 24 | ``` 25 | aws cloudformation create-stack --stack-name EC2-Test --template-body file://Templates/ec2-instance-template.yml --parameters file://Parameters/ec2-params.json --capabilities CAPABILITY_NAMED_IAM --region us-east-1 26 | 27 | ``` 28 | -------------------------------------------------------------------------------- /Deployment/README_image_builder_nginx.md: -------------------------------------------------------------------------------- 1 | ### Get the ARN of the Image Builder Role 2 | ``` 3 | aws iam list-roles --query "Roles[?RoleName == 'example-role'].[RoleName, Arn]" 4 | ``` 5 | 6 | ### Assume the Image Builder role using the ARN provided from previous step 7 | ``` 8 | aws sts assume-role --role-arn "arn:aws:iam::123456789012:role/example-role" --role-session-name AWSCLI-Session 9 | ``` 10 | 11 | ### Using the Content from the previous step update the following environment variables 12 | ``` 13 | export AWS_ACCESS_KEY_ID=RoleAccessKeyID 14 | export AWS_SECRET_ACCESS_KEY=RoleSecretKey 15 | export AWS_SESSION_TOKEN=RoleSessionToken 16 | ``` 17 | 18 | ### Double check that you have assumed the correct role 19 | ``` 20 | aws sts get-caller-identity 21 | ``` 22 | 23 | ### Create a prefix in existing S3 bucket called components only if it is not already there 24 | ``` 25 | aws s3api put-object --bucket demobucket23232142 --key components/ 26 | ``` 27 | 28 | 29 | ### Create zip nginx proxy file for linux-cis directory 30 | ``` 31 | zip -r linux-cis.zip LinuxCis 32 | ``` 33 | 34 | ### Upload linux cis zip file to a S3 bucket 35 | ``` 36 | aws s3 cp linux-cis.zip s3://demobucket23232142/components/ 37 | ``` 38 | 39 | 40 | ### Create zip Nginx config file for Nginx directory 41 | ``` 42 | zip -r nginx.zip Nginx 43 | ``` 44 | 45 | ### Upload Nginx zip file to a S3 bucket 46 | ``` 47 | aws s3 cp nginx.zip s3://demobucket23232142/components/ 48 | ``` 49 | 50 | ### Upload ansible cis playbook file to a S3 bucket 51 | ``` 52 | aws s3 cp AnsibleConfig/cis_playbook.yml s3://demobucket23232142/components/ 53 | ``` 54 | 55 | ### Upload ansible nginx playbook file to a S3 bucket 56 | ``` 57 | aws s3 cp AnsibleConfig/nginx_playbook.yml s3://demobucket23232142/components/ 58 | ``` 59 | 60 | 61 | ### Upload ec2 Imagebuilder Component file 62 | ``` 63 | aws s3 cp AnsibleConfig/component-nginx.yml s3://demobucket23232142/components/ 64 | ``` 65 | 66 | aws cloudformation create-stack \ 67 | --stack-name ib-nginx00 \ 68 | --template-body file://Templates/nginx-image-builder.yml \ 69 | --parameters file://Parameters/nginx-image-builder-params.json \ 70 | --capabilities CAPABILITY_NAMED_IAM \ 71 | --region us-east-1 72 | -------------------------------------------------------------------------------- /Deployment/README_infrastructure_ssm_params.md: -------------------------------------------------------------------------------- 1 | #### USAGE: 2 | ``` 3 | This template creates Systems Manager Parameter Store values which are used for automating the installation of AWS Services. 4 | ``` 5 | 6 | #### EDIT: infrastructure-ssm-parameters.json 7 | - NginxConfigStackName 8 | - NetworkStackName 9 | 10 | 11 | #### RUN: deploy infrastructure-ssm-parameters 12 | 13 | ``` 14 | aws cloudformation create-stack \ 15 | --stack-name \ 16 | --template-body file:///infrastructure-ssm-params.yml \ 17 | --parameters file:///infrastructure-ssm-parameters.json \ 18 | --capabilities CAPABILITY_IAM \ 19 | -—region 20 | 21 | ``` 22 | 23 | **Example** 24 | ``` 25 | aws cloudformation create-stack --stack-name Infra-SSM-Params --template-body file://Templates/infrastructure-ssm-params.yml --parameters file://Parameters/infrastructure-ssm-parameters.json --capabilities CAPABILITY_IAM --region us-east-1 26 | ``` 27 | -------------------------------------------------------------------------------- /Deployment/README_launch_config.md: -------------------------------------------------------------------------------- 1 | #### Create a new Launch Config 2 | ``` 3 | aws autoscaling create-launch-configuration --launch-configuration-name --image-id --instance-type --iam-instance-profile --security-groups --associate-public-ip-address 4 | ``` 5 | 6 | #### Example 7 | ``` 8 | aws autoscaling create-launch-configuration --launch-configuration-name launch-config-2 --image-id ami-XXXXXX --instance-type --iam-instance-profile NginxBlueGreen-NginxInstanceProfile-XXXXXX --security-groups sg-XXXXXX --associate-public-ip-address 9 | ``` 10 | 11 | #### Get the Nginx Proxy Stack ID 12 | ``` 13 | aws cloudformation list-exports | grep 14 | ``` 15 | 16 | #### Example 17 | ``` 18 | aws cloudformation list-exports | grep NginxProxies 19 | ``` 20 | 21 | #### Get the Nginx Proxies Stack Outputs 22 | ``` 23 | aws cloudformation list-exports --query "Exports[?ExportingStackId=='']" 24 | ``` 25 | 26 | #### Example 27 | ``` 28 | aws cloudformation list-exports --query "Exports[?ExportingStackId=='arn:aws:cloudformation:us-east-1::stack/NginxProxies/XXXXXX-XXXXXX-XXXXXX -XXXXXX-XXXXXX']" 29 | ``` 30 | 31 | #### Update ASG with new Launch Config 32 | ``` 33 | aws autoscaling update-auto-scaling-group --auto-scaling-group-name --launch-configuration-name 34 | ``` 35 | 36 | #### Example 37 | ``` 38 | aws autoscaling update-auto-scaling-group --auto-scaling-group-name NginxProxies-NginxInstanceASG1-XXXXXX --launch-configuration-name NginxProxies-NginxInstanceLC-XXXXXX 39 | ``` 40 | 41 | #### Update ASG with new Launch Config Instances 42 | ``` 43 | aws autoscaling start-instance-refresh --auto-scaling-group-name --preferences '{"InstanceWarmup": 120, "MinHealthyPercentage": 50}' 44 | ``` 45 | 46 | #### Example 47 | ``` 48 | aws autoscaling start-instance-refresh --auto-scaling-group-name NginxProxies-NginxInstanceASG1-XXXXXX --preferences '{"InstanceWarmup": 120, "MinHealthyPercentage": 50}' --region us-east-1 49 | ``` 50 | -------------------------------------------------------------------------------- /Deployment/README_s3.md: -------------------------------------------------------------------------------- 1 | #### USAGE: 2 | ``` 3 | Generic KMS Encrypted S3 bucket with built in Security Controls that restrict both public access to the Bucket as well any unencrypted connections to the Bucket. 4 | ``` 5 | 6 | #### EDIT: s3-params.json 7 | - TeamName 8 | - BucketName 9 | - KMSMasterKeyAlias 10 | - RoleName 11 | 12 | #### RUN: deploy s3 13 | 14 | ``` 15 | aws cloudformation create-stack \ 16 | --stack-name \ 17 | --template-body file:///s3-bucket.yaml \ 18 | --parameters file:///s3-params.json \ 19 | --capabilities CAPABILITY_IAM -—region 20 | ``` 21 | 22 | **Example** 23 | ``` 24 | aws cloudformation create-stack --stack-name -S3 --template-body file://Templates/s3-bucket.yaml --parameters file://Parameters/s3-params.json --capabilities CAPABILITY_IAM --region us-east-1 25 | ``` 26 | -------------------------------------------------------------------------------- /Deployment/README_vpc.md: -------------------------------------------------------------------------------- 1 | #### USAGE: 2 | ``` 3 | This template creates a Multi-AZ (two Availability Zones), multi-subnet VPC infrastructure and associates one Non RFC 1918 CIDR Block to the newly created VPC. 4 | 5 | This template also deploys VPC endpoints which allow communication to AWS Services without having to traverse the internet. 6 | ``` 7 | 8 | #### EDIT: vpc-params.json 9 | ``` 10 | - VPCCIDR 11 | - Environment 12 | - AvailabilityZones 13 | - PublicSubnet1ACIDR 14 | - PublicSubnet2ACIDR 15 | - PrivateSubnet2Z1CIDR 16 | - PrivateSubnet2Z2CIDR 17 | - PrivateSubnet4Z1CIDR 18 | - PrivateSubnet4Z2CIDR 19 | ``` 20 | 21 | #### RUN: deploy vpc 22 | ``` 23 | aws cloudformation create-stack \ 24 | --stack-name \ 25 | --template-body file:///vpc.yml \ 26 | --parameters file://vpc-params.json \ 27 | --capabilities CAPABILITY_IAM \ 28 | -—region 29 | ``` 30 | 31 | **Example** 32 | ``` 33 | aws cloudformation create-stack --stack-name VPC-Sandbox00 --template-body file://Templates/vpc.yml --parameters file://Parameters/vpc-params.json --capabilities CAPABILITY_IAM --region us-east-1 34 | ``` 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /LinuxCis/.ansible-lint: -------------------------------------------------------------------------------- 1 | --- 2 | exclude_paths: 3 | - ./tasks/old_content 4 | x: 5 | - '303' 6 | -------------------------------------------------------------------------------- /LinuxCis/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.retry 3 | .DS_Store 4 | .vscode-root 5 | test.yml 6 | tests/local-test.yml 7 | tests/.vagrant 8 | tests/Vagrantfile 9 | tests/test-inv 10 | tests/*.html 11 | tests/*.txt 12 | tests/*.retry 13 | .Python 14 | .molecule/ 15 | bin/ 16 | /etc/ 17 | include/ 18 | lib/ 19 | pip-selfcheck.json 20 | share/ 21 | 22 | -------------------------------------------------------------------------------- /LinuxCis/.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | ignore: | 3 | bin/ 4 | lib/ 5 | include/ 6 | share/ 7 | extends: default 8 | 9 | rules: 10 | braces: 11 | min-spaces-inside: 0 12 | max-spaces-inside: 1 13 | min-spaces-inside-empty: -1 14 | max-spaces-inside-empty: -1 15 | brackets: 16 | min-spaces-inside: 0 17 | max-spaces-inside: 0 18 | min-spaces-inside-empty: -1 19 | max-spaces-inside-empty: -1 20 | colons: 21 | max-spaces-before: 0 22 | max-spaces-after: 1 23 | commas: 24 | max-spaces-before: 0 25 | min-spaces-after: 1 26 | max-spaces-after: 1 27 | comments: 28 | level: warning 29 | require-starting-space: false 30 | min-spaces-from-content: 1 31 | comments-indentation: disable 32 | document-end: disable 33 | document-start: disable 34 | empty-lines: 35 | max: 3 36 | max-start: 0 37 | max-end: 0 38 | hyphens: 39 | max-spaces-after: 1 40 | indentation: 41 | spaces: consistent 42 | indent-sequences: true 43 | check-multi-line-strings: false 44 | key-duplicates: enable 45 | line-length: 46 | max: 500 47 | allow-non-breakable-words: true 48 | allow-non-breakable-inline-mappings: false 49 | new-line-at-end-of-file: enable 50 | new-lines: 51 | type: unix 52 | trailing-spaces: enable 53 | truthy: disable 54 | -------------------------------------------------------------------------------- /LinuxCis/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2015 MindPoint Group http://www.mindpointgroup.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /LinuxCis/README.md: -------------------------------------------------------------------------------- 1 | RHEL 7 CIS STIG 2 | ================ 3 | 4 | Based on [CIS RedHat Enterprise Linux 7 Benchmark v2.1.1 - 01-31-2017 ](https://community.cisecurity.org/collab/public/index.php). 5 | 6 | This repo originated from work done by [Sam Doran](https://github.com/samdoran/ansible-role-stig) 7 | 8 | Requirements 9 | ------------ 10 | 11 | You should carefully read through the tasks to make sure these changes will not break your systems before running this playbook. 12 | If you want to do a dry run without changing anything, set the below sections (rhel7cis_section1-6) to false. 13 | 14 | Role Variables 15 | -------------- 16 | There are many role variables defined in defaults/main.yml. This list shows the most important. 17 | 18 | **rhel7cis_notauto**: Run CIS checks that we typically do NOT want to automate due to the high probability of breaking the system (Default: false) 19 | 20 | **rhel7cis_section1**: CIS - General Settings (Section 1) (Default: true) 21 | 22 | **rhel7cis_section2**: CIS - Services settings (Section 2) (Default: true) 23 | 24 | **rhel7cis_section3**: CIS - Network settings (Section 3) (Default: true) 25 | 26 | **rhel7cis_section4**: CIS - Logging and Auditing settings (Section 4) (Default: true) 27 | 28 | **rhel7cis_section5**: CIS - Access, Authentication and Authorization settings (Section 5) (Default: true) 29 | 30 | **rhel7cis_section6**: CIS - System Maintenance settings (Section 6) (Default: true) 31 | 32 | ##### Disable all selinux functions 33 | `rhel7cis_selinux_disable: false` 34 | 35 | 36 | Dependencies 37 | ------------ 38 | 39 | Ansible > 2.2 40 | 41 | Example Playbook 42 | ------------------------- 43 | 44 | This sample playbook should be run in a folder that is above the main RHEL7-CIS / RHEL7-CIS-devel folder. 45 | 46 | ``` 47 | - name: Harden AMI 48 | hosts: localhost 49 | become: yes 50 | 51 | roles: 52 | - RHEL7-CIS 53 | ``` 54 | 55 | Tags 56 | ---- 57 | Many tags are available for precise control of what is and is not changed. 58 | 59 | Some examples of using tags: 60 | 61 | ``` 62 | # Audit and patch the file 63 | ansible-playbook file.yml --tags="patch" 64 | ``` 65 | 66 | License 67 | ------- 68 | 69 | MIT 70 | -------------------------------------------------------------------------------- /LinuxCis/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | remote_tmp = /tmp 3 | roles_path = /ansibleloc/roles 4 | -------------------------------------------------------------------------------- /LinuxCis/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for RHEL7-CIS 3 | rhel7cis_skip_for_travis: false 4 | 5 | rhel7cis_notauto: false 6 | rhel7cis_section1: true 7 | rhel7cis_section2: true 8 | rhel7cis_section3: true 9 | rhel7cis_section4: true 10 | rhel7cis_section5: true 11 | rhel7cis_section6: true 12 | 13 | rhel7cis_selinux_disable: false 14 | 15 | # These variables correspond with the CIS rule IDs or paragraph numbers defined in 16 | # the CIS benchmark documents. 17 | # PLEASE NOTE: These work in coordination with the section # group variables and tags. 18 | # You must enable an entire section in order for the variables below to take effect. 19 | # Section 1 rules 20 | rhel7cis_rule_1_1_1_1: true 21 | rhel7cis_rule_1_1_1_2: true 22 | rhel7cis_rule_1_1_1_3: true 23 | rhel7cis_rule_1_1_1_4: true 24 | rhel7cis_rule_1_1_1_5: true 25 | rhel7cis_rule_1_1_1_6: true 26 | rhel7cis_rule_1_1_1_7: true 27 | rhel7cis_rule_1_1_1_8: true 28 | rhel7cis_rule_1_1_2: true 29 | rhel7cis_rule_1_1_3: true 30 | rhel7cis_rule_1_1_4: true 31 | rhel7cis_rule_1_1_5: true 32 | rhel7cis_rule_1_1_6: true 33 | rhel7cis_rule_1_1_7: true 34 | rhel7cis_rule_1_1_8: true 35 | rhel7cis_rule_1_1_9: true 36 | rhel7cis_rule_1_1_10: true 37 | rhel7cis_rule_1_1_11: true 38 | rhel7cis_rule_1_1_12: true 39 | rhel7cis_rule_1_1_13: true 40 | rhel7cis_rule_1_1_14: true 41 | rhel7cis_rule_1_1_15: true 42 | rhel7cis_rule_1_1_16: true 43 | rhel7cis_rule_1_1_17: true 44 | rhel7cis_rule_1_1_18: true 45 | rhel7cis_rule_1_1_19: true 46 | rhel7cis_rule_1_1_20: true 47 | rhel7cis_rule_1_1_21: true 48 | rhel7cis_rule_1_1_22: true 49 | rhel7cis_rule_1_2_1: true 50 | rhel7cis_rule_1_2_2: true 51 | rhel7cis_rule_1_2_3: true 52 | rhel7cis_rule_1_2_4: true 53 | rhel7cis_rule_1_2_5: true 54 | rhel7cis_rule_1_3_1: true 55 | rhel7cis_rule_1_3_2: true 56 | rhel7cis_rule_1_4_1: true 57 | rhel7cis_rule_1_4_2: true 58 | rhel7cis_rule_1_4_3: true 59 | rhel7cis_rule_1_5_1: true 60 | rhel7cis_rule_1_5_2: true 61 | rhel7cis_rule_1_5_3: true 62 | rhel7cis_rule_1_5_4: true 63 | rhel7cis_rule_1_6_1_1: true 64 | rhel7cis_rule_1_6_1_2: true 65 | rhel7cis_rule_1_6_1_3: true 66 | rhel7cis_rule_1_6_1_4: true 67 | rhel7cis_rule_1_6_1_5: true 68 | rhel7cis_rule_1_6_2: true 69 | rhel7cis_rule_1_7_1_1: true 70 | rhel7cis_rule_1_7_1_2: true 71 | rhel7cis_rule_1_7_1_3: true 72 | rhel7cis_rule_1_7_1_4: true 73 | rhel7cis_rule_1_7_1_5: true 74 | rhel7cis_rule_1_7_1_6: true 75 | rhel7cis_rule_1_7_2: true 76 | rhel7cis_rule_1_8: true 77 | 78 | # Section 2 rules 79 | rhel7cis_rule_2_1_1: true 80 | rhel7cis_rule_2_1_2: true 81 | rhel7cis_rule_2_1_3: true 82 | rhel7cis_rule_2_1_4: true 83 | rhel7cis_rule_2_1_5: true 84 | rhel7cis_rule_2_1_6: true 85 | rhel7cis_rule_2_1_7: true 86 | rhel7cis_rule_2_2_1_1: true 87 | rhel7cis_rule_2_2_1_2: true 88 | rhel7cis_rule_2_2_1_3: true 89 | rhel7cis_rule_2_2_2: true 90 | rhel7cis_rule_2_2_3: true 91 | rhel7cis_rule_2_2_4: true 92 | rhel7cis_rule_2_2_5: true 93 | rhel7cis_rule_2_2_6: true 94 | rhel7cis_rule_2_2_7: true 95 | rhel7cis_rule_2_2_8: true 96 | rhel7cis_rule_2_2_9: true 97 | rhel7cis_rule_2_2_10: true 98 | rhel7cis_rule_2_2_11: true 99 | rhel7cis_rule_2_2_12: true 100 | rhel7cis_rule_2_2_13: true 101 | rhel7cis_rule_2_2_14: true 102 | rhel7cis_rule_2_2_15: true 103 | rhel7cis_rule_2_2_16: true 104 | rhel7cis_rule_2_2_17: true 105 | rhel7cis_rule_2_2_18: true 106 | rhel7cis_rule_2_2_19: true 107 | rhel7cis_rule_2_2_20: true 108 | rhel7cis_rule_2_2_21: true 109 | rhel7cis_rule_2_3_1: true 110 | rhel7cis_rule_2_3_2: true 111 | rhel7cis_rule_2_3_3: true 112 | rhel7cis_rule_2_3_4: true 113 | rhel7cis_rule_2_3_5: true 114 | 115 | # Section 3 rules 116 | rhel7cis_rule_3_1_1: true 117 | rhel7cis_rule_3_1_2: true 118 | rhel7cis_rule_3_2_1: true 119 | rhel7cis_rule_3_2_2: true 120 | rhel7cis_rule_3_2_3: true 121 | rhel7cis_rule_3_2_4: true 122 | rhel7cis_rule_3_2_5: true 123 | rhel7cis_rule_3_2_6: true 124 | rhel7cis_rule_3_2_7: true 125 | rhel7cis_rule_3_2_8: true 126 | rhel7cis_rule_3_3_1: true 127 | rhel7cis_rule_3_3_2: true 128 | rhel7cis_rule_3_3_3: true 129 | rhel7cis_rule_3_4_1: true 130 | rhel7cis_rule_3_4_2: true 131 | rhel7cis_rule_3_4_3: true 132 | rhel7cis_rule_3_4_4: true 133 | rhel7cis_rule_3_4_5: true 134 | rhel7cis_rule_3_5_1: true 135 | rhel7cis_rule_3_5_2: true 136 | rhel7cis_rule_3_5_3: true 137 | rhel7cis_rule_3_5_4: true 138 | rhel7cis_rule_3_6_1: true 139 | rhel7cis_rule_3_6_2: true 140 | rhel7cis_rule_3_6_3: true 141 | rhel7cis_rule_3_6_4: true 142 | rhel7cis_rule_3_6_5: true 143 | 144 | # Section 4 rules 145 | rhel7cis_rule_4_1_1_1: true 146 | rhel7cis_rule_4_1_1_2: true 147 | rhel7cis_rule_4_1_1_3: true 148 | rhel7cis_rule_4_1_2: true 149 | rhel7cis_rule_4_1_3: true 150 | rhel7cis_rule_4_1_4: true 151 | rhel7cis_rule_4_1_5: true 152 | rhel7cis_rule_4_1_6: true 153 | rhel7cis_rule_4_1_7: true 154 | rhel7cis_rule_4_1_8: true 155 | rhel7cis_rule_4_1_9: true 156 | rhel7cis_rule_4_1_10: true 157 | rhel7cis_rule_4_1_11: true 158 | rhel7cis_rule_4_1_12: true 159 | rhel7cis_rule_4_1_13: true 160 | rhel7cis_rule_4_1_14: true 161 | rhel7cis_rule_4_1_15: true 162 | rhel7cis_rule_4_1_16: true 163 | rhel7cis_rule_4_1_17: true 164 | rhel7cis_rule_4_1_18: true 165 | rhel7cis_rule_4_2_3: true 166 | rhel7cis_rule_4_2_1_1: true 167 | rhel7cis_rule_4_2_1_2: true 168 | rhel7cis_rule_4_2_1_3: true 169 | rhel7cis_rule_4_2_1_4: true 170 | rhel7cis_rule_4_2_1_5: true 171 | rhel7cis_rule_4_2_2_1: true 172 | rhel7cis_rule_4_2_2_2: true 173 | rhel7cis_rule_4_2_2_3: true 174 | rhel7cis_rule_4_2_2_4: true 175 | rhel7cis_rule_4_2_2_5: true 176 | rhel7cis_rule_4_2_4: true 177 | rhel7cis_rule_4_3: true 178 | 179 | # Section 5 rules 180 | rhel7cis_rule_5_1_1: true 181 | rhel7cis_rule_5_1_2: true 182 | rhel7cis_rule_5_1_3: true 183 | rhel7cis_rule_5_1_4: true 184 | rhel7cis_rule_5_1_5: true 185 | rhel7cis_rule_5_1_6: true 186 | rhel7cis_rule_5_1_7: true 187 | rhel7cis_rule_5_1_8: true 188 | rhel7cis_rule_5_2_1: true 189 | rhel7cis_rule_5_2_2: true 190 | rhel7cis_rule_5_2_3: true 191 | rhel7cis_rule_5_2_4: true 192 | rhel7cis_rule_5_2_5: true 193 | rhel7cis_rule_5_2_6: true 194 | rhel7cis_rule_5_2_7: true 195 | rhel7cis_rule_5_2_8: true 196 | rhel7cis_rule_5_2_9: true 197 | rhel7cis_rule_5_2_10: true 198 | rhel7cis_rule_5_2_11: true 199 | rhel7cis_rule_5_2_12: true 200 | rhel7cis_rule_5_2_13: true 201 | rhel7cis_rule_5_2_14: true 202 | rhel7cis_rule_5_2_15: true 203 | rhel7cis_rule_5_2_16: true 204 | rhel7cis_rule_5_3_1: true 205 | rhel7cis_rule_5_3_2: true 206 | rhel7cis_rule_5_3_3: true 207 | rhel7cis_rule_5_3_4: true 208 | rhel7cis_rule_5_4_1_1: true 209 | rhel7cis_rule_5_4_1_2: true 210 | rhel7cis_rule_5_4_1_3: true 211 | rhel7cis_rule_5_4_1_4: true 212 | rhel7cis_rule_5_4_2: true 213 | rhel7cis_rule_5_4_3: true 214 | rhel7cis_rule_5_4_4: true 215 | 216 | # Section 6 rules 217 | rhel7cis_rule_6_1_1: true 218 | rhel7cis_rule_6_1_2: true 219 | rhel7cis_rule_6_1_3: true 220 | rhel7cis_rule_6_1_4: true 221 | rhel7cis_rule_6_1_5: true 222 | rhel7cis_rule_6_1_6: true 223 | rhel7cis_rule_6_1_7: true 224 | rhel7cis_rule_6_1_8: true 225 | rhel7cis_rule_6_1_9: true 226 | rhel7cis_rule_6_1_10: true 227 | rhel7cis_rule_6_1_11: true 228 | rhel7cis_rule_6_1_12: true 229 | rhel7cis_rule_6_1_13: true 230 | rhel7cis_rule_6_1_14: true 231 | rhel7cis_rule_6_2_1: true 232 | rhel7cis_rule_6_2_2: true 233 | rhel7cis_rule_6_2_3: true 234 | rhel7cis_rule_6_2_4: true 235 | rhel7cis_rule_6_2_5: true 236 | rhel7cis_rule_6_2_6: true 237 | rhel7cis_rule_6_2_7: true 238 | rhel7cis_rule_6_2_8: true 239 | rhel7cis_rule_6_2_9: true 240 | rhel7cis_rule_6_2_10: true 241 | rhel7cis_rule_6_2_11: true 242 | rhel7cis_rule_6_2_12: true 243 | rhel7cis_rule_6_2_14: true 244 | rhel7cis_rule_6_2_15: true 245 | rhel7cis_rule_6_2_16: true 246 | rhel7cis_rule_6_2_17: true 247 | rhel7cis_rule_6_2_18: true 248 | rhel7cis_rule_6_2_19: true 249 | 250 | # Service configuration booleans set true to keep service 251 | rhel7cis_avahi_server: false 252 | rhel7cis_cups_server: false 253 | rhel7cis_dhcp_server: false 254 | rhel7cis_ldap_server: false 255 | rhel7cis_telnet_server: false 256 | rhel7cis_nfs_server: false 257 | rhel7cis_rpc_server: false 258 | rhel7cis_ntalk_server: false 259 | rhel7cis_rsyncd_server: false 260 | rhel7cis_tftp_server: false 261 | rhel7cis_rsh_server: false 262 | rhel7cis_nis_server: false 263 | rhel7cis_snmp_server: false 264 | rhel7cis_squid_server: false 265 | rhel7cis_smb_server: false 266 | rhel7cis_dovecot_server: false 267 | rhel7cis_httpd_server: false 268 | rhel7cis_vsftpd_server: false 269 | rhel7cis_named_server: false 270 | rhel7cis_nfs_rpc_server: false 271 | rhel7cis_is_mail_server: false 272 | rhel7cis_bind: false 273 | rhel7cis_vsftpd: false 274 | rhel7cis_httpd: false 275 | rhel7cis_dovecot: false 276 | rhel7cis_samba: false 277 | rhel7cis_squid: false 278 | rhel7cis_net_snmp: false 279 | rhel7cis_allow_autofs: false 280 | 281 | # xinetd required 282 | rhel7cis_xinetd_required: false 283 | 284 | # RedHat Satellite Subscription items 285 | rhel7cis_rhnsd_required: false 286 | 287 | # 1.4.2 Bootloader password 288 | rhel7cis_bootloader_password: random 289 | rhel7cis_set_boot_pass: false 290 | 291 | # System network parameters (host only OR host and router) 292 | rhel7cis_is_router: false 293 | 294 | # IPv6 required 295 | rhel7cis_ipv6_required: true 296 | 297 | # AIDE 298 | rhel7cis_config_aide: true 299 | # AIDE cron settings 300 | rhel7cis_aide_cron: 301 | cron_user: root 302 | cron_file: /etc/crontab 303 | aide_job: '/usr/sbin/aide --check' 304 | aide_minute: 0 305 | aide_hour: 5 306 | aide_day: '*' 307 | aide_month: '*' 308 | aide_weekday: '*' 309 | 310 | # SELinux policy 311 | rhel7cis_selinux_pol: targeted 312 | 313 | # Whether or not to run tasks related to auditing/patching the desktop environment 314 | rhel7cis_gui: no 315 | 316 | # Set to 'true' if X Windows is needed in your environment 317 | rhel7cis_xwindows_required: no 318 | 319 | rhel7cis_openldap_clients_required: false 320 | rhel7cis_telnet_required: false 321 | rhel7cis_talk_required: false 322 | rhel7cis_rsh_required: false 323 | rhel7cis_ypbind_required: false 324 | 325 | # Time Synchronization 326 | rhel7cis_time_synchronization: chrony 327 | #rhel7cis_time_synchronization: ntp 328 | 329 | rhel7cis_time_synchronization_servers: 330 | - 0.pool.ntp.org 331 | - 1.pool.ntp.org 332 | - 2.pool.ntp.org 333 | - 3.pool.ntp.org 334 | 335 | rhel7cis_chrony_server_options: "minpoll 8" 336 | rhel7cis_ntp_server_options: "iburst" 337 | 338 | # 3.4.2 | PATCH | Ensure /etc/hosts.allow is configured 339 | rhel7cis_host_allow: 340 | - "10.0.0.0/255.0.0.0" 341 | - "172.16.0.0/255.240.0.0" 342 | - "192.168.0.0/255.255.0.0" 343 | 344 | #rhel7cis_firewall: firewalld 345 | #rhel7cis_firewall: iptables 346 | 347 | rhel7cis_firewall_services: 348 | - ssh 349 | - dhcpv6-client 350 | 351 | # Warning Banner Content (issue, issue.net, motd) 352 | rhel7cis_warning_banner: | 353 | Authorized uses only. All activity may be monitored and reported. 354 | # End Banner 355 | 356 | ## Section4 vars 357 | 358 | rhel7cis_auditd: 359 | admin_space_left_action: halt 360 | max_log_file_action: keep_logs 361 | 362 | rhel7cis_logrotate: "daily" 363 | 364 | rhel7cis_sudolog: /var/log/secure 365 | 366 | ## Section5 vars 367 | 368 | rhel7cis_sshd: 369 | clientalivecountmax: 3 370 | clientaliveinterval: 300 371 | ciphers: "aes256-ctr,aes192-ctr,aes128-ctr" 372 | macs: "hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com" 373 | logingracetime: 60 374 | # - make sure you understand the precedence when working with these values!! 375 | #allowusers: 376 | #allowgroups: systems dba 377 | #denyusers: 378 | #denygroups: 379 | 380 | rhel7cis_pass: 381 | max_days: 90 382 | min_days: 7 383 | warn_age: 7 384 | 385 | rhel7cis_pwquality: 386 | minlen: '14' 387 | dcredit: '-1' 388 | ucredit: '-1' 389 | ocredit: '-1' 390 | lcredit: '-1' 391 | 392 | # Syslog system 393 | rhel7cis_syslog: rsyslog 394 | #rhel7cis_syslog: syslog-ng 395 | 396 | rhel7cis_vartmp: 397 | source: /tmp 398 | fstype: none 399 | opts: "defaults,nodev,nosuid,noexec,bind" 400 | enabled: no 401 | 402 | rhel7cis_rule_5_4_2_min_uid: 1000 403 | -------------------------------------------------------------------------------- /LinuxCis/files/etc/systemd/system/tmp.mount: -------------------------------------------------------------------------------- 1 | # This file is part of systemd. 2 | # 3 | # systemd is free software; you can redistribute it and/or modify it 4 | # under the terms of the GNU Lesser General Public License as published by 5 | # the Free Software Foundation; either version 2.1 of the License, or 6 | # (at your option) any later version. 7 | 8 | [Unit] 9 | Description=Temporary Directory 10 | Documentation=man:hier(7) 11 | Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems 12 | ConditionPathIsSymbolicLink=!/tmp 13 | DefaultDependencies=no 14 | Conflicts=umount.target 15 | Before=local-fs.target umount.target 16 | 17 | [Mount] 18 | What=tmpfs 19 | Where=/tmp 20 | Type=tmpfs 21 | Options=mode=1777,strictatime,noexec,nodev,nosuid 22 | 23 | # Make 'systemctl enable tmp.mount' work: 24 | [Install] 25 | WantedBy=local-fs.target 26 | -------------------------------------------------------------------------------- /LinuxCis/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for RHEL7-CIS 3 | 4 | - name: sysctl flush ipv4 route table 5 | become: yes 6 | sysctl: 7 | name: net.ipv4.route.flush 8 | value: 1 9 | sysctl_set: yes 10 | when: ansible_virtualization_type != "docker" 11 | 12 | - name: sysctl flush ipv6 route table 13 | become: yes 14 | sysctl: 15 | name: net.ipv6.route.flush 16 | value: 1 17 | sysctl_set: yes 18 | when: ansible_virtualization_type != "docker" 19 | 20 | - name: systemd restart tmp.mount 21 | become: yes 22 | systemd: 23 | name: tmp.mount 24 | daemon_reload: yes 25 | enabled: yes 26 | masked: no 27 | state: reloaded 28 | 29 | - name: systemd restart var-tmp.mount 30 | become: yes 31 | systemd: 32 | name: var-tmp.mount 33 | daemon_reload: yes 34 | enabled: yes 35 | masked: no 36 | state: reloaded 37 | 38 | - name: generate new grub config 39 | become: yes 40 | command: grub2-mkconfig -o "{{ grub_cfg.stat.lnk_source }}" 41 | 42 | # - name: restart firewalld 43 | # become: yes 44 | # service: 45 | # name: firewalld 46 | # state: restarted 47 | 48 | - name: restart xinetd 49 | become: yes 50 | service: 51 | name: xinetd 52 | state: restarted 53 | 54 | - name: restart sshd 55 | debug: 56 | msg: "checking /etc/ssh/sshd_config first" 57 | changed_when: true 58 | notify: 59 | - generate host keys 60 | - check sshd configuration 61 | - restart sshd - after config check 62 | 63 | - name: generate host keys 64 | command: '/usr/bin/ssh-keygen -A' 65 | register: ssh_host_keys 66 | 67 | - name: check sshd configuration 68 | command: '/usr/sbin/sshd -t' 69 | register: sshd_config 70 | changed_when: "sshd_config.rc != 0" 71 | 72 | - name: restart sshd - after config check 73 | service: 74 | name: sshd 75 | state: restarted 76 | 77 | - name: reload dconf 78 | become: yes 79 | command: dconf update 80 | 81 | - name: restart auditd 82 | command: /sbin/service auditd restart 83 | changed_when: no 84 | check_mode: no 85 | failed_when: no 86 | args: 87 | warn: no 88 | when: 89 | - not rhel7cis_skip_for_travis 90 | tags: 91 | - skip_ansible_lint 92 | 93 | - name: grub2cfg 94 | command: /sbin/grub2-mkconfig -o /boot/grub2/grub.cfg 95 | ignore_errors: True 96 | -------------------------------------------------------------------------------- /LinuxCis/library/grub_crypt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | from __future__ import (absolute_import, division, print_function) 5 | __metaclass__ = type 6 | 7 | import crypt 8 | import random 9 | import string 10 | from ansible.module_utils.basic import AnsibleModule 11 | 12 | 13 | def gen_pass(size=16, chars=string.ascii_letters + string.digits): 14 | '''Generate a random password.''' 15 | return ''.join(random.choice(chars) for x in range(size)) 16 | 17 | 18 | def gen_salt(salt): 19 | '''Generate a random salt.''' 20 | ret = '' 21 | if not salt: 22 | with open('/dev/urandom', 'rb') as urandom: 23 | while True: 24 | byte = urandom.read(1) 25 | if byte in string.ascii_letters + string.digits + './': 26 | ret += byte 27 | if len(ret) == 16: 28 | break 29 | return '$6$%s' % ret 30 | return '$6$%s' % salt 31 | 32 | 33 | def main(): 34 | '''Return a crypt-ed password for use with GRUB2''' 35 | module = AnsibleModule( 36 | argument_spec=dict( 37 | salt=dict(required=False, default=None), 38 | password=dict( 39 | no_log=True, 40 | required=False, 41 | default='random', 42 | type='str' 43 | ), 44 | ) 45 | 46 | ) 47 | salt = module.params['salt'] 48 | password = module.params['password'] 49 | if password == 'random': 50 | password = gen_pass() 51 | sha512_salt = gen_salt(salt) 52 | salted_pass = crypt.crypt(password, sha512_salt) 53 | module.exit_json(changed=False, passhash=salted_pass) 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /LinuxCis/requirements.txt: -------------------------------------------------------------------------------- 1 | ansible-lint 2 | yamllint 3 | tox 4 | molecule 5 | jmespath 6 | -------------------------------------------------------------------------------- /LinuxCis/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for RHEL7-CIS 3 | - name: Check OS version and family 4 | fail: 5 | msg: "This role can only be run against RHEL 7. {{ ansible_distribution }} {{ ansible_distribution_major_version }} is not supported." 6 | when: 7 | - ansible_os_family == 'RedHat' 8 | - ansible_distribution_major_version is version_compare('7', '!=') 9 | - ansible_distribution_major_version is version_compare('2', '!=') 10 | tags: 11 | - always 12 | 13 | - name: Check ansible version 14 | fail: 15 | msg: You must use ansible 2.1 or greater 16 | when: not ansible_version.full is version_compare('2.1', '>=') 17 | tags: 18 | - always 19 | 20 | - include: prelim.yml 21 | become: yes 22 | tags: 23 | - prelim_tasks 24 | - always 25 | 26 | - include: section1.yml 27 | become: yes 28 | when: rhel7cis_section1|bool 29 | tags: 30 | - rhel7cis_section1 31 | 32 | - include: section2.yml 33 | become: yes 34 | when: rhel7cis_section2|bool 35 | 36 | - include: section3.yml 37 | become: yes 38 | when: rhel7cis_section3|bool 39 | 40 | - include: section4.yml 41 | become: yes 42 | when: rhel7cis_section4|bool 43 | 44 | - include: section5.yml 45 | become: yes 46 | when: rhel7cis_section5|bool 47 | 48 | - include: section6.yml 49 | become: yes 50 | when: rhel7cis_section6|bool 51 | 52 | - include: post.yml 53 | become: yes 54 | tags: 55 | - post_tasks 56 | - always 57 | -------------------------------------------------------------------------------- /LinuxCis/tasks/post.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Post tasks 3 | 4 | - name: Perform YUM package cleanup 5 | command: yum -y autoremove 6 | changed_when: no 7 | ignore_errors: yes 8 | tags: 9 | - skip_ansible_lint 10 | -------------------------------------------------------------------------------- /LinuxCis/tasks/prelim.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Preliminary tasks that should always be run 3 | # List users in order to look files inside each home directory 4 | - name: "PRELIM | List users accounts" 5 | command: "awk -F: '{print $1}' /etc/passwd" 6 | register: passwd 7 | changed_when: no 8 | check_mode: no 9 | 10 | - name: "PRELIM | List home directories" 11 | find: 12 | paths: 13 | - /home 14 | patterns: 15 | - '.bash_profile' 16 | depth: 2 17 | recurse: yes 18 | hidden: yes 19 | register: homes 20 | 21 | - name: "PRELIM | Resolve home directories to usernames" 22 | command: "id -un {{ item }}" 23 | with_items: "{{ homes | json_query('files[*].path') | map('dirname') | map('basename') | list }}" 24 | changed_when: no 25 | check_mode: no 26 | ignore_errors: yes 27 | register: home_usernames 28 | 29 | - name: "PRELIM | List all users" 30 | set_fact: 31 | users: "{{ list_passwd | union(list_homes) | unique }}" 32 | vars: 33 | list_passwd: "{{ passwd | json_query('stdout_lines') }}" 34 | list_homes: "{{ home_usernames.results | json_query('[*].stdout') }}" 35 | 36 | - name: "PRELIM | Gather accounts with empty password fields" 37 | command: "awk -F: '($2 == \"\" ) {j++;print $1; } END {exit j}' /etc/shadow" 38 | register: empty_password_accounts 39 | changed_when: no 40 | check_mode: no 41 | 42 | - name: "PRELIM | Gather UID 0 accounts other than root" 43 | command: "awk -F: '($3 == 0 && $1 != \"root\") {i++;print $1 } END {exit i}' /etc/passwd" 44 | register: uid_zero_accounts_except_root 45 | changed_when: no 46 | check_mode: no 47 | 48 | - name: "PRELIM | Section 4.1 | Configure System Accounting (auditd)" 49 | yum: 50 | name: audit 51 | state: present 52 | 53 | - name: "PRELIM | Section 5.1 | Configure cron" 54 | yum: 55 | name: cronie 56 | state: present 57 | 58 | - name: "PRELIM | Check if prelink package is installed" 59 | command: rpm -q prelink 60 | args: 61 | warn: false 62 | register: prelink_installed 63 | changed_when: no 64 | failed_when: no 65 | check_mode: no 66 | tags: 67 | - skip_ansible_lint 68 | 69 | - name: "PRELIM | Check if postfix package is installed" 70 | command: rpm -q postfix 71 | args: 72 | warn: false 73 | register: postfix_installed 74 | changed_when: no 75 | failed_when: no 76 | check_mode: no 77 | tags: 78 | - skip_ansible_lint 79 | 80 | # Individual service checks 81 | - name: "PRELIM | Check for xinetd service" 82 | shell: "systemctl show xinetd | grep LoadState | cut -d = -f 2" 83 | register: xinetd_service_status 84 | changed_when: no 85 | check_mode: no 86 | tags: 87 | - skip_ansible_lint # ANSIBLE0006 88 | 89 | - name: "PRELIM | Check for ntpd service" 90 | shell: "systemctl show ntpd | grep LoadState | cut -d = -f 2" 91 | register: ntpd_service_status 92 | changed_when: no 93 | check_mode: no 94 | tags: 95 | - skip_ansible_lint # ANSIBLE0006 96 | 97 | 98 | - name: "PRELIM | Check for chronyd service" 99 | shell: "systemctl show chronyd | grep LoadState | cut -d = -f 2" 100 | register: chronyd_service_status 101 | changed_when: no 102 | check_mode: no 103 | tags: 104 | - skip_ansible_lint # ANSIBLE0006 105 | 106 | - name: "PRELIM | Check for avahi-daemon service" 107 | shell: "systemctl show avahi-daemon | grep LoadState | cut -d = -f 2" 108 | register: avahi_service_status 109 | changed_when: no 110 | check_mode: no 111 | tags: 112 | - skip_ansible_lint # ANSIBLE0006 113 | 114 | - name: "PRELIM | Check for cups service" 115 | shell: "systemctl show cups | grep LoadState | cut -d = -f 2" 116 | register: cups_service_status 117 | changed_when: no 118 | check_mode: no 119 | tags: 120 | - skip_ansible_lint # ANSIBLE0006 121 | 122 | - name: "PRELIM | Check for dhcpd service" 123 | shell: "systemctl show dhcpd | grep LoadState | cut -d = -f 2" 124 | register: dhcpd_service_status 125 | changed_when: no 126 | check_mode: no 127 | tags: 128 | - skip_ansible_lint # ANSIBLE0006 129 | 130 | - name: "PRELIM | Check for slapd service" 131 | shell: "systemctl show slapd | grep LoadState | cut -d = -f 2" 132 | register: slapd_service_status 133 | changed_when: no 134 | check_mode: no 135 | tags: 136 | - skip_ansible_lint # ANSIBLE0006 137 | 138 | - name: "PRELIM | Check for nfs service" 139 | shell: "systemctl show nfs | grep LoadState | cut -d = -f 2" 140 | register: nfs_service_status 141 | changed_when: no 142 | check_mode: no 143 | tags: 144 | - skip_ansible_lint # ANSIBLE0006 145 | 146 | - name: "PRELIM | Check for rpcbind service" 147 | shell: "systemctl show rpcbind | grep LoadState | cut -d = -f 2" 148 | register: rpcbind_service_status 149 | changed_when: no 150 | check_mode: no 151 | tags: 152 | - skip_ansible_lint # ANSIBLE0006 153 | 154 | - name: "PRELIM | Check for named service" 155 | shell: "systemctl show named | grep LoadState | cut -d = -f 2" 156 | register: named_service_status 157 | changed_when: no 158 | check_mode: no 159 | tags: 160 | - skip_ansible_lint # ANSIBLE0006 161 | 162 | - name: "PRELIM | Check for vsftpd service" 163 | shell: "systemctl show vsftpd | grep LoadState | cut -d = -f 2" 164 | register: vsftpd_service_status 165 | changed_when: no 166 | check_mode: no 167 | tags: 168 | - skip_ansible_lint # ANSIBLE0006 169 | 170 | - name: "PRELIM | Check for httpd service" 171 | shell: "systemctl show httpd | grep LoadState | cut -d = -f 2" 172 | register: httpd_service_status 173 | changed_when: no 174 | check_mode: no 175 | tags: 176 | - skip_ansible_lint # ANSIBLE0006 177 | 178 | - name: "PRELIM | Check for dovecot service" 179 | shell: "systemctl show dovecot | grep LoadState | cut -d = -f 2" 180 | register: dovecot_service_status 181 | changed_when: no 182 | check_mode: no 183 | tags: 184 | - skip_ansible_lint # ANSIBLE0006 185 | 186 | - name: "PRELIM | Check for smb service" 187 | shell: "systemctl show smb | grep LoadState | cut -d = -f 2" 188 | register: smb_service_status 189 | changed_when: no 190 | check_mode: no 191 | tags: 192 | - skip_ansible_lint # ANSIBLE0006 193 | 194 | - name: "PRELIM | Check for squid service" 195 | shell: "systemctl show squid | grep LoadState | cut -d = -f 2" 196 | register: squid_service_status 197 | changed_when: no 198 | check_mode: no 199 | tags: 200 | - skip_ansible_lint # ANSIBLE0006 201 | 202 | - name: "PRELIM | Check for snmpd service" 203 | shell: "systemctl show snmpd | grep LoadState | cut -d = -f 2" 204 | register: snmpd_service_status 205 | changed_when: no 206 | check_mode: no 207 | tags: 208 | - skip_ansible_lint # ANSIBLE0006 209 | 210 | - name: "PRELIM | Check for ypserv service" 211 | shell: "systemctl show ypserv | grep LoadState | cut -d = -f 2" 212 | register: ypserv_service_status 213 | changed_when: no 214 | check_mode: no 215 | tags: 216 | - skip_ansible_lint # ANSIBLE0006 217 | 218 | - name: "PRELIM | Check for rsh.socket service" 219 | shell: "systemctl show rsh.socket | grep LoadState | cut -d = -f 2" 220 | register: rsh_service_status 221 | changed_when: no 222 | check_mode: no 223 | tags: 224 | - skip_ansible_lint # ANSIBLE0006 225 | 226 | - name: "PRELIM | Check for rlogin.socket service" 227 | shell: "systemctl show rlogin.socket | grep LoadState | cut -d = -f 2" 228 | register: rlogin_service_status 229 | changed_when: no 230 | check_mode: no 231 | tags: 232 | - skip_ansible_lint # ANSIBLE0006 233 | 234 | - name: "PRELIM | Check for rexec.socket service" 235 | shell: "systemctl show rexec.socket | grep LoadState | cut -d = -f 2" 236 | register: rexec_service_status 237 | changed_when: no 238 | check_mode: no 239 | tags: 240 | - skip_ansible_lint # ANSIBLE0006 241 | 242 | - name: "PRELIM | Check for telnet service" 243 | shell: "systemctl show telnet | grep LoadState | cut -d = -f 2" 244 | register: telnet_service_status 245 | changed_when: no 246 | check_mode: no 247 | tags: 248 | - skip_ansible_lint # ANSIBLE0006 249 | 250 | - name: "PRELIM | Check for tftp service" 251 | shell: "systemctl show tftp | grep LoadState | cut -d = -f 2" 252 | register: tftp_service_status 253 | changed_when: no 254 | check_mode: no 255 | tags: 256 | - skip_ansible_lint # ANSIBLE0006 257 | 258 | - name: "PRELIM | Check for rsyncd service" 259 | shell: "systemctl show rsyncd | grep LoadState | cut -d = -f 2" 260 | register: rsyncd_service_status 261 | changed_when: no 262 | check_mode: no 263 | tags: 264 | - skip_ansible_lint # ANSIBLE0006 265 | 266 | - name: "PRELIM | Check for ntalk service" 267 | shell: "systemctl show ntalk | grep LoadState | cut -d = -f 2" 268 | register: ntalk_service_status 269 | changed_when: no 270 | check_mode: no 271 | tags: 272 | - skip_ansible_lint # ANSIBLE0006 273 | 274 | - name: "PRELIM | Check for autofs service" 275 | shell: "systemctl show autofs | grep LoadState | cut -d = -f 2" 276 | register: autofs_service_status 277 | changed_when: no 278 | check_mode: no 279 | tags: 280 | - skip_ansible_lint # ANSIBLE0006 281 | 282 | - name: "PRELIM | Check for rhnsd service" 283 | shell: "systemctl show rhnsd | grep LoadState | cut -d = -f 2" 284 | register: rhnsd_service_status 285 | changed_when: no 286 | check_mode: no 287 | tags: 288 | - skip_ansible_lint # ANSIBLE0006 289 | -------------------------------------------------------------------------------- /LinuxCis/tasks/section2.yml: -------------------------------------------------------------------------------- 1 | - name: "SCORED | 2.1.1 | PATCH | Ensure chargen services are not enabled | chargen-dgram,chargen-stream" 2 | block: 3 | - name: "SCORED | 2.1.1 | PATCH | Ensure chargen services are not enabled | chargen-dgram" 4 | stat: 5 | path: /etc/xinetd.d/chargen-dgram 6 | register: chargen_dgram_service 7 | 8 | - name: "SCORED | 2.1.1 | PATCH | Ensure chargen services are not enabled | chargen-dgram" 9 | command: chkconfig chargen-dgram off 10 | notify: restart xinetd 11 | when: chargen_dgram_service.stat.exists 12 | tags: 13 | - skip_ansible_lint 14 | 15 | - name: "SCORED | 2.1.1 | PATCH | Ensure chargen services are not enabled | chargen-stream" 16 | stat: 17 | path: /etc/xinetd.d/chargen-stream 18 | register: chargen_stream_service 19 | 20 | - name: "SCORED | 2.1.1 | PATCH | Ensure chargen services are not enabled | chargen-stream" 21 | command: chkconfig chargen-stream off 22 | notify: restart xinetd 23 | when: chargen_stream_service.stat.exists 24 | tags: 25 | - skip_ansible_lint 26 | when: 27 | - rhel7cis_rule_2_1_1|bool 28 | tags: 29 | - level1 30 | - scored 31 | - services 32 | - patch 33 | - rule_2.1.1 34 | 35 | - name: "SCORED | 2.1.2 | PATCH | Ensure daytime services are not enabled | daytime-dgram,daytime-stream" 36 | block: 37 | - name: "SCORED | 2.1.2 | PATCH | Ensure daytime services are not enabled | daytime-dgram" 38 | stat: 39 | path: /etc/xinetd.d/daytime-dgram 40 | register: daytime_dgram_service 41 | 42 | - name: "SCORED | 2.1.2 | PATCH | Ensure daytime services are not enabled | daytime-dgram" 43 | command: chkconfig daytime-dgram off 44 | notify: restart xinetd 45 | when: daytime_dgram_service.stat.exists 46 | tags: 47 | - skip_ansible_lint 48 | 49 | - name: "SCORED | 2.1.2 | PATCH | Ensure daytime services are not enabled | daytime-stream" 50 | stat: 51 | path: /etc/xinetd.d/daytime-stream 52 | register: daytime_stream_service 53 | 54 | - name: "SCORED | 2.1.2 | PATCH | Ensure daytime services are not enabled | daytime-stream" 55 | command: chkconfig daytime-stream off 56 | notify: restart xinetd 57 | when: daytime_stream_service.stat.exists 58 | tags: 59 | - skip_ansible_lint 60 | when: 61 | - rhel7cis_rule_2_1_2|bool 62 | tags: 63 | - level1 64 | - scored 65 | - patch 66 | - rule_2.1.2 67 | 68 | - name: "SCORED | 2.1.3 | PATCH | Ensure discard services are not enabled | discard-dgram,discard-stream" 69 | block: 70 | - name: "SCORED | 2.1.3 | PATCH | Ensure discard services are not enabled | discard-dgram" 71 | stat: 72 | path: /etc/xinetd.d/discard-dgram 73 | register: discard_dgram_service 74 | 75 | - name: "SCORED | 2.1.3 | PATCH | Ensure discard services are not enabled | discard-dgram" 76 | command: chkconfig discard-dgram off 77 | notify: restart xinetd 78 | when: discard_dgram_service.stat.exists 79 | tags: 80 | - skip_ansible_lint 81 | 82 | - name: "SCORED | 2.1.3 | PATCH | Ensure discard services are not enabled | discard-stream" 83 | stat: 84 | path: /etc/xinetd.d/discard-stream 85 | register: discard_stream_service 86 | 87 | - name: "SCORED | 2.1.3 | PATCH | Ensure discard services are not enabled | discard-stream" 88 | command: chkconfig discard-stream off 89 | notify: restart xinetd 90 | when: discard_stream_service.stat.exists 91 | tags: 92 | - skip_ansible_lint 93 | 94 | when: 95 | - rhel7cis_rule_2_1_3|bool 96 | tags: 97 | - level1 98 | - scored 99 | - patch 100 | - rule_2.1.3 101 | 102 | - name: "SCORED | 2.1.4 | PATCH | Ensure echo services are not enabled | echo-dgram,echo-stream" 103 | block: 104 | - name: "SCORED | 2.1.4 | PATCH | Ensure echo services are not enabled | echo-dgram" 105 | stat: 106 | path: /etc/xinetd.d/echo-dgram 107 | register: echo_dgram_service 108 | 109 | - name: "SCORED | 2.1.4 | PATCH | Ensure echo services are not enabled | echo-dgram" 110 | command: chkconfig echo-dgram off 111 | notify: restart xinetd 112 | when: echo_dgram_service.stat.exists 113 | tags: 114 | - skip_ansible_lint 115 | 116 | - name: "SCORED | 2.1.4 | PATCH | Ensure echo services are not enabled | echo-stream" 117 | stat: 118 | path: /etc/xinetd.d/echo-stream 119 | register: echo_stream_service 120 | 121 | - name: "SCORED | 2.1.4 | PATCH | Ensure echo services are not enabled | echo-stream" 122 | command: chkconfig echo-stream off 123 | notify: restart xinetd 124 | when: echo_stream_service.stat.exists 125 | tags: 126 | - skip_ansible_lint 127 | 128 | when: 129 | - rhel7cis_rule_2_1_4|bool 130 | tags: 131 | - level1 132 | - scored 133 | - patch 134 | - rule_2.1.4 135 | 136 | - name: "SCORED | 2.1.5 | PATCH | Ensure time services are not enabled | time-dgram,time-stream" 137 | block: 138 | - name: "SCORED | 2.1.5 | PATCH | Ensure time services are not enabled | time-dgram" 139 | stat: 140 | path: /etc/xinetd.d/time-dgram 141 | register: time_dgram_service 142 | 143 | - name: "SCORED | 2.1.5 | PATCH | Ensure time services are not enabled | time-dgram" 144 | command: chkconfig time-dgram off 145 | notify: restart xinetd 146 | when: time_dgram_service.stat.exists 147 | tags: 148 | - skip_ansible_lint 149 | 150 | - name: "SCORED | 2.1.5 | PATCH | Ensure time services are not enabled | time-stream" 151 | stat: 152 | path: /etc/xinetd.d/time-stream 153 | register: time_stream_service 154 | 155 | - name: "SCORED | 2.1.5 | PATCH | Ensure time services are not enabled | time-stream" 156 | command: chkconfig time-stream off 157 | notify: restart xinetd 158 | when: time_stream_service.stat.exists 159 | tags: 160 | - skip_ansible_lint 161 | 162 | when: 163 | - rhel7cis_rule_2_1_5|bool 164 | tags: 165 | - level1 166 | - scored 167 | - patch 168 | - rule_2.1.5 169 | 170 | - name: "SCORED | 2.1.6 | PATCH | Ensure tftp server is not enabled" 171 | block: 172 | - name: "SCORED | 2.1.6 | PATCH | Ensure tftp server is not enabled" 173 | stat: 174 | path: /etc/xinetd.d/tftp 175 | register: tftp_service 176 | 177 | - name: "SCORED | 2.1.6 | PATCH | Ensure tftp server is not enabled" 178 | command: chkconfig tftp off 179 | notify: restart xinetd 180 | when: 181 | - tftp_service.stat.exists 182 | - not rhel7cis_tftp_server 183 | tags: 184 | - skip_ansible_lint 185 | 186 | when: 187 | - rhel7cis_rule_2_1_6|bool 188 | tags: 189 | - level1 190 | - scored 191 | - patch 192 | - rule_2.1.6 193 | 194 | - name: "SCORED | 2.1.7 | PATCH | Ensure xinetd is not enabled" 195 | service: 196 | name: xinetd 197 | state: stopped 198 | enabled: no 199 | when: 200 | - xinetd_service_status.stdout == "loaded" and not rhel7cis_xinetd_required 201 | - rhel7cis_rule_2_1_7|bool 202 | tags: 203 | - level1 204 | - patch 205 | - scored 206 | - rule_2.1.7 207 | 208 | - name: "NOTSCORED | 2.2.1.1 | PATCH | Ensure time synchronization is in use - service install" 209 | yum: 210 | name: "{{ rhel7cis_time_synchronization }}" 211 | state: present 212 | when: 213 | - rhel7cis_rule_2_2_1_1|bool 214 | tags: 215 | - level1 216 | - patch 217 | - rule_2.2.1.1 218 | 219 | - name: "NOTSCORED | 2.2.1.1 | PATCH | Ensure time synchronization is in use - service start" 220 | service: 221 | name: "{{ rhel7cis_time_synchronization }}d" 222 | state: started 223 | enabled: yes 224 | when: 225 | - rhel7cis_rule_2_2_1_1|bool 226 | tags: 227 | - level1 228 | - patch 229 | - rule_2.2.1.1 230 | 231 | - name: "NOTSCORED | 2.2.1.1 | PATCH | Ensure time synchronization is in use - service stop ntp" 232 | service: 233 | name: ntpd 234 | state: stopped 235 | enabled: no 236 | when: 237 | - rhel7cis_time_synchronization == "chrony" and ntpd_service_status.stdout == "loaded" 238 | - rhel7cis_rule_2_2_1_1|bool 239 | tags: 240 | - level1 241 | - patch 242 | - rule_2.2.1.1 243 | 244 | - name: "NOTSCORED | 2.2.1.1 | PATCH | Ensure time synchronization is in use - service stop chrony" 245 | service: 246 | name: chronyd 247 | state: stopped 248 | enabled: no 249 | ignore_errors: yes 250 | when: 251 | - rhel7cis_time_synchronization == "ntp" and chronyd_service_status.stdout == "loaded" 252 | - rhel7cis_rule_2_2_1_1|bool 253 | tags: 254 | - level1 255 | - patch 256 | - rule_2.2.1.1 257 | 258 | - name: "SCORED | 2.2.1.2 | PATCH | Ensure ntp is configured | modify /etc/ntp.conf" 259 | template: 260 | src: ntp.conf.j2 261 | dest: /etc/ntp.conf 262 | owner: root 263 | group: root 264 | mode: 0644 265 | when: 266 | - rhel7cis_time_synchronization == "ntp" 267 | - rhel7cis_rule_2_2_1_2|bool 268 | tags: 269 | - level1 270 | - patch 271 | - rule_2.2.1.2 272 | 273 | - name: "SCORED | 2.2.1.2 | PATCH | Ensure ntp is configured | modify /etc/sysconfig/ntpd" 274 | lineinfile: 275 | dest: /etc/sysconfig/ntpd 276 | regexp: "^(#)?OPTIONS" 277 | line: "OPTIONS=\"-u ntp:ntp\"" 278 | when: 279 | - rhel7cis_time_synchronization == "ntp" 280 | - rhel7cis_rule_2_2_1_2|bool 281 | tags: 282 | - level1 283 | - patch 284 | - rule_2.2.1.2 285 | 286 | - name: "SCORED | 2.2.1.2 | PATCH | Ensure ntp is configured | modify /usr/lib/systemd/system/ntpd.service" 287 | lineinfile: 288 | dest: /usr/lib/systemd/system/ntpd.service 289 | regexp: "^(#)?ExecStart" 290 | line: "ExecStart=/usr/sbin/ntpd -u ntp:ntp $OPTIONS" 291 | when: 292 | - rhel7cis_time_synchronization == "ntp" 293 | - rhel7cis_rule_2_2_1_2|bool 294 | tags: 295 | - level1 296 | - patch 297 | - rule_2.2.1.2 298 | 299 | - name: "SCORED | 2.2.1.3 | PATCH | Ensure chrony is configured" 300 | template: 301 | src: chrony.conf.j2 302 | dest: /etc/chrony.conf 303 | owner: root 304 | group: root 305 | mode: 0644 306 | when: 307 | - rhel7cis_time_synchronization == "chrony" 308 | - rhel7cis_rule_2_2_1_3|bool 309 | tags: 310 | - level1 311 | - patch 312 | - rule_2.2.1.3 313 | 314 | - name: "SCORED | 2.2.1.3 | PATCH | Ensure chrony is configured | modify /etc/sysconfig/chronyd | 1" 315 | lineinfile: 316 | dest: /etc/sysconfig/chronyd 317 | regexp: "^(#)?OPTIONS" 318 | line: "OPTIONS=\"-u chrony\"" 319 | state: present 320 | create: yes 321 | when: 322 | - rhel7cis_time_synchronization == "chrony" 323 | - rhel7cis_rule_2_2_1_3|bool 324 | tags: 325 | - level1 326 | - patch 327 | - rule_2.2.1.3 328 | 329 | - name: "SCORED | 2.2.2 | PATCH | Ensure X Window System is not installed" 330 | yum: 331 | state: absent 332 | name: 333 | - "@X Window System" 334 | - "xorg-x11*" 335 | when: 336 | - not rhel7cis_xwindows_required 337 | - rhel7cis_rule_2_2_2|bool 338 | tags: 339 | - level1 340 | - scored 341 | - xwindows 342 | - patch 343 | - rule_2.2.2 344 | 345 | - name: "SCORED | 2.2.3 | PATCH | Ensure Avahi Server is not enabled" 346 | service: 347 | name: avahi-daemon 348 | state: stopped 349 | enabled: no 350 | when: 351 | - not rhel7cis_avahi_server 352 | - avahi_service_status.stdout == "loaded" 353 | - rhel7cis_rule_2_2_3|bool 354 | tags: 355 | - level1 356 | - scored 357 | - avahi 358 | - services 359 | - patch 360 | - rule_2.2.3 361 | 362 | - name: "SCORED | 2.2.4 | PATCH | Ensure CUPS is not enabled" 363 | service: 364 | name: cups 365 | state: stopped 366 | enabled: no 367 | when: 368 | - not rhel7cis_cups_server 369 | - cups_service_status.stdout == "loaded" 370 | - rhel7cis_rule_2_2_4|bool 371 | tags: 372 | - level1 373 | - scored 374 | - cups 375 | - services 376 | - patch 377 | - rule_2.2.4 378 | 379 | - name: "SCORED | 2.2.5 | PATCH | Ensure DHCP Server is not enabled" 380 | service: 381 | name: dhcpd 382 | state: stopped 383 | enabled: no 384 | when: 385 | - not rhel7cis_dhcp_server 386 | - dhcpd_service_status.stdout == "loaded" 387 | - rhel7cis_rule_2_2_5|bool 388 | tags: 389 | - level1 390 | - scored 391 | - dhcp 392 | - services 393 | - patch 394 | - rule_2.2.5 395 | 396 | - name: "SCORED | 2.2.6 | PATCH | Ensure LDAP server is not enabled" 397 | service: 398 | name: slapd 399 | state: stopped 400 | enabled: no 401 | when: 402 | - not rhel7cis_ldap_server 403 | - slapd_service_status.stdout == "loaded" 404 | - rhel7cis_rule_2_2_6|bool 405 | tags: 406 | - level1 407 | - scored 408 | - ldap 409 | - services 410 | - patch 411 | - rule_2.2.6 412 | 413 | - name: "SCORED | 2.2.7 | PATCH | Ensure NFS and RPC are not enabled" 414 | service: 415 | name: nfs 416 | state: stopped 417 | enabled: no 418 | when: 419 | - not rhel7cis_nfs_rpc_server 420 | - nfs_service_status.stdout == "loaded" 421 | - rhel7cis_rule_2_2_7|bool 422 | tags: 423 | - level1 424 | - scored 425 | - nfs 426 | - rpc 427 | - services 428 | - patch 429 | - rule_2.2.7 430 | 431 | - name: "SCORED | 2.2.7 | PATCH | Ensure RPC is not enabled" 432 | service: 433 | name: rpcbind 434 | state: stopped 435 | enabled: no 436 | when: 437 | - not rhel7cis_nfs_rpc_server 438 | - rpcbind_service_status.stdout == "loaded" 439 | - rhel7cis_rule_2_2_7|bool 440 | tags: 441 | - level1 442 | - scored 443 | - nfs 444 | - rpc 445 | - services 446 | - patch 447 | - rule_2.2.7 448 | 449 | - name: "SCORED | 2.2.8 | PATCH | Ensure DNS Server is not enabled" 450 | service: 451 | name: named 452 | state: stopped 453 | enabled: no 454 | when: 455 | - not rhel7cis_named_server 456 | - named_service_status.stdout == "loaded" 457 | - rhel7cis_rule_2_2_8|bool 458 | tags: 459 | - level1 460 | - patch 461 | - rule_2.2.8 462 | 463 | - name: "SCORED | 2.2.9 | PATCH | Ensure FTP Server is not enabled" 464 | service: 465 | name: vsftpd 466 | state: stopped 467 | enabled: no 468 | when: 469 | - not rhel7cis_vsftpd_server 470 | - vsftpd_service_status.stdout == "loaded" 471 | - rhel7cis_rule_2_2_9|bool 472 | tags: 473 | - level1 474 | - patch 475 | - rule_2.2.9 476 | 477 | - name: "SCORED | 2.2.10 | PATCH | Ensure HTTP server is not enabled" 478 | service: 479 | name: httpd 480 | state: stopped 481 | enabled: no 482 | when: 483 | - not rhel7cis_httpd_server 484 | - httpd_service_status.stdout == "loaded" 485 | - rhel7cis_rule_2_2_10|bool 486 | tags: 487 | - level1 488 | - patch 489 | - rule_2.2.10 490 | 491 | - name: "SCORED | 2.2.11 | PATCH | Ensure IMAP and POP3 server is not enabled" 492 | service: 493 | name: dovecot 494 | state: stopped 495 | enabled: no 496 | when: 497 | - not rhel7cis_dovecot_server 498 | - dovecot_service_status.stdout == "loaded" 499 | - rhel7cis_rule_2_2_11|bool 500 | tags: 501 | - level1 502 | - patch 503 | - rule_2.2.11 504 | 505 | - name: "SCORED | 2.2.12 | PATCH | Ensure Samba is not enabled" 506 | service: 507 | name: smb 508 | state: stopped 509 | enabled: no 510 | when: 511 | - not rhel7cis_smb_server 512 | - smb_service_status.stdout == "loaded" 513 | - rhel7cis_rule_2_2_12|bool 514 | tags: 515 | - level1 516 | - patch 517 | - rule_2.2.12 518 | 519 | - name: "SCORED | 2.2.13 | PATCH | Ensure HTTP Proxy Server is not enabled" 520 | service: 521 | name: squid 522 | state: stopped 523 | enabled: no 524 | when: 525 | - not rhel7cis_squid_server 526 | - squid_service_status.stdout == "loaded" 527 | - rhel7cis_rule_2_2_13|bool 528 | tags: 529 | - level1 530 | - patch 531 | - rule_2.2.13 532 | 533 | - name: "SCORED | 2.2.14 | PATCH | Ensure SNMP Server is not enabled" 534 | service: 535 | name: snmpd 536 | state: stopped 537 | enabled: no 538 | when: 539 | - not rhel7cis_snmp_server 540 | - snmpd_service_status.stdout == "loaded" 541 | - rhel7cis_rule_2_2_14|bool 542 | tags: 543 | - level1 544 | - patch 545 | - rule_2.2.14 546 | 547 | - name: "SCORED | 2.2.15 | PATCH | Ensure mail transfer agent is configured for local-only mode" 548 | lineinfile: 549 | dest: /etc/postfix/main.cf 550 | regexp: "^(#)?inet_interfaces" 551 | line: "inet_interfaces = localhost" 552 | when: 553 | - not rhel7cis_is_mail_server 554 | - postfix_installed.rc == 0 555 | - rhel7cis_rule_2_2_15|bool 556 | tags: 557 | - level1 558 | - patch 559 | - rule_2.2.15 560 | 561 | - name: "SCORED | 2.2.16 | PATCH | Ensure NIS Server is not enabled" 562 | service: 563 | name: ypserv 564 | state: stopped 565 | enabled: no 566 | when: 567 | - not rhel7cis_nis_server 568 | - ypserv_service_status.stdout == "loaded" 569 | - rhel7cis_rule_2_2_16|bool 570 | tags: 571 | - level1 572 | - patch 573 | - rule_2.2.16 574 | 575 | - name: "SCORED | 2.2.17 | PATCH | Ensure rsh server is not enabled | rsh" 576 | service: 577 | name: rsh.socket 578 | state: stopped 579 | enabled: no 580 | when: 581 | - not rhel7cis_rsh_server 582 | - rsh_service_status.stdout == "loaded" 583 | - rhel7cis_rule_2_2_17|bool 584 | tags: 585 | - level1 586 | - patch 587 | - rule_2.2.17 588 | 589 | - name: "SCORED | 2.2.17 | PATCH | Ensure rsh server is not enabled | rlogin" 590 | service: 591 | name: rlogin.socket 592 | state: stopped 593 | enabled: no 594 | when: 595 | - not rhel7cis_rsh_server 596 | - rlogin_service_status.stdout == "loaded" 597 | - rhel7cis_rule_2_2_17|bool 598 | tags: 599 | - level1 600 | - patch 601 | - rule_2.2.17 602 | 603 | - name: "SCORED | 2.2.17 | PATCH | Ensure rsh server is not enabled | rexec" 604 | service: 605 | name: rexec.socket 606 | state: stopped 607 | enabled: no 608 | when: 609 | - not rhel7cis_rsh_server 610 | - rexec_service_status.stdout == "loaded" 611 | - rhel7cis_rule_2_2_17|bool 612 | tags: 613 | - level1 614 | - patch 615 | - rule_2.2.17 616 | 617 | - name: "SCORED | 2.2.18 | PATCH | Ensure telnet server is not enabled" 618 | service: 619 | name: telnet 620 | state: stopped 621 | enabled: no 622 | when: 623 | - not rhel7cis_telnet_server 624 | - telnet_service_status.stdout == "loaded" 625 | - rhel7cis_rule_2_2_18|bool 626 | tags: 627 | - level1 628 | - patch 629 | - rule_2.2.18 630 | 631 | - name: "SCORED | 2.2.19 | PATCH | Ensure tftp server is not enabled" 632 | service: 633 | name: tftp 634 | state: stopped 635 | enabled: no 636 | when: 637 | - not rhel7cis_tftp_server 638 | - tftp_service_status.stdout == "loaded" 639 | - rhel7cis_rule_2_2_19|bool 640 | tags: 641 | - level1 642 | - scored 643 | - insecure_services 644 | - tftp 645 | - patch 646 | - rule_2.2.19 647 | 648 | - name: "SCORED | 2.2.20 | PATCH | Ensure rsync service is not enabled " 649 | service: 650 | name: rsyncd 651 | state: stopped 652 | enabled: no 653 | when: 654 | - not rhel7cis_rsyncd_server 655 | - rsyncd_service_status.stdout == "loaded" 656 | - rhel7cis_rule_2_2_20|bool 657 | tags: 658 | - level1 659 | - patch 660 | - rule_2.2.20 661 | 662 | - name: "SCORED | 2.2.21 | PATCH | Ensure talk server is not enabled" 663 | service: 664 | name: ntalk 665 | state: stopped 666 | enabled: no 667 | when: 668 | - not rhel7cis_ntalk_server 669 | - ntalk_service_status.stdout == "loaded" 670 | - rhel7cis_rule_2_2_21|bool 671 | tags: 672 | - level1 673 | - patch 674 | - rule_2.2.21 675 | 676 | - name: "SCORED | 2.3.1 | PATCH | Ensure NIS Client is not installed" 677 | yum: 678 | name: ypbind 679 | state: absent 680 | when: 681 | - not rhel7cis_ypbind_required 682 | - rhel7cis_rule_2_3_1|bool 683 | tags: 684 | - level1 685 | - patch 686 | - rule_2.3.1 687 | 688 | - name: "SCORED | 2.3.2 | PATCH | Ensure rsh client is not installed" 689 | yum: 690 | name: rsh 691 | state: absent 692 | when: 693 | - not rhel7cis_rsh_required 694 | - rhel7cis_rule_2_3_2|bool 695 | tags: 696 | - level1 697 | - patch 698 | - rule_2.3.2 699 | 700 | - name: "SCORED | 2.3.3 | PATCH | Ensure talk client is not installed" 701 | yum: 702 | name: talk 703 | state: absent 704 | when: 705 | - not rhel7cis_talk_required 706 | - rhel7cis_rule_2_3_3|bool 707 | tags: 708 | - level1 709 | - patch 710 | - rule_2.3.3 711 | 712 | - name: "SCORED | 2.3.4 | PATCH | Ensure telnet client is not installed" 713 | yum: 714 | name: telnet 715 | state: absent 716 | when: 717 | - not rhel7cis_telnet_required 718 | - rhel7cis_rule_2_3_4|bool 719 | tags: 720 | - level1 721 | - patch 722 | - rule_2.3.4 723 | 724 | - name: "SCORED | 2.3.5 | PATCH | Ensure LDAP client is not installed" 725 | yum: 726 | name: openldap-clients 727 | state: absent 728 | when: 729 | - not rhel7cis_openldap_clients_required 730 | - rhel7cis_rule_2_3_5|bool 731 | tags: 732 | - level1 733 | - patch 734 | - rule_2.3.5 735 | -------------------------------------------------------------------------------- /LinuxCis/tasks/section3.yml: -------------------------------------------------------------------------------- 1 | - name: "SCORED | 3.1.1 | PATCH | Ensure IP forwarding is disabled" 2 | sysctl: 3 | name: net.ipv4.ip_forward 4 | value: '0' 5 | state: present 6 | reload: yes 7 | ignoreerrors: yes 8 | notify: 9 | - sysctl flush ipv4 route table 10 | when: 11 | - not rhel7cis_is_router 12 | - rhel7cis_rule_3_1_1|bool 13 | tags: 14 | - level1 15 | - sysctl 16 | - patch 17 | - rule_3.1.1 18 | 19 | - name: "SCORED | 3.1.2 | PATCH | Ensure packet redirect sending is disabled" 20 | sysctl: 21 | name: '{{ item.name }}' 22 | value: '{{ item.value }}' 23 | sysctl_set: yes 24 | state: present 25 | reload: yes 26 | ignoreerrors: yes 27 | with_items: 28 | - { name: net.ipv4.conf.all.send_redirects, value: 0 } 29 | - { name: net.ipv4.conf.default.send_redirects, value: 0 } 30 | notify: 31 | - sysctl flush ipv4 route table 32 | when: 33 | - not rhel7cis_is_router 34 | - rhel7cis_rule_3_1_2|bool 35 | tags: 36 | - level1 37 | - sysctl 38 | - patch 39 | - rule_3.1.2 40 | 41 | - name: "SCORED | 3.2.1 | PATCH | Ensure source routed packets are not accepted" 42 | sysctl: 43 | name: '{{ item.name }}' 44 | value: '{{ item.value }}' 45 | sysctl_set: yes 46 | state: present 47 | reload: yes 48 | ignoreerrors: yes 49 | with_items: 50 | - { name: net.ipv4.conf.all.accept_source_route, value: 0 } 51 | - { name: net.ipv4.conf.default.accept_source_route, value: 0 } 52 | notify: 53 | - sysctl flush ipv4 route table 54 | when: 55 | - rhel7cis_rule_3_2_1|bool 56 | tags: 57 | - level1 58 | - sysctl 59 | - patch 60 | - rule_3.2.1 61 | 62 | - name: "SCORED | 3.2.2 | PATCH | Ensure ICMP redirects are not accepted" 63 | sysctl: 64 | name: '{{ item.name }}' 65 | value: '{{ item.value }}' 66 | sysctl_set: yes 67 | state: present 68 | reload: yes 69 | ignoreerrors: yes 70 | with_items: 71 | - { name: net.ipv4.conf.all.accept_redirects, value: 0 } 72 | - { name: net.ipv4.conf.default.accept_redirects, value: 0 } 73 | notify: 74 | - sysctl flush ipv4 route table 75 | when: 76 | - rhel7cis_rule_3_2_2|bool 77 | tags: 78 | - level1 79 | - sysctl 80 | - patch 81 | - rule_3.2.2 82 | 83 | - name: "SCORED | 3.2.3 | PATCH | Ensure secure ICMP redirects are not accepted" 84 | sysctl: 85 | name: '{{ item.name }}' 86 | value: '{{ item.value }}' 87 | sysctl_set: yes 88 | state: present 89 | reload: yes 90 | ignoreerrors: yes 91 | with_items: 92 | - { name: net.ipv4.conf.all.secure_redirects, value: 0 } 93 | - { name: net.ipv4.conf.default.secure_redirects, value: 0 } 94 | notify: 95 | - sysctl flush ipv4 route table 96 | when: 97 | - rhel7cis_rule_3_2_3|bool 98 | tags: 99 | - level1 100 | - sysctl 101 | - patch 102 | - rule_3.2.3 103 | 104 | - name: "SCORED | 3.2.4 | PATCH | Ensure suspicious packets are logged" 105 | sysctl: 106 | name: '{{ item.name }}' 107 | value: '{{ item.value }}' 108 | sysctl_set: yes 109 | state: present 110 | reload: yes 111 | ignoreerrors: yes 112 | with_items: 113 | - { name: net.ipv4.conf.all.log_martians, value: 1 } 114 | - { name: net.ipv4.conf.default.log_martians, value: 1 } 115 | notify: 116 | - sysctl flush ipv4 route table 117 | when: 118 | - rhel7cis_rule_3_2_4|bool 119 | tags: 120 | - level1 121 | - sysctl 122 | - patch 123 | - rule_3.2.4 124 | 125 | - name: "SCORED | 3.2.5 | PATCH | Ensure broadcast ICMP requests are ignored" 126 | sysctl: 127 | name: net.ipv4.icmp_echo_ignore_broadcasts 128 | value: '1' 129 | state: present 130 | reload: yes 131 | ignoreerrors: yes 132 | notify: 133 | - sysctl flush ipv4 route table 134 | when: 135 | - rhel7cis_rule_3_2_5|bool 136 | tags: 137 | - level1 138 | - sysctl 139 | - patch 140 | - rule_3.2.5 141 | 142 | - name: "SCORED | 3.2.6 | PATCH | Ensure bogus ICMP responses are ignored" 143 | sysctl: 144 | name: net.ipv4.icmp_ignore_bogus_error_responses 145 | value: '1' 146 | state: present 147 | reload: yes 148 | ignoreerrors: yes 149 | notify: 150 | - sysctl flush ipv4 route table 151 | when: 152 | - rhel7cis_rule_3_2_6|bool 153 | tags: 154 | - level1 155 | - sysctl 156 | - patch 157 | - rule_3.2.6 158 | 159 | - name: "SCORED | 3.2.7 | PATCH | Ensure Reverse Path Filtering is enabled" 160 | sysctl: 161 | name: '{{ item.name }}' 162 | value: '{{ item.value }}' 163 | sysctl_set: yes 164 | state: present 165 | reload: yes 166 | ignoreerrors: yes 167 | with_items: 168 | - { name: net.ipv4.conf.all.rp_filter, value: 1 } 169 | - { name: net.ipv4.conf.default.rp_filter, value: 1 } 170 | notify: 171 | - sysctl flush ipv4 route table 172 | when: 173 | - rhel7cis_rule_3_2_7|bool 174 | tags: 175 | - level1 176 | - sysctl 177 | - patch 178 | - rule_3.2.7 179 | 180 | - name: "SCORED | 3.2.8 | PATCH | Ensure TCP SYN Cookies is enabled" 181 | sysctl: 182 | name: net.ipv4.tcp_syncookies 183 | value: 1 184 | state: present 185 | reload: yes 186 | ignoreerrors: yes 187 | notify: 188 | - sysctl flush ipv4 route table 189 | when: 190 | - rhel7cis_rule_3_2_8|bool 191 | tags: 192 | - level1 193 | - sysctl 194 | - patch 195 | - rule_3.2.8 196 | 197 | - name: "SCORED | 3.3.1 | PATCH | Ensure IPv6 router advertisements are not accepted" 198 | sysctl: 199 | name: '{{ item.name }}' 200 | value: '{{ item.value }}' 201 | sysctl_set: yes 202 | state: present 203 | reload: yes 204 | ignoreerrors: yes 205 | with_items: 206 | - { name: net.ipv6.conf.all.accept_ra, value: 0 } 207 | - { name: net.ipv6.conf.default.accept_ra, value: 0 } 208 | notify: 209 | - sysctl flush ipv6 route table 210 | when: 211 | - rhel7cis_ipv6_required | bool 212 | - rhel7cis_rule_3_3_1|bool 213 | tags: 214 | - level1 215 | - sysctl 216 | - patch 217 | - rule_3.3.1 218 | 219 | - name: "SCORED | 3.3.2 | PATCH | Ensure IPv6 redirects are not accepted" 220 | sysctl: 221 | name: '{{ item.name }}' 222 | value: '{{ item.value }}' 223 | sysctl_set: yes 224 | state: present 225 | reload: yes 226 | ignoreerrors: yes 227 | with_items: 228 | - { name: net.ipv6.conf.all.accept_redirects, value: 0 } 229 | - { name: net.ipv6.conf.default.accept_redirects, value: 0 } 230 | notify: 231 | - sysctl flush ipv6 route table 232 | when: 233 | - rhel7cis_ipv6_required | bool 234 | - rhel7cis_rule_3_3_2|bool 235 | tags: 236 | - level1 237 | - sysctl 238 | - patch 239 | - rule_3.3.2 240 | 241 | - name: "NOTSCORED | 3.3.3 | PATCH | Ensure IPv6 is disabled" 242 | lineinfile: 243 | dest: /etc/default/grub 244 | regexp: '^(GRUB_CMDLINE_LINUX=.*(?!.*ipv6\.disable=1)\"[^\"]+)(\".*)' 245 | line: '\1 ipv6.disable=1\2' 246 | backrefs: yes 247 | notify: 248 | - grub2cfg 249 | when: 250 | - not rhel7cis_ipv6_required 251 | - rhel7cis_rule_3_3_3|bool 252 | tags: 253 | - level1 254 | - patch 255 | - rule_3.3.3 256 | 257 | - name: "SCORED | 3.4.1 | PATCH | Ensure TCP Wrappers is installed" 258 | yum: 259 | name: tcp_wrappers 260 | state: present 261 | when: 262 | - rhel7cis_rule_3_4_1|bool 263 | tags: 264 | - level1 265 | - patch 266 | - rule_3.4.1 267 | 268 | - name: "SCORED | 3.4.2 | PATCH | Ensure /etc/hosts.allow is configured" 269 | template: 270 | src: hosts.allow.j2 271 | dest: /etc/hosts.allow 272 | owner: root 273 | group: root 274 | mode: 0644 275 | when: 276 | - rhel7cis_rule_3_4_2|bool 277 | tags: 278 | - level1 279 | - patch 280 | - rule_3.4.2 281 | 282 | - name: "SCORED | 3.4.3 | PATCH | Ensure /etc/hosts.deny is configured" 283 | lineinfile: 284 | dest: /etc/hosts.deny 285 | regexp: "^(#)?ALL" 286 | line: "ALL: ALL" 287 | when: 288 | - rhel7cis_rule_3_4_3|bool 289 | tags: 290 | - level1 291 | - patch 292 | - rule_3.4.3 293 | 294 | - name: "SCORED | 3.4.4 | PATCH | Ensure permissions on /etc/hosts.allow are configured" 295 | file: 296 | dest: /etc/hosts.allow 297 | owner: root 298 | group: root 299 | mode: 0644 300 | when: 301 | - rhel7cis_rule_3_4_4|bool 302 | tags: 303 | - level1 304 | - patch 305 | - rule_3.4.4 306 | 307 | - name: "SCORED | 3.4.5 | PATCH | Ensure permissions on /etc/hosts.deny are 644" 308 | file: 309 | dest: /etc/hosts.deny 310 | owner: root 311 | group: root 312 | mode: 0644 313 | when: 314 | - rhel7cis_rule_3_4_5|bool 315 | tags: 316 | - level1 317 | - patch 318 | - rule_3.4.5 319 | 320 | - name: "NOTSCORED | 3.5.1 | PATCH | Ensure DCCP is disabled" 321 | lineinfile: 322 | dest: /etc/modprobe.d/CIS.conf 323 | regexp: "^(#)?install dccp(\\s|$)" 324 | line: "install dccp /bin/true" 325 | create: yes 326 | when: 327 | - rhel7cis_rule_3_5_1|bool 328 | tags: 329 | - level1 330 | - patch 331 | - rule_3.5.1 332 | 333 | - name: "NOTSCORED | 3.5.2 | PATCH | Ensure SCTP is disabled" 334 | lineinfile: 335 | dest: /etc/modprobe.d/CIS.conf 336 | regexp: "^(#)?install sctp(\\s|$)" 337 | line: "install sctp /bin/true" 338 | create: yes 339 | when: 340 | - rhel7cis_rule_3_5_2|bool 341 | tags: 342 | - level1 343 | - patch 344 | - rule_3.5.2 345 | 346 | - name: "NOTSCORED | 3.5.3 | PATCH | Ensure RDS is disabled" 347 | lineinfile: 348 | dest: /etc/modprobe.d/CIS.conf 349 | regexp: "^(#)?install rds(\\s|$)" 350 | line: "install rds /bin/true" 351 | create: yes 352 | when: 353 | - rhel7cis_rule_3_5_3|bool 354 | tags: 355 | - level1 356 | - patch 357 | - rule_3.5.3 358 | 359 | - name: "NOTSCORED | 3.5.4 | PATCH | Ensure TIPC is disabled" 360 | lineinfile: 361 | dest: /etc/modprobe.d/CIS.conf 362 | regexp: "^(#)?install tipc(\\s|$)" 363 | line: "install tipc /bin/true" 364 | create: yes 365 | when: 366 | - rhel7cis_rule_3_5_4|bool 367 | tags: 368 | - level1 369 | - patch 370 | - rule_3.5.4 371 | 372 | # - name: "SCORED | 3.6 | PATCH | Ensure firewalld is installed and started | CUSTOM" 373 | # yum: 374 | # name: firewalld 375 | # state: present 376 | # when: rhel7cis_firewall == "firewalld" 377 | # notify: restart firewalld 378 | # tags: 379 | # - level1 380 | # - patch 381 | # - rule_3.6 382 | 383 | # - name: "SCORED | 3.6 | PATCH | Ensure firewalld is installed and started | CUSTOM" 384 | # service: 385 | # name: firewalld 386 | # state: started 387 | # enabled: yes 388 | # when: rhel7cis_firewall == "firewalld" 389 | # tags: 390 | # - level1 391 | # - patch 392 | # - rule_3.6 393 | 394 | # - name: "SCORED | 3.6.1 | PATCH | Ensure iptables is installed" 395 | # yum: 396 | # name: iptables 397 | # state: present 398 | # when: 399 | # - rhel7cis_firewall == "iptables" 400 | # - rhel7cis_rule_3_6_1|bool 401 | # tags: 402 | # - level1 403 | # - patch 404 | # - rule_3.6.1 405 | # 406 | # - name: "SCORED | 3.6.1 | PATCH | Ensure iptables is installed and started" 407 | # service: 408 | # name: iptables 409 | # state: started 410 | # enabled: yes 411 | # when: 412 | # - rhel7cis_firewall == "iptables" 413 | # - rhel7cis_rule_3_6_1|bool 414 | # tags: 415 | # - level1 416 | # - patch 417 | # - rule_3.6.1 418 | 419 | # - name: "SCORED | 3.6.2 | PATCH | Ensure default deny firewall policy" 420 | # lineinfile: 421 | # dest: /etc/firewalld/firewalld.conf 422 | # regexp: "^DefaultZone" 423 | # line: "DefaultZone=drop" 424 | # when: 425 | # - rhel7cis_firewall == "firewalld" 426 | # - rhel7cis_rule_3_6_2|bool 427 | # tags: 428 | # - level1 429 | # - patch 430 | # - rule_3.6.2 431 | 432 | # - name: "SCORED | 3.6.2 | PATCH | Ensure default deny firewall policy" 433 | # firewalld: 434 | # state: enabled 435 | # zone: drop 436 | # permanent: true 437 | # when: 438 | # - rhel7cis_firewall == "firewalld" 439 | # - rhel7cis_rule_3_6_2|bool 440 | # - ansible_connection != 'docker' 441 | # tags: 442 | # - level1 443 | # - patch 444 | # - rule_3.6.2 445 | 446 | # - name: "SCORED | 3.6.2 | PATCH | Ensure default deny firewall policy" 447 | # command: /bin/true 448 | # changed_when: no 449 | # when: 450 | # - rhel7cis_firewall == "iptables" 451 | # - rhel7cis_rule_3_6_2|bool 452 | # tags: 453 | # - level1 454 | # - patch 455 | # - rule_3.6.2 456 | # - notimplemented 457 | # 458 | # - name: "SCORED | 3.6.3 | PATCH | Ensure loopback traffic is configured" 459 | # command: /bin/true 460 | # changed_when: no 461 | # when: 462 | # - rhel7cis_firewall == "iptables" 463 | # - rhel7cis_rule_3_6_3|bool 464 | # tags: 465 | # - level1 466 | # - patch 467 | # - rule_3.6.3 468 | # - notimplemented 469 | 470 | # - name: "NOTSCORED | 3.6.4 | PATCH | Ensure outbound and established connections are configured" 471 | # command: /bin/true 472 | # changed_when: no 473 | # when: 474 | # - rhel7cis_firewall == "iptables" 475 | # - rhel7cis_rule_3_6_4|bool 476 | # tags: 477 | # - level1 478 | # - patch 479 | # - rule_3.6.4 480 | # - notimplemented 481 | 482 | # - name: "SCORED | 3.6.5 | PATCH | Ensure firewall rules exist for all open ports" 483 | # firewalld: 484 | # service: "{{ item }}" 485 | # state: enabled 486 | # zone: drop 487 | # permanent: true 488 | # immediate: true 489 | # notify: restart firewalld 490 | # with_items: "{{ rhel7cis_firewall_services }}" 491 | # when: 492 | # - rhel7cis_firewall == "firewalld" 493 | # - rhel7cis_rule_3_6_5|bool 494 | # - ansible_connection != 'docker' 495 | # tags: 496 | # - level1 497 | # - patch 498 | # - rule_3.6.5 499 | 500 | # - name: "SCORED | 3.6.5 | PATCH | Ensure firewall rules exist for all open ports" 501 | # command: /bin/true 502 | # changed_when: no 503 | # when: 504 | # - rhel7cis_firewall == "iptables" 505 | # - rhel7cis_rule_3_6_5|bool 506 | # tags: 507 | # - level1 508 | # - patch 509 | # - rule_3.6.5 510 | # - notimplemented 511 | # 512 | # - name: "NOTSCORED | 3.7 | PATCH | Ensure wireless interfaces are disabled" 513 | # command: /bin/true 514 | # changed_when: no 515 | # tags: 516 | # - level1 517 | # - level2 518 | # - patch 519 | # - rule_3.7 520 | -------------------------------------------------------------------------------- /LinuxCis/tasks/section4.yml: -------------------------------------------------------------------------------- 1 | - name: "NOTSCORED | 4.1.1.1 | PATCH | Ensure audit log storage size is configured" 2 | lineinfile: 3 | dest: /etc/audit/auditd.conf 4 | regexp: "^max_log_file( |=)" 5 | line: "max_log_file = 10" 6 | state: present 7 | when: 8 | - rhel7cis_rule_4_1_1_1|bool 9 | notify: restart auditd 10 | tags: 11 | - level2 12 | - auditd 13 | - patch 14 | - rule_4.1.1.1 15 | 16 | - name: "SCORED | 4.1.1.2 | PATCH | Ensure system is disabled when audit logs are full" 17 | lineinfile: 18 | dest: /etc/audit/auditd.conf 19 | regexp: "^admin_space_left_action" 20 | line: "admin_space_left_action = {{ rhel7cis_auditd['admin_space_left_action'] }}" 21 | state: present 22 | when: 23 | - rhel7cis_rule_4_1_1_2|bool 24 | notify: restart auditd 25 | tags: 26 | - level2 27 | - auditd 28 | - patch 29 | - rule_4.1.1.2 30 | 31 | - name: "SCORED | 4.1.1.2 | PATCH | Ensure email on non-admin audit space alert" 32 | lineinfile: 33 | dest: /etc/audit/auditd.conf 34 | regexp: "^space_left_action" 35 | line: "space_left_action = email" 36 | state: present 37 | when: 38 | - rhel7cis_rule_4_1_1_2|bool 39 | notify: restart auditd 40 | tags: 41 | - level2 42 | - auditd 43 | - patch 44 | - rule_4.1.1.2 45 | 46 | - name: "SCORED | 4.1.1.3 | PATCH | Ensure audit logs are not automatically deleted" 47 | lineinfile: 48 | dest: /etc/audit/auditd.conf 49 | regexp: "^max_log_file_action" 50 | line: "max_log_file_action = {{ rhel7cis_auditd['max_log_file_action'] }}" 51 | state: present 52 | when: 53 | - rhel7cis_rule_4_1_1_3|bool 54 | notify: restart auditd 55 | tags: 56 | - level2 57 | - auditd 58 | - patch 59 | - rule_4.1.1.3 60 | 61 | - name: "SCORED | 4.1.2 | PATCH | Ensure auditd service is enabled" 62 | service: 63 | name: auditd 64 | state: started 65 | enabled: yes 66 | when: 67 | - not rhel7cis_skip_for_travis 68 | - rhel7cis_rule_4_1_2|bool 69 | - ansible_connection != 'docker' 70 | tags: 71 | - level2 72 | - auditd 73 | - patch 74 | - rule_4.1.2 75 | 76 | - name: "SCORED | 4.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled" 77 | replace: 78 | dest: /etc/default/grub 79 | regexp: '(^GRUB_CMDLINE_LINUX\s*\=\s*)(?:")(.+)(?- 222 | set -o pipefail && 223 | for i in $(df | grep '^/dev' | awk '{ print $NF }'); do 224 | find $i -xdev -type f -perm -4000 -o -type f -perm -2000 2>/dev/null; 225 | done 226 | register: priv_procs 227 | changed_when: no 228 | check_mode: no 229 | when: 230 | - rhel7cis_rule_4_1_12|bool 231 | tags: 232 | - level2 233 | - auditd 234 | - patch 235 | - rule_4.1.12 236 | 237 | - name: "SCORED | 4.1.12 | PATCH | Ensure use of privileged commands is collected" 238 | template: 239 | src: audit/rhel7cis_rule_4_1_12.rules.j2 240 | dest: /etc/audit/rules.d/rhel7cis_rule_4_1_12.rules 241 | owner: root 242 | group: root 243 | mode: 0600 244 | notify: restart auditd 245 | when: 246 | - rhel7cis_rule_4_1_12|bool 247 | tags: 248 | - level2 249 | - auditd 250 | - patch 251 | - rule_4.1.12 252 | 253 | - name: "SCORED | 4.1.13 | PATCH | Ensure successful file system mounts are collected" 254 | template: 255 | src: audit/rhel7cis_rule_4_1_13.rules.j2 256 | dest: /etc/audit/rules.d/rhel7cis_rule_4_1_13.rules 257 | owner: root 258 | group: root 259 | mode: 0600 260 | when: 261 | - rhel7cis_rule_4_1_13|bool 262 | notify: restart auditd 263 | tags: 264 | - level2 265 | - auditd 266 | - patch 267 | - rule_4.1.13 268 | 269 | - name: "SCORED | 4.1.14 | PATCH | Ensure file deletion events by users are collected" 270 | template: 271 | src: audit/rhel7cis_rule_4_1_14.rules.j2 272 | dest: /etc/audit/rules.d/rhel7cis_rule_4_1_14.rules 273 | owner: root 274 | group: root 275 | mode: 0600 276 | when: 277 | - rhel7cis_rule_4_1_14|bool 278 | notify: restart auditd 279 | tags: 280 | - level2 281 | - auditd 282 | - patch 283 | - rule_4.1.14 284 | 285 | - name: "SCORED | 4.1.15 | PATCH | Ensure changes to system administration scope (sudoers) is collected" 286 | template: 287 | src: audit/rhel7cis_rule_4_1_15.rules.j2 288 | dest: /etc/audit/rules.d/rhel7cis_rule_4_1_15.rules 289 | owner: root 290 | group: root 291 | mode: 0600 292 | when: 293 | - rhel7cis_rule_4_1_15|bool 294 | notify: restart auditd 295 | tags: 296 | - level2 297 | - auditd 298 | - patch 299 | - rule_4.1.15 300 | 301 | - name: "SCORED | 4.1.16 | PATCH | Ensure system administrator actions (sudolog) are collected" 302 | template: 303 | src: audit/rhel7cis_rule_4_1_16.rules.j2 304 | dest: /etc/audit/rules.d/rhel7cis_rule_4_1_16.rules 305 | owner: root 306 | group: root 307 | mode: 0600 308 | when: 309 | - rhel7cis_rule_4_1_16|bool 310 | notify: restart auditd 311 | tags: 312 | - level2 313 | - auditd 314 | - patch 315 | - rule_4.1.16 316 | 317 | - name: "SCORED | 4.1.17 | PATCH | Ensure kernel module loading and unloading is collected" 318 | template: 319 | src: audit/rhel7cis_rule_4_1_17.rules.j2 320 | dest: /etc/audit/rules.d/rhel7cis_rule_4_1_17.rules 321 | owner: root 322 | group: root 323 | mode: 0600 324 | when: 325 | - rhel7cis_rule_4_1_17|bool 326 | notify: restart auditd 327 | tags: 328 | - level2 329 | - auditd 330 | - patch 331 | - rule_4.1.17 332 | 333 | - name: "SCORED | 4.1.18 | PATCH | Ensure the audit configuration is immutable" 334 | template: 335 | src: audit/rhel7cis_rule_4_1_18.rules.j2 336 | dest: /etc/audit/rules.d/rhel7cis_rule_4_1_18.rules 337 | owner: root 338 | group: root 339 | mode: 0600 340 | when: 341 | - rhel7cis_rule_4_1_18|bool 342 | notify: restart auditd 343 | tags: 344 | - level2 345 | - auditd 346 | - patch 347 | - rule_4.1.18 348 | 349 | - name: "SCORED | 4.2.3 | PATCH | Ensure rsyslog or syslog-ng is installed" 350 | yum: 351 | name: "{{ rhel7cis_syslog }}" 352 | state: present 353 | when: 354 | - rhel7cis_rule_4_2_3|bool 355 | tags: 356 | - level1 357 | - level2 358 | - patch 359 | - rule_4.2.3 360 | 361 | - name: "SCORED | 4.2.1.1 | PATCH | Ensure rsyslog Service is enabled" 362 | command: /bin/true 363 | changed_when: no 364 | when: 365 | - rhel7cis_rule_4_2_1_1|bool 366 | tags: 367 | - level1 368 | - level2 369 | - patch 370 | - rule_4.2.1.1 371 | - notimplemented 372 | 373 | - name: "NOTSCORED | 4.2.1.2 | PATCH | Ensure logging is configured" 374 | command: /bin/true 375 | changed_when: no 376 | when: 377 | - rhel7cis_rule_4_2_1_2|bool 378 | tags: 379 | - level1 380 | - level2 381 | - patch 382 | - rule_4.2.1.2 383 | - notimplemented 384 | 385 | - name: "SCORED | 4.2.1.3 | PATCH | Ensure rsyslog default file permissions configured" 386 | lineinfile: 387 | dest: /etc/rsyslog.conf 388 | regexp: '^\$FileCreateMode' 389 | line: '$FileCreateMode 0640' 390 | when: 391 | - rhel7cis_rule_4_2_1_3|bool 392 | tags: 393 | - level1 394 | - level2 395 | - patch 396 | - rule_4.2.1.3 397 | 398 | - name: "SCORED | 4.2.1.4 | PATCH | Ensure rsyslog is configured to send logs to a remote log host" 399 | command: /bin/true 400 | changed_when: no 401 | when: 402 | - rhel7cis_rule_4_2_1_4|bool 403 | tags: 404 | - level1 405 | - level2 406 | - patch 407 | - rule_4.2.1.4 408 | - notimplemented 409 | 410 | - name: "NOTSCORED | 4.2.1.5 | PATCH | Ensure remote rsyslog messages are only accepted on designated log hosts." 411 | command: /bin/true 412 | changed_when: no 413 | when: 414 | - rhel7cis_rule_4_2_1_5|bool 415 | tags: 416 | - level1 417 | - level2 418 | - patch 419 | - rule_4.2.1.5 420 | - notimplemented 421 | 422 | - name: "NOTSCORED | 4.2.1.5 | PATCH | Ensure remote rsyslog messages are only accepted on designated log hosts." 423 | command: /bin/true 424 | changed_when: no 425 | when: 426 | - rhel7cis_rule_4_2_1_5|bool 427 | tags: 428 | - level1 429 | - level2 430 | - patch 431 | - rule_4.2.1.5 432 | - notimplemented 433 | 434 | - name: "SCORED | 4.2.2.1 | PATCH | Ensure syslog-ng service is enabled" 435 | command: /bin/true 436 | changed_when: no 437 | when: 438 | - rhel7cis_rule_4_2_2_1|bool 439 | tags: 440 | - level1 441 | - level2 442 | - patch 443 | - rule_4.2.2.1 444 | - notimplemented 445 | 446 | - name: "NOTSCORED | 4.2.2.2 | PATCH | Ensure logging is configured" 447 | command: /bin/true 448 | changed_when: no 449 | when: 450 | - rhel7cis_rule_4_2_2_2|bool 451 | tags: 452 | - level1 453 | - level2 454 | - patch 455 | - rule_4.2.2.2 456 | - notimplemented 457 | 458 | - name: "SCORED | 4.2.2.3 | PATCH | Ensure syslog-ng default file permissions configured" 459 | command: /bin/true 460 | changed_when: no 461 | when: 462 | - rhel7cis_rule_4_2_2_3|bool 463 | tags: 464 | - level1 465 | - level2 466 | - patch 467 | - rule_4.2.2.3 468 | - notimplemented 469 | 470 | - name: "NOTSCORED | 4.2.2.4 | PATCH | Ensure syslog-ng is configured to send logs to a remote log host" 471 | command: /bin/true 472 | changed_when: no 473 | when: 474 | - rhel7cis_rule_4_2_2_4|bool 475 | tags: 476 | - level1 477 | - level2 478 | - patch 479 | - rule_4.2.2.4 480 | - notimplemented 481 | 482 | - name: "NOTSCORED | 4.2.2.5 | PATCH | Ensure remote syslog-ng messages are only accepted on designated log hosts" 483 | command: /bin/true 484 | changed_when: no 485 | when: 486 | - rhel7cis_rule_4_2_2_5|bool 487 | tags: 488 | - level1 489 | - level2 490 | - patch 491 | - rule_4.2.2.5 492 | - notimplemented 493 | 494 | - name: "SCORED | 4.2.4 | PATCH | Ensure permissions on all logfiles are configured" 495 | command: find /var/log -type f -exec chmod g-wx,o-rwx {} + 496 | changed_when: no 497 | failed_when: no 498 | when: 499 | - rhel7cis_rule_4_2_4|bool 500 | tags: 501 | - level1 502 | - level2 503 | - patch 504 | - rule_4.2.4 505 | 506 | - name: "NOTSCORED | 4.3 | PATCH | Ensure logrotate is configured" 507 | find: 508 | paths: /etc/logrotate.d/ 509 | register: log_rotates 510 | tags: 511 | - level1 512 | - level2 513 | - patch 514 | - rule_4.3 515 | 516 | - name: "NOTSCORED | 4.3 | PATCH | Ensure logrotate is configured" 517 | replace: 518 | path: "{{ item.path }}" 519 | regexp: '^(\s*)(daily|weekly|monthly|yearly)$' 520 | replace: "\\1{{ rhel7cis_logrotate }}" 521 | with_items: 522 | - "{{ log_rotates.files }}" 523 | - { path: "/etc/logrotate.conf" } 524 | when: 525 | - rhel7cis_rule_4_3|bool 526 | tags: 527 | - level1 528 | - level2 529 | - patch 530 | - rule_4.3 531 | -------------------------------------------------------------------------------- /LinuxCis/tasks/section5.yml: -------------------------------------------------------------------------------- 1 | - name: "SCORED | 5.1.1 | PATCH | Ensure cron daemon is enabled" 2 | service: 3 | name: crond 4 | enabled: yes 5 | when: 6 | - rhel7cis_rule_5_1_1|bool 7 | tags: 8 | - level1 9 | - level2 10 | - patch 11 | - rule_5.1.1 12 | 13 | - name: "SCORED | 5.1.2 | PATCH | Ensure permissions on /etc/crontab are configured" 14 | file: 15 | dest: /etc/crontab 16 | owner: root 17 | group: root 18 | mode: 0600 19 | when: 20 | - rhel7cis_rule_5_1_2|bool 21 | tags: 22 | - level1 23 | - level2 24 | - patch 25 | - rule_5.1.2 26 | 27 | - name: "SCORED | 5.1.3 | PATCH | Ensure permissions on /etc/cron.hourly are configured" 28 | file: 29 | dest: /etc/cron.hourly 30 | state: directory 31 | owner: root 32 | group: root 33 | mode: 0700 34 | when: 35 | - rhel7cis_rule_5_1_3|bool 36 | tags: 37 | - level1 38 | - level2 39 | - patch 40 | - rule_5.1.3 41 | 42 | - name: "SCORED | 5.1.4 | PATCH | Ensure permissions on /etc/cron.daily are configured" 43 | file: 44 | dest: /etc/cron.daily 45 | state: directory 46 | owner: root 47 | group: root 48 | mode: 0700 49 | when: 50 | - rhel7cis_rule_5_1_4|bool 51 | tags: 52 | - level1 53 | - level2 54 | - patch 55 | - rule_5.1.4 56 | 57 | - name: "SCORED | 5.1.5 | PATCH | Ensure permissions on /etc/cron.weekly are configured" 58 | file: 59 | dest: /etc/cron.weekly 60 | state: directory 61 | owner: root 62 | group: root 63 | mode: 0700 64 | when: 65 | - rhel7cis_rule_5_1_5|bool 66 | tags: 67 | - level1 68 | - level2 69 | - patch 70 | - rule_5.1.5 71 | 72 | - name: "SCORED | 5.1.6 | PATCH | Ensure permissions on /etc/cron.monthly are configured" 73 | file: 74 | dest: /etc/cron.monthly 75 | state: directory 76 | owner: root 77 | group: root 78 | mode: 0700 79 | when: 80 | - rhel7cis_rule_5_1_6|bool 81 | tags: 82 | - level1 83 | - level2 84 | - patch 85 | - rule_5.1.6 86 | 87 | - name: "SCORED | 5.1.7 | PATCH | Ensure permissions on /etc/cron.d are configured" 88 | file: 89 | dest: /etc/cron.d 90 | state: directory 91 | owner: root 92 | group: root 93 | mode: 0700 94 | when: 95 | - rhel7cis_rule_5_1_7|bool 96 | tags: 97 | - level1 98 | - level2 99 | - patch 100 | - rule_5.1.7 101 | 102 | - name: "SCORED | 5.1.8 | PATCH | Ensure at/cron is restricted to authorized users" 103 | block: 104 | - name: "SCORED | 5.1.8 | PATCH | Ensure at/cron is restricted to authorized users" 105 | file: 106 | dest: /etc/at.deny 107 | state: absent 108 | 109 | - name: "SCORED | 5.1.8 | PATCH | Check if at.allow exists" 110 | stat: 111 | path: "/etc/at.allow" 112 | register: p 113 | 114 | - name: "SCORED | 5.1.8 | PATCH | Ensure at/cron is restricted to authorized users" 115 | file: 116 | dest: /etc/at.allow 117 | state: '{{ "file" if p.stat.exists else "touch" }}' 118 | owner: root 119 | group: root 120 | mode: 0600 121 | 122 | - name: "SCORED | 5.1.8 | PATCH | Ensure at/cron is restricted to authorized users" 123 | file: 124 | dest: /etc/cron.deny 125 | state: absent 126 | 127 | - name: "SCORED | 5.1.8 | PATCH | Check if cron.allow exists" 128 | stat: 129 | path: "/etc/cron.allow" 130 | register: p 131 | 132 | - name: "SCORED | 5.1.8 | PATCH | Ensure at/cron is restricted to authorized users" 133 | file: 134 | dest: /etc/cron.allow 135 | state: '{{ "file" if p.stat.exists else "touch" }}' 136 | owner: root 137 | group: root 138 | mode: 0600 139 | when: 140 | - rhel7cis_rule_5_1_8|bool 141 | tags: 142 | - level1 143 | - level2 144 | - patch 145 | - rule_5.1.8 146 | 147 | - name: "CI | 5.2 | PATCH | Ensure host keys are present." 148 | command: /usr/bin/ssh-keygen -A 149 | args: 150 | creates: /etc/ssh/ssh_host_ed25519_key 151 | 152 | - name: "SCORED | 5.2.1 | PATCH | Ensure permissions on /etc/ssh/sshd_config are configured" 153 | file: 154 | dest: /etc/ssh/sshd_config 155 | state: file 156 | owner: root 157 | group: root 158 | mode: 0600 159 | when: 160 | - rhel7cis_rule_5_2_1|bool 161 | tags: 162 | - level1 163 | - level2 164 | - patch 165 | - rule_5.2.1 166 | 167 | - name: "SCORED | 5.2.2 | PATCH | Ensure SSH Protocol is set to 2" 168 | lineinfile: 169 | state: present 170 | dest: /etc/ssh/sshd_config 171 | regexp: '(?i)^Protocol' 172 | line: 'Protocol 2' 173 | validate: /usr/sbin/sshd -t -f %s 174 | when: 175 | - rhel7cis_rule_5_2_2|bool 176 | 177 | tags: 178 | - level1 179 | - level2 180 | - patch 181 | - rule_5.2.2 182 | 183 | - name: "SCORED | 5.2.3 | PATCH | Ensure SSH LogLevel is set to INFO" 184 | lineinfile: 185 | state: present 186 | dest: /etc/ssh/sshd_config 187 | regexp: '(?i)^LogLevel' 188 | line: 'LogLevel INFO' 189 | validate: /usr/sbin/sshd -t -f %s 190 | when: 191 | - rhel7cis_rule_5_2_3|bool 192 | notify: restart sshd 193 | tags: 194 | - level1 195 | - level2 196 | - patch 197 | - rule_5.2.3 198 | 199 | - name: "SCORED | 5.2.4 | PATCH | Ensure SSH X11 forwarding is disabled" 200 | lineinfile: 201 | state: present 202 | dest: /etc/ssh/sshd_config 203 | regexp: '(?i)^X11Forwarding' 204 | line: 'X11Forwarding no' 205 | validate: /usr/sbin/sshd -t -f %s 206 | when: 207 | - rhel7cis_rule_5_2_4|bool 208 | notify: restart sshd 209 | tags: 210 | - level1 211 | - level2 212 | - patch 213 | - rule_5.2.4 214 | 215 | - name: "SCORED | 5.2.5 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less" 216 | lineinfile: 217 | state: present 218 | dest: /etc/ssh/sshd_config 219 | regexp: '(?i)^(#)?MaxAuthTries \d' 220 | line: 'MaxAuthTries 4' 221 | validate: /usr/sbin/sshd -t -f %s 222 | when: 223 | - rhel7cis_rule_5_2_5|bool 224 | notify: restart sshd 225 | tags: 226 | - level1 227 | - level2 228 | - patch 229 | - rule_5.2.5 230 | 231 | - name: "SCORED | 5.2.6 | PATCH | Ensure SSH IgnoreRhosts is enabled" 232 | lineinfile: 233 | state: present 234 | dest: /etc/ssh/sshd_config 235 | regexp: '(?i)^IgnoreRhosts' 236 | line: 'IgnoreRhosts yes' 237 | validate: /usr/sbin/sshd -t -f %s 238 | when: 239 | - rhel7cis_rule_5_2_6|bool 240 | notify: restart sshd 241 | tags: 242 | - level1 243 | - level2 244 | - patch 245 | - rule_5.2.6 246 | 247 | - name: "SCORED | 5.2.7 | PATCH | Ensure SSH HostbasedAuthentication is disabled" 248 | lineinfile: 249 | state: present 250 | dest: /etc/ssh/sshd_config 251 | regexp: '(?i)^HostbasedAuthentication' 252 | line: 'HostbasedAuthentication no' 253 | validate: /usr/sbin/sshd -t -f %s 254 | when: 255 | - rhel7cis_rule_5_2_7|bool 256 | notify: restart sshd 257 | tags: 258 | - level1 259 | - level2 260 | - patch 261 | - rule_5.2.7 262 | 263 | - name: "SCORED | 5.2.8 | PATCH | Ensure SSH root login is disabled" 264 | lineinfile: 265 | state: present 266 | dest: /etc/ssh/sshd_config 267 | regexp: '(?i)^PermitRootLogin' 268 | line: 'PermitRootLogin no' 269 | validate: /usr/sbin/sshd -t -f %s 270 | when: 271 | - rhel7cis_rule_5_2_8|bool 272 | notify: restart sshd 273 | tags: 274 | - level1 275 | - level2 276 | - patch 277 | - rule_5.2.8 278 | 279 | - name: "SCORED | 5.2.9 | PATCH | Ensure SSH PermitEmptyPasswords is disabled" 280 | lineinfile: 281 | state: present 282 | dest: /etc/ssh/sshd_config 283 | regexp: '(?i)^PermitEmptyPasswords' 284 | line: 'PermitEmptyPasswords no' 285 | validate: /usr/sbin/sshd -t -f %s 286 | when: 287 | - rhel7cis_rule_5_2_9|bool 288 | notify: restart sshd 289 | tags: 290 | - level1 291 | - level2 292 | - patch 293 | - rule_5.2.9 294 | 295 | - name: "SCORED | 5.2.10 | PATCH | Ensure SSH PermitUserEnvironment is disabled" 296 | lineinfile: 297 | state: present 298 | dest: /etc/ssh/sshd_config 299 | regexp: '(?i)^PermitUserEnvironment' 300 | line: 'PermitUserEnvironment no' 301 | validate: /usr/sbin/sshd -t -f %s 302 | when: 303 | - rhel7cis_rule_5_2_10|bool 304 | notify: restart sshd 305 | tags: 306 | - level1 307 | - level2 308 | - patch 309 | - rule_5.2.10 310 | 311 | - name: "SCORED | 5.2.11 | PATCH | Ensure only approved ciphers are used" 312 | lineinfile: 313 | state: present 314 | dest: /etc/ssh/sshd_config 315 | regexp: '(?i)^Ciphers' 316 | line: "Ciphers {{ rhel7cis_sshd['ciphers'] }}" 317 | validate: /usr/sbin/sshd -t -f %s 318 | when: 319 | - rhel7cis_rule_5_2_11|bool 320 | notify: restart sshd 321 | tags: 322 | - level1 323 | - level2 324 | - patch 325 | - rule_5.2.11 326 | 327 | - name: "SCORED | 5.2.12 | PATCH | Ensure only approved MAC algorithms are used" 328 | lineinfile: 329 | state: present 330 | dest: /etc/ssh/sshd_config 331 | regexp: '(?i)^MACs' 332 | line: "MACs {{ rhel7cis_sshd['macs'] }}" 333 | validate: /usr/sbin/sshd -t -f %s 334 | when: 335 | - rhel7cis_rule_5_2_12|bool 336 | notify: restart sshd 337 | tags: 338 | - level1 339 | - level2 340 | - patch 341 | - rule_5.2.12 342 | 343 | - name: "SCORED | 5.2.13 | PATCH | Ensure SSH Idle Timeout Interval is configured" 344 | block: 345 | - name: "SCORED | 5.2.13 | PATCH | Ensure SSH Idle Timeout Interval is configured" 346 | lineinfile: 347 | state: present 348 | dest: /etc/ssh/sshd_config 349 | regexp: '(?i)^ClientAliveInterval' 350 | line: "ClientAliveInterval {{ rhel7cis_sshd['clientaliveinterval'] }}" 351 | validate: /usr/sbin/sshd -t -f %s 352 | notify: restart sshd 353 | 354 | - name: "SCORED | 5.2.13 | PATCH | Ensure SSH ClientAliveCountMax set to <= 3" 355 | lineinfile: 356 | state: present 357 | dest: /etc/ssh/sshd_config 358 | regexp: '(?i)^ClientAliveCountMax' 359 | line: "ClientAliveCountMax {{ rhel7cis_sshd['clientalivecountmax'] }}" 360 | validate: /usr/sbin/sshd -t -f %s 361 | notify: restart sshd 362 | when: 363 | - rhel7cis_rule_5_2_13|bool 364 | tags: 365 | - level1 366 | - level2 367 | - patch 368 | - rule_5.2.13 369 | 370 | - name: "SCORED | 5.2.14 | PATCH | Ensure SSH LoginGraceTime is set to one minute or less" 371 | lineinfile: 372 | state: present 373 | dest: /etc/ssh/sshd_config 374 | regexp: '(?i)^LoginGraceTime' 375 | line: "LoginGraceTime {{ rhel7cis_sshd['logingracetime'] }}" 376 | validate: /usr/sbin/sshd -t -f %s 377 | when: 378 | - rhel7cis_rule_5_2_14|bool 379 | notify: restart sshd 380 | tags: 381 | - level1 382 | - level2 383 | - patch 384 | - rule_5.2.14 385 | 386 | - name: "SCORED | 5.2.15 | PATCH | Ensure SSH access is limited" 387 | block: 388 | - name: "SCORED | 5.2.15 | PATCH | Ensure SSH access is limited - allowusers" 389 | lineinfile: 390 | state: present 391 | dest: /etc/ssh/sshd_config 392 | regexp: "(?i)^AllowUsers" 393 | line: AllowUsers {{ rhel7cis_sshd['allowusers'] }} 394 | validate: /usr/sbin/sshd -t -f %s 395 | notify: 396 | - restart sshd 397 | when: 398 | - rhel7cis_sshd['allowusers'] | default('') 399 | 400 | - name: "SCORED | 5.2.15 | PATCH | Ensure SSH access is limited - allowgroups" 401 | lineinfile: 402 | state: present 403 | dest: /etc/ssh/sshd_config 404 | regexp: "(?i)^AllowGroups" 405 | line: AllowGroups {{ rhel7cis_sshd['allowgroups'] }} 406 | validate: /usr/sbin/sshd -t -f %s 407 | notify: 408 | - restart sshd 409 | when: 410 | - rhel7cis_sshd['allowgroups'] | default('') 411 | 412 | - name: "SCORED | 5.2.15 | PATCH | Ensure SSH access is limited - denyusers" 413 | lineinfile: 414 | state: present 415 | dest: /etc/ssh/sshd_config 416 | regexp: "(?i)^DenyUsers" 417 | line: DenyUsers {{ rhel7cis_sshd['denyusers'] }} 418 | validate: /usr/sbin/sshd -t -f %s 419 | notify: 420 | - restart sshd 421 | when: 422 | - rhel7cis_sshd['denyusers'] | default('') 423 | 424 | - name: "SCORED | 5.2.15 | PATCH | Ensure SSH access is limited - denygroups" 425 | lineinfile: 426 | state: present 427 | dest: /etc/ssh/sshd_config 428 | regexp: "(?i)^DenyGroups" 429 | line: DenyGroups {{ rhel7cis_sshd['denygroups'] }} 430 | validate: /usr/sbin/sshd -t -f %s 431 | notify: 432 | - restart sshd 433 | when: 434 | - rhel7cis_sshd['denygroups'] | default('') 435 | when: 436 | - rhel7cis_rule_5_2_15|bool 437 | tags: 438 | - level1 439 | - level2 440 | - patch 441 | - rule_5.2.15 442 | 443 | - name: "SCORED | 5.2.16 | PATCH | Ensure SSH warning banner is configured" 444 | lineinfile: 445 | state: present 446 | dest: /etc/ssh/sshd_config 447 | regexp: '(?i)^Banner' 448 | line: 'Banner /etc/issue.net' 449 | validate: /usr/sbin/sshd -t -f %s 450 | when: 451 | - rhel7cis_rule_5_2_16|bool 452 | notify: restart sshd 453 | tags: 454 | - level1 455 | - level2 456 | - patch 457 | - rule_5.2.16 458 | 459 | - name: "SCORED | 5.3.1 | PATCH | Ensure password creation requirements are configured" 460 | lineinfile: 461 | state: present 462 | dest: /etc/security/pwquality.conf 463 | regexp: ^{{ item.key }}[ =] 464 | line: '{{ item.key }} = {{ item.value }}' 465 | with_dict: "{{ rhel7cis_pwquality }}" 466 | when: 467 | - rhel7cis_rule_5_3_1|bool 468 | tags: 469 | - level1 470 | - level2 471 | - patch 472 | - rule_5.3.1 473 | 474 | - name: "SCORED | 5.3.2 | PATCH | Ensure lockout for failed password attempts is configured" 475 | command: /bin/true 476 | changed_when: no 477 | when: 478 | - rhel7cis_rule_5_3_2|bool 479 | tags: 480 | - level1 481 | - level2 482 | - patch 483 | - rule_5.3.2 484 | - notimplemented 485 | 486 | - name: "SCORED | 5.3.3 | PATCH | Ensure password reuse is limited" 487 | command: /bin/true 488 | changed_when: no 489 | when: 490 | - rhel7cis_rule_5_3_3|bool 491 | tags: 492 | - level1 493 | - level2 494 | - patch 495 | - rule_5.3.3 496 | - notimplemented 497 | 498 | - name: "SCORED | 5.3.4 | PATCH | Ensure password hashing algorithm is SHA-512" 499 | command: authconfig --passalgo=sha512 --update 500 | changed_when: no 501 | failed_when: no 502 | when: 503 | - rhel7cis_rule_5_3_4|bool 504 | tags: 505 | - level1 506 | - level2 507 | - patch 508 | - rule_5.3.4 509 | 510 | - name: "SCORED | 5.4.1.1 | PATCH | Ensure password expiration is 90 days or less" 511 | lineinfile: 512 | state: present 513 | dest: /etc/login.defs 514 | regexp: '^PASS_MAX_DAYS' 515 | line: "PASS_MAX_DAYS {{ rhel7cis_pass['max_days'] }}" 516 | when: 517 | - rhel7cis_rule_5_4_1_1|bool 518 | tags: 519 | - level1 520 | - level2 521 | - patch 522 | - rule_5.4.1.1 523 | 524 | - name: "SCORED | 5.4.1.2 | PATCH | Ensure minimum days between password changes is 7 or more" 525 | lineinfile: 526 | state: present 527 | dest: /etc/login.defs 528 | regexp: '^PASS_MIN_DAYS' 529 | line: "PASS_MIN_DAYS {{ rhel7cis_pass['min_days'] }}" 530 | when: 531 | - rhel7cis_rule_5_4_1_2|bool 532 | tags: 533 | - level1 534 | - level2 535 | - patch 536 | - rule_5.4.1.2 537 | 538 | - name: "SCORED | 5.4.1.3 | PATCH | Ensure password expiration warning days is 7 or more" 539 | lineinfile: 540 | state: present 541 | dest: /etc/login.defs 542 | regexp: '^PASS_WARN_AGE' 543 | line: "PASS_WARN_AGE {{ rhel7cis_pass['warn_age'] }}" 544 | when: 545 | - rhel7cis_rule_5_4_1_3|bool 546 | tags: 547 | - level1 548 | - level2 549 | - patch 550 | - rule_5.4.1.3 551 | 552 | - name: "SCORED | 5.4.1.4 | PATCH | Ensure inactive password lock is 30 days or less" 553 | command: /bin/true 554 | changed_when: no 555 | when: 556 | - rhel7cis_rule_5_4_1_4|bool 557 | tags: 558 | - level1 559 | - level2 560 | - patch 561 | - rule_5.4.1.4 562 | - notimplemented 563 | 564 | - name: "SCORED | 5.4.2 | PATCH | Ensure system accounts are non-login" 565 | shell: "awk -F: '($3 < {{ rhel7cis_rule_5_4_2_min_uid }}) {print $1 }' /etc/passwd" 566 | changed_when: no 567 | check_mode: no 568 | register: system_account 569 | when: 570 | - rhel7cis_rule_5_4_2|bool 571 | tags: 572 | - level1 573 | - level2 574 | - patch 575 | - rule_5.4.2 576 | 577 | - name: "SCORED | 5.4.2 | PATCH | Ensure system accounts are non-login" 578 | user: 579 | name: "{{ item }}" 580 | password_lock: true 581 | with_items: 582 | - "{{ system_account.stdout_lines }}" 583 | when: 584 | - rhel7cis_rule_5_4_2|bool 585 | - item != "root" 586 | tags: 587 | - level1 588 | - level2 589 | - patch 590 | - rule_5.4.2 591 | 592 | - name: "SCORED | 5.4.2 | PATCH | Ensure system accounts are non-login" 593 | user: 594 | name: "{{ item }}" 595 | shell: /sbin/nologin 596 | with_items: 597 | - "{{ system_account.stdout_lines }}" 598 | when: 599 | - rhel7cis_rule_5_4_2|bool 600 | - item != "root" 601 | - item != "sync" 602 | - item != "shutdown" 603 | - item != "halt" 604 | tags: 605 | - level1 606 | - level2 607 | - patch 608 | - rule_5.4.2 609 | 610 | - name: "SCORED | 5.4.3 | PATCH | Ensure default group for the root account is GID 0" 611 | command: usermod -g 0 root 612 | changed_when: no 613 | failed_when: no 614 | when: 615 | - rhel7cis_rule_5_4_3|bool 616 | tags: 617 | - level1 618 | - level2 619 | - patch 620 | - rule_5.4.3 621 | 622 | - name: "SCORED | 5.4.4 | PATCH | Ensure default user umask is 027 or more restrictive" 623 | block: 624 | - name: "SCORED | 5.4.4 | PATCH | Ensure default user umask is 027 or more restrictive - /etc/bashrc" 625 | replace: 626 | path: /etc/bashrc 627 | regexp: '(^\s+umask) 002' 628 | replace: '\1 027' 629 | 630 | - name: "SCORED | 5.4.4 | PATCH | Ensure default user umask is 027 or more restrictive - /etc/profile" 631 | replace: 632 | path: /etc/profile 633 | regexp: '(^\s+umask) 002' 634 | replace: '\1 027' 635 | when: 636 | - rhel7cis_rule_5_4_4|bool 637 | tags: 638 | - level1 639 | - level2 640 | - patch 641 | - rule_5.4.4 642 | 643 | - name: "NOTSCORED | 5.5 | PATCH | Ensure root login is restricted to system console" 644 | command: /bin/true 645 | changed_when: no 646 | tags: 647 | - level1 648 | - level2 649 | - patch 650 | - rule_5.5 651 | - notimplemented 652 | 653 | - name: "SCORED | 5.6 | PATCH | Ensure access to the su command is restricted" 654 | lineinfile: 655 | state: present 656 | dest: /etc/pam.d/su 657 | regexp: '^(#)?auth\s+required\s+pam_wheel\.so' 658 | line: 'auth required pam_wheel.so use_uid' 659 | tags: 660 | - level1 661 | - level2 662 | - patch 663 | - rule_5.6 664 | 665 | - name: "SCORED | 5.6 | PATCH | Ensure access to the su command is restricted - wheel group contains root" 666 | user: 667 | name: root 668 | groups: wheel 669 | tags: 670 | - level1 671 | - level2 672 | - patch 673 | - rule_5.6 674 | -------------------------------------------------------------------------------- /LinuxCis/tasks/section6.yml: -------------------------------------------------------------------------------- 1 | - name: "NOTSCORED | 6.1.1 | PATCH | Audit system file permissions" 2 | command: /bin/true 3 | changed_when: no 4 | when: 5 | - rhel7cis_rule_6_1_1|bool 6 | tags: 7 | - level2 8 | - patch 9 | - rule_6.1.1 10 | - notimplemented 11 | 12 | - name: "SCORED | 6.1.2 | PATCH | Ensure permissions on /etc/passwd are configured" 13 | file: 14 | dest: /etc/passwd 15 | owner: root 16 | group: root 17 | mode: 0644 18 | when: 19 | - rhel7cis_rule_6_1_2|bool 20 | tags: 21 | - level1 22 | - level2 23 | - patch 24 | - rule_6.1.2 25 | 26 | - name: "SCORED | 6.1.3 | PATCH | Ensure permissions on /etc/shadow are configured" 27 | file: 28 | dest: /etc/shadow 29 | owner: root 30 | group: root 31 | mode: 0000 32 | when: 33 | - rhel7cis_rule_6_1_3|bool 34 | tags: 35 | - level1 36 | - level2 37 | - patch 38 | - rule_6.1.3 39 | 40 | - name: "SCORED | 6.1.4 | PATCH | Ensure permissions on /etc/group are configured" 41 | file: 42 | dest: /etc/group 43 | owner: root 44 | group: root 45 | mode: 0644 46 | when: 47 | - rhel7cis_rule_6_1_4|bool 48 | tags: 49 | - level1 50 | - level2 51 | - patch 52 | - rule_6.1.4 53 | 54 | - name: "SCORED | 6.1.5 | PATCH | Ensure permissions on /etc/gshadow are configured" 55 | file: 56 | dest: /etc/gshadow 57 | owner: root 58 | group: root 59 | mode: 0000 60 | when: 61 | - rhel7cis_rule_6_1_5|bool 62 | tags: 63 | - level1 64 | - level2 65 | - patch 66 | - rule_6.1.5 67 | 68 | - name: "SCORED | 6.1.6 | PATCH | Ensure permissions on /etc/passwd- are configured" 69 | file: 70 | dest: /etc/passwd- 71 | owner: root 72 | group: root 73 | mode: 0600 74 | when: 75 | - rhel7cis_rule_6_1_6|bool 76 | tags: 77 | - level1 78 | - level2 79 | - patch 80 | - rule_6.1.6 81 | 82 | - name: "SCORED | 6.1.7 | PATCH | Ensure permissions on /etc/shadow- are configured" 83 | file: 84 | dest: /etc/shadow- 85 | owner: root 86 | group: root 87 | mode: 0000 88 | when: 89 | - rhel7cis_rule_6_1_7|bool 90 | tags: 91 | - level1 92 | - level2 93 | - patch 94 | - rule_6.1.7 95 | 96 | - name: "SCORED | 6.1.8 | PATCH | Ensure permissions on /etc/group- are configured" 97 | file: 98 | dest: /etc/group- 99 | owner: root 100 | group: root 101 | mode: 0600 102 | when: 103 | - rhel7cis_rule_6_1_8|bool 104 | tags: 105 | - level1 106 | - level2 107 | - patch 108 | - rule_6.1.8 109 | 110 | - name: "SCORED | 6.1.9 | PATCH | Ensure permissions on /etc/gshadow- are configured" 111 | file: 112 | dest: /etc/gshadow- 113 | owner: root 114 | group: root 115 | mode: 0600 116 | when: 117 | - rhel7cis_rule_6_1_9|bool 118 | tags: 119 | - level1 120 | - level2 121 | - patch 122 | - rule_6.1.9 123 | 124 | - name: "SCORED | 6.1.10 | PATCH | Ensure no world writable files exist" 125 | command: /bin/true 126 | changed_when: no 127 | when: 128 | - rhel7cis_rule_6_1_10|bool 129 | tags: 130 | - level1 131 | - level2 132 | - patch 133 | - rule_6.1.10 134 | - notimplemented 135 | 136 | - name: "SCORED | 6.1.11 | PATCH | Ensure no unowned files or directories exist" 137 | command: /bin/true 138 | changed_when: no 139 | when: 140 | - rhel7cis_rule_6_1_11|bool 141 | tags: 142 | - level1 143 | - level2 144 | - patch 145 | - rule_6.1.11 146 | - notimplemented 147 | 148 | - name: "SCORED | 6.1.12 | PATCH | Ensure no ungrouped files or directories exist" 149 | command: /bin/true 150 | changed_when: no 151 | when: 152 | - rhel7cis_rule_6_1_12|bool 153 | tags: 154 | - level1 155 | - level2 156 | - patch 157 | - rule_6.1.12 158 | - notimplemented 159 | 160 | - name: "NOTSCORED | 6.1.13 | PATCH | Audit SUID executables" 161 | command: /bin/true 162 | changed_when: no 163 | when: 164 | - rhel7cis_rule_6_1_13|bool 165 | tags: 166 | - level1 167 | - level2 168 | - patch 169 | - rule_6.1.13 170 | - notimplemented 171 | 172 | - name: "NOTSCORED | 6.1.14 | PATCH | Audit SGID executables" 173 | command: /bin/true 174 | changed_when: no 175 | when: 176 | - rhel7cis_rule_6_1_14|bool 177 | tags: 178 | - level1 179 | - level2 180 | - patch 181 | - rule_6.1.14 182 | - notimplemented 183 | 184 | - name: "SCORED | 6.2.1 | PATCH | Ensure password fields are not empty" 185 | command: passwd -l {{ item }} 186 | changed_when: no 187 | failed_when: no 188 | with_items: "{{ empty_password_accounts.stdout_lines }}" 189 | when: 190 | - empty_password_accounts.rc 191 | - rhel7cis_rule_6_2_1|bool 192 | tags: 193 | - level1 194 | - level2 195 | - patch 196 | - rule_6.2.1 197 | 198 | - name: "SCORED | 6.2.2 | PATCH | Ensure no legacy '+' entries exist in /etc/passwd" 199 | command: sed -i '/^+/ d' /etc/passwd 200 | changed_when: no 201 | failed_when: no 202 | when: 203 | - rhel7cis_rule_6_2_2|bool 204 | tags: 205 | - level1 206 | - level2 207 | - patch 208 | - rule_6.2.2 209 | - skip_ansible_lint # ANSIBLE0006 210 | 211 | - name: "SCORED | 6.2.3 | PATCH | Ensure no legacy '+' entries exist in /etc/shadow" 212 | command: sed -i '/^+/ d' /etc/shadow 213 | changed_when: no 214 | failed_when: no 215 | when: 216 | - rhel7cis_rule_6_2_3|bool 217 | tags: 218 | - level1 219 | - level2 220 | - patch 221 | - rule_6.2.3 222 | - skip_ansible_lint # ANSIBLE0006 223 | 224 | - name: "SCORED | 6.2.4 | PATCH | Ensure no legacy '+' entries exist in /etc/group" 225 | command: sed -i '/^+/ d' /etc/group 226 | changed_when: no 227 | failed_when: no 228 | when: 229 | - rhel7cis_rule_6_2_4|bool 230 | tags: 231 | - level1 232 | - level2 233 | - patch 234 | - rule_6.2.4 235 | - skip_ansible_lint # ANSIBLE0006 236 | 237 | - name: "SCORED | 6.2.5 | PATCH | Ensure root is the only UID 0 account" 238 | command: passwd -l {{ item }} 239 | changed_when: no 240 | failed_when: no 241 | with_items: "{{ uid_zero_accounts_except_root.stdout_lines }}" 242 | when: 243 | - uid_zero_accounts_except_root.rc 244 | - rhel7cis_rule_6_2_5|bool 245 | tags: 246 | - level1 247 | - level2 248 | - patch 249 | - rule_6.2.5 250 | 251 | - name: "SCORED | 6.2.6 | PATCH | Ensure root PATH Integrity" 252 | command: /bin/true 253 | changed_when: no 254 | when: 255 | - rhel7cis_rule_6_2_6|bool 256 | tags: 257 | - level1 258 | - level2 259 | - patch 260 | - rule_6.2.6 261 | - notimplemented 262 | 263 | - name: "SCORED | 6.2.7 | PATCH | Ensure all users' home directories exist" 264 | command: /bin/true 265 | changed_when: no 266 | when: 267 | - rhel7cis_rule_6_2_7|bool 268 | tags: 269 | - level1 270 | - level2 271 | - patch 272 | - rule_6.2.7 273 | - notimplemented 274 | 275 | - name: "SCORED | 6.2.8 | PATCH | Ensure users' home directories permissions are 750 or more restrictive" 276 | command: /bin/true 277 | changed_when: no 278 | when: 279 | - rhel7cis_rule_6_2_8|bool 280 | tags: 281 | - level1 282 | - level2 283 | - patch 284 | - rule_6.2.8 285 | - notimplemented 286 | 287 | - name: "SCORED | 6.2.9 | PATCH | Ensure users own their home directories" 288 | command: /bin/true 289 | changed_when: no 290 | when: 291 | - rhel7cis_rule_6_2_9|bool 292 | tags: 293 | - level1 294 | - level2 295 | - patch 296 | - rule_6.2.9 297 | - notimplemented 298 | 299 | - name: "SCORED | 6.2.10 | PATCH | Ensure users' dot files are not group or world writable" 300 | command: /bin/true 301 | changed_when: no 302 | when: 303 | - rhel7cis_rule_6_2_10|bool 304 | tags: 305 | - level1 306 | - level2 307 | - patch 308 | - rule_6.2.10 309 | - notimplemented 310 | 311 | - name: "SCORED | 6.2.11 | PATCH | Ensure no users have .forward files" 312 | file: 313 | state: absent 314 | dest: "~{{ item }}/.forward" 315 | with_items: "{{ users }}" 316 | when: 317 | - rhel7cis_rule_6_2_11|bool 318 | tags: 319 | - level1 320 | - level2 321 | - patch 322 | - rule_6.2.11 323 | 324 | - name: "SCORED | 6.2.12 | PATCH | Ensure no users have .netrc files" 325 | file: 326 | state: absent 327 | dest: "~{{ item }}/.netrc" 328 | with_items: "{{ users }}" 329 | when: 330 | - rhel7cis_rule_6_2_12|bool 331 | tags: 332 | - level1 333 | - level2 334 | - patch 335 | - rule_6.2.12 336 | 337 | # - name: "SCORED | 6.2.13 | PATCH | Ensure users' .netrc Files are not group or world accessible" 338 | # file: 339 | # mode: 0600 340 | # dest: "~{{ item }}/.netrc" 341 | # with_items: "{{ users.stdout_lines }}" 342 | # tags: 343 | # - level1 344 | # - level2 345 | # - patch 346 | # - rule_6.2.13 347 | 348 | - name: "SCORED | 6.2.14 | PATCH | Ensure no users have .rhosts files" 349 | file: 350 | state: absent 351 | dest: "~{{ item }}/.rhosts" 352 | with_items: "{{ users }}" 353 | when: 354 | - rhel7cis_rule_6_2_14|bool 355 | tags: 356 | - level1 357 | - level2 358 | - patch 359 | - rule_6.2.14 360 | 361 | - name: "SCORED | 6.2.15 | PATCH | Ensure all groups in /etc/passwd exist in /etc/group" 362 | command: /bin/true 363 | changed_when: no 364 | when: 365 | - rhel7cis_rule_6_2_15|bool 366 | tags: 367 | - level1 368 | - level2 369 | - patch 370 | - rule_6.2.15 371 | - notimplemented 372 | 373 | - name: "SCORED | 6.2.16 | PATCH | Ensure no duplicate UIDs exist" 374 | command: /bin/true 375 | changed_when: no 376 | when: 377 | - rhel7cis_rule_6_2_16|bool 378 | tags: 379 | - level1 380 | - level2 381 | - patch 382 | - rule_6.2.16 383 | - notimplemented 384 | 385 | - name: "SCORED | 6.2.17 | PATCH | Ensure no duplicate GIDs exist" 386 | command: /bin/true 387 | changed_when: no 388 | when: 389 | - rhel7cis_rule_6_2_17|bool 390 | tags: 391 | - level1 392 | - level2 393 | - patch 394 | - rule_6.2.17 395 | - notimplemented 396 | 397 | - name: "SCORED | 6.2.18 | PATCH | Ensure no duplicate user names exist" 398 | command: /bin/true 399 | changed_when: no 400 | when: 401 | - rhel7cis_rule_6_2_18|bool 402 | tags: 403 | - level1 404 | - level2 405 | - patch 406 | - rule_6.2.18 407 | - notimplemented 408 | 409 | - name: "SCORED | 6.2.19 | PATCH | Ensure no duplicate group names exist" 410 | command: /bin/true 411 | changed_when: no 412 | when: 413 | - rhel7cis_rule_6_2_19|bool 414 | tags: 415 | - level1 416 | - level2 417 | - patch 418 | - rule_6.2.19 419 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_10.rules.j2: -------------------------------------------------------------------------------- 1 | -a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod 2 | -a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod 3 | -a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod 4 | {% if ansible_architecture == 'x86_64' -%} 5 | -a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod 6 | -a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod 7 | -a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod 8 | {% endif %} 9 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_11.rules.j2: -------------------------------------------------------------------------------- 1 | -a always,exit -F arch=b32 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -F key=access 2 | -a always,exit -F arch=b32 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -F key=access 3 | {% if ansible_architecture == 'x86_64' -%} 4 | -a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -F key=access 5 | -a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -F key=access 6 | {% endif %} 7 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_12.rules.j2: -------------------------------------------------------------------------------- 1 | {% for proc in priv_procs.stdout_lines -%} 2 | -a always,exit -F path={{ proc }} -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_13.rules.j2: -------------------------------------------------------------------------------- 1 | -a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts 2 | -a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k export 3 | {% if ansible_architecture == 'x86_64' -%} 4 | -a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts 5 | -a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k export 6 | {% endif %} 7 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_14.rules.j2: -------------------------------------------------------------------------------- 1 | -a always,exit -F arch=b32 -S rmdir,unlink,unlinkat,rename -S renameat -F auid>=1000 -F auid!=4294967295 -F key=delete 2 | {% if ansible_architecture == 'x86_64' -%} 3 | -a always,exit -F arch=b64 -S rmdir,unlink,unlinkat,rename -S renameat -F auid>=1000 -F auid!=4294967295 -F key=delete 4 | {% endif %} 5 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_15.rules.j2: -------------------------------------------------------------------------------- 1 | -w /etc/sudoers -p wa -k scope 2 | -w /etc/sudoers.d/ -p wa -k scope 3 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_16.rules.j2: -------------------------------------------------------------------------------- 1 | -w {{ rhel7cis_sudolog }} -p wa -k actions 2 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_17.rules.j2: -------------------------------------------------------------------------------- 1 | -w /usr/sbin/insmod -p x -k modules 2 | -w /usr/sbin/rmmod -p x -k modules 3 | -w /usr/sbin/modprobe -p x -k modules 4 | {% if ansible_architecture == 'x86_64' -%} 5 | -a always,exit -F arch=b64 -S init_module -S delete_module -k modules 6 | {% endif %} 7 | -a always,exit -F arch=b32 -S init_module -S delete_module -k modules 8 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_18.rules.j2: -------------------------------------------------------------------------------- 1 | -e 2 2 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_4.rules.j2: -------------------------------------------------------------------------------- 1 | -a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change 2 | -a always,exit -F arch=b32 -S clock_settime -F a0=0x0 -k time-change 3 | {% if ansible_architecture == 'x86_64' -%} 4 | -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change 5 | -a always,exit -F arch=b64 -S clock_settime -F a0=0x0 -k time-change 6 | {% endif %} 7 | -w /etc/localtime -p wa -k time-change 8 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_5.rules.j2: -------------------------------------------------------------------------------- 1 | -w /etc/group -p wa -k identity 2 | -w /etc/passwd -p wa -k identity 3 | -w /etc/gshadow -p wa -k identity 4 | -w /etc/shadow -p wa -k identity 5 | -w /etc/security/opasswd -p wa -k identity 6 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_6.rules.j2: -------------------------------------------------------------------------------- 1 | -a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale 2 | -w /etc/issue -p wa -k system-locale 3 | -w /etc/issue.net -p wa -k system-locale 4 | -w /etc/hosts -p wa -k system-locale 5 | -w /etc/sysconfig/network -p wa -k system-locale 6 | -w /etc/sysconfig/network-scripts/ -p wa -k system-locale 7 | {% if ansible_architecture == 'x86_64' -%} 8 | -a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_7.rules.j2: -------------------------------------------------------------------------------- 1 | -w /etc/selinux/ -p wa -k MAC-policy 2 | -w /usr/share/selinux/ -p wa -k MAC-policy 3 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_8.rules.j2: -------------------------------------------------------------------------------- 1 | -w /var/log/tallylog -p wa -k logins 2 | -w /var/log/lastlog -p wa -k logins 3 | -w /var/run/faillock/ -p wa -k logins 4 | -------------------------------------------------------------------------------- /LinuxCis/templates/audit/rhel7cis_rule_4_1_9.rules.j2: -------------------------------------------------------------------------------- 1 | -w /var/run/utmp -p wa -k session 2 | -w /var/log/wtmp -p wa -k logins 3 | -w /var/log/btmp -p wa -k logins 4 | -------------------------------------------------------------------------------- /LinuxCis/templates/chrony.conf.j2: -------------------------------------------------------------------------------- 1 | # This the default chrony.conf file for the Debian chrony package. After 2 | # editing this file use the command 'invoke-rc.d chrony restart' to make 3 | # your changes take effect. John Hasler 1998-2008 4 | 5 | # See www.pool.ntp.org for an explanation of these servers. Please 6 | # consider joining the project if possible. If you can't or don't want to 7 | # use these servers I suggest that you try your ISP's nameservers. We mark 8 | # the servers 'offline' so that chronyd won't try to connect when the link 9 | # is down. Scripts in /etc/ppp/ip-up.d and /etc/ppp/ip-down.d use chronyc 10 | # commands to switch it on when a dialup link comes up and off when it goes 11 | # down. Code in /etc/init.d/chrony attempts to determine whether or not 12 | # the link is up at boot time and set the online status accordingly. If 13 | # you have an always-on connection such as cable omit the 'offline' 14 | # directive and chronyd will default to online. 15 | # 16 | # Note that if Chrony tries to go "online" and dns lookup of the servers 17 | # fails they will be discarded. Thus under some circumstances it is 18 | # better to use IP numbers than host names. 19 | 20 | {% for server in rhel7cis_time_synchronization_servers -%} 21 | server {{ server }} {{ rhel7cis_chrony_server_options }} 22 | {% endfor %} 23 | 24 | # Look here for the admin password needed for chronyc. The initial 25 | # password is generated by a random process at install time. You may 26 | # change it if you wish. 27 | 28 | keyfile /etc/chrony/chrony.keys 29 | 30 | # Set runtime command key. Note that if you change the key (not the 31 | # password) to anything other than 1 you will need to edit 32 | # /etc/ppp/ip-up.d/chrony, /etc/ppp/ip-down.d/chrony, /etc/init.d/chrony 33 | # and /etc/cron.weekly/chrony as these scripts use it to get the password. 34 | 35 | commandkey 1 36 | 37 | # I moved the driftfile to /var/lib/chrony to comply with the Debian 38 | # filesystem standard. 39 | 40 | driftfile /var/lib/chrony/chrony.drift 41 | 42 | # Comment this line out to turn off logging. 43 | 44 | log tracking measurements statistics 45 | logdir /var/log/chrony 46 | 47 | # Stop bad estimates upsetting machine clock. 48 | 49 | maxupdateskew 100.0 50 | 51 | # Dump measurements when daemon exits. 52 | 53 | dumponexit 54 | 55 | # Specify directory for dumping measurements. 56 | 57 | dumpdir /var/lib/chrony 58 | 59 | # Let computer be a server when it is unsynchronised. 60 | 61 | local stratum 10 62 | 63 | # Allow computers on the unrouted nets to use the server. 64 | 65 | #allow 10/8 66 | #allow 192.168/16 67 | #allow 172.16/12 68 | 69 | # This directive forces `chronyd' to send a message to syslog if it 70 | # makes a system clock adjustment larger than a threshold value in seconds. 71 | 72 | logchange 0.5 73 | 74 | # This directive defines an email address to which mail should be sent 75 | # if chronyd applies a correction exceeding a particular threshold to the 76 | # system clock. 77 | 78 | # mailonchange root@localhost 0.5 79 | 80 | # This directive tells chrony to regulate the real-time clock and tells it 81 | # Where to store related data. It may not work on some newer motherboards 82 | # that use the HPET real-time clock. It requires enhanced real-time 83 | # support in the kernel. I've commented it out because with certain 84 | # combinations of motherboard and kernel it is reported to cause lockups. 85 | 86 | # rtcfile /var/lib/chrony/chrony.rtc 87 | 88 | # If the last line of this file reads 'rtconutc' chrony will assume that 89 | # the CMOS clock is on UTC (GMT). If it reads '# rtconutc' or is absent 90 | # chrony will assume local time. The line (if any) was written by the 91 | # chrony postinst based on what it found in /etc/default/rcS. You may 92 | # change it if necessary. 93 | rtconutc 94 | -------------------------------------------------------------------------------- /LinuxCis/templates/etc/issue.j2: -------------------------------------------------------------------------------- 1 | {{ rhel7cis_warning_banner }} 2 | -------------------------------------------------------------------------------- /LinuxCis/templates/etc/issue.net.j2: -------------------------------------------------------------------------------- 1 | {{ rhel7cis_warning_banner }} 2 | -------------------------------------------------------------------------------- /LinuxCis/templates/etc/motd.j2: -------------------------------------------------------------------------------- 1 | {{ rhel7cis_warning_banner }} 2 | -------------------------------------------------------------------------------- /LinuxCis/templates/hosts.allow.j2: -------------------------------------------------------------------------------- 1 | # 2 | # hosts.allow This file contains access rules which are used to 3 | # allow or deny connections to network services that 4 | # either use the tcp_wrappers library or that have been 5 | # started through a tcp_wrappers-enabled xinetd. 6 | # 7 | # See 'man 5 hosts_options' and 'man 5 hosts_access' 8 | # for information on rule syntax. 9 | # See 'man tcpd' for information on tcp_wrappers 10 | # 11 | ALL: {% for iprange in rhel7cis_host_allow -%}{{ iprange }}{% if not loop.last %}, {% endif %}{% endfor %} 12 | -------------------------------------------------------------------------------- /LinuxCis/templates/ntp.conf.j2: -------------------------------------------------------------------------------- 1 | # For more information about this file, see the man pages 2 | # ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5). 3 | 4 | driftfile /var/lib/ntp/drift 5 | 6 | # Permit time synchronization with our time source, but do not 7 | # permit the source to query or modify the service on this system. 8 | #restrict default nomodify notrap nopeer noquery 9 | restrict -4 default kod nomodify notrap nopeer noquery 10 | restrict -6 default kod nomodify notrap nopeer noquery 11 | 12 | # Permit all access over the loopback interface. This could 13 | # be tightened as well, but to do so would effect some of 14 | # the administrative functions. 15 | restrict 127.0.0.1 16 | restrict ::1 17 | 18 | # Hosts on local network are less restricted. 19 | #restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap 20 | 21 | # Use public servers from the pool.ntp.org project. 22 | # Please consider joining the pool (http://www.pool.ntp.org/join.html). 23 | {% for server in rhel7cis_time_synchronization_servers -%} 24 | server {{ server }} {{ rhel7cis_ntp_server_options }} 25 | {% endfor %} 26 | 27 | #broadcast 192.168.1.255 autokey # broadcast server 28 | #broadcastclient # broadcast client 29 | #broadcast 224.0.1.1 autokey # multicast server 30 | #multicastclient 224.0.1.1 # multicast client 31 | #manycastserver 239.255.254.254 # manycast server 32 | #manycastclient 239.255.254.254 autokey # manycast client 33 | 34 | # Enable public key cryptography. 35 | #crypto 36 | 37 | includefile /etc/ntp/crypto/pw 38 | 39 | # Key file containing the keys and key identifiers used when operating 40 | # with symmetric key cryptography. 41 | keys /etc/ntp/keys 42 | 43 | # Specify the key identifiers which are trusted. 44 | #trustedkey 4 8 42 45 | 46 | # Specify the key identifier to use with the ntpdc utility. 47 | #requestkey 8 48 | 49 | # Specify the key identifier to use with the ntpq utility. 50 | #controlkey 8 51 | 52 | # Enable writing of statistics records. 53 | #statistics clockstats cryptostats loopstats peerstats 54 | 55 | # Disable the monitoring facility to prevent amplification attacks using ntpdc 56 | # monlist command when default restrict does not include the noquery flag. See 57 | # CVE-2013-5211 for more details. 58 | # Note: Monitoring will not be disabled with the limited restriction flag. 59 | disable monitor 60 | -------------------------------------------------------------------------------- /Nginx/.ansible-lint: -------------------------------------------------------------------------------- 1 | skip_list: 2 | - '106' 3 | -------------------------------------------------------------------------------- /Nginx/.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | */__pycache__ 3 | *.pyc 4 | -------------------------------------------------------------------------------- /Nginx/.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 120 7 | level: warning 8 | 9 | ignore: | 10 | .github/stale.yml 11 | .travis.yml 12 | -------------------------------------------------------------------------------- /Nginx/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Jeff Geerling 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Nginx/README.md: -------------------------------------------------------------------------------- 1 | # Ansible Role: Nginx 2 | 3 | **Note:** Please consider using the official [NGINX Ansible role](https://github.com/nginxinc/ansible-role-nginx) from NGINX, Inc. 4 | 5 | Installs Nginx on RedHat, Debian/Ubuntu OS. 6 | 7 | This role installs and configures the latest version of Nginx from the Nginx RedHat-based and Debian-based systems package manager. This is not a production ready configuration and will need addtional configurations and settings to match your environment. 8 | 9 | ## Requirements 10 | 11 | None. 12 | 13 | ## Dependencies 14 | 15 | None. 16 | 17 | ## Example Playbook 18 | 19 | - hosts: server 20 | roles: 21 | - { role: nginx } 22 | 23 | ## License 24 | 25 | MIT / BSD -------------------------------------------------------------------------------- /Nginx/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Used only for Debian/Ubuntu installation, as the -t option for apt. 3 | nginx_default_release: "" 4 | 5 | # Use the official Nginx PPA for Ubuntu, and the version to use if so. 6 | nginx_ppa_use: false 7 | nginx_ppa_version: stable 8 | 9 | # The name of the nginx package to install. 10 | nginx_package_name: "nginx" 11 | 12 | nginx_service_state: started 13 | nginx_service_enabled: true 14 | 15 | nginx_conf_template: "nginx.conf.j2" 16 | nginx_vhost_template: "vhost.j2" 17 | 18 | nginx_doc_root: "/var/www/helloworld" 19 | 20 | nginx_worker_processes: >- 21 | "{{ ansible_processor_vcpus | default(ansible_processor_count) }}" 22 | nginx_worker_connections: "1024" 23 | nginx_multi_accept: "off" 24 | 25 | nginx_error_log: "/var/log/nginx/error.log warn" 26 | nginx_access_log: "/var/log/nginx/access.log main buffer=16k flush=2m" 27 | 28 | nginx_sendfile: "on" 29 | nginx_tcp_nopush: "on" 30 | nginx_tcp_nodelay: "on" 31 | 32 | nginx_keepalive_timeout: "65" 33 | nginx_keepalive_requests: "100" 34 | 35 | nginx_server_tokens: "on" 36 | 37 | nginx_client_max_body_size: "64m" 38 | 39 | nginx_server_names_hash_bucket_size: "64" 40 | 41 | nginx_proxy_cache_path: "" 42 | 43 | nginx_extra_conf_options: "" 44 | # Example extra main options, used within the main nginx's context: 45 | # nginx_extra_conf_options: | 46 | # env VARIABLE; 47 | # include /etc/nginx/main.d/*.conf; 48 | 49 | nginx_extra_http_options: "" 50 | # Example extra http options, printed inside the main server http config: 51 | # nginx_extra_http_options: | 52 | # proxy_buffering off; 53 | # proxy_set_header X-Real-IP $remote_addr; 54 | # proxy_set_header X-Scheme $scheme; 55 | # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 56 | # proxy_set_header Host $http_host; 57 | 58 | nginx_remove_default_vhost: false 59 | nginx_vhosts: 60 | - listen: "8080" 61 | server_name: "helloworld" 62 | root: "/var/www/helloworld" 63 | index: "index.html index.htm" 64 | filename: "helloworld.conf" #/etc/nginx/conf.d 65 | 66 | 67 | 68 | 69 | nginx_upstreams: [] 70 | # - name: myapp1 71 | # strategy: "ip_hash" # "least_conn", etc. 72 | # keepalive: 16 # optional 73 | # servers: { 74 | # "srv1.example.com", 75 | # "srv2.example.com weight=3", 76 | # "srv3.example.com" 77 | # } 78 | 79 | nginx_log_format: |- 80 | '$remote_addr - $remote_user [$time_local] "$request" ' 81 | '$status $body_bytes_sent "$http_referer" ' 82 | '"$http_user_agent" "$http_x_forwarded_for"' 83 | -------------------------------------------------------------------------------- /Nginx/files/index.html: -------------------------------------------------------------------------------- 1 | ________ ________ ________ ___ ___ ___ ________ _____ ______ ___ 2 | |\ ___ \|\ ____\|\ ___ \|\ \ |\ \ / /| |\ __ \|\ _ \ _ \|\ \ ___ 3 | \ \ \\ \ \ \ \___|\ \ \\ \ \ \ \ \ \ \/ / / \ \ \|\ \ \ \\\__\ \ \ \ \|\__\ 4 | \ \ \\ \ \ \ \ __\ \ \\ \ \ \ \ \ \ / / \ \ __ \ \ \\|__| \ \ \ \|__| 5 | \ \ \\ \ \ \ \|\ \ \ \\ \ \ \ \ / \/ \ \ \ \ \ \ \ \ \ \ \ \ ___ 6 | \ \__\\ \__\ \_______\ \__\\ \__\ \__\/ /\ \ \ \__\ \__\ \__\ \ \__\ \__\|\__\ 7 | \|__| \|__|\|_______|\|__| \|__|\|__/__/ /\ __\ \|__|\|__|\|__| \|__|\|__|\|__| 8 | |__|/ \|__| 9 | 10 | 11 | ___ ___ _______ ___ ___ ________ ___ __ ________ ________ ___ ________ 12 | |\ \|\ \|\ ___ \ |\ \ |\ \ |\ __ \ |\ \ |\ \|\ __ \|\ __ \|\ \ |\ ___ \ 13 | \ \ \\\ \ \ __/|\ \ \ \ \ \ \ \ \|\ \ \ \ \ \ \ \ \ \|\ \ \ \|\ \ \ \ \ \ \_|\ \ 14 | \ \ __ \ \ \_|/_\ \ \ \ \ \ \ \ \\\ \ \ \ \ __\ \ \ \ \\\ \ \ _ _\ \ \ \ \ \ \\ \ 15 | \ \ \ \ \ \ \_|\ \ \ \____\ \ \____\ \ \\\ \ \ \ \|\__\_\ \ \ \\\ \ \ \\ \\ \ \____\ \ \_\\ \ 16 | \ \__\ \__\ \_______\ \_______\ \_______\ \_______\ \ \____________\ \_______\ \__\\ _\\ \_______\ \_______\ 17 | \|__|\|__|\|_______|\|_______|\|_______|\|_______| \|____________|\|_______|\|__|\|__|\|_______|\|_______| -------------------------------------------------------------------------------- /Nginx/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart nginx 3 | systemd: 4 | name: nginx 5 | state: restarted 6 | enabled: yes 7 | 8 | - name: validate nginx configuration 9 | command: nginx -t -c /etc/nginx/nginx.conf 10 | changed_when: false 11 | 12 | - name: reload nginx 13 | systemd: 14 | name: nginx 15 | state: reloaded 16 | -------------------------------------------------------------------------------- /Nginx/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Variable setup. 3 | - name: Include OS-specific variables. 4 | include_vars: "{{ ansible_os_family }}.yml" 5 | 6 | - name: Define nginx_user. 7 | set_fact: 8 | nginx_user: "{{ __nginx_user }}" 9 | when: nginx_user is not defined 10 | 11 | - debug: 12 | msg: "This is ansible_os_family {{ ansible_os_family }} and ansible_distribution major {{ ansible_distribution_major_version }}" 13 | 14 | # Setup/install tasks. 15 | - include_tasks: setup-RedHat.yml 16 | when: 17 | - ansible_os_family == 'RedHat' 18 | - ansible_distribution_major_version is version_compare('7', '==') or ansible_distribution_major_version is version_compare('2', '==') 19 | tags: 20 | - always 21 | 22 | - include_tasks: setup-Ubuntu.yml 23 | when: ansible_distribution == 'Ubuntu' 24 | 25 | - include_tasks: setup-Debian.yml 26 | when: ansible_os_family == 'Debian' 27 | 28 | # Vhost configuration. 29 | - import_tasks: vhosts.yml 30 | 31 | # Nginx setup. 32 | - name: Copy nginx configuration in place. 33 | template: 34 | src: "{{ nginx_conf_template }}" 35 | dest: "{{ nginx_conf_file_path }}" 36 | owner: root 37 | group: "{{ root_group }}" 38 | mode: 0644 39 | notify: 40 | - reload nginx 41 | 42 | - name: Ensure nginx service is running as configured. 43 | service: 44 | name: nginx 45 | state: "{{ nginx_service_state }}" 46 | enabled: "{{ nginx_service_enabled }}" 47 | 48 | - name: Created web server doc root 49 | file: 50 | path: "{{ nginx_doc_root }}" 51 | state: directory 52 | mode: '0755' 53 | 54 | - name: Copy index.html to directory 55 | copy: 56 | src: ../files/index.html 57 | dest: "{{ nginx_doc_root }}" 58 | owner: root 59 | group: "{{ root_group }}" 60 | mode: "0644" 61 | -------------------------------------------------------------------------------- /Nginx/tasks/setup-Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Update apt cache. 3 | apt: 4 | update_cache: yes 5 | cache_valid_time: 86400 6 | changed_when: false 7 | 8 | - name: Ensure nginx is installed. 9 | apt: 10 | name: "{{ nginx_package_name }}" 11 | state: present 12 | default_release: "{{ nginx_default_release }}" 13 | -------------------------------------------------------------------------------- /Nginx/tasks/setup-RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Enable install nginx 3 | command: amazon-linux-extras install -y nginx1 4 | become: yes 5 | 6 | - name: Ensure nginx is installed. 7 | systemd: 8 | name: "{{ nginx_package_name }}" 9 | state: started 10 | enabled: yes 11 | -------------------------------------------------------------------------------- /Nginx/tasks/setup-Ubuntu.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure dirmngr is installed (gnupg dependency). 3 | apt: 4 | name: dirmngr 5 | state: present 6 | 7 | - name: Add PPA for Nginx (if configured). 8 | apt_repository: 9 | repo: 'ppa:nginx/{{ nginx_ppa_version }}' 10 | state: present 11 | update_cache: true 12 | register: nginx_ppa_added 13 | when: nginx_ppa_use | bool 14 | 15 | - name: Ensure nginx will reinstall if the PPA was just added. 16 | apt: 17 | name: nginx 18 | state: absent 19 | when: nginx_ppa_added is changed 20 | tags: ['skip_ansible_lint'] 21 | -------------------------------------------------------------------------------- /Nginx/tasks/vhosts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Remove default nginx vhost config file (if configured). 3 | file: 4 | path: "{{ nginx_default_vhost_path }}" 5 | state: absent 6 | when: nginx_remove_default_vhost | bool 7 | notify: restart nginx 8 | 9 | - name: Ensure nginx_vhost_path exists. 10 | file: 11 | path: "{{ nginx_vhost_path }}" 12 | state: directory 13 | mode: 0755 14 | notify: reload nginx 15 | 16 | - name: Add managed vhost config files. 17 | template: 18 | src: "{{ item.template|default(nginx_vhost_template) }}" 19 | dest: "{{ nginx_vhost_path }}/{{ item.filename|default(item.server_name.split(' ')[0] ~ '.conf') }}" 20 | force: true 21 | owner: root 22 | group: "{{ root_group }}" 23 | mode: 0644 24 | when: item.state|default('present') != 'absent' 25 | with_items: "{{ nginx_vhosts }}" 26 | notify: reload nginx 27 | tags: 28 | - skip_ansible_lint 29 | 30 | - name: Remove managed vhost config files. 31 | file: 32 | path: "{{ nginx_vhost_path }}/{{ item.filename|default(item.server_name.split(' ')[0] ~ '.conf') }}" 33 | state: absent 34 | when: item.state|default('present') == 'absent' 35 | with_items: "{{ nginx_vhosts }}" 36 | notify: reload nginx 37 | tags: 38 | - skip_ansible_lint 39 | 40 | - name: Remove legacy vhosts.conf file. 41 | file: 42 | path: "{{ nginx_vhost_path }}/vhosts.conf" 43 | state: absent 44 | notify: reload nginx 45 | -------------------------------------------------------------------------------- /Nginx/templates/nginx.conf.j2: -------------------------------------------------------------------------------- 1 | user {{ nginx_user }}; 2 | 3 | error_log {{ nginx_error_log }}; 4 | pid {{ nginx_pidfile }}; 5 | 6 | {% block worker %} 7 | worker_processes {{ nginx_worker_processes }}; 8 | {% endblock %} 9 | 10 | {% if nginx_extra_conf_options %} 11 | {{ nginx_extra_conf_options }} 12 | {% endif %} 13 | 14 | {% block events %} 15 | events { 16 | worker_connections {{ nginx_worker_connections }}; 17 | multi_accept {{ nginx_multi_accept }}; 18 | } 19 | {% endblock %} 20 | 21 | http { 22 | {% block http_begin %}{% endblock %} 23 | 24 | {% block http_basic %} 25 | include {{ nginx_mime_file_path }}; 26 | default_type application/octet-stream; 27 | 28 | server_names_hash_bucket_size {{ nginx_server_names_hash_bucket_size }}; 29 | 30 | client_max_body_size {{ nginx_client_max_body_size }}; 31 | 32 | log_format main {{ nginx_log_format|indent(23) }}; 33 | 34 | access_log {{ nginx_access_log }}; 35 | 36 | sendfile {{ nginx_sendfile }}; 37 | tcp_nopush {{ nginx_tcp_nopush }}; 38 | tcp_nodelay {{ nginx_tcp_nodelay }}; 39 | 40 | keepalive_timeout {{ nginx_keepalive_timeout }}; 41 | keepalive_requests {{ nginx_keepalive_requests }}; 42 | 43 | server_tokens {{ nginx_server_tokens }}; 44 | {% if nginx_proxy_cache_path %} 45 | proxy_cache_path {{ nginx_proxy_cache_path }}; 46 | {% endif %} 47 | {% endblock %} 48 | 49 | {% block http_gzip %} 50 | # gzip on; 51 | {% endblock %} 52 | 53 | {% if nginx_extra_http_options %} 54 | {{ nginx_extra_http_options|indent(4, False) }} 55 | {% endif %} 56 | 57 | {% block http_upstream %} 58 | {% for upstream in nginx_upstreams %} 59 | upstream {{ upstream.name }} { 60 | {% if upstream.strategy is defined %} 61 | {{ upstream.strategy }}; 62 | {% endif %} 63 | {% for server in upstream.servers %} 64 | server {{ server }}; 65 | {% endfor %} 66 | {% if upstream.keepalive is defined %} 67 | keepalive {{ upstream.keepalive }}; 68 | {% endif %} 69 | } 70 | {% endfor %} 71 | {% endblock %} 72 | 73 | {% block http_includes %} 74 | include {{ nginx_conf_path }}/*.conf; 75 | {% if nginx_conf_path != nginx_vhost_path %} 76 | include {{ nginx_vhost_path }}/*; 77 | {% endif %} 78 | {% endblock %} 79 | 80 | {% block http_end %}{% endblock %} 81 | } 82 | -------------------------------------------------------------------------------- /Nginx/templates/vhost.j2: -------------------------------------------------------------------------------- 1 | {% block server_redirect %} 2 | {% if item.server_name_redirect is defined %} 3 | server { 4 | listen {{ item.listen | default('8080') }}; 5 | server_name {{ item.server_name_redirect }}; 6 | return 301 $scheme://{{ item.server_name.split(' ')[0] }}$request_uri; 7 | } 8 | {% endif %} 9 | {% endblock %} 10 | 11 | server { 12 | {% block server_begin %}{% endblock %} 13 | 14 | {% block server_basic -%} 15 | listen {{ item.listen | default('8080') }}; 16 | 17 | {% if item.server_name is defined %} 18 | server_name {{ item.server_name }}; 19 | {% endif %} 20 | 21 | {% if item.root is defined %} 22 | root {{ item.root }}; 23 | {% endif %} 24 | 25 | index {{ item.index | default('index.html index.htm') }}; 26 | 27 | {% if item.error_page is defined %} 28 | error_page {{ item.error_page }}; 29 | {% endif %} 30 | {% if item.access_log is defined %} 31 | access_log {{ item.access_log }}; 32 | {% endif %} 33 | {% if item.error_log is defined %} 34 | error_log {{ item.error_log }} error; 35 | {% endif %} 36 | 37 | {% if item.return is defined %} 38 | return {{ item.return }}; 39 | {% endif %} 40 | {% endblock %} 41 | 42 | {% block server_end %}{% endblock %} 43 | 44 | {% if item.extra_parameters is defined %} 45 | {{ item.extra_parameters|indent(4) }} 46 | {% endif %} 47 | } 48 | -------------------------------------------------------------------------------- /Nginx/vars/Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | root_group: root 3 | nginx_conf_path: /etc/nginx/conf.d 4 | nginx_conf_file_path: /etc/nginx/nginx.conf 5 | nginx_mime_file_path: /etc/nginx/mime.types 6 | nginx_pidfile: /run/nginx.pid 7 | nginx_vhost_path: /etc/nginx/sites-enabled 8 | nginx_default_vhost_path: /etc/nginx/sites-enabled/default 9 | __nginx_user: "www-data" 10 | -------------------------------------------------------------------------------- /Nginx/vars/RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | root_group: root 3 | nginx_conf_path: /etc/nginx/conf.d 4 | nginx_conf_file_path: /etc/nginx/nginx.conf 5 | nginx_mime_file_path: /etc/nginx/mime.types 6 | nginx_pidfile: /var/run/nginx.pid 7 | nginx_vhost_path: /etc/nginx/conf.d 8 | nginx_default_vhost_path: /etc/nginx/conf.d/default.conf 9 | __nginx_user: "nginx" 10 | -------------------------------------------------------------------------------- /Parameters/infrastructure-ssm-parameters.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ParameterKey": "S3IAMConfigStackName", 4 | "ParameterValue": "s3-iam-config" 5 | }, 6 | { 7 | "ParameterKey": "NetworkStackName", 8 | "ParameterValue": "vpc-config" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /Parameters/kms-params.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ParameterKey": "KeyName", 4 | "ParameterValue": "DemoKey" 5 | }, 6 | { 7 | "ParameterKey": "UserARN", 8 | "ParameterValue": "arn:aws:iam::1234567891012:root" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /Parameters/nginx-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ParameterKey" : "Environment", 4 | "ParameterValue" : "dev" 5 | }, 6 | { 7 | "ParameterKey": "NetworkStackName", 8 | "ParameterValue" : "vpc-config" 9 | }, 10 | { 11 | "ParameterKey" : "S3IAMConfigStackName", 12 | "ParameterValue" : "s3-iam-config" 13 | }, 14 | { 15 | "ParameterKey": "AmiId", 16 | "ParameterValue" : "" 17 | }, 18 | { 19 | "ParameterKey": "ApplicationName", 20 | "ParameterValue" : "Nginx" 21 | }, 22 | { 23 | "ParameterKey": "ALBName", 24 | "ParameterValue" : "DemoNLB" 25 | }, 26 | { 27 | "ParameterKey": "TargetGroupName", 28 | "ParameterValue" : "DemoTG" 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /Parameters/nginx-image-builder-params.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ParameterKey": "Environment", 4 | "ParameterValue": "dev" 5 | }, 6 | { 7 | "ParameterKey": "ImageBuilderBucketName", 8 | "ParameterValue": "" 9 | }, 10 | { 11 | "ParameterKey": "NetworkStackName", 12 | "ParameterValue": "vpc-config" 13 | }, 14 | { 15 | "ParameterKey": "KMSStackName", 16 | "ParameterValue": "kms-config" 17 | }, 18 | { 19 | "ParameterKey": "S3ConfigStackName", 20 | "ParameterValue": "s3-iam-config" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /Parameters/s3-iam-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ParameterKey" : "Environment", 4 | "ParameterValue" : "dev" 5 | }, 6 | { 7 | "ParameterKey": "NetworkStackName", 8 | "ParameterValue" : "vpc-config" 9 | }, 10 | { 11 | "ParameterKey" : "KMSStackName", 12 | "ParameterValue" : "kms-config" 13 | }, 14 | { 15 | "ParameterKey": "DemoConfigS3BucketName", 16 | "ParameterValue" : "" 17 | }, 18 | { 19 | "ParameterKey" : "EC2InstanceRoleName", 20 | "ParameterValue" : "EC2InstanceRole" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /Parameters/vpc-endpoint-params.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ParameterKey" : "Environment", 4 | "ParameterValue" : "dev" 5 | }, 6 | { 7 | "ParameterKey": "NetworkStackName", 8 | "ParameterValue" : "vpc-config" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /Parameters/vpc-params.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ParameterKey" : "VPCCIDR", 4 | "ParameterValue" : "10.0.0.0/16" 5 | }, 6 | { 7 | "ParameterKey" : "Environment", 8 | "ParameterValue" : "dev" 9 | }, 10 | { 11 | "ParameterKey" : "AvailabilityZones", 12 | "ParameterValue" : "us-east-1a, us-east-1c" 13 | }, 14 | { 15 | "ParameterKey" : "PublicSubnet1ACIDR", 16 | "ParameterValue" : "10.0.1.0/24" 17 | }, 18 | { 19 | "ParameterKey" : "PublicSubnet2ACIDR", 20 | "ParameterValue" : "10.0.2.0/24" 21 | }, 22 | { 23 | "ParameterKey" : "PrivateSubnet2Z1CIDR", 24 | "ParameterValue" : "10.0.3.0/24" 25 | }, 26 | { 27 | "ParameterKey" : "PrivateSubnet2Z2CIDR", 28 | "ParameterValue" : "10.0.4.0/24" 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deploying CIS Level 1 hardened AMIs with Amazon EC2 Image Builder 2 | In this post, we demonstrate how to create an automated process that builds and deploys Center for Internet Security (CIS) Level 1 hardened AMIs. The pattern that we deploy includes Image Builder, a CIS Level 1 hardened AMI, an application running on EC2 instances, and Amazon Inspector for security analysis. You deploy the AMI configured with the Image Builder pipeline to an application stack. The application stack consists of EC2 instances running Nginx. Lastly, we show you how to re-hydrate your application stack with a new AMI utilizing AWS CloudFormation and Amazon EC2 launch templates. You use Amazon Inspector to scan the EC2 instances launched from the Image Builder-generated AMI against the CIS Level 1 Benchmark. 3 | 4 | ## Motivation 5 | A common scenario AWS customers face is how to build processes that configure secure AWS resources that can be leveraged throughout the organization. You need to move fast in the cloud without compromising security best practices. Amazon Elastic Compute Cloud (Amazon EC2) allows you to deploy virtual machines in the AWS Cloud. EC2 AMIs provide the configuration utilized to launch an EC2 instance. You can use AMIs for several use cases, such as configuring applications, applying security policies, and configuring development environments. Developers and system administrators can deploy configuration AMIs to bring up EC2 resources that require little-to-no setup. Often times, multiple patterns are adopted for building and deploying AMIs. Because of this, you need the ability to create a centralized, automated pattern that can output secure, customizable AMIs. 6 | 7 | After going through this exercise, you should understand how to build, manage, and deploy AMIs to an application stack. The infrastructure deployed with this pipeline includes a basic web application, but you can use this pattern to fit many needs. After running through this post, you should feel comfortable using this pattern to configure an AMI pipeline for your organization. 8 | 9 | ## Tech/framework used 10 | Image Builder allows you to develop an automated workflow for creating AMIs to fit your organization’s needs. You can streamline the creation and distribution of secure images, automate your patching process, and define security and application configuration into custom AWS AMIs. In this post, you use the following AWS services to implement this solution: 11 | 12 | AWS CloudFormation – AWS CloudFormation allows you to use domain-specific languages or simple text files to model and provision, in an automated and secure manner, all the resources needed for your applications across all Regions and accounts. You can deploy AWS resources in a safe, repeatable manner, and automate the provisioning of infrastructure. 13 | 14 | AWS KMS – Amazon Key Management Service (AWS KMS) is a fully managed service for creating and managing cryptographic keys. These keys are natively integrated with most AWS services. You use a KMS key in this post to encrypt resources. 15 | 16 | Amazon S3 – Amazon Simple Storage Service (Amazon S3) is an object storage service utilized for storing and encrypting data. We use Amazon S3 to store our configuration files. 17 | 18 | AWS Auto Scaling – AWS Auto Scaling allows you to build scaling plans that automate how groups of different resources respond to changes in demand. You can optimize availability, costs, or a balance of both. We use Auto Scaling to manage Nginx on Amazon EC2. 19 | 20 | Launch templates – Launch templates contain configurations such as AMI ID, instance type, and security group. Launch templates enable you to store launch parameters so that they don’t have to be specified every time instances are launched. 21 | 22 | Amazon Inspector – This automated security assessment service improves the security and compliance of applications deployed on AWS. Amazon Inspector automatically assesses applications for exposures, vulnerabilities, and deviations from best practices. 23 | 24 | ## Features 25 | You deploy the following CloudFormation templates. These CloudFormation templates have a great deal of configurations. They deploy the following resources: 26 | 27 | vpc.yml – Contains all the core networking configuration. It deploys the VPC, two private subnets, two public subnets, and the route tables. The private subnets utilize a NAT gateway to communicate to the internet. The public subnets have full outbound access to the IGW. 28 | 29 | kms.yml – Contains the AWS KMS configuration that we use for encrypting resources. The KMS key policy is also configured in this template. 30 | 31 | s3-iam-config.yml – Contains the launch configuration and autoscaling groups for the initial Nginx launch. For updates and patching to Nginx, we use Image Builder to build those changes. 32 | 33 | infrastructure-ssm-params.yml – Contains the Systems Manager parameter store configuration. The parameters are populated by using outputs from other CloudFormation templates. 34 | 35 | nginx-config.yml – Contains the configuration for Nginx. Additionally, this template contains the network load balancer, target groups, security groups, and EC2 instance AWS Identity and Access Management (IAM) roles. 36 | 37 | nginx-image-builder.yml – Contains the configuration for the Image Builder pipeline that we use to build AMIs. 38 | 39 | ## How to use? 40 | To deploy this project follow the step by step instructions found here. 41 | 42 | ## Security 43 | 44 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 45 | 46 | ## License 47 | 48 | This library is licensed under the MIT-0 License. See the LICENSE file. 49 | -------------------------------------------------------------------------------- /Templates/infrastructure-ssm-params.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | Description: >- 3 | This template creates Systems Manager Parametor Store values which are 4 | utilized for automating the install of AWS Services. 5 | 6 | Parameters: 7 | 8 | S3IAMConfigStackName: 9 | Description: Stack name which contains all of the Nginx configuration 10 | Type: String 11 | Default: s3-iam-config 12 | 13 | NetworkStackName: 14 | Description: Stack name which contains all of the VPC configuration 15 | Type: String 16 | Default: vpc-config 17 | 18 | NginxConfigStackName: 19 | Description: Stack name which contains all of the VPC configuration 20 | Type: String 21 | Default: nginx-config 22 | 23 | InstanceType: 24 | Type: String 25 | Default: t3.large 26 | Description: Instance type to use to launch the Nginx instances. 27 | AllowedValues: 28 | - t3.nano 29 | - t3.micro 30 | - t3.small 31 | - t3.medium 32 | - t3.large 33 | - m4.large 34 | - m4.xlarge 35 | - m4.2xlarge 36 | - m5.large 37 | - m5.xlarge 38 | - m5.2xlarge 39 | - c4.large 40 | - c4.xlarge 41 | - c4.large 42 | - c5.large 43 | - c5.xlarge 44 | - c5.large 45 | 46 | Resources: 47 | 48 | ALBSSMParameter: 49 | Type: AWS::SSM::Parameter 50 | Properties: 51 | Name: /infrastructure/nginx/alb/dnsname 52 | Type: String 53 | Value: 54 | Fn::ImportValue: !Sub "${NginxConfigStackName}-ALB-DNS-Name" 55 | Description: SSM Parameter for the DNS name of the Nginx Network Load Balancer. 56 | 57 | VPCIDParameter: 58 | Type: AWS::SSM::Parameter 59 | Properties: 60 | Name: /infrastructure/nginx/vpc/vpcid 61 | Type: String 62 | Value: 63 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" 64 | Description: SSM Parameter for the VPC ID. 65 | 66 | InstanceProfileParameter: 67 | Type: AWS::SSM::Parameter 68 | Properties: 69 | Name: /infrastructure/nginx/ec2/instanceprofilename 70 | Type: String 71 | Value: 72 | Fn::ImportValue: !Sub "${NginxConfigStackName}-Instance-Profile-Name" 73 | Description: SSM Parameter for the Nginx Instance Profile. 74 | 75 | NginxSGParameter: 76 | Type: AWS::SSM::Parameter 77 | Properties: 78 | Name: /infrastructure/nginx/ec2/securitygroup 79 | Type: String 80 | Value: 81 | Fn::ImportValue: !Sub "${NginxConfigStackName}-Nginx-Instance-SG" 82 | Description: SSM Parameter for the VPC ID. 83 | 84 | NginxInstanceASG1Parameter: 85 | Type: AWS::SSM::Parameter 86 | Properties: 87 | Name: /phns/infrastructure/nginx/ec2/autoscalinggroupname 88 | Type: String 89 | Value: 90 | Fn::ImportValue: !Sub "${NginxConfigStackName}-Nginx-Instance-ASG1" 91 | Description: SSM Parameter for the EC2 ASG. 92 | 93 | EC2InstanceTypeParameter: 94 | Type: AWS::SSM::Parameter 95 | Properties: 96 | Name: /phns/infrastructure/nginx/ec2/instancetype 97 | Type: String 98 | Value: !Ref InstanceType 99 | Description: SSM Parameter for the EC2 Instance Type. 100 | 101 | Outputs: 102 | 103 | ALBSSMParameter: 104 | Description: Nginx ALB SSM Parameter Name 105 | Value: !Ref ALBSSMParameter 106 | Export: 107 | Name: !Sub '${AWS::StackName}-ALBSSMParameter' 108 | 109 | EC2InstanceTypeParameter: 110 | Description: Nginx EC2 Instance Type Parameter Name 111 | Value: !Ref EC2InstanceTypeParameter 112 | Export: 113 | Name: !Sub '${AWS::StackName}-EC2InstanceTypeParameter' 114 | 115 | NginxInstanceASG1Parameter: 116 | Description: Nginx EC2 ASG Parameter Name 117 | Value: !Ref NginxInstanceASG1Parameter 118 | Export: 119 | Name: !Sub '${AWS::StackName}-NginxInstanceASG1Parameter' 120 | 121 | NginxSGParameter: 122 | Description: Nginx EC2 SG Parameter Name 123 | Value: !Ref NginxSGParameter 124 | Export: 125 | Name: !Sub '${AWS::StackName}-NginxSGParameter' 126 | 127 | InstanceProfileParameter: 128 | Description: Nginx EC2 Instance Profile Parameter Name 129 | Value: !Ref InstanceProfileParameter 130 | Export: 131 | Name: !Sub '${AWS::StackName}-InstanceProfileParameter' 132 | 133 | VPCIDParameter: 134 | Description: Nginx VPC ID SSM Parameter Name 135 | Value: !Ref VPCIDParameter 136 | Export: 137 | Name: !Sub '${AWS::StackName}-VPCIDParameter' 138 | -------------------------------------------------------------------------------- /Templates/kms.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: > 3 | This Template deloys a KMS customer managed CMK for AWS services. We also 4 | configure the KMS Key Policy and grant permissions use the key to our 5 | deployment roles. 6 | 7 | Parameters: 8 | Service: 9 | Description: 'Which AWS service is allowed to use this CMK?' 10 | Type: String 11 | Default: ALL_SERVICES 12 | 13 | KeyName: 14 | Description: 'Name of the KMS Key' 15 | Type: String 16 | 17 | UserARN: 18 | Description: ARN of User Role for this particular Key access. Provide comma delimited values for multiple roles. 19 | Type: CommaDelimitedList 20 | 21 | Resources: 22 | KMSKey: 23 | Type: 'AWS::KMS::Key' 24 | Metadata: 25 | cfn_nag: 26 | rules_to_suppress: 27 | - id: F19 28 | reason: "Supressing requirement for logging warning for testing purposes" 29 | Properties: 30 | KeyPolicy: 31 | Version: '2012-10-17' 32 | Statement: 33 | - Sid: Allow cloudtrail use of the key 34 | Effect: Allow 35 | Principal: 36 | Service: 37 | "cloudtrail.amazonaws.com" 38 | Action: 39 | - "kms:Encrypt" 40 | - "kms:Decrypt" 41 | - "kms:GenerateDataKey*" 42 | - "kms:DescribeKey" 43 | Resource: '*' 44 | - Sid: Allow NLB use of the key 45 | Effect: Allow 46 | Principal: 47 | Service: 48 | "delivery.logs.amazonaws.com" 49 | Action: 50 | - "kms:EnableKeyRotation" 51 | - "kms:EnableKey" 52 | - "kms:Decrypt" 53 | - "kms:ListKeyPolicies" 54 | - "kms:PutKeyPolicy" 55 | - "kms:GetKeyPolicy" 56 | - "kms:DisableKey" 57 | - "kms:GenerateDataKeyPair" 58 | - "kms:DisableKeyRotation" 59 | - "kms:RetireGrant" 60 | - "kms:UpdateAlias" 61 | - "kms:ListKeys" 62 | - "kms:Encrypt" 63 | - "kms:GetKeyRotationStatus" 64 | - "kms:ScheduleKeyDeletion" 65 | - "kms:ListAliases" 66 | - "kms:RevokeGrant" 67 | - "kms:GenerateDataKey" 68 | - "kms:CreateAlias" 69 | - "kms:DescribeKey" 70 | - "kms:CreateKey" 71 | - "kms:DeleteAlias" 72 | - "kms:CreateGrant" 73 | Resource: '*' 74 | - Sid: Allow Management Roles use of the key 75 | Effect: Allow 76 | Principal: 77 | AWS: !Ref UserARN 78 | Action: 79 | - "kms:*" 80 | Resource: '*' 81 | 82 | 83 | KMSKeyAlias: 84 | Type: AWS::KMS::Alias 85 | Properties: 86 | AliasName: !Sub 'alias/${KeyName}' 87 | TargetKeyId: 88 | Ref: KMSKey 89 | 90 | Outputs: 91 | KMSKeyARN: 92 | Description: KMS Key ARN 93 | Value: !GetAtt KMSKey.Arn 94 | Export: 95 | Name: 96 | Fn::Sub: "${AWS::StackName}-KMS-ARN" 97 | 98 | KeyId: 99 | Description: 'Key id.' 100 | Value: !Ref KMSKey 101 | Export: 102 | Name: !Sub '${AWS::StackName}-KeyId' 103 | -------------------------------------------------------------------------------- /Templates/nginx-config.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 9 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 10 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 11 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 12 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 13 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | 15 | AWSTemplateFormatVersion: 2010-09-09 16 | Description: >- 17 | This template creates a Multi-AZ (two Availability Zones), multi-subnet VPC infrastructure and 18 | associates one Non RFC 1918 CIDR Block to the newly created VPC. 19 | **WARNING** This template creates AWS resources You will be billed for the AWS resources used if you 20 | create a stack from this template. 21 | 22 | Parameters: 23 | 24 | Environment: 25 | AllowedValues: 26 | - 'dev' 27 | - 'devops' 28 | - 'uat' 29 | Description: >- 30 | Set environment in which the VPC will be created. 31 | Type: String 32 | 33 | ApplicationName: 34 | Description: >- 35 | Application name. 36 | Type: String 37 | Default: demo-ALB 38 | 39 | AmiId: 40 | Type: String 41 | Description: >- 42 | Hardened AMI generated by Image Builder. 43 | 44 | InstanceType: 45 | Type: String 46 | Default: t3.large 47 | Description: Instance type to use to launch the Nginx instances. 48 | AllowedValues: 49 | - t3.nano 50 | - t3.micro 51 | - t3.small 52 | - t3.medium 53 | - t3.large 54 | - m4.large 55 | - m4.xlarge 56 | - m4.2xlarge 57 | - m5.large 58 | - m5.xlarge 59 | - m5.2xlarge 60 | - c4.large 61 | - c4.xlarge 62 | - c4.large 63 | - c5.large 64 | - c5.xlarge 65 | - c5.large 66 | 67 | ALBName: 68 | Type: String 69 | 70 | ALBScheme: 71 | Type: String 72 | Default: internet-facing 73 | 74 | ALBType: 75 | Type: String 76 | Default: application 77 | 78 | ALBIpAddressType: 79 | Type: String 80 | Default: ipv4 81 | 82 | TargetGroupName: 83 | Type: String 84 | 85 | TGHealthCheckIntervalSeconds: 86 | Type: Number 87 | Default: 30 88 | 89 | TGHealthCheckProtocol: 90 | Type: String 91 | Default: HTTP 92 | 93 | TGHealthyThresholdCount: 94 | Type: Number 95 | Default: 2 96 | 97 | TGPort: 98 | Type: Number 99 | Default: 8080 100 | 101 | TGProtocol: 102 | Type: String 103 | Default: HTTP 104 | 105 | TGType: 106 | Type: String 107 | Default: instance 108 | 109 | TGUnhealthyThresholdCount: 110 | Type: Number 111 | Default: 2 112 | 113 | ListenerPort: 114 | Type: Number 115 | Default: 8080 116 | 117 | ListenerProtocol: 118 | Type: String 119 | Default: HTTP 120 | 121 | ListenerDefaultActionsType: 122 | Type: String 123 | Default: forward 124 | 125 | NetworkStackName: 126 | Description: Stack name which has all of the VPC configuration 127 | Type: String 128 | 129 | S3IAMConfigStackName: 130 | Description: Stack name which has all of the Nginx S3 configuration 131 | Type: String 132 | 133 | InstanceProfileName: 134 | Type: String 135 | Description: Name of the Instance Profile Nginx Proxies will use 136 | Default: NginxInstanceProfile 137 | 138 | 139 | Resources: 140 | 141 | NginxInstanceProfile: 142 | Type: AWS::IAM::InstanceProfile 143 | Properties: 144 | InstanceProfileName: !Ref InstanceProfileName 145 | Roles: 146 | - Fn::ImportValue: !Sub "${S3IAMConfigStackName}-Nginx-Instance-Role-Name" 147 | Path: / 148 | 149 | ALBSG: 150 | Type: AWS::EC2::SecurityGroup 151 | Properties: 152 | GroupDescription: Allows HTTP traffic to the Application Load Balancer 153 | SecurityGroupIngress: 154 | - CidrIp: 155 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" 156 | FromPort: 8080 157 | ToPort: 8080 158 | IpProtocol: tcp 159 | SecurityGroupEgress: 160 | - CidrIp: 161 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" 162 | FromPort: 8080 163 | ToPort: 8080 164 | IpProtocol: tcp 165 | Tags: 166 | - Key: Name 167 | Value: !Sub 'ALB SG - ${AWS::StackName}' 168 | VpcId: 169 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" 170 | 171 | NginxInstanceSG: 172 | Type: AWS::EC2::SecurityGroup 173 | Properties: 174 | GroupDescription: Allows HTTP and HTTPS from vpc 175 | SecurityGroupIngress: 176 | - CidrIp: 177 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" 178 | FromPort: 8080 179 | ToPort: 8080 180 | IpProtocol: tcp 181 | - SourceSecurityGroupId: !Ref ALBSG 182 | FromPort: 8080 183 | ToPort: 8080 184 | IpProtocol: tcp 185 | Tags: 186 | - Key: Name 187 | Value: !Sub 'Nginx Instance SG - ${AWS::StackName}' 188 | VpcId: 189 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" 190 | 191 | LaunchTemplate: 192 | Type: AWS::EC2::LaunchTemplate 193 | Properties: 194 | LaunchTemplateData: 195 | InstanceType: !Ref InstanceType 196 | ImageId: !Ref AmiId 197 | IamInstanceProfile: 198 | Arn: 199 | Fn::GetAtt: 200 | - NginxInstanceProfile 201 | - Arn 202 | SecurityGroupIds: 203 | - !Ref NginxInstanceSG 204 | LaunchTemplateName: LaunchTemplate 205 | 206 | ALB: 207 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer 208 | Properties: 209 | IpAddressType: !Ref ALBIpAddressType 210 | Name: !Ref ALBName 211 | Scheme: !Ref ALBScheme 212 | SecurityGroups: 213 | - !Ref ALBSG 214 | Subnets: 215 | - Fn::ImportValue: !Sub "${NetworkStackName}-PublicSubnet1AID" 216 | - Fn::ImportValue: !Sub "${NetworkStackName}-PublicSubnet2AID" 217 | Tags: 218 | - Key: Application 219 | Value: !Ref ApplicationName 220 | - Key: Environment 221 | Value: !Ref Environment 222 | Type: !Ref ALBType 223 | 224 | TargetGroup: 225 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 226 | Properties: 227 | Name: !Ref TargetGroupName 228 | HealthCheckEnabled: true 229 | HealthCheckIntervalSeconds: !Ref TGHealthCheckIntervalSeconds 230 | HealthCheckProtocol: !Ref TGHealthCheckProtocol 231 | HealthyThresholdCount: !Ref TGHealthyThresholdCount 232 | HealthCheckPort: 8080 233 | Port: !Ref TGPort 234 | Protocol: !Ref TGProtocol 235 | TargetType: !Ref TGType 236 | UnhealthyThresholdCount: !Ref TGUnhealthyThresholdCount 237 | VpcId: 238 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" 239 | 240 | NginxListener: 241 | Type: AWS::ElasticLoadBalancingV2::Listener 242 | Properties: 243 | DefaultActions: 244 | - Type: !Ref ListenerDefaultActionsType 245 | TargetGroupArn: !Ref TargetGroup 246 | LoadBalancerArn: !Ref ALB 247 | Port: !Ref ListenerPort 248 | Protocol: !Ref ListenerProtocol 249 | 250 | NginxInstanceASG1: 251 | Type: AWS::AutoScaling::AutoScalingGroup 252 | Properties: 253 | DesiredCapacity: 2 254 | HealthCheckGracePeriod: 300 255 | HealthCheckType: EC2 256 | LaunchTemplate: 257 | LaunchTemplateId: !Ref LaunchTemplate 258 | Version: !GetAtt LaunchTemplate.LatestVersionNumber 259 | MaxSize: 5 260 | MinSize: 1 261 | TargetGroupARNs: 262 | - Ref: TargetGroup 263 | VPCZoneIdentifier: 264 | - Fn::ImportValue: !Sub "${NetworkStackName}-PrivateSubnet2Z1ID" 265 | - Fn::ImportValue: !Sub "${NetworkStackName}-PrivateSubnet2Z2ID" 266 | Tags: 267 | - Key: Name 268 | Value: !Sub 'NginxInstance-${AWS::StackName}' 269 | PropagateAtLaunch: "true" 270 | 271 | TestingInstanceRole: 272 | Type: AWS::IAM::Role 273 | Properties: 274 | AssumeRolePolicyDocument: 275 | Version: '2012-10-17' 276 | Statement: 277 | - Effect: Allow 278 | Principal: 279 | Service: 280 | - ec2.amazonaws.com 281 | Action: 282 | - sts:AssumeRole 283 | Path: / 284 | ManagedPolicyArns: 285 | - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM 286 | Policies: 287 | - PolicyName: root 288 | PolicyDocument: 289 | Version: '2012-10-17' 290 | Statement: 291 | - Effect: Allow 292 | Action: 293 | - ec2:DescribeRegions 294 | Resource: '*' 295 | 296 | TestingInstanceProfile: 297 | Type: AWS::IAM::InstanceProfile 298 | Properties: 299 | Roles: 300 | - !Ref TestingInstanceRole 301 | Path: / 302 | 303 | TestingInstance: 304 | Type: AWS::EC2::Instance 305 | DependsOn: 306 | - NginxInstanceASG1 307 | Properties: 308 | IamInstanceProfile: !Ref TestingInstanceProfile 309 | ImageId: !Ref AmiId 310 | InstanceType: t3.nano 311 | SecurityGroupIds: 312 | - !Ref LinuxPrivateSG 313 | SubnetId: 314 | Fn::ImportValue: !Sub "${NetworkStackName}-PrivateSubnet2Z1ID" 315 | Tags: 316 | - Key: Name 317 | Value: !Sub 'TestingInstance-${AWS::StackName}' 318 | 319 | LinuxPrivateSG: 320 | Type: 'AWS::EC2::SecurityGroup' 321 | Properties: 322 | GroupDescription: Linux EC2 Security Group 323 | SecurityGroupIngress: 324 | - IpProtocol: tcp 325 | CidrIp: 326 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" 327 | FromPort: 8080 328 | ToPort: 8080 329 | SecurityGroupEgress: 330 | - IpProtocol: tcp 331 | FromPort: 0 332 | ToPort: 65535 333 | CidrIp: 0.0.0.0/0 334 | VpcId: 335 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" 336 | 337 | Outputs: 338 | ALB: 339 | Description: Nginx Network Load Balancer ARN 340 | Value: !Ref ALB 341 | Export: 342 | Name: !Sub '${AWS::StackName}-ALB' 343 | ALBDNSName: 344 | Description: Nginx Network Load Balancer DNS Name 345 | Value: !GetAtt ALB.DNSName 346 | Export: 347 | Name: !Sub "${AWS::StackName}-ALB-DNS-Name" 348 | InstanceProfileName: 349 | Description: Nginx Instance Profile Name 350 | Value: !Ref InstanceProfileName 351 | Export: 352 | Name: !Sub "${AWS::StackName}-Instance-Profile-Name" 353 | NginxInstanceSG: 354 | Description: Nginx Instance Security Group 355 | Value: !Ref NginxInstanceSG 356 | Export: 357 | Name: !Sub "${AWS::StackName}-Nginx-Instance-SG" 358 | NginxInstanceASG1: 359 | Description: Nginx Autoscaling Group Name 360 | Value: !Ref NginxInstanceASG1 361 | Export: 362 | Name: !Sub "${AWS::StackName}-Nginx-Instance-ASG1" 363 | -------------------------------------------------------------------------------- /Templates/nginx-image-builder.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: "2010-09-09" 2 | 3 | Description: 4 | This template will deploy a sample EC2 ImageBuilder pipeline that will generate an AmazonLinux2 AMI. 5 | 6 | Parameters: 7 | Environment: 8 | Type: String 9 | Description: >- 10 | The values allowed for sandbox and dev. 11 | AllowedValues: 12 | - 'dev' 13 | - 'devops' 14 | - 'uat' 15 | 16 | ImageBuilderBucketName: 17 | Type: String 18 | Description: >- 19 | Enter the Name of the bucket where ImageBuilder Config lives. 20 | 21 | NetworkStackName: 22 | Description: Stack name which has all of the VPC configuration 23 | Type: String 24 | 25 | KMSStackName: 26 | Description: Stack name which has all of the KMS configuration 27 | Type: String 28 | 29 | S3ConfigStackName: 30 | Description: Stack name which has all of the Nginx S3 configuration 31 | Type: String 32 | 33 | S3PublicIpRange: 34 | Description: >- 35 | Run the following command for the list of ip address 36 | curl https://ip-ranges.amazonaws.com/ip-ranges.json | jq -r '.prefixes[] | select(.region=="us-east-1") | select(.service=="S3") | .ip_prefix' 37 | Type: String 38 | Default: "0.0.0.0/0" 39 | 40 | Resources: 41 | 42 | InstanceProfile: 43 | Type: AWS::IAM::InstanceProfile 44 | Properties: 45 | InstanceProfileName: !Sub '${AWS::StackName}-EC2ImageBuilder-Profile' 46 | Path: / 47 | Roles: 48 | - Fn::ImportValue: !Sub "${S3ConfigStackName}-Image-Builder-Role-Name" 49 | 50 | ImageBuilderSG: 51 | Type: 'AWS::EC2::SecurityGroup' 52 | Properties: 53 | GroupDescription: Linux EC2 Security Group 54 | SecurityGroupIngress: 55 | - IpProtocol: tcp 56 | CidrIp: 57 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCCIDR" 58 | FromPort: 8080 59 | ToPort: 8080 60 | - IpProtocol: tcp 61 | CidrIp: !Ref S3PublicIpRange 62 | FromPort: 443 63 | ToPort: 443 64 | SecurityGroupEgress: 65 | - IpProtocol: tcp 66 | FromPort: 0 67 | ToPort: 65535 68 | CidrIp: 0.0.0.0/0 69 | VpcId: 70 | Fn::ImportValue: !Sub "${NetworkStackName}-VPCID" 71 | 72 | ImageBuilderSNSTopic: 73 | Type: AWS::SNS::Topic 74 | Properties: 75 | KmsMasterKeyId: 76 | Fn::ImportValue: !Sub "${KMSStackName}-KeyId" 77 | TopicName: "NginxImageBuilderTopic" 78 | 79 | ResourceGroup: 80 | Type: "AWS::Inspector::ResourceGroup" 81 | Properties: 82 | ResourceGroupTags: 83 | - Key: "ResourceGroup" 84 | Value: "Nginx" 85 | 86 | AssessmentTarget: 87 | Type: AWS::Inspector::AssessmentTarget 88 | Properties: 89 | AssessmentTargetName : "NginxAssessmentTarget" 90 | ResourceGroupArn : !Ref ResourceGroup 91 | 92 | Component: 93 | Type: AWS::ImageBuilder::Component 94 | Properties: 95 | Name: !Sub '${AWS::StackName}-LinuxCis-Component' 96 | Platform: Linux 97 | Version: 1.0.0 98 | Description: 'This component will create an AMI with CIS level 1 Nginx playbook.' 99 | ChangeDescription: 'Initial Version' 100 | KmsKeyId: 101 | Fn::ImportValue: !Sub "${KMSStackName}-KMS-ARN" 102 | Tags: 103 | build: helloworld 104 | Uri: !Sub 's3://${ImageBuilderBucketName}/components/component-nginx.yml' 105 | 106 | Recipe: 107 | Type: AWS::ImageBuilder::ImageRecipe 108 | Properties: 109 | Name: !Sub '${AWS::StackName}-LinuxCis-Recipe' 110 | Description: 'This recipe will create an AMI based on AmazonLinux2 AMI and set the root drive to 50GB' 111 | Version: 1.0.0 112 | WorkingDirectory: "/workdir" 113 | ParentImage: !Sub 'arn:aws:imagebuilder:${AWS::Region}:aws:image/amazon-linux-2-x86/x.x.x' 114 | Components: 115 | - ComponentArn: !Ref Component 116 | BlockDeviceMappings: 117 | - DeviceName: /dev/xvda 118 | Ebs: 119 | DeleteOnTermination: true 120 | VolumeSize: 50 121 | VolumeType: gp2 122 | Encrypted: true # use aws/ebs key so we can share across regions 123 | # Iops: 300 124 | 125 | Infrastructure: 126 | Type: AWS::ImageBuilder::InfrastructureConfiguration 127 | Properties: 128 | Name: !Sub '${AWS::StackName}-LinuxCis-Infrastructure' 129 | Description: 'This infrastructure configuration will launch into our custom ImageBuilder VPC' 130 | InstanceProfileName: !Ref InstanceProfile 131 | SecurityGroupIds: 132 | - !Ref ImageBuilderSG 133 | SubnetId: 134 | Fn::ImportValue: !Sub "${NetworkStackName}-PublicSubnet1AID" 135 | TerminateInstanceOnFailure: false 136 | SnsTopicArn: !Ref ImageBuilderSNSTopic 137 | InstanceTypes: 138 | - t3.medium 139 | - t3.large 140 | Logging: 141 | S3Logs: 142 | S3BucketName: !Ref ImageBuilderBucketName 143 | S3KeyPrefix: 'nginx-imagebuilder' 144 | 145 | Distribution: 146 | Type: AWS::ImageBuilder::DistributionConfiguration 147 | Properties: 148 | Name: !Sub '${AWS::StackName}-LinuxNginx-Distribution' 149 | Description: 'This distribution configuration will deploy our AMI to the current region' 150 | Distributions: 151 | - Region: !Ref 'AWS::Region' 152 | AmiDistributionConfiguration: 153 | Name: !Sub '${AWS::StackName}-LinuxNginx-{{ imagebuilder:buildDate }}' # the {{imagebuilder:buildDate}} variable is required in the output AMI name 154 | AmiTags: 155 | Name: !Sub '${AWS::StackName}-LinuxNginx-Ami' 156 | 157 | Pipeline: 158 | Type: AWS::ImageBuilder::ImagePipeline 159 | Properties: 160 | Name: !Sub '${AWS::StackName}-LinuxNginx-Pipeline' 161 | Description: 'Deploys a sample AmazonLinux2 Ami to current region' 162 | Status: ENABLED 163 | ImageRecipeArn: !Ref Recipe 164 | InfrastructureConfigurationArn: !Ref Infrastructure 165 | DistributionConfigurationArn: !Ref Distribution 166 | ImageTestsConfiguration: 167 | ImageTestsEnabled: false 168 | TimeoutMinutes: 60 169 | Schedule: 170 | ScheduleExpression: cron(0 5 1 * ? *) 171 | PipelineExecutionStartCondition: 'EXPRESSION_MATCH_ONLY' 172 | 173 | # Uncomment this block if you want an initial AMI to be created during Stack Creation 174 | # Warning: This can take between 30-90 minutes for the stack to finish completion 175 | # EC2 ImageBuilder Image 176 | IBImage: 177 | Type: AWS::ImageBuilder::Image 178 | Properties: 179 | ImageRecipeArn: !Ref Recipe 180 | InfrastructureConfigurationArn: !Ref Infrastructure 181 | DistributionConfigurationArn: !Ref Distribution 182 | ImageTestsConfiguration: 183 | ImageTestsEnabled: false 184 | TimeoutMinutes: 60 185 | Tags: 186 | ResourceGroup: 'Nginx' 187 | -------------------------------------------------------------------------------- /Templates/s3-iam-config.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 9 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 10 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 11 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 12 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 13 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | 15 | AWSTemplateFormatVersion: 2010-09-09 16 | Description: >- 17 | This template creates a the encrypted S3 Bucket which stores Nginx Config 18 | files. This template also creates the roles utilized for setting up the 19 | Nginx Proxies. 20 | 21 | Parameters: 22 | 23 | Environment: 24 | AllowedValues: 25 | - 'dev' 26 | - 'devops' 27 | - 'uat' 28 | Description: >- 29 | Set environment in which the VPC will be created. 30 | Type: String 31 | 32 | DemoConfigS3BucketName: 33 | Type: String 34 | 35 | EC2InstanceRoleName: 36 | Type: String 37 | Default: EC2InstanceRole 38 | 39 | EC2ImageBuilderRoleName: 40 | Type: String 41 | Default: EC2ImageBuilderRole 42 | 43 | S3PutLambdaRoleName: 44 | Type: String 45 | Default: NginxS3PutLambdaRole 46 | 47 | NetworkStackName: 48 | Description: Stack name which has all of the VPC configuration 49 | Type: String 50 | 51 | KMSStackName: 52 | Description: Stack name which has all of the KMS configuration 53 | Type: String 54 | 55 | Resources: 56 | 57 | # S3 Bucket where Nginx Config and Image Builder Config will live 58 | S3Bucket: 59 | Type: AWS::S3::Bucket 60 | Properties: 61 | BucketName: !Ref DemoConfigS3BucketName 62 | VersioningConfiguration: 63 | Status: Enabled 64 | BucketEncryption: 65 | ServerSideEncryptionConfiguration: 66 | - ServerSideEncryptionByDefault: 67 | SSEAlgorithm: aws:kms 68 | KMSMasterKeyID: 69 | Fn::ImportValue: !Sub "${KMSStackName}-KeyId" 70 | PublicAccessBlockConfiguration: 71 | BlockPublicAcls: true 72 | IgnorePublicAcls: true 73 | BlockPublicPolicy: true 74 | RestrictPublicBuckets: true 75 | 76 | S3BucketPolicy: 77 | Type: AWS::S3::BucketPolicy 78 | Properties: 79 | Bucket: !Ref S3Bucket 80 | PolicyDocument: 81 | Version: 2012-10-17 82 | Statement: 83 | - Action: 84 | - 's3:GetObject' 85 | Effect: Deny 86 | Resource: 87 | - !GetAtt 'S3Bucket.Arn' 88 | - !Sub '${S3Bucket.Arn}/*' 89 | Principal: '*' 90 | Condition: 91 | Bool: 92 | 'aws:SecureTransport': 93 | - 'false' 94 | 95 | S3PutLambdaRole: 96 | Type: AWS::IAM::Role 97 | Properties: 98 | RoleName: !Ref S3PutLambdaRoleName 99 | AssumeRolePolicyDocument: 100 | Version: '2012-10-17' 101 | Statement: 102 | - Effect: Allow 103 | Principal: 104 | Service: 105 | - lambda.amazonaws.com 106 | Action: 107 | - sts:AssumeRole 108 | Path: / 109 | ManagedPolicyArns: 110 | - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 111 | Policies: 112 | - PolicyName: root 113 | PolicyDocument: 114 | Version: '2012-10-17' 115 | Statement: 116 | - Effect: Allow 117 | Action: 118 | - s3:PutObject 119 | - s3:DeleteObject 120 | Resource: !Sub '${S3Bucket.Arn}*' 121 | 122 | EC2InstanceRole: 123 | Type: AWS::IAM::Role 124 | Properties: 125 | RoleName: !Ref EC2InstanceRoleName 126 | AssumeRolePolicyDocument: 127 | Version: '2012-10-17' 128 | Statement: 129 | - Effect: Allow 130 | Principal: 131 | Service: 132 | - lambda.amazonaws.com 133 | - ssm.amazonaws.com 134 | - ec2.amazonaws.com 135 | - s3.amazonaws.com 136 | Action: 137 | - sts:AssumeRole 138 | Path: / 139 | ManagedPolicyArns: 140 | - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM 141 | - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy 142 | Policies: 143 | - PolicyName: root 144 | PolicyDocument: 145 | Version: '2012-10-17' 146 | Statement: 147 | - Effect: Allow 148 | Action: 149 | - s3:Get* 150 | - s3:List* 151 | - s3:Put* 152 | Resource: !Sub '${S3Bucket.Arn}*' 153 | - Effect: Allow 154 | Action: 155 | - ec2:ModifyInstanceAttribute 156 | Resource: '*' 157 | - Effect: Allow 158 | Action: 159 | - kms:Decrypt 160 | Resource: '*' 161 | 162 | ImageBuilderIamRole: 163 | Type: AWS::IAM::Role 164 | Properties: 165 | # RoleName: !Sub '${AWS::StackName}-EC2ImageBuilderRole' 166 | RoleName: !Ref EC2ImageBuilderRoleName 167 | Description: 'This role will grant EC2 ImageBuilder minimum neccessary permissions to allow pipelines to execute' 168 | MaxSessionDuration: 3600 # in seconds 169 | Path: / 170 | AssumeRolePolicyDocument: 171 | Version: 2012-10-17 172 | Statement: 173 | - Effect: Allow 174 | Principal: 175 | Service: 176 | - ec2.amazonaws.com 177 | - ssm.amazonaws.com 178 | - imagebuilder.amazonaws.com 179 | AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root' 180 | Action: 181 | - sts:AssumeRole 182 | ManagedPolicyArns: 183 | - 'arn:aws:iam::aws:policy/EC2InstanceProfileForImageBuilder' 184 | - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore' 185 | Policies: 186 | - PolicyName: GrantS3Read 187 | PolicyDocument: 188 | Statement: 189 | - Sid: GrantS3Read 190 | Effect: Allow 191 | Action: 192 | - s3:List* 193 | - s3:Get* 194 | - s3:Put* 195 | Resource: !Sub 'arn:aws:s3:::${S3Bucket}*' 196 | - PolicyName: DecryptKms 197 | PolicyDocument: 198 | Statement: 199 | - Sid: DecryptKms 200 | Effect: Allow 201 | Action: 202 | - kms:Decrypt 203 | - kms:Encrypt 204 | - kms:GenerateDataKey* 205 | - ec2:DescribeImages 206 | - ssm:PutParameter 207 | Resource: '*' 208 | - PolicyName: GrantSsm 209 | PolicyDocument: 210 | Statement: 211 | - Sid: GrantSsm 212 | Effect: Allow 213 | Action: 214 | - ssm:SendCommand 215 | Resource: 216 | - 'arn:aws:ssm:us-east-1::document/AmazonInspector-ManageAWSAgent' 217 | - !Sub 'arn:aws:ec2:us-east-1:${AWS::AccountId}:*/*' 218 | - PolicyName: Ec2Tags 219 | PolicyDocument: 220 | Statement: 221 | - Sid: TagOnCreate 222 | Effect: Allow 223 | Action: 224 | - ec2:CreateTags 225 | - ec2:RunInstances 226 | Resource: !Sub 'arn:aws:ec2:us-east-1:${AWS::AccountId}:*/*' 227 | - PolicyName: InspectorResource 228 | PolicyDocument: 229 | Statement: 230 | - Sid: InspectorGroup 231 | Effect: Allow 232 | Action: 233 | - inspector:Create* 234 | - inspector:Get* 235 | - inspector:Describe* 236 | - inspector:List* 237 | - inspector:Set* 238 | - inspector:Start* 239 | - inspector:Stop* 240 | - inspector:PreviewAgents 241 | Resource: '*' 242 | - PolicyName: NginxScript 243 | PolicyDocument: 244 | Statement: 245 | - Sid: NginxRunScript 246 | Effect: Allow 247 | Action: 248 | - cloudformation:SignalResource 249 | - ec2:ModifyInstanceAttribute 250 | Resource: !Sub 'arn:aws:ec2:us-east-1:${AWS::AccountId}:*/*' 251 | 252 | Outputs: 253 | 254 | EC2InstanceRoleArn: 255 | Value: !GetAtt EC2InstanceRole.Arn 256 | Export: 257 | Name: !Sub "${AWS::StackName}-Nginx-Instance-Role-ARN" 258 | 259 | EC2InstanceRoleName: 260 | Value: !Ref EC2InstanceRole 261 | Export: 262 | Name: !Sub "${AWS::StackName}-Nginx-Instance-Role-Name" 263 | 264 | S3PutLambdaRoleArn: 265 | Value: !GetAtt S3PutLambdaRole.Arn 266 | Export: 267 | Name: !Sub "${AWS::StackName}-S3-Put-Lambda-Role-ARN" 268 | 269 | S3PutLambdaRoleName: 270 | Value: !Ref S3PutLambdaRole 271 | Export: 272 | Name: !Sub "${AWS::StackName}-S3-Put-Lambda-Role-Name" 273 | 274 | ImageBuilderRoleArn: 275 | Value: !GetAtt ImageBuilderIamRole.Arn 276 | Export: 277 | Name: !Sub "${AWS::StackName}-Image-Builder-Role-ARN" 278 | 279 | ImageBuilderRoleName: 280 | Value: !Ref ImageBuilderIamRole 281 | Export: 282 | Name: !Sub "${AWS::StackName}-Image-Builder-Role-Name" 283 | 284 | S3BucketArn: 285 | Description: S3 Bucket ARN 286 | Value: !GetAtt S3Bucket.Arn 287 | Export: 288 | Name: 289 | Fn::Sub: "${AWS::StackName}-Bucket-ARN" 290 | 291 | S3BucketName: 292 | Description: S3 Bucket Name 293 | Value: !Ref S3Bucket 294 | Export: 295 | Name: 296 | Fn::Sub: "${AWS::StackName}-Bucket-Name" 297 | -------------------------------------------------------------------------------- /Templates/vpc.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this 3 | # software and associated documentation files (the "Software"), to deal in the Software 4 | # without restriction, including without limitation the rights to use, copy, modify, 5 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 6 | # permit persons to whom the Software is furnished to do so. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 9 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 10 | # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 11 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 12 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 13 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | 15 | AWSTemplateFormatVersion: 2010-09-09 16 | Description: >- 17 | This template creates a Multi-AZ (two Availability Zones), multi-subnet VPC infrastructure and 18 | associates one Non RFC 1918 CIDR Block to the newly created VPC. 19 | **WARNING** This template creates AWS resources You will be billed for the AWS resources used if you 20 | create a stack from this template. 21 | Metadata: 22 | 'AWS::CloudFormation::Interface': 23 | ParameterGroups: 24 | - Label: 25 | default: Availability Zone Configuration 26 | # Specify the Availability Zones and how many should be used for the subnets 27 | Parameters: 28 | - AvailabilityZones 29 | - Label: 30 | default: Network Configuration 31 | # Specify VPC, Public, Private and Partner Subnets 32 | Parameters: 33 | - VPCCIDR 34 | - Environment 35 | - AvailabilityZones 36 | - PublicSubnet1ACIDR 37 | - PublicSubnet2ACIDR 38 | - PrivateSubnet2Z1CIDR 39 | - PrivateSubnet2Z2CIDR 40 | # Parameter Labels 41 | ParameterLabels: 42 | AvailabilityZones: 43 | default: Availability Zones 44 | PrivateSubnet2Z1CIDR: 45 | default: Private subnet 1 AZ 1 CIDR 46 | PrivateSubnet2Z2CIDR: 47 | default: Private subnet 2 AZ 2 CIDR 48 | PublicSubnet1ACIDR: 49 | default: Public subnet 1A CIDR 50 | PublicSubnet2ACIDR: 51 | default: Public subnet 2A CIDR 52 | Environment: 53 | default: Environment for the VPC 54 | VPCCIDR: 55 | default: VPC CIDR 56 | AmiId: 57 | default: AMI ID pointer in AWS Systems Manager Parameter Store 58 | InstanceType: 59 | default: Instance type to use to launch the Squid instances 60 | WhitelistDomains: 61 | default: List of whitelisted domains separated by a comma 62 | # This section outlines the allowed, default and types of values for each parameter. 63 | Parameters: 64 | AvailabilityZones: 65 | Description: >- 66 | Please specify two (2) or three (3 -optional) Availability Zones which will be used by the subnets in the VPC. Note: The 67 | logical order is preserved. 68 | Type: 'List' 69 | Default: us-east-1a,us-east-1c 70 | # The allowed list of environments that can be associated with the VPC creation 71 | Environment: 72 | Description: >- 73 | Set environment in which the VPC will be created. 74 | Type: String 75 | 76 | PrivateSubnet2Z1CIDR: 77 | AllowedPattern: >- 78 | ^(\d{1,2})?\.(\d{1,3})?\.(\d{1,3})?\.(\d{1,3})?\/(\d{1,3}|\d{1,3})?$ 79 | ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/xx 80 | Default: 10.0.10.0/25 81 | Description: CIDR block for Private subnet 1 AZ 1 located in Availability Zone 1 82 | Type: String 83 | 84 | PrivateSubnet2Z2CIDR: 85 | AllowedPattern: >- 86 | ^(\d{1,2})?\.(\d{1,3})?\.(\d{1,3})?\.(\d{1,3})?\/(\d{1,3}|\d{1,3})?$ 87 | ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/xx 88 | Default: 10.0.32.0/24 89 | Description: CIDR block for Private subnet 2 AZ 2 located in Availability Zone 2 90 | Type: String 91 | 92 | PublicSubnet1ACIDR: 93 | AllowedPattern: >- 94 | ^(\d{1,2})?\.(\d{1,3})?\.(\d{1,3})?\.(\d{1,3})?\/(\d{1,3}|\d{1,3})?$ 95 | ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/xx 96 | Default: 10.0.128.0/25 97 | Description: CIDR block for the public DMZ subnet 1A located in Availability Zone 1 98 | Type: String 99 | 100 | PublicSubnet2ACIDR: 101 | AllowedPattern: >- 102 | ^(\d{1,2})?\.(\d{1,3})?\.(\d{1,3})?\.(\d{1,3})?\/(\d{1,3}|\d{1,3})?$ 103 | ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/xx 104 | Default: 10.0.144.0/25 105 | Description: CIDR block for the public DMZ subnet 2A located in Availability Zone 2 106 | Type: String 107 | 108 | VPCCIDR: 109 | AllowedPattern: >- 110 | ^(\d{1,2})?\.(\d{1,3})?\.(\d{1,3})?\.(\d{1,3})?\/(\d{1,3}|\d{1,3})?$ 111 | ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/xx 112 | Description: CIDR block for the VPC 113 | Type: String 114 | 115 | # This section outlines the AWS resources that will be created as a result of running 116 | # this CloudFormation stack. 117 | Resources: 118 | # VPC 119 | VPC: 120 | Type: 'AWS::EC2::VPC' 121 | Properties: 122 | CidrBlock: !Ref VPCCIDR 123 | EnableDnsSupport: 'true' 124 | EnableDnsHostnames: 'true' 125 | Tags: 126 | - Key: Name 127 | Value: !Join [ "-", [ !Ref Environment, !Ref 'AWS::Region' ] ] 128 | 129 | # Internet Gateway 130 | InternetGateway: 131 | Type: 'AWS::EC2::InternetGateway' 132 | Properties: 133 | Tags: 134 | - Key: Name 135 | Value: !Join [ "-", [ !Ref Environment, igw ] ] 136 | - Key: Network 137 | Value: Public 138 | 139 | # Virtual Private Gateway 140 | VPCGWGatewayAttachment: 141 | Type: AWS::EC2::VPCGatewayAttachment 142 | Properties: 143 | VpcId: !Ref VPC 144 | InternetGatewayId: !Ref InternetGateway 145 | 146 | NAT: 147 | Type: AWS::EC2::NatGateway 148 | Properties: 149 | AllocationId: !GetAtt EIP.AllocationId 150 | SubnetId: 151 | Ref: PublicSubnet1A 152 | 153 | EIP: 154 | Type: AWS::EC2::EIP 155 | Properties: 156 | Domain: vpc 157 | 158 | Route: 159 | Type: AWS::EC2::Route 160 | Properties: 161 | RouteTableId: !Ref PrivateSubnetRouteTable1 162 | DestinationCidrBlock: 0.0.0.0/0 163 | NatGatewayId: 164 | Ref: NAT 165 | 166 | 167 | # All the subnet resources DependsOn the Non RFC 1918 VPC CIDR Block to be created. 168 | # This avoids the race/synchronization situation where the creation of 169 | # any subnet requiring that resource does not occur before that resource is created. 170 | PublicSubnet1A: 171 | Type: 'AWS::EC2::Subnet' 172 | DependsOn: 173 | - VPC 174 | Properties: 175 | VpcId: !Ref VPC 176 | CidrBlock: !Ref PublicSubnet1ACIDR 177 | AvailabilityZone: !Select 178 | - '0' 179 | - !Ref AvailabilityZones 180 | Tags: 181 | - Key: Name 182 | Value: !Join [ "-", [ !Ref Environment, public, subnet1 ] ] 183 | - Key: Network 184 | Value: Public 185 | MapPublicIpOnLaunch: true 186 | 187 | PublicSubnet2A: 188 | Type: 'AWS::EC2::Subnet' 189 | DependsOn: 190 | - VPC 191 | Properties: 192 | VpcId: !Ref VPC 193 | CidrBlock: !Ref PublicSubnet2ACIDR 194 | AvailabilityZone: !Select 195 | - '1' 196 | - !Ref AvailabilityZones 197 | Tags: 198 | - Key: Name 199 | Value: !Join [ "-", [ !Ref Environment, public, subnet2 ] ] 200 | - Key: Network 201 | Value: Public 202 | MapPublicIpOnLaunch: true 203 | 204 | PrivateSubnet2Z1: 205 | Type: 'AWS::EC2::Subnet' 206 | DependsOn: 207 | - VPC 208 | Properties: 209 | VpcId: !Ref VPC 210 | CidrBlock: !Ref PrivateSubnet2Z1CIDR 211 | AvailabilityZone: !Select 212 | - '0' 213 | - !Ref AvailabilityZones 214 | Tags: 215 | - Key: Name 216 | Value: !Join [ "-", [ !Ref Environment, private, subnet1 ] ] 217 | - Key: Network 218 | Value: Private 219 | 220 | PrivateSubnet2Z2: 221 | Type: 'AWS::EC2::Subnet' 222 | DependsOn: 223 | - VPC 224 | Properties: 225 | VpcId: !Ref VPC 226 | CidrBlock: !Ref PrivateSubnet2Z2CIDR 227 | AvailabilityZone: !Select 228 | - '1' 229 | - !Ref AvailabilityZones 230 | Tags: 231 | - Key: Name 232 | Value: !Join [ "-", [ !Ref Environment, private, subnet2 ] ] 233 | - Key: Network 234 | Value: Private 235 | 236 | PrivateSubnetRouteTable1: 237 | Type: 'AWS::EC2::RouteTable' 238 | Properties: 239 | VpcId: !Ref VPC 240 | Tags: 241 | - Key: Name 242 | Value: !Join [ "-", [ !Ref Environment, private, routetable ] ] 243 | - Key: Network 244 | Value: Private 245 | 246 | PrivateSubnet2Z1RouteTableAssociation: 247 | Type: 'AWS::EC2::SubnetRouteTableAssociation' 248 | Properties: 249 | SubnetId: !Ref PrivateSubnet2Z1 250 | RouteTableId: !Ref PrivateSubnetRouteTable1 251 | 252 | PrivateSubnet2Z2RouteTableAssociation: 253 | Type: 'AWS::EC2::SubnetRouteTableAssociation' 254 | Properties: 255 | SubnetId: !Ref PrivateSubnet2Z2 256 | RouteTableId: !Ref PrivateSubnetRouteTable1 257 | 258 | PublicSubnetRouteTable1: 259 | Type: 'AWS::EC2::RouteTable' 260 | Properties: 261 | VpcId: !Ref VPC 262 | Tags: 263 | - Key: Name 264 | Value: !Join [ "-", [ !Ref Environment, public, routetable ] ] 265 | - Key: Network 266 | Value: Public 267 | 268 | PublicSubnetRoute1: 269 | DependsOn: VPCGWGatewayAttachment 270 | Type: 'AWS::EC2::Route' 271 | Properties: 272 | RouteTableId: !Ref PublicSubnetRouteTable1 273 | DestinationCidrBlock: 0.0.0.0/0 274 | GatewayId: !Ref InternetGateway 275 | 276 | PublicSubnet1ARouteTableAssociation: 277 | Type: 'AWS::EC2::SubnetRouteTableAssociation' 278 | Properties: 279 | SubnetId: !Ref PublicSubnet1A 280 | RouteTableId: !Ref PublicSubnetRouteTable1 281 | 282 | PublicSubnet2ARouteTableAssociation: 283 | Type: 'AWS::EC2::SubnetRouteTableAssociation' 284 | Properties: 285 | SubnetId: !Ref PublicSubnet2A 286 | RouteTableId: !Ref PublicSubnetRouteTable1 287 | 288 | # Security Groups 289 | PublicSecurityGroup: 290 | Type: AWS::EC2::SecurityGroup 291 | Properties: 292 | GroupDescription: Security Group for Public Instances 293 | VpcId: !Ref VPC 294 | Tags: 295 | - Key: Name 296 | Value: !Join [ "-", [ sample, !Ref Environment, public, sg ] ] 297 | 298 | PrivateSecurityGroup: 299 | Type: AWS::EC2::SecurityGroup 300 | Properties: 301 | GroupDescription: Security Group for Private Instances 302 | VpcId: !Ref VPC 303 | Tags: 304 | - Key: Name 305 | Value: !Join [ "-", [ sample, !Ref Environment, private, sg ] ] 306 | 307 | # Network Access Lists 308 | PublicNetworkAcl: 309 | Type: AWS::EC2::NetworkAcl 310 | Properties: 311 | VpcId: !Ref VPC 312 | Tags: 313 | - Key: Name 314 | Value: !Join [ "-", [ !Ref Environment, public, nacl ] ] 315 | 316 | PublicNetworkAclIngressEntry: 317 | Type: AWS::EC2::NetworkAclEntry 318 | Properties: 319 | NetworkAclId: 320 | Ref: PublicNetworkAcl 321 | RuleNumber: '100' 322 | Protocol: "-1" 323 | RuleAction: allow 324 | CidrBlock: 0.0.0.0/0 325 | 326 | PublicNetworkAclEgressEntry: 327 | Type: AWS::EC2::NetworkAclEntry 328 | Properties: 329 | NetworkAclId: 330 | Ref: PublicNetworkAcl 331 | RuleNumber: '100' 332 | Protocol: "-1" 333 | RuleAction: allow 334 | Egress: 'true' 335 | CidrBlock: 0.0.0.0/0 336 | 337 | PublicSubnet1ANACLAssociation: 338 | Type: 'AWS::EC2::SubnetNetworkAclAssociation' 339 | Properties: 340 | SubnetId: !Ref PublicSubnet1A 341 | NetworkAclId: !Ref PublicNetworkAcl 342 | 343 | PublicSubnet2ANACLAssociation: 344 | Type: 'AWS::EC2::SubnetNetworkAclAssociation' 345 | Properties: 346 | SubnetId: !Ref PublicSubnet2A 347 | NetworkAclId: !Ref PublicNetworkAcl 348 | 349 | PrivateNetworkAcl: 350 | Type: AWS::EC2::NetworkAcl 351 | Properties: 352 | VpcId: !Ref VPC 353 | Tags: 354 | - Key: Name 355 | Value: !Join [ "-", [ !Ref Environment, private, nacl ] ] 356 | 357 | PrivateNetworkAclIngressEntry: 358 | Type: AWS::EC2::NetworkAclEntry 359 | Properties: 360 | NetworkAclId: 361 | Ref: PrivateNetworkAcl 362 | RuleNumber: '100' 363 | Protocol: "-1" 364 | RuleAction: allow 365 | CidrBlock: 0.0.0.0/0 366 | 367 | PrivateNetworkAclEgressEntry: 368 | Type: AWS::EC2::NetworkAclEntry 369 | Properties: 370 | NetworkAclId: 371 | Ref: PrivateNetworkAcl 372 | RuleNumber: '100' 373 | Protocol: "-1" 374 | RuleAction: allow 375 | Egress: 'true' 376 | CidrBlock: 0.0.0.0/0 377 | 378 | PrivateSubnet2Z1NACLAssociation: 379 | Type: 'AWS::EC2::SubnetNetworkAclAssociation' 380 | Properties: 381 | SubnetId: !Ref PrivateSubnet2Z1 382 | NetworkAclId: !Ref PrivateNetworkAcl 383 | 384 | PrivateSubnet2Z2NACLAssociation: 385 | Type: 'AWS::EC2::SubnetNetworkAclAssociation' 386 | Properties: 387 | SubnetId: !Ref PrivateSubnet2Z2 388 | NetworkAclId: !Ref PrivateNetworkAcl 389 | 390 | # This represents the outputs from from running the CloudFormation stack which typically 391 | # corresponds to the AWS resources being consumed. 392 | Outputs: 393 | PrivateSubnet2Z1CIDR: 394 | Description: Private subnet 1 AZ 1 CIDR in Availability Zone 1 395 | Value: !Ref PrivateSubnet2Z1CIDR 396 | Export: 397 | Name: !Sub '${AWS::StackName}-PrivateSubnet2Z1CIDR' 398 | PrivateSubnet2Z1ID: 399 | Description: Private subnet 1 AZ 1 ID in Availability Zone 1 400 | Value: !Ref PrivateSubnet2Z1 401 | Export: 402 | Name: !Sub '${AWS::StackName}-PrivateSubnet2Z1ID' 403 | PrivateSubnet2Z1CIDR: 404 | Description: Private subnet 1 AZ 1 CIDR in Availability Zone 1 405 | Value: !Ref PrivateSubnet2Z1CIDR 406 | Export: 407 | Name: !Sub '${AWS::StackName}-PrivateSubnet2Z1CIDR' 408 | PrivateSubnet2Z1ID: 409 | Description: Private subnet 1 AZ 1 ID in Availability Zone 1 410 | Value: !Ref PrivateSubnet2Z1 411 | Export: 412 | Name: !Sub '${AWS::StackName}-PrivateSubnet2Z1ID' 413 | PrivateSubnet2Z2CIDR: 414 | Description: Private subnet 1 AZ 1 CIDR in Availability Zone 1 415 | Value: !Ref PrivateSubnet2Z2CIDR 416 | Export: 417 | Name: !Sub '${AWS::StackName}-PrivateSubnet2Z2CIDR' 418 | PrivateSubnet2Z2ID: 419 | Description: Private subnet 2 AZ 2 ID in Availability Zone 2 420 | Value: !Ref PrivateSubnet2Z2 421 | Export: 422 | Name: !Sub '${AWS::StackName}-PrivateSubnet2Z2ID' 423 | PublicSubnet1ACIDR: 424 | Description: Public subnet 1A CIDR in Availability Zone 1 425 | Value: !Ref PublicSubnet1ACIDR 426 | Export: 427 | Name: !Sub '${AWS::StackName}-PublicSubnet1ACIDR' 428 | PublicSubnet1AID: 429 | Description: Public subnet 1A ID in Availability Zone 1 430 | Value: !Ref PublicSubnet1A 431 | Export: 432 | Name: !Sub '${AWS::StackName}-PublicSubnet1AID' 433 | PublicSubnet2ACIDR: 434 | Description: Public subnet 2A CIDR in Availability Zone 2 435 | Value: !Ref PublicSubnet2ACIDR 436 | Export: 437 | Name: !Sub '${AWS::StackName}-PublicSubnet2ACIDR' 438 | PublicSubnet2AID: 439 | Description: Public subnet 2A ID in Availability Zone 2 440 | Value: !Ref PublicSubnet2A 441 | Export: 442 | Name: !Sub '${AWS::StackName}-PublicSubnet2AID' 443 | PrivateSubnetRouteTable1: 444 | Value: !Ref PrivateSubnetRouteTable1 445 | Description: Private subnet route table 446 | Export: 447 | Name: !Sub '${AWS::StackName}-PrivateSubnetRouteTable1' 448 | PublicSubnetRouteTable1: 449 | Value: !Ref PublicSubnetRouteTable1 450 | Description: Public subnet route table 451 | Export: 452 | Name: !Sub '${AWS::StackName}-PublicSubnetRouteTable1' 453 | VPCCIDR: 454 | Value: !Ref VPCCIDR 455 | Description: VPC CIDR 456 | Export: 457 | Name: !Sub '${AWS::StackName}-VPCCIDR' 458 | VPCID: 459 | Value: !Ref VPC 460 | Description: VPC ID 461 | Export: 462 | Name: !Sub '${AWS::StackName}-VPCID' 463 | --------------------------------------------------------------------------------