diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..2baf4c56 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*.sh] +# like -i=4 +indent_style = space +indent_size = 4 + +binary_next_line = true # like -bn +switch_case_indent = true # like -ci +space_redirects = true # like -sr +keep_padding = true # like -kp diff --git a/.github/labeler.yaml b/.github/labeler.yaml new file mode 100644 index 00000000..38eaa325 --- /dev/null +++ b/.github/labeler.yaml @@ -0,0 +1,86 @@ +--- +# Area +area/github: + - changed-files: + - any-glob-to-any-file: ".github/**/*" + +area/pre-commit: + - changed-files: + - any-glob-to-any-file: ".pre-commit-config.yaml" + - any-glob-to-any-file: ".hooks/**/*" + +area/license: + - changed-files: + - any-glob-to-any-file: "LICENSE" + +area/readme: + - changed-files: + - any-glob-to-any-file: "README.md" + +area/roles: + - changed-files: + - any-glob-to-any-file: "ansible/roles/**/*" + +area/playbooks: + - changed-files: + - any-glob-to-any-file: "ansible/playbooks/**/*" + +area/taskfiles: + - changed-files: + - any-glob-to-any-file: "Taskfile.yaml" + +area/terraform: + - changed-files: + - any-glob-to-any-file: "ad/*/providers/terraform/**/*" + +area/packer: + - changed-files: + - any-glob-to-any-file: "packer/**/*" + +area/docker: + - changed-files: + - any-glob-to-any-file: "Dockerfile" + +area/docs: + - changed-files: + - any-glob-to-any-file: "docs/**/*" + +area/scripts: + - changed-files: + - any-glob-to-any-file: "scripts/**/*" + +area/extensions: + - changed-files: + - any-glob-to-any-file: "extensions/**/*" + +area/python: + - changed-files: + - any-glob-to-any-file: "goad/**/*" + - any-glob-to-any-file: "goad.py" + - any-glob-to-any-file: "pyproject.toml" + - any-glob-to-any-file: "poetry.lock" + +area/ad-labs: + - changed-files: + - any-glob-to-any-file: "ad/**/*" + +# Lab variants +lab/GOAD: + - changed-files: + - any-glob-to-any-file: "ad/GOAD/**/*" + +lab/GOAD-Light: + - changed-files: + - any-glob-to-any-file: "ad/GOAD-Light/**/*" + +lab/GOAD-Mini: + - changed-files: + - any-glob-to-any-file: "ad/GOAD-Mini/**/*" + +lab/NHA: + - changed-files: + - any-glob-to-any-file: "ad/NHA/**/*" + +lab/SCCM: + - changed-files: + - any-glob-to-any-file: "ad/SCCM/**/*" diff --git a/.github/labels.yaml b/.github/labels.yaml new file mode 100644 index 00000000..c1b9e45c --- /dev/null +++ b/.github/labels.yaml @@ -0,0 +1,132 @@ +--- +# Area +- name: area/github + color: "72CCF3" # Light Blue + description: >- + Changes made to github actions + +- name: area/pre-commit + color: "BC9BE3" # Lavender + description: >- + Changes made to pre-commit hooks + +- name: area/license + color: "F4D1B7" # Peach + description: >- + Changes made to license file + +- name: area/readme + color: "84B6EB" # Steel Blue + description: >- + Changes made to README.md file + +- name: area/roles + color: "FF6600" # Orange + description: >- + Changes made to Ansible roles + +- name: area/playbooks + color: "FF99CC" # Pink + description: >- + Changes made to playbooks directory + +- name: area/taskfiles + color: "66CCFF" # Sky Blue + description: >- + Changes made to taskfiles + +- name: area/terraform + color: "7B42BC" # Terraform Purple + description: >- + Changes made to Terraform/provider configs + +- name: area/packer + color: "02A8EF" # Packer Blue + description: >- + Changes made to Packer configurations + +- name: area/docker + color: "2496ED" # Docker Blue + description: >- + Changes made to Docker configurations + +- name: area/docs + color: "0075CA" # Documentation Blue + description: >- + Changes made to documentation + +- name: area/scripts + color: "A8D08D" # Sage Green + description: >- + Changes made to utility scripts + +- name: area/extensions + color: "E0C068" # Amber + description: >- + Changes made to extensions (ELK, Exchange, Wazuh, etc.) + +- name: area/python + color: "3776AB" # Python Blue + description: >- + Changes made to Python application code + +- name: area/ad-labs + color: "D4A017" # Gold + description: >- + Changes made to AD lab definitions + +# Lab variants +- name: lab/GOAD + color: "C0392B" # Dark Red + description: >- + Changes made to GOAD lab + +- name: lab/GOAD-Light + color: "E74C3C" # Light Red + description: >- + Changes made to GOAD-Light lab + +- name: lab/GOAD-Mini + color: "F1948A" # Salmon + description: >- + Changes made to GOAD-Mini lab + +- name: lab/NHA + color: "8E44AD" # Wisteria + description: >- + Changes made to NHA lab + +- name: lab/SCCM + color: "2980B9" # Belize Blue + description: >- + Changes made to SCCM lab + +# Renovate +- name: renovate/container + color: "FFC300" # Golden Yellow +- name: renovate/github-action + color: "FFD700" # Gold +- name: renovate/github-release + color: "FFE4B5" # Moccasin + +# Semantic Type +- name: type/digest + color: "FFEC19" # Yellow +- name: type/patch + color: "FF9800" # Dark Orange +- name: type/minor + color: "FF6B6B" # Salmon +- name: type/major + color: "F6412D" # Red Orange +- name: type/break + color: "FF0000" # Bright Red + +# Uncategorized +- name: bug + color: "D93F0B" # Dark Red +- name: do-not-merge + color: "B60205" # Blood Red +- name: docs + color: "0075CA" # Documentation Blue +- name: enhancement + color: "A2EEEF" # Light Blue diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 00000000..fa772583 --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,133 @@ +{ + $schema: 'https://docs.renovatebot.com/renovate-schema.json', + gitAuthor: 'cowdogmoo-renovate-bot <157187596+cowdogmoo-renovate-bot[bot]@users.noreply.github.com>', + extends: [ + 'config:recommended', + 'docker:enableMajor', + ':disableRateLimiting', + ':dependencyDashboard', + ':semanticCommits', + ':enablePreCommit', + ':automergeDigest', + 'helpers:pinGitHubActionDigests', + ], + dependencyDashboardLabels: [ + 'renovate-dashboard', + ], + dependencyDashboardTitle: 'Renovate Dashboard 🤖', + suppressNotifications: [ + 'prIgnoreNotification', + ], + rebaseWhen: 'conflicted', + commitBodyTable: true, + labels: [ + 'renovate', + ], + 'pre-commit': { + enabled: true, + }, + pip_requirements: { + managerFilePatterns: [ + '/(^|/)requirements\\.txt$/', + '/(^|/)\\.hooks/requirements\\.txt$/', + ], + }, + packageRules: [ + { + description: 'Auto merge Galaxy dependencies', + matchManagers: [ + 'ansible-galaxy', + ], + automerge: true, + automergeType: 'pr', + matchUpdateTypes: [ + 'minor', + 'patch', + ], + }, + { + description: 'Auto-merge GitHub Actions', + matchManagers: [ + 'github-actions', + ], + automerge: true, + automergeType: 'pr', + matchUpdateTypes: [ + 'major', + 'minor', + 'patch', + ], + }, + { + description: 'Auto-merge pre-commit hooks', + matchManagers: [ + 'pre-commit', + ], + automerge: true, + automergeType: 'pr', + matchUpdateTypes: [ + 'minor', + 'patch', + ], + }, + { + description: 'Auto-merge pip dependencies', + matchManagers: [ + 'pip_requirements', + ], + automerge: true, + automergeType: 'pr', + matchUpdateTypes: [ + 'minor', + 'patch', + ], + }, + { + description: 'Group Ansible Galaxy dependencies', + matchManagers: [ + 'ansible-galaxy', + ], + groupName: 'ansible-dependencies', + }, + ], + customManagers: [ + { + customType: 'regex', + description: 'Update Python version in GitHub Actions workflows', + managerFilePatterns: [ + '/^\\.github\\/workflows\\/[^/]+\\.ya?ml$/', + ], + matchStrings: [ + 'PYTHON_VERSION:\\s*["\']?(?[0-9.]+)["\']?', + ], + depNameTemplate: 'python', + datasourceTemplate: 'python-version', + }, + { + customType: 'regex', + description: 'Update Go version in GitHub Actions workflows', + managerFilePatterns: [ + '/^\\.github\\/workflows\\/[^/]+\\.ya?ml$/', + ], + matchStrings: [ + 'GO_VERSION:\\s*["\']?(?[0-9.]+)["\']?', + ], + depNameTemplate: 'go', + datasourceTemplate: 'golang-version', + }, + { + customType: 'regex', + description: 'Update Task version in GitHub Actions workflows', + managerFilePatterns: [ + '/^\\.github\\/workflows\\/[^/]+\\.ya?ml$/', + ], + matchStrings: [ + 'TASK_VERSION:\\s*(?[0-9.]+)', + ], + depNameTemplate: 'task', + datasourceTemplate: 'github-releases', + packageNameTemplate: 'go-task/task', + extractVersionTemplate: '^v(?.+)$', + }, + ], +} diff --git a/.github/workflows/meta-labeler.yaml b/.github/workflows/meta-labeler.yaml new file mode 100644 index 00000000..aaaefe19 --- /dev/null +++ b/.github/workflows/meta-labeler.yaml @@ -0,0 +1,28 @@ +--- +name: "Labeler" +on: + pull_request_target: + branches: ["main"] + types: ["opened", "synchronize"] + +permissions: + contents: read + pull-requests: write + +jobs: + labeler: + name: Labeler + runs-on: ubuntu-latest + steps: + - name: Generate Token + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 + id: app-token + with: + app-id: "${{ secrets.BOT_APP_ID }}" + private-key: "${{ secrets.BOT_APP_PRIVATE_KEY }}" + + - name: Labeler + uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 + with: + configuration-path: .github/labeler.yaml + repo-token: "${{ steps.app-token.outputs.token }}" diff --git a/.github/workflows/meta-sync-labels.yaml b/.github/workflows/meta-sync-labels.yaml new file mode 100644 index 00000000..7352b21b --- /dev/null +++ b/.github/workflows/meta-sync-labels.yaml @@ -0,0 +1,36 @@ +--- +name: "Meta Sync labels" +on: + workflow_dispatch: + push: + branches: ["main"] + paths: [".github/labels.yaml"] + +permissions: + contents: read + issues: write + pull-requests: write + +jobs: + labels: + name: Sync Labels + runs-on: ubuntu-latest + steps: + - name: Generate Token + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 + id: app-token + with: + app-id: "${{ secrets.BOT_APP_ID }}" + private-key: "${{ secrets.BOT_APP_PRIVATE_KEY }}" + + - name: Set up git repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + token: "${{ steps.app-token.outputs.token }}" + + - name: Sync Labels + uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3 + with: + config-file: .github/labels.yaml + token: "${{ steps.app-token.outputs.token }}" + delete-other-labels: true diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml new file mode 100644 index 00000000..e3b8186b --- /dev/null +++ b/.github/workflows/pre-commit.yaml @@ -0,0 +1,71 @@ +--- +name: Pre-Commit +on: + merge_group: + pull_request: + branches: + - main + types: + - opened + - synchronize + - reopened + push: + branches: + - main + schedule: + # Run once a week (see https://crontab.guru) + - cron: "0 0 * * 0" + workflow_dispatch: + +# Cancel any in-progress job when a new workflow is triggered +concurrency: + cancel-in-progress: true + group: pre-commit-${{ github.workflow }}-${{ github.ref }} + +env: + GO_VERSION: "1.26.1" + PYTHON_VERSION: "3.14.3" + TASK_X_REMOTE_TASKFILES: "1" + TASK_VERSION: 3.49.1 + +jobs: + pre-commit: + name: Update pre-commit hooks and run pre-commit + runs-on: ubuntu-latest + steps: + - name: Checkout git repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' + cache-dependency-path: '.hooks/requirements.txt' + + - name: Install dependencies + run: | + python3 -m pip install -r .hooks/requirements.txt + + - name: Install Ansible collections + run: | + ansible-galaxy collection install -r requirements.yml --force + ansible-galaxy collection install -r ansible/requirements.yml --force + + - name: Set up Go + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install go module dependencies + run: | + go install mvdan.cc/sh/v3/cmd/shfmt@latest + + - name: Setup go-task + run: | + sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin v${{ env.TASK_VERSION }} + task --version + + - name: Run pre-commit + run: | + pre-commit run --show-diff-on-failure --color=always --all-files diff --git a/.github/workflows/renovate.yaml b/.github/workflows/renovate.yaml new file mode 100644 index 00000000..55aeb0e3 --- /dev/null +++ b/.github/workflows/renovate.yaml @@ -0,0 +1,78 @@ +--- +name: "\U0001F916 Renovate" +on: + push: + branches: ["main"] + paths: + - .github/renovate.json5 + schedule: + # Run every week on sunday and wednesday at 00:00 UTC + - cron: "0 0 * * 0,3" + workflow_dispatch: + inputs: + dryRun: + description: Dry Run + type: boolean + default: false + required: true + logLevel: + description: Log Level + type: choice + default: info + options: + - debug + - info + required: true + version: + description: Renovate Version + default: latest + required: true + +concurrency: + cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.event.number || github.ref }} + +# Retrieve BOT_USER_ID via `curl -s "https://api.github.com/users/${BOT_USERNAME}%5Bbot%5D" | jq .id` +env: + RENOVATE_ONBOARDING_CONFIG_FILE_NAME: .github/renovate.json5 + RENOVATE_GIT_AUTHOR: "${{ secrets.BOT_USERNAME }} <${{ secrets.BOT_USER_ID }}+${{ secrets.BOT_USERNAME }}[bot]@users.noreply.github.com>" + +# Permissions block for GitHub App +permissions: + actions: write + contents: write + issues: write + pull-requests: write + statuses: read + +jobs: + renovate: + name: Renovate + runs-on: ubuntu-latest + steps: + - name: Generate Token + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 + id: app-token + with: + app-id: "${{ secrets.BOT_APP_ID }}" + private-key: "${{ secrets.BOT_APP_PRIVATE_KEY }}" + + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + token: "${{ steps.app-token.outputs.token }}" + + - name: Renovate + uses: renovatebot/github-action@68a3ea99af6ad249940b5a9fdf44fc6d7f14378b # v46.1.6 + env: + LOG_LEVEL: "${{ inputs.logLevel || 'info' }}" + RENOVATE_AUTODISCOVER: true + RENOVATE_AUTODISCOVER_FILTER: "${{ github.repository }}" + RENOVATE_DRY_RUN: "${{ inputs.dryRun }}" + RENOVATE_INTERNAL_CHECKS_FILTER: strict + RENOVATE_PLATFORM: github + RENOVATE_PLATFORM_COMMIT: true + with: + configurationFile: "${{ env.RENOVATE_ONBOARDING_CONFIG_FILE_NAME }}" + token: "${{ steps.app-token.outputs.token }}" + renovate-version: "${{ inputs.version || 'full' }}" diff --git a/.hooks/linters/ansible-lint.yaml b/.hooks/linters/ansible-lint.yaml index 1c3e7b21..01515906 100644 --- a/.hooks/linters/ansible-lint.yaml +++ b/.hooks/linters/ansible-lint.yaml @@ -3,6 +3,7 @@ # and not relative to the CWD of execution. CLI arguments passed to the --exclude # option are parsed relative to the CWD of execution. exclude_paths: + - .claude/ - .github/ # Files with unskippable load-failure (unicode/runtime) or syntax-check issues - ad/GOAD-Light/files/dc01/templates/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0f4e0355..c2cb7a73 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: hooks: - id: codespell entry: codespell -q 3 -f -S ".git,.github,README.md" - exclude: '(\.min\.css\.map|\.css\.map|\.min\.map|\.min\.js|sysmonconfig-export\.xml|jquery\.validate\.(min\.)?js)$' + exclude: '(\.min\.css\.map|\.css\.map|\.min\.map|\.min\.js|sysmonconfig-export\.xml|jquery\.validate\.(min\.)?js|jquery-3\.4\.1(\.slim)?\.js|modernizr-[\d\.]+\.js)$' - repo: https://github.com/jumanjihouse/pre-commit-hooks rev: 3.0.0 @@ -54,6 +54,7 @@ repos: - id: ansible-lint entry: ansible-lint -v --force-color -c .hooks/linters/ansible-lint.yaml language: python + language_version: python3 # do not pass files to ansible-lint, see: # https://github.com/ansible-community/ansible-lint/issues/611 # pass_filenames: false diff --git a/ad/GOAD-variant-1/data/inventory b/ad/GOAD-variant-1/data/inventory index 9f063d91..dcbe0a83 100644 --- a/ad/GOAD-variant-1/data/inventory +++ b/ad/GOAD-variant-1/data/inventory @@ -47,7 +47,7 @@ dc03 srv02 srv03 -; domain controler (mandatory) +; domain controller (mandatory) ; usage : ad-acl.yml, ad-data.yml, ad-relations.yml, laps.yml [dc] dc01 @@ -64,13 +64,13 @@ srv03 ; usage : ad-servers.yml, laps.yml [workstation] -; parent domain controler (mandatory) +; parent domain controller (mandatory) ; usage : ad-servers.yml [parent_dc] dc01 dc03 -; child domain controler (need a fqdn child_name.parent_name) +; child domain controller (need a fqdn child_name.parent_name) ; usage : ad-servers.yml [child_dc] dc02 diff --git a/ad/GOAD/data/inventory b/ad/GOAD/data/inventory index 9f063d91..dcbe0a83 100644 --- a/ad/GOAD/data/inventory +++ b/ad/GOAD/data/inventory @@ -47,7 +47,7 @@ dc03 srv02 srv03 -; domain controler (mandatory) +; domain controller (mandatory) ; usage : ad-acl.yml, ad-data.yml, ad-relations.yml, laps.yml [dc] dc01 @@ -64,13 +64,13 @@ srv03 ; usage : ad-servers.yml, laps.yml [workstation] -; parent domain controler (mandatory) +; parent domain controller (mandatory) ; usage : ad-servers.yml [parent_dc] dc01 dc03 -; child domain controler (need a fqdn child_name.parent_name) +; child domain controller (need a fqdn child_name.parent_name) ; usage : ad-servers.yml [child_dc] dc02 diff --git a/ansible/roles/common/tasks/chocolatey.yml b/ansible/roles/common/tasks/chocolatey.yml index 507cc65b..39d191c1 100644 --- a/ansible/roles/common/tasks/chocolatey.yml +++ b/ansible/roles/common/tasks/chocolatey.yml @@ -1,17 +1,17 @@ - name: Ensure chocolatey is installed - win_chocolatey: + chocolatey.chocolatey.win_chocolatey: name: - chocolatey - chocolatey-core.extension state: present - name: Disable enhanced exit codes - win_chocolatey_feature: + chocolatey.chocolatey.win_chocolatey_feature: name: useEnhancedExitCodes state: disabled - name: Install multiple packages sequentially - win_chocolatey: + chocolatey.chocolatey.win_chocolatey: name: '{{ item }}' state: present with_items: diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml index 0802db0c..29ad6428 100644 --- a/ansible/roles/common/tasks/main.yml +++ b/ansible/roles/common/tasks/main.yml @@ -8,7 +8,7 @@ when: force_dns_server | bool - name: Set a proxy for specific protocols - ansible.windows.win_inet_proxy: + community.windows.win_inet_proxy: proxy: http: "{{ ad_http_proxy }}" https: "{{ ad_https_proxy }}" @@ -16,7 +16,7 @@ when: enable_http_proxy | bool - name: Configure IE to use a specific proxy per protocol - ansible.windows.win_inet_proxy: + community.windows.win_inet_proxy: proxy: http: "{{ ad_http_proxy }}" https: "{{ ad_https_proxy }}" @@ -140,7 +140,7 @@ until: firewall_result is not failed - name: Add a network static route - ansible.windows.win_route: + community.windows.win_route: destination: "{{ route_network }}" gateway: "{{ route_gateway }}" metric: 1 diff --git a/ansible/roles/dc_dns_conditional_forwarder/tasks/main.yml b/ansible/roles/dc_dns_conditional_forwarder/tasks/main.yml index 966d52cb..47ddce34 100644 --- a/ansible/roles/dc_dns_conditional_forwarder/tasks/main.yml +++ b/ansible/roles/dc_dns_conditional_forwarder/tasks/main.yml @@ -1,6 +1,6 @@ --- - name: Add DNS server zone - ansible.windows.win_dns_zone: + community.windows.win_dns_zone: name: "{{ item }}" type: forwarder replication: "{{ replication }}" diff --git a/ansible/roles/dns_conditional_forwarder/tasks/main.yml b/ansible/roles/dns_conditional_forwarder/tasks/main.yml index 18687f1c..952a3623 100644 --- a/ansible/roles/dns_conditional_forwarder/tasks/main.yml +++ b/ansible/roles/dns_conditional_forwarder/tasks/main.yml @@ -1,6 +1,6 @@ --- - name: Add DNS server zone - ansible.windows.win_dns_zone: + community.windows.win_dns_zone: name: "{{ zone_name }}" type: forwarder replication: "{{ replication }}" diff --git a/ansible/roles/laps/dc/library/win_ad_dacl.ps1 b/ansible/roles/laps/dc/library/win_ad_dacl.ps1 old mode 100644 new mode 100755 diff --git a/ansible/roles/laps/dc/library/win_ad_object.ps1 b/ansible/roles/laps/dc/library/win_ad_object.ps1 old mode 100644 new mode 100755 diff --git a/ansible/roles/laps/dc/library/win_gpo.ps1 b/ansible/roles/laps/dc/library/win_gpo.ps1 old mode 100644 new mode 100755 diff --git a/ansible/roles/laps/dc/library/win_gpo_link.ps1 b/ansible/roles/laps/dc/library/win_gpo_link.ps1 old mode 100644 new mode 100755 diff --git a/ansible/roles/laps/dc/library/win_gpo_reg.ps1 b/ansible/roles/laps/dc/library/win_gpo_reg.ps1 old mode 100644 new mode 100755 diff --git a/ansible/roles/parent_child_dns/tasks/main.yml b/ansible/roles/parent_child_dns/tasks/main.yml index 3ac31862..662161d1 100644 --- a/ansible/roles/parent_child_dns/tasks/main.yml +++ b/ansible/roles/parent_child_dns/tasks/main.yml @@ -24,7 +24,7 @@ - "'already exists' not in dns_delegation_result.stderr" - name: Create conditional forwarder to child domain - ansible.windows.win_dns_zone: + community.windows.win_dns_zone: name: "{{ item }}" type: forwarder replication: "forest" diff --git a/ansible/roles/sccm/config/boundary/library/sccm_boundary.ps1 b/ansible/roles/sccm/config/boundary/library/sccm_boundary.ps1 old mode 100644 new mode 100755 diff --git a/ansible/roles/sccm/config/boundary/library/sccm_boundary_group.ps1 b/ansible/roles/sccm/config/boundary/library/sccm_boundary_group.ps1 old mode 100644 new mode 100755 diff --git a/ansible/roles/sccm/config/boundary/library/sccm_boundary_to_boundarygroup.ps1 b/ansible/roles/sccm/config/boundary/library/sccm_boundary_to_boundarygroup.ps1 old mode 100644 new mode 100755 diff --git a/ansible/roles/vulns/adcs_templates/files/ADCSTemplate/ADCSTemplate.psm1 b/ansible/roles/vulns/adcs_templates/files/ADCSTemplate/ADCSTemplate.psm1 index 2d33b8f2..3897a79e 100755 --- a/ansible/roles/vulns/adcs_templates/files/ADCSTemplate/ADCSTemplate.psm1 +++ b/ansible/roles/vulns/adcs_templates/files/ADCSTemplate/ADCSTemplate.psm1 @@ -128,7 +128,7 @@ param( [switch]$Enroll, [switch]$AutoEnroll ) - ## Potential issue here that the AD: drive may not be targetting the selected DC in the -SERVER parameter + ## Potential issue here that the AD: drive may not be targeting the selected DC in the -SERVER parameter $TemplatePath = "AD:\" + (Get-ADCSTemplate -DisplayName $DisplayName -Server $Server).DistinguishedName $acl = Get-ACL $TemplatePath $InheritedObjectType = [GUID]'00000000-0000-0000-0000-000000000000' @@ -344,7 +344,7 @@ param( #endregion #region PERMISSIONS - ## Potential issue here that the AD: drive may not be targetting the selected DC in the -SERVER parameter + ## Potential issue here that the AD: drive may not be targeting the selected DC in the -SERVER parameter If ($PSBoundParameters.ContainsKey('Identity')) { If ($AutoEnroll) { Set-ADCSTemplateACL -DisplayName $DisplayName -Server $Server -Type Allow -Identity $Identity -Enroll -AutoEnroll diff --git a/ansible/roles/vulns/autologon/tasks/main.yml b/ansible/roles/vulns/autologon/tasks/main.yml index 208cfb20..e3ec85f9 100644 --- a/ansible/roles/vulns/autologon/tasks/main.yml +++ b/ansible/roles/vulns/autologon/tasks/main.yml @@ -1,6 +1,6 @@ --- - name: Add windows autologon - ansible.windows.win_auto_logon: + community.windows.win_auto_logon: username: "{{ item.value.username }}" password: "{{ item.value.password }}" with_dict: "{{ vulns_vars }}" diff --git a/ansible/roles/vulns/disable_firewall/tasks/main.yml b/ansible/roles/vulns/disable_firewall/tasks/main.yml index e16d99ae..c0e59e8a 100644 --- a/ansible/roles/vulns/disable_firewall/tasks/main.yml +++ b/ansible/roles/vulns/disable_firewall/tasks/main.yml @@ -1,6 +1,6 @@ --- - name: Disable Domain firewall - ansible.windows.win_firewall: + community.windows.win_firewall: state: disabled profiles: - Domain diff --git a/extensions/exchange/ansible/roles/ludus_exchange/defaults/main.yml b/extensions/exchange/ansible/roles/ludus_exchange/defaults/main.yml index 6306e6a2..f33c1713 100644 --- a/extensions/exchange/ansible/roles/ludus_exchange/defaults/main.yml +++ b/extensions/exchange/ansible/roles/ludus_exchange/defaults/main.yml @@ -1,22 +1,22 @@ -#Exchange Details -ludus_install_directory: /opt/ludus -exchange_dotnet_install_path: "https://download.visualstudio.microsoft.com/download/pr/2d6bb6b2-226a-4baa-bdec-798822606ff1/8494001c276a4b96804cde7829c04d7f/ndp48-x86-x64-allos-enu.exe" -vcredist2013_install_path: "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe" -rewrite_module_path: "https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi" -ucma_runtime_path: "https://download.microsoft.com/download/2/C/4/2C47A5C1-A1F3-4843-B9FE-84C0032C61EC/UcmaRuntimeSetup.exe" -ludus_exchange_iso_url: "https://download.microsoft.com/download/d/7/b/d7bcf78a-00d2-4a46-a3d2-7d506116bcd2/ExchangeServer2019-x64-CU9.ISO" -ludus_exchange2016_iso_url: "https://download.microsoft.com/download/2/5/8/258D30CF-CA4C-433A-A618-FB7E6BCC4EEE/ExchangeServer2016-x64-cu12.iso" -# This pulls the netbios_name out of the domain assigned to this machine in the ludus range config -ludus_exchange_domain: "{{ (ludus | selectattr('vm_name', 'match', inventory_hostname))[0].domain.fqdn.split('.')[0] }}" -# This pulls the vm_name of the primary-dc for the domain assigned to this machine in the ludus range config -ludus_exchange_dc: "{{ (ludus | selectattr('domain', 'defined') | selectattr('domain.fqdn', 'match', ludus_exchange_domain) | selectattr('domain.role', 'match', 'primary-dc'))[0].hostname }}" -# This pulls the hostname from the ludus config for this host -ludus_exchange_host: "{{ (ludus | selectattr('vm_name', 'match', inventory_hostname))[0].hostname }}" -ludus_exchange_domain_username: "{{ ludus_exchange_domain }}\\{{ defaults.ad_domain_admin }}" -ludus_exchange_domain_password: "{{ defaults.ad_domain_admin_password }}" -#SendConnector Details -send_connector_name: "" # Default of the send connector -send_connector_smtpserver: "" # Smart hosts for the send connector -send_connector_address_spaces: - - "SMTP:*;1" # Address spaces for the send connector -send_connector_source_transport_servers: "{{ (ludus | selectattr('vm_name', 'match', inventory_hostname))[0].hostname }}" # Source transport servers for the send connector +#Exchange Details +ludus_install_directory: /opt/ludus +exchange_dotnet_install_path: "https://download.visualstudio.microsoft.com/download/pr/2d6bb6b2-226a-4baa-bdec-798822606ff1/8494001c276a4b96804cde7829c04d7f/ndp48-x86-x64-allos-enu.exe" +vcredist2013_install_path: "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe" +rewrite_module_path: "https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi" +ucma_runtime_path: "https://download.microsoft.com/download/2/C/4/2C47A5C1-A1F3-4843-B9FE-84C0032C61EC/UcmaRuntimeSetup.exe" +ludus_exchange_iso_url: "https://download.microsoft.com/download/d/7/b/d7bcf78a-00d2-4a46-a3d2-7d506116bcd2/ExchangeServer2019-x64-CU9.ISO" +ludus_exchange2016_iso_url: "https://download.microsoft.com/download/2/5/8/258D30CF-CA4C-433A-A618-FB7E6BCC4EEE/ExchangeServer2016-x64-cu12.iso" +# This pulls the netbios_name out of the domain assigned to this machine in the ludus range config +ludus_exchange_domain: "{{ (ludus | selectattr('vm_name', 'match', inventory_hostname))[0].domain.fqdn.split('.')[0] }}" +# This pulls the vm_name of the primary-dc for the domain assigned to this machine in the ludus range config +ludus_exchange_dc: "{{ (ludus | selectattr('domain', 'defined') | selectattr('domain.fqdn', 'match', ludus_exchange_domain) | selectattr('domain.role', 'match', 'primary-dc'))[0].hostname }}" +# This pulls the hostname from the ludus config for this host +ludus_exchange_host: "{{ (ludus | selectattr('vm_name', 'match', inventory_hostname))[0].hostname }}" +ludus_exchange_domain_username: "{{ ludus_exchange_domain }}\\{{ defaults.ad_domain_admin }}" +ludus_exchange_domain_password: "{{ defaults.ad_domain_admin_password }}" +#SendConnector Details +send_connector_name: "" # Default of the send connector +send_connector_smtpserver: "" # Smart hosts for the send connector +send_connector_address_spaces: + - "SMTP:*;1" # Address spaces for the send connector +send_connector_source_transport_servers: "{{ (ludus | selectattr('vm_name', 'match', inventory_hostname))[0].hostname }}" # Source transport servers for the send connector diff --git a/extensions/exchange/ansible/roles/ludus_exchange/meta/main.yml b/extensions/exchange/ansible/roles/ludus_exchange/meta/main.yml index 85d91c3f..363a761c 100644 --- a/extensions/exchange/ansible/roles/ludus_exchange/meta/main.yml +++ b/extensions/exchange/ansible/roles/ludus_exchange/meta/main.yml @@ -1,29 +1,29 @@ ---- -dependencies: [] - -galaxy_info: - role_name: ludus_exchange - author: aleemladha - description: Install Exchange 2019 or Exchange 2016 to a Windows server - company: aleemladha - license: GPLv3 - min_ansible_version: "2.10" - platforms: - - name: Windows - versions: - - "2012R2" - - "2019" - - "2022" - - galaxy_tags: - - windows - - security - - adcs - - active directory - - exchange server - - server - -collections: - - ansible.windows - - community.windows - - community.general +--- +dependencies: [] + +galaxy_info: + role_name: ludus_exchange + author: aleemladha + description: Install Exchange 2019 or Exchange 2016 to a Windows server + company: aleemladha + license: GPLv3 + min_ansible_version: "2.10" + platforms: + - name: Windows + versions: + - "2012R2" + - "2019" + - "2022" + + galaxy_tags: + - windows + - security + - adcs + - active directory + - exchange server + - server + +collections: + - ansible.windows + - community.windows + - community.general diff --git a/extensions/exchange/ansible/roles/ludus_exchange/tasks/ludus-exchange-2016-install.yml b/extensions/exchange/ansible/roles/ludus_exchange/tasks/ludus-exchange-2016-install.yml index c4d79b04..0ec97976 100644 --- a/extensions/exchange/ansible/roles/ludus_exchange/tasks/ludus-exchange-2016-install.yml +++ b/extensions/exchange/ansible/roles/ludus_exchange/tasks/ludus-exchange-2016-install.yml @@ -1,44 +1,44 @@ ---- -- name: Mount Exchange 2016 ISO - community.windows.win_disk_image: - image_path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange2016_iso_url.split('/') | last }}" - state: present - register: iso_mount - -- name: Prepare Schema - ansible.windows.win_shell: | - & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareSchema - vars: - ansible_become: true - ansible_become_method: runas - ansible_become_user: "{{ ludus_exchange_domain_username }}" - ansible_become_password: "{{ ludus_exchange_domain_password }}" - -- name: Prepare Active Directory - ansible.windows.win_shell: | - & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareAD /OrganizationName:"{{ ludus_exchange_domain }}" - vars: - ansible_become: true - ansible_become_method: runas - ansible_become_user: "{{ ludus_exchange_domain_username }}" - ansible_become_password: "{{ ludus_exchange_domain_password }}" - -- name: Install Exchange 2016 - ansible.windows.win_shell: | - & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /Mode:Install /Role:Mailbox - vars: - ansible_become: true - ansible_become_method: runas - ansible_become_user: "{{ ludus_exchange_domain_username }}" - ansible_become_password: "{{ ludus_exchange_domain_password }}" - -- name: Unmount ISO - community.windows.win_disk_image: - image_path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange2016_iso_url.split('/') | last }}" - state: absent - - -- name: Remove ISO file - ansible.windows.win_file: - path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange2016_iso_url.split('/') | last }}" - state: absent +--- +- name: Mount Exchange 2016 ISO + community.windows.win_disk_image: + image_path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange2016_iso_url.split('/') | last }}" + state: present + register: iso_mount + +- name: Prepare Schema + ansible.windows.win_shell: | + & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareSchema + vars: + ansible_become: true + ansible_become_method: runas + ansible_become_user: "{{ ludus_exchange_domain_username }}" + ansible_become_password: "{{ ludus_exchange_domain_password }}" + +- name: Prepare Active Directory + ansible.windows.win_shell: | + & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareAD /OrganizationName:"{{ ludus_exchange_domain }}" + vars: + ansible_become: true + ansible_become_method: runas + ansible_become_user: "{{ ludus_exchange_domain_username }}" + ansible_become_password: "{{ ludus_exchange_domain_password }}" + +- name: Install Exchange 2016 + ansible.windows.win_shell: | + & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /Mode:Install /Role:Mailbox + vars: + ansible_become: true + ansible_become_method: runas + ansible_become_user: "{{ ludus_exchange_domain_username }}" + ansible_become_password: "{{ ludus_exchange_domain_password }}" + +- name: Unmount ISO + community.windows.win_disk_image: + image_path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange2016_iso_url.split('/') | last }}" + state: absent + + +- name: Remove ISO file + ansible.windows.win_file: + path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange2016_iso_url.split('/') | last }}" + state: absent diff --git a/extensions/exchange/ansible/roles/ludus_exchange/tasks/ludus-exchange-2019-install.yml b/extensions/exchange/ansible/roles/ludus_exchange/tasks/ludus-exchange-2019-install.yml index c621cedd..c1d32d7d 100644 --- a/extensions/exchange/ansible/roles/ludus_exchange/tasks/ludus-exchange-2019-install.yml +++ b/extensions/exchange/ansible/roles/ludus_exchange/tasks/ludus-exchange-2019-install.yml @@ -1,43 +1,43 @@ ---- -- name: Mount Exchange ISO - community.windows.win_disk_image: - image_path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange_iso_url.split('/') | last }}" - state: present - register: iso_mount - -- name: Prepare Schema - ansible.windows.win_shell: | - & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareSchema - vars: - ansible_become: true - ansible_become_method: runas - ansible_become_user: "{{ ludus_exchange_domain_username }}" - ansible_become_password: "{{ ludus_exchange_domain_password }}" - -- name: Prepare Active Directory - ansible.windows.win_shell: | - & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareAD /OrganizationName:"{{ ludus_exchange_domain }}" - vars: - ansible_become: true - ansible_become_method: runas - ansible_become_user: "{{ ludus_exchange_domain_username }}" - ansible_become_password: "{{ ludus_exchange_domain_password }}" - -- name: Install Exchange - ansible.windows.win_shell: | - & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /Mode:Install /Role:Mailbox - vars: - ansible_become: true - ansible_become_method: runas - ansible_become_user: "{{ ludus_exchange_domain_username }}" - ansible_become_password: "{{ ludus_exchange_domain_password }}" - -- name: Unmount ISO - community.windows.win_disk_image: - image_path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange_iso_url.split('/') | last }}" - state: absent - -- name: Remove ISO file - ansible.windows.win_file: - path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange_iso_url.split('/') | last }}" - state: absent +--- +- name: Mount Exchange ISO + community.windows.win_disk_image: + image_path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange_iso_url.split('/') | last }}" + state: present + register: iso_mount + +- name: Prepare Schema + ansible.windows.win_shell: | + & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareSchema + vars: + ansible_become: true + ansible_become_method: runas + ansible_become_user: "{{ ludus_exchange_domain_username }}" + ansible_become_password: "{{ ludus_exchange_domain_password }}" + +- name: Prepare Active Directory + ansible.windows.win_shell: | + & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /PrepareAD /OrganizationName:"{{ ludus_exchange_domain }}" + vars: + ansible_become: true + ansible_become_method: runas + ansible_become_user: "{{ ludus_exchange_domain_username }}" + ansible_become_password: "{{ ludus_exchange_domain_password }}" + +- name: Install Exchange + ansible.windows.win_shell: | + & {{ iso_mount.mount_paths[0] }}Setup.exe /IAcceptExchangeServerLicenseTerms /Mode:Install /Role:Mailbox + vars: + ansible_become: true + ansible_become_method: runas + ansible_become_user: "{{ ludus_exchange_domain_username }}" + ansible_become_password: "{{ ludus_exchange_domain_password }}" + +- name: Unmount ISO + community.windows.win_disk_image: + image_path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange_iso_url.split('/') | last }}" + state: absent + +- name: Remove ISO file + ansible.windows.win_file: + path: "{{ ludus_exchange_iso_directory }}\\{{ ludus_exchange_iso_url.split('/') | last }}" + state: absent diff --git a/extensions/ws01/ansible/install.yml b/extensions/ws01/ansible/install.yml index f4792bdb..8c897e72 100644 --- a/extensions/ws01/ansible/install.yml +++ b/extensions/ws01/ansible/install.yml @@ -50,7 +50,7 @@ - include_role: name: "security/{{secu}}" vars: - security_vars : "{{ lab.hosts[dict_key].security_vars[secu] | default({}) }}" + security_vars: "{{ lab.hosts[dict_key].security_vars[secu] | default({}) }}" domain: "{{lab.hosts[dict_key].domain}}" domain_username: "{{member_domain}}\\{{admin_user}}" domain_password: "{{lab.domains[member_domain].domain_password}}" diff --git a/globalsettings.ini b/globalsettings.ini index bd8313d9..9e74b7e6 100644 --- a/globalsettings.ini +++ b/globalsettings.ini @@ -1,5 +1,5 @@ [all:vars] -; This is the global inventory file, data here will override all lab or provider inventory datas +; This is the global inventory file, data here will override all lab or provider inventory data ; modify this to add layouts to VMs ; https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-language-pack-default-values ; French : 0000040C @@ -9,7 +9,7 @@ ; the first in the list will be the default layout (here: FR | US) keyboard_layouts=["0000040C", "00000409"] -; Uncoment to not use SSL in ansible (usefull if you get Digest initialization failed: initialization error with vagrant) +; Uncomment to not use SSL in ansible (useful if you get Digest initialization failed: initialization error with vagrant) # ansible_winrm_transport=basic # ansible_port=5985 diff --git a/goad/provider/terraform/azure.py b/goad/provider/terraform/azure.py index 7523af69..89ca1a0d 100644 --- a/goad/provider/terraform/azure.py +++ b/goad/provider/terraform/azure.py @@ -137,7 +137,7 @@ def status(self): table.add_row(vm.vm_id, vm.name, vm.location, power_state, ','.join(vm_public_ips), ','.join(vm_private_ips)) print(table) except Exception as e: - Log.error('Error retreiving running vms') + Log.error('Error retrieving running vms') return False def start(self): @@ -177,7 +177,7 @@ def stop(self): Log.success(f'vm {vm.name} deallocate (no more billed)') self.status() except Exception as e: - Log.error('Error stoping the lab vms') + Log.error('Error stopping the lab vms') return False def start_vm(self, vm_name): @@ -285,7 +285,7 @@ def _get_az_jumpbox_ip(self): public_ip = network_client.public_ip_addresses.get(nic_resource_group, public_ip_name) return public_ip.ip_address except Exception as e: - Log.error('Error retreiving jumpbox ip') + Log.error('Error retrieving jumpbox ip') return False return None diff --git a/scripts/check.sh b/scripts/check.sh index eb350f47..e8a9ec51 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# shellcheck disable=SC2329 +# shellcheck disable=SC2317,SC2329 # This source code come from the opensource project DetectionLab : https://github.com/clong/DetectionLab # This script is meant to verify that your system is configured to build the lab successfully. diff --git a/scripts/generate-instance-mapping.sh b/scripts/generate-instance-mapping.sh index 7f2d2785..dbd1b9c5 100755 --- a/scripts/generate-instance-mapping.sh +++ b/scripts/generate-instance-mapping.sh @@ -62,7 +62,7 @@ echo "" echo "✓ Mapping generated successfully: ${OUTPUT_FILE}" echo "" echo "Contents:" -cat "${OUTPUT_FILE}" | jq '.' +jq '.' "${OUTPUT_FILE}" # Show summary instance_count=$(echo "$mapping" | jq '.instance_to_ip | length') diff --git a/scripts/run-playbook-with-retry.sh b/scripts/run-playbook-with-retry.sh index 0fc3c5cb..b03bebcf 100755 --- a/scripts/run-playbook-with-retry.sh +++ b/scripts/run-playbook-with-retry.sh @@ -90,9 +90,9 @@ cleanup_stale_ssm_sessions() { for session_id in $sessions; do if [[ -n "$session_id" && "$session_id" != "None" ]]; then - aws ssm terminate-session --session-id "$session_id" --region "$region" > /dev/null 2>&1 && { + if aws ssm terminate-session --session-id "$session_id" --region "$region" > /dev/null 2>&1; then ((terminated++)) - } || true + fi fi done done diff --git a/scripts/validate-goad-vulns.sh b/scripts/validate-goad-vulns.sh index eec087f8..28d0c265 100755 --- a/scripts/validate-goad-vulns.sh +++ b/scripts/validate-goad-vulns.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# shellcheck disable=SC2329 +# shellcheck disable=SC2317,SC2329 # validate-goad-vulns.sh - Validate GOAD vulnerability configurations # Based on: docs/GOAD-vulnerabilities-comprehensive.md #