├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── ansible ├── ansible.cfg ├── hosts.yaml ├── playbook.yaml ├── roles │ └── oefenweb.fail2ban │ │ ├── .ansible-lint │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── Dockerfile │ │ ├── LICENSE.txt │ │ ├── README.md │ │ ├── Vagrantfile │ │ ├── defaults │ │ └── main.yml │ │ ├── files │ │ └── empty │ │ ├── handlers │ │ └── main.yml │ │ ├── meta │ │ ├── .galaxy_install_info │ │ └── main.yml │ │ ├── tasks │ │ └── main.yml │ │ ├── templates │ │ └── etc │ │ │ └── fail2ban │ │ │ ├── fail2ban.local.j2 │ │ │ └── jail.local.j2 │ │ ├── tests │ │ ├── inventory │ │ ├── test.yml │ │ └── vagrant.yml │ │ └── vars │ │ └── main.yml └── vars │ └── default.yaml ├── digital-ocean ├── cloud-init.yaml ├── firewall.tf ├── main.tf ├── network.tf ├── output.tf ├── server.tf ├── templates │ └── host.cfg └── variables.tf └── gcp ├── firewall.tf ├── main.tf ├── network.tf ├── output.tf ├── server.tf ├── templates └── host.cfg └── variables.tf /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | 2 | # These are supported funding model platforms 3 | 4 | # github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 5 | # patreon: # Replace with a single Patreon username 6 | # open_collective: # Replace with a single Open Collective username 7 | # ko_fi: # Replace with a single Ko-fi username 8 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 9 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 10 | # liberapay: # Replace with a single Liberapay username 11 | # issuehunt: # Replace with a single IssueHunt username 12 | # otechie: # Replace with a single Otechie username 13 | custom: ['https://www.buymeacoffee.com/aaaguirrep'] 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Desktop (please complete the following information):** 28 | 29 | - OS: [e.g. Win, Lin, macOS] 30 | - Docker version [e.g. 22] 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .terraform 3 | *.tfstate* 4 | *credentials/ -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at a_aguirre117@hotmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Pentest image 2 | 3 | Want to contribute to docker image? We provide the next guide to help you get started. 4 | 5 | ## Reporting Issues 6 | 7 | A great way to contribute to the project is to send a detailed report when you encounter an issue. To make things easier for contributors and maintainers, we use github issues option. 8 | 9 | Please make sure to include a reproduction repository so that bugs can be reproduced without great efforts. The better a bug can be reproduced, the faster we can start fixing it! 10 | 11 | ## Pull Requests 12 | 13 | We'd love to see your pull requests, even if it's just to fix a typo! 14 | 15 | However, any significant improvement should be associated to an existing feature request or bug report. 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Arsenio Aguirre 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 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, 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

Offensive Docker VPS

3 | 4 | Create a VPS on Google Cloud Platform or Digital Ocean easily to use [Offensive Docker](https://github.com/aaaguirrep/offensive-docker) and launch the assessments to the targets. 5 | 6 | :tada::tada:**Digital Ocean Bonus**:tada::tada: 7 | You can sign up with my referral link and get $100 free credit to try it out! 8 | 9 | #### Table of contents 10 | 11 | - [Requirements](#requirements) 12 | - [Usage](#usage) 13 | - [1.- Clone the repository](#1--clone-the-repository) 14 | - [2.- Credentials](#2--credentials) 15 | - [For Google Cloud Platform](#for-google-cloud-platform) 16 | - [For Digital Ocean](#for-digital-ocean) 17 | - [SSH Private and Public keys](#ssh-private-and-public-keys) 18 | - [3.- Full Automation: Terraform and Ansible](#3--full-automation-terraform-and-ansible) 19 | - [Google Cloud Platform](#google-cloud-platform) 20 | - [Digital Ocean](#digital-ocean) 21 | - [4.- Access to VPS](#4--access-to-vps) 22 | - [5.- Destroy the VPS](#5--destroy-the-vps) 23 | - [:shield: Security](#shield-security) 24 | - [:coffee: Donations](#coffee-donations) 25 | - [Contributing](#contributing) 26 | - [:chart_with_upwards_trend: Stargazers over time](#chart_with_upwards_trend-stargazers-over-time) 27 | - [License](#license) 28 | 29 | ### Requirements 30 | 31 | - Terraform installed (Version used: v0.13.4) 32 | - Ansible installed (Version used: 2.9.12) 33 | - SSH private and public keys 34 | - Google Cloud Platform or Digital Ocean account. 35 | 36 | ### Usage 37 | 38 | #### 1.- Clone the repository 39 | 40 | ```console 41 | git clone --depth 1 https://github.com/aaaguirrep/offensive-docker-vps.git vps 42 | cd vps 43 | ``` 44 | 45 | #### 2.- Credentials 46 | 47 | - Create credentials folder. 48 | 49 | ```console 50 | mkdir credentials 51 | ``` 52 | 53 | ##### For Google Cloud Platform 54 | 55 | - Create a new project. 56 | - Create service account with "Compute Admin" role and download a key in json format in credentials folder. 57 | - Rename the key to gcp.json 58 | - Enable "Compute Engine API" for the project. 59 | 60 | ##### For Digital Ocean 61 | 62 | - Create a Personal access tokens with write permission and copy it. [See Tutorial](https://www.digitalocean.com/docs/apis-clis/api/create-personal-access-token/) 63 | 64 | ##### SSH Private and Public keys 65 | 66 | - Inside credentials folder run `ssh-keygen -t rsa -f offensive` in the terminal. Empty passphrase is ok. 67 | - It creates two files: private and public key. 68 | 69 | #### 3.- Full Automation: Terraform and Ansible 70 | 71 | ##### Google Cloud Platform 72 | 73 | - Enter to gcp folder and modify the next value: 74 | - In main.tf file change the project value with your project-id. 75 | - Run the next commands: 76 | 77 | ```console 78 | # Initialize terraform provider 79 | $ terraform init 80 | Terraform has been successfully initialized! 81 | 82 | # Create the resources 83 | $ terraform apply -auto-approve 84 | Apply complete! Resources: 6 added, 0 changed, 0 destroyed. 85 | Outputs: 86 | external_ip = x.x.x.x 87 | ``` 88 | 89 | - Copy the external_ip value 90 | 91 | **Note:** The instance type and the region used are: n1-standard-1 and us-central1. You can change the values on server.tf and main.tf 92 | 93 | **Demo** 94 | [![asciicast](https://asciinema.org/a/359398.png)](https://asciinema.org/a/359398) 95 | 96 | ##### Digital Ocean 97 | 98 | - Enter to digital-ocean folder 99 | - With the personal access token copied run `export TF_VAR_do_token="Personal_Access_Token_Here"` 100 | - Run the next commands: 101 | 102 | ```console 103 | # Initialize terraform provider 104 | $ terraform init 105 | Terraform has been successfully initialized! 106 | 107 | # Create the resources 108 | $ terraform apply -auto-approve 109 | Apply complete! Resources: 6 added, 0 changed, 0 destroyed. 110 | Outputs: 111 | external_ip = x.x.x.x 112 | ``` 113 | 114 | - Copy the external_ip value 115 | 116 | **Note:** The droplet type and the region used are: s-2vcpu-4gb and nyc3. You can change the values on server.tf and variables.tf 117 | 118 | **Demo** 119 | [![asciicast](https://asciinema.org/a/359408.png)](https://asciinema.org/a/359408) 120 | 121 | #### 4.- Access to VPS 122 | 123 | - In gcp or digital-ocean folder run the next command. Change x.x.x.x by external_ip value copied. 124 | 125 | ```Console 126 | # Access to VPS 127 | $ ssh offensive@x.x.x.x -i ../credentials/offensive 128 | ``` 129 | 130 | **Demo** 131 | [![asciicast](https://asciinema.org/a/352904.png)](https://asciinema.org/a/352904) 132 | 133 | #### 5.- Destroy the VPS 134 | 135 | - In gcp or digital-ocean folder run the next command. 136 | 137 | ```Console 138 | # Destroy the resource 139 | $ terraform destroy -auto-approve 140 | ``` 141 | 142 | :warning:**Note:** For Digital Ocean, if you dont have a default VPC created in the region used it shows an error to destroy the VPC but no problem, it will destroy the others resources. 143 | 144 | ### :shield: Security 145 | 146 | The service fail2ban has been installed to avoid brute force and block non-authorized users. :ghost::ghost: 147 | 148 | ### :coffee: Donations 149 | 150 | Thanks for your donations, are always appreciated. 151 | 152 | [![Buy me a coffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/aaaguirrep) 153 | 154 | ### Contributing 155 | 156 | [Contributing Guide](CONTRIBUTING.md) 157 | 158 | ### :chart_with_upwards_trend: Stargazers over time 159 | 160 | [![Stargazers over time](https://starchart.cc/aaaguirrep/offensive-docker-vps.svg)](https://starchart.cc/aaaguirrep/offensive-docker-vps) 161 | 162 | ### License 163 | 164 | [MIT](LICENSE) 165 | 166 | Copyright (c) 2020, Arsenio Aguirre 167 | -------------------------------------------------------------------------------- /ansible/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | inventory = hosts.yaml 3 | private_key_file = ../credentials/offensive 4 | remote_user = offensive 5 | host_key_checking = False 6 | roles_path = ./roles -------------------------------------------------------------------------------- /ansible/hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | children: 3 | lab: 4 | hosts: 5 | x.x.x.x: -------------------------------------------------------------------------------- /ansible/playbook.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: lab 3 | become: true 4 | vars_files: 5 | - vars/default.yaml 6 | 7 | pre_tasks: 8 | - name: Test connection 9 | ping: 10 | data: Connection successful 11 | tags: 12 | - connection 13 | 14 | roles: 15 | - oefenweb.fail2ban 16 | 17 | vars: 18 | fail2ban_services: 19 | - name: sshd 20 | port: 22 21 | maxretry: 1 22 | bantime: -1 23 | 24 | tasks: 25 | - name: Update and install packages 26 | apt: 27 | name: [ 'apt-transport-https', 'ca-certificates', 'curl', 'gnupg-agent', 'software-properties-common' , 'python3-pip', 'virtualenv', 'python3-setuptools', 'zsh'] 28 | state: present 29 | update_cache: yes 30 | 31 | - name: Add docker GPG apt key 32 | apt_key: 33 | url: https://download.docker.com/linux/ubuntu/gpg 34 | state: present 35 | 36 | - name: Add docker repository 37 | apt_repository: 38 | repo: deb https://download.docker.com/linux/ubuntu bionic stable 39 | state: present 40 | 41 | - name: Update apt and install docker-ce 42 | apt: 43 | name: docker-ce 44 | state: latest 45 | update_cache: yes 46 | 47 | - name: Adding user to docker group 48 | user: 49 | name: "{{ username }}" 50 | groups: ["docker"] 51 | append: yes 52 | 53 | - name: Install docker module for python 54 | pip: 55 | name: docker 56 | 57 | - name: Download Offensive Docker image 58 | docker_image: 59 | name: "{{ docker_image }}" 60 | source: pull 61 | 62 | - name: Change default shell to zsh 63 | user: 64 | name: "{{ username }}" 65 | shell: /bin/zsh 66 | 67 | - name: Set TERM environment variable 68 | lineinfile: 69 | dest: /etc/environment 70 | line: 'TERM=xterm-256color' 71 | 72 | - name: Clone oh-my-tmux repository 73 | git: 74 | repo: 'https://github.com/gpakosz/.tmux.git' 75 | dest: /home/{{ username }}/.tmux 76 | depth: '1' 77 | force: yes 78 | 79 | - name: Clone oh-my-zsh repository 80 | git: 81 | repo: 'https://github.com/ohmyzsh/ohmyzsh.git' 82 | dest: /home/{{ username }}/.oh-my-zsh 83 | depth: '1' 84 | force: yes 85 | 86 | - name: Create a symbolic link for install oh-my-tmux 87 | file: 88 | src: /home/{{ username }}/.tmux/.tmux.conf 89 | dest: /home/{{ username }}/.tmux.conf 90 | owner: "{{ username }}" 91 | group: "{{ username }}" 92 | state: link 93 | force: yes 94 | 95 | - name: Copy oh-my-zsh configuration file to .zshrc 96 | copy: 97 | src: /home/{{ username }}/.tmux/.tmux.conf.local 98 | dest: /home/{{ username }}/ 99 | remote_src: yes 100 | owner: "{{ username }}" 101 | mode: '0644' 102 | 103 | - name: Change oh-my-zsh ownership, group and permissions 104 | file: 105 | path: /home/{{ username }}/.oh-my-zsh 106 | state: directory 107 | recurse: yes 108 | owner: "{{ username }}" 109 | group: "{{ username }}" 110 | mode: '0555' 111 | 112 | - name: Copy oh-my-zsh configuration file to .zshrc 113 | copy: 114 | src: /home/{{ username }}/.oh-my-zsh/templates/zshrc.zsh-template 115 | dest: /home/{{ username }}/.zshrc 116 | remote_src: yes 117 | owner: "{{ username }}" 118 | mode: '0644' 119 | 120 | - name: Download zsh-syntax-highlighting plugin 121 | git: 122 | repo: 'https://github.com/zsh-users/zsh-syntax-highlighting.git' 123 | dest: /home/{{ username }}/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting 124 | depth: '1' 125 | force: yes 126 | 127 | - name: Download zsh-completions plugin 128 | git: 129 | repo: 'https://github.com/zsh-users/zsh-completions.git' 130 | dest: /home/{{ username }}/.oh-my-zsh/custom/plugins/zsh-completions 131 | depth: '1' 132 | force: yes 133 | 134 | - name: Download zsh-history-substring-search plugin 135 | git: 136 | repo: 'https://github.com/zsh-users/zsh-history-substring-search.git' 137 | dest: /home/{{ username }}/.oh-my-zsh/custom/plugins/zsh-history-substring-search 138 | depth: '1' 139 | force: yes 140 | 141 | - name: Download zsh-autosuggestions plugin 142 | git: 143 | repo: 'https://github.com/zsh-users/zsh-autosuggestions.git' 144 | dest: /home/{{ username }}/.oh-my-zsh/custom/plugins/zsh-autosuggestions 145 | depth: '1' 146 | force: yes 147 | 148 | - name: Enable oh-my-zsh plugins 149 | lineinfile: 150 | path: /home/{{ username }}/.zshrc 151 | regexp: '^plugins=\(' 152 | line: plugins=(git docker tmux ubuntu colored-man-pages zsh-syntax-highlighting zsh-completions history-substring-search zsh-autosuggestions) 153 | 154 | - name: zsh-completions configuration 155 | lineinfile: 156 | path: /home/{{ username }}/.zshrc 157 | state: present 158 | firstmatch: yes 159 | insertafter: '^plugins=\(' 160 | line: autoload -U compinit && compinit 161 | 162 | - name: Configuration finished 163 | debug: 164 | msg: System configured correctly. -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/.ansible-lint: -------------------------------------------------------------------------------- 1 | skip_list: 2 | - '405' 3 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/.gitignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | ###################### 3 | .DS_Store 4 | .DS_Store? 5 | ._* 6 | .Spotlight-V100 7 | .Trashes 8 | Icon? 9 | ehthumbs.db 10 | Thumbs.db 11 | 12 | # IDE files # 13 | ################# 14 | /.settings 15 | /.buildpath 16 | /.project 17 | /nbproject 18 | *.komodoproject 19 | *.kpf 20 | /.idea 21 | 22 | # Vagrant files # 23 | .virtualbox/ 24 | .vagrant/ 25 | vagrant_ansible_inventory_* 26 | ansible.cfg 27 | 28 | # Other files # 29 | ############### 30 | !empty 31 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: required 3 | dist: xenial 4 | 5 | language: python 6 | python: 7 | - "2.7" 8 | - "3.5" 9 | 10 | env: 11 | - ANSIBLE_VERSION=latest 12 | - ANSIBLE_VERSION=2.9.9 13 | - ANSIBLE_VERSION=2.9.8 14 | - ANSIBLE_VERSION=2.9.7 15 | - ANSIBLE_VERSION=2.9.6 16 | - ANSIBLE_VERSION=2.9.5 17 | - ANSIBLE_VERSION=2.9.4 18 | - ANSIBLE_VERSION=2.9.3 19 | - ANSIBLE_VERSION=2.9.2 20 | - ANSIBLE_VERSION=2.9.1 21 | - ANSIBLE_VERSION=2.9.0 22 | - ANSIBLE_VERSION=2.8.12 23 | - ANSIBLE_VERSION=2.8.11 24 | - ANSIBLE_VERSION=2.8.10 25 | - ANSIBLE_VERSION=2.8.9 26 | - ANSIBLE_VERSION=2.8.8 27 | - ANSIBLE_VERSION=2.8.7 28 | - ANSIBLE_VERSION=2.8.6 29 | - ANSIBLE_VERSION=2.8.5 30 | - ANSIBLE_VERSION=2.8.4 31 | - ANSIBLE_VERSION=2.8.3 32 | - ANSIBLE_VERSION=2.8.2 33 | - ANSIBLE_VERSION=2.8.1 34 | - ANSIBLE_VERSION=2.8.0 35 | - ANSIBLE_VERSION=2.7.18 36 | - ANSIBLE_VERSION=2.7.17 37 | - ANSIBLE_VERSION=2.7.16 38 | - ANSIBLE_VERSION=2.7.15 39 | - ANSIBLE_VERSION=2.7.14 40 | - ANSIBLE_VERSION=2.7.13 41 | - ANSIBLE_VERSION=2.7.12 42 | - ANSIBLE_VERSION=2.7.11 43 | - ANSIBLE_VERSION=2.7.10 44 | - ANSIBLE_VERSION=2.7.9 45 | - ANSIBLE_VERSION=2.7.8 46 | - ANSIBLE_VERSION=2.7.7 47 | - ANSIBLE_VERSION=2.7.6 48 | - ANSIBLE_VERSION=2.7.5 49 | - ANSIBLE_VERSION=2.7.4 50 | - ANSIBLE_VERSION=2.7.3 51 | - ANSIBLE_VERSION=2.7.2 52 | - ANSIBLE_VERSION=2.7.1 53 | - ANSIBLE_VERSION=2.7.0 54 | - ANSIBLE_VERSION=2.6.20 55 | - ANSIBLE_VERSION=2.6.19 56 | - ANSIBLE_VERSION=2.6.18 57 | - ANSIBLE_VERSION=2.6.17 58 | - ANSIBLE_VERSION=2.6.16 59 | - ANSIBLE_VERSION=2.6.15 60 | - ANSIBLE_VERSION=2.6.14 61 | - ANSIBLE_VERSION=2.6.13 62 | - ANSIBLE_VERSION=2.6.12 63 | - ANSIBLE_VERSION=2.6.11 64 | - ANSIBLE_VERSION=2.6.10 65 | - ANSIBLE_VERSION=2.6.9 66 | - ANSIBLE_VERSION=2.6.8 67 | - ANSIBLE_VERSION=2.6.7 68 | - ANSIBLE_VERSION=2.6.6 69 | - ANSIBLE_VERSION=2.6.5 70 | - ANSIBLE_VERSION=2.6.4 71 | - ANSIBLE_VERSION=2.6.3 72 | - ANSIBLE_VERSION=2.6.2 73 | - ANSIBLE_VERSION=2.6.1 74 | - ANSIBLE_VERSION=2.6.0 75 | 76 | branches: 77 | only: 78 | - master 79 | 80 | before_install: 81 | - sudo apt-get update -qq 82 | 83 | # Remove fail2ban 84 | - sudo apt-get remove --purge --yes fail2ban 85 | 86 | install: 87 | # Install Ansible. 88 | - if [ "$ANSIBLE_VERSION" = "latest" ]; then pip install ansible; else pip install ansible==$ANSIBLE_VERSION; fi 89 | - if [ "$ANSIBLE_VERSION" = "latest" ]; then pip install ansible-lint; fi 90 | 91 | script: 92 | # Check the role/playbook's syntax. 93 | - ansible-playbook -i tests/inventory tests/test.yml --syntax-check 94 | 95 | # Run the role/playbook with ansible-playbook. 96 | - ansible-playbook -i tests/inventory tests/test.yml -vvvv 97 | 98 | # Run the role/playbook again, checking to make sure it's idempotent. 99 | - > 100 | ansible-playbook -i tests/inventory tests/test.yml 101 | | grep -q 'changed=0.*failed=0' 102 | && (echo 'Idempotence test: pass' && exit 0) 103 | || (echo 'Idempotence test: fail' && exit 1) 104 | 105 | - if [ "$ANSIBLE_VERSION" = "latest" ]; then ansible-lint tests/test.yml; fi 106 | 107 | notifications: 108 | email: false 109 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 110 | slack: 111 | rooms: 112 | secure: "E8KSKkYziMU6hSXE3pnstb7xGrkMiPoYQekxhJcXGb76a3LOKOfaiN8GkBXMpzoaOI2VzFXYBNQOFXy0DXHY3l0KrbDFAXfR3MYaqmdh+0J8d+hZnWB2T8FwObxsTiD+qnkOBThdt7Q8HedPx59Z08MsOo3EY6h0M9iLJ02ybMU=" 113 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | MAINTAINER Mischa ter Smitten 3 | 4 | # python 5 | RUN apt-get update && \ 6 | DEBIAN_FRONTEND=noninteractive apt-get install -y python-minimal python-dev curl && \ 7 | apt-get clean 8 | RUN curl -sL https://bootstrap.pypa.io/get-pip.py | python - 9 | RUN rm -rf $HOME/.cache 10 | 11 | # ansible 12 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y gcc libffi-dev libssl-dev && \ 13 | apt-get clean 14 | RUN pip install ansible==2.6.2 15 | RUN rm -rf $HOME/.cache 16 | 17 | # provision 18 | COPY . /etc/ansible/roles/ansible-role 19 | WORKDIR /etc/ansible/roles/ansible-role 20 | RUN ansible-playbook -i tests/inventory tests/test.yml --connection=local 21 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Oefenweb.nl 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/README.md: -------------------------------------------------------------------------------- 1 | # fail2ban 2 | 3 | [![Build Status](https://travis-ci.org/Oefenweb/ansible-fail2ban.svg?branch=master)](https://travis-ci.org/Oefenweb/ansible-fail2ban) [![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-fail2ban-blue.svg)](https://galaxy.ansible.com/Oefenweb/fail2ban) 4 | 5 | Set up fail2ban in Debian-like systems. 6 | 7 | ## Requirements 8 | 9 | None 10 | 11 | ## Variables 12 | 13 | - `fail2ban_loglevel`: [default: `3`, or `INFO` in newer versions]: Sets the loglevel output (e.g. `1 = ERROR`, `2 = WARN`, `3 = INFO`, `4 = DEBUG`) 14 | - `fail2ban_logtarget`: [default: `/var/log/fail2ban.log`]: Sets the log target. This could be a file, SYSLOG, STDERR or STDOUT 15 | - `fail2ban_syslog_target`: [default: `/var/log/fail2ban.log`]: 16 | - `fail2ban_syslog_facility`: [default: `1`]: 17 | - `fail2ban_socket`: [default: `/var/run/fail2ban/fail2ban.sock`]: Sets the socket file, which is used to communicate with the daemon 18 | - `fail2ban_pidfile`: [default: `/var/run/fail2ban/fail2ban.pid`]: Sets the pid file, which is used to to store the process ID of the daemon (Only works on `fail2ban >= 0.8.9`) 19 | - `fail2ban_dbpurgeage`: [default: `86400`]: Sets age at which bans should be purged from the database 20 | 21 | - `fail2ban_ignoreips`: [default: `[127.0.0.1/8]`]: Which IP address/CIDR mask/DNS host should be ignored from fail2ban's actions 22 | - `fail2ban_bantime`: [default: `600`]: Sets the bantime 23 | - `fail2ban_maxretry`: [default: `3`]: Maximum number of retries before the host is put into jail 24 | - `fail2ban_findtime`: [default: `600`]: A host is banned if it has generated `fail2ban_maxretry` during the last `fail2ban_findtime` 25 | - `fail2ban_backend`: [default: `auto`]: Specifies the backend used to get files modification 26 | - `fail2ban_banaction`: [default: `iptables-multiport`]: Sets the global/default banaction 27 | - `fail2ban_mta`: [default: `sendmail`]: Email action 28 | - `fail2ban_protocol`: [default: `tcp`]: Sets the default protocol 29 | - `fail2ban_chain`: [default: `INPUT`]: Specifies the chain where jumps would need to be added in iptables-* actions 30 | - `fail2ban_action`: [default: `%(action_)s`]: Default action. **Note that variables (including the actions defined elsewhere in the config files) must be wrapped in python-style `%(` and `)s` so they are expanded** 31 | - `fail2ban_sendername`: [default: `Fail2ban`]: The 'from' name for emails sent by mta actions. NB: Use `fail2ban_sender` to set the 'from' email address. 32 | - `fail2ban_sender`: [optional]: The 'from' address for emails sent by mta actions. 33 | - `fail2ban_filterd_path`: [optional]: Path to directory containing filters to copy (**note the trailing slash**) 34 | - `fail2ban_actiond_path`: [optional]: Path to directory containing actions to copy (**note the trailing slash**) 35 | - `fail2ban_jaild_path`: [optional]: Path to directory containing jails to copy (**note the trailing slash**) 36 | 37 | - `fail2ban_services` [default see `defaults/main.yml`]: Service definitions 38 | - `fail2ban_services.{n}.name` [required]: Service name (e.g. `ssh`) 39 | - `fail2ban_services.{n}.enabled` [default: `true`]: Whether or not enabled 40 | - `fail2ban_services.{n}.*` [optional]: Name of the option 41 | - `fail2ban_services.{n}.*.*` [optional]: Value of the option 42 | 43 | ## Dependencies 44 | 45 | None 46 | 47 | ## Example(s) 48 | 49 | ### Simple 50 | 51 | ```yaml 52 | --- 53 | - hosts: all 54 | roles: 55 | - fail2ban 56 | ``` 57 | 58 | ### Enable sshd filter (with non-default settings) 59 | 60 | ```yaml 61 | --- 62 | - hosts: all 63 | roles: 64 | - fail2ban 65 | vars: 66 | fail2ban_services: 67 | # In older versions of Fail2Ban this is called ssh 68 | - name: sshd 69 | port: 2222 70 | maxretry: 5 71 | bantime: -1 72 | ``` 73 | 74 | ### Add custom filters (from outside the role) 75 | 76 | ```yaml 77 | --- 78 | - hosts: all 79 | roles: 80 | - fail2ban 81 | vars: 82 | fail2ban_filterd_path: ../../../files/fail2ban/etc/fail2ban/filter.d/ 83 | fail2ban_services: 84 | - name: apache-wordpress-logins 85 | port: http,https 86 | filter: apache-wordpress-logins 87 | logpath: /var/log/apache2/access.log 88 | maxretry: 5 89 | findtime: 120 90 | ``` 91 | 92 | ## License 93 | 94 | MIT 95 | 96 | ## Author Information 97 | 98 | Mischa ter Smitten (based on work of [ANXS](https://github.com/ANXS)) 99 | 100 | ## Feedback, bug-reports, requests, ... 101 | 102 | Are [welcome](https://github.com/Oefenweb/ansible-fail2ban/issues)! 103 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby ts=2 sw=2 tw=0 et : 3 | 4 | role = File.basename(File.expand_path(File.dirname(__FILE__))) 5 | 6 | boxes = [ 7 | { 8 | :name => "ubuntu-1204", 9 | :box => "bento/ubuntu-12.04", 10 | :ip => '10.0.0.11', 11 | :cpu => "50", 12 | :ram => "256" 13 | }, 14 | { 15 | :name => "ubuntu-1404", 16 | :box => "bento/ubuntu-14.04", 17 | :ip => '10.0.0.12', 18 | :cpu => "50", 19 | :ram => "256" 20 | }, 21 | { 22 | :name => "ubuntu-1604", 23 | :box => "bento/ubuntu-16.04", 24 | :ip => '10.0.0.13', 25 | :cpu => "50", 26 | :ram => "256" 27 | }, 28 | { 29 | :name => "ubuntu-1804", 30 | :box => "bento/ubuntu-18.04", 31 | :ip => '10.0.0.14', 32 | :cpu => "50", 33 | :ram => "384" 34 | }, 35 | { 36 | :name => "debian-7", 37 | :box => "bento/debian-7", 38 | :ip => '10.0.0.15', 39 | :cpu => "50", 40 | :ram => "256" 41 | }, 42 | { 43 | :name => "debian-8", 44 | :box => "bento/debian-8", 45 | :ip => '10.0.0.16', 46 | :cpu => "50", 47 | :ram => "256" 48 | }, 49 | { 50 | :name => "debian-9", 51 | :box => "bento/debian-9", 52 | :ip => '10.0.0.17', 53 | :cpu => "50", 54 | :ram => "256" 55 | }, 56 | { 57 | :name => "debian-10", 58 | :box => "bento/debian-10", 59 | :ip => '10.0.0.18', 60 | :cpu => "50", 61 | :ram => "256" 62 | }, 63 | ] 64 | 65 | Vagrant.configure("2") do |config| 66 | boxes.each do |box| 67 | config.vm.define box[:name] do |vms| 68 | vms.vm.box = box[:box] 69 | vms.vm.hostname = "ansible-#{role}-#{box[:name]}" 70 | 71 | vms.vm.provider "virtualbox" do |v| 72 | v.customize ["modifyvm", :id, "--cpuexecutioncap", box[:cpu]] 73 | v.customize ["modifyvm", :id, "--memory", box[:ram]] 74 | end 75 | 76 | vms.vm.network :private_network, ip: box[:ip] 77 | 78 | vms.vm.provision :ansible do |ansible| 79 | ansible.playbook = "tests/vagrant.yml" 80 | ansible.verbose = "vv" 81 | end 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # defaults file for fail2ban 2 | --- 3 | fail2ban_loglevel: "{{ 'INFO' if (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('16.04', '>=') or ansible_distribution == 'Debian' and ansible_distribution_version is version('9', '>=')) else 3 }}" 4 | fail2ban_logtarget: /var/log/fail2ban.log 5 | fail2ban_syslog_target: /var/log/fail2ban.log 6 | fail2ban_syslog_facility: 1 7 | fail2ban_socket: /var/run/fail2ban/fail2ban.sock 8 | fail2ban_pidfile: /var/run/fail2ban/fail2ban.pid 9 | fail2ban_dbpurgeage: 86400 10 | 11 | fail2ban_sendername: 'Fail2ban' 12 | 13 | fail2ban_ignoreips: 14 | - 127.0.0.1/8 15 | - ::1 16 | fail2ban_bantime: 600 17 | fail2ban_maxretry: 3 18 | fail2ban_findtime: 600 19 | fail2ban_backend: auto 20 | fail2ban_destemail: root@localhost 21 | fail2ban_banaction: iptables-multiport 22 | fail2ban_mta: sendmail 23 | fail2ban_protocol: tcp 24 | fail2ban_chain: INPUT 25 | fail2ban_action: '%(action_)s' 26 | 27 | fail2ban_services: 28 | - name: "{{ 'sshd' if (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('16.04', '>=') or ansible_distribution == 'Debian' and ansible_distribution_version is version('9', '>=')) else 'ssh' }}" 29 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/files/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaaguirrep/offensive-docker-vps/81d35730b456294b0c4ee998b4d965e0d107c105/ansible/roles/oefenweb.fail2ban/files/empty -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # handlers file for fail2ban 2 | --- 3 | - name: restart fail2ban 4 | service: 5 | name: fail2ban 6 | state: restarted 7 | when: service_default_state | default('started') == 'started' 8 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/meta/.galaxy_install_info: -------------------------------------------------------------------------------- 1 | install_date: Mon Aug 17 03:14:48 2020 2 | version: v3.3.13 3 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/meta/main.yml: -------------------------------------------------------------------------------- 1 | # meta file for fail2ban 2 | --- 3 | galaxy_info: 4 | role_name: fail2ban 5 | author: Mischa ter Smitten 6 | company: Oefenweb.nl B.V. 7 | description: Set up fail2ban in Debian-like systems 8 | license: MIT 9 | min_ansible_version: 2.6.0 10 | platforms: 11 | - name: Ubuntu 12 | versions: 13 | - precise 14 | - trusty 15 | - xenial 16 | - bionic 17 | - name: Debian 18 | versions: 19 | - wheezy 20 | - jessie 21 | - stretch 22 | - buster 23 | galaxy_tags: 24 | - system 25 | - networking 26 | dependencies: [] 27 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # tasks file for fail2ban 2 | --- 3 | - name: install 4 | apt: 5 | name: "{{ fail2ban_dependencies }}" 6 | state: "{{ apt_install_state | default('latest') }}" 7 | update_cache: true 8 | cache_valid_time: "{{ apt_update_cache_valid_time | default(3600) }}" 9 | tags: 10 | - configuration 11 | - fail2ban 12 | - fail2ban-install 13 | 14 | - name: update configuration file - /etc/fail2ban/fail2ban.local 15 | template: 16 | src: etc/fail2ban/fail2ban.local.j2 17 | dest: /etc/fail2ban/fail2ban.local 18 | owner: root 19 | group: root 20 | mode: 0644 21 | notify: restart fail2ban 22 | tags: 23 | - configuration 24 | - fail2ban 25 | - fail2ban-configuration 26 | 27 | - name: update configuration file - /etc/fail2ban/jail.local 28 | template: 29 | src: etc/fail2ban/jail.local.j2 30 | dest: /etc/fail2ban/jail.local 31 | owner: root 32 | group: root 33 | mode: 0644 34 | notify: restart fail2ban 35 | tags: 36 | - configuration 37 | - fail2ban 38 | - fail2ban-configuration 39 | 40 | - name: copy filters 41 | copy: 42 | src: "{{ fail2ban_filterd_path }}" 43 | dest: /etc/fail2ban/filter.d/ 44 | owner: root 45 | group: root 46 | mode: 0644 47 | when: fail2ban_filterd_path is defined 48 | notify: restart fail2ban 49 | tags: 50 | - configuration 51 | - fail2ban 52 | - fail2ban-filters 53 | 54 | - name: copy actions 55 | copy: 56 | src: "{{ fail2ban_actiond_path }}" 57 | dest: /etc/fail2ban/action.d/ 58 | owner: root 59 | group: root 60 | mode: 0644 61 | when: fail2ban_actiond_path is defined 62 | notify: restart fail2ban 63 | tags: 64 | - configuration 65 | - fail2ban 66 | - fail2ban-actions 67 | 68 | - name: copy jails 69 | copy: 70 | src: "{{ fail2ban_jaild_path }}" 71 | dest: /etc/fail2ban/jail.d/ 72 | owner: root 73 | group: root 74 | mode: 0644 75 | when: fail2ban_jaild_path is defined 76 | notify: restart fail2ban 77 | tags: 78 | - configuration 79 | - fail2ban 80 | - fail2ban-jails 81 | 82 | - name: start and enable service 83 | service: 84 | name: fail2ban 85 | state: "{{ service_default_state | default('started') }}" 86 | enabled: "{{ service_default_enabled | default(true) | bool }}" 87 | tags: 88 | - configuration 89 | - fail2ban 90 | - fail2ban-start-enable-service 91 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/templates/etc/fail2ban/fail2ban.local.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | # Overrides values from the fail2ban.conf configuration file. 4 | # 5 | # For comments relating to each setting see fail2ban.conf 6 | 7 | [Definition] 8 | 9 | loglevel = {{ fail2ban_loglevel }} 10 | logtarget = {{ fail2ban_logtarget }} 11 | 12 | {% if fail2ban_logtarget == "SYSLOG" %} 13 | syslog-target = {{ fail2ban_syslog_target }} 14 | syslog-facility = {{ fail2ban_syslog_facility }} 15 | {% endif %} 16 | 17 | socket = {{ fail2ban_socket }} 18 | 19 | pidfile = {{ fail2ban_pidfile }} 20 | 21 | dbpurgeage = {{ fail2ban_dbpurgeage }} 22 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/templates/etc/fail2ban/jail.local.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | # Fail2Ban local configuration file. 4 | # Overrides changes in the main jail file, /etc/fail2ban/jail.conf 5 | # Use this file to change local settings. 6 | 7 | [DEFAULT] 8 | 9 | # "ignoreip" can be an IP address, a CIDR mask or a DNS host 10 | ignoreip = {{ fail2ban_ignoreips | join(' ') }} 11 | bantime = {{ fail2ban_bantime }} 12 | maxretry = {{ fail2ban_maxretry }} 13 | findtime = {{ fail2ban_findtime }} 14 | 15 | # "backend" specifies the backend used to get files modification. Available 16 | # options are "gamin", "polling" and "auto". 17 | # yoh: For some reason Debian shipped python-gamin didn't work as expected 18 | # This issue left ToDo, so polling is default backend for now 19 | backend = {{ fail2ban_backend }} 20 | 21 | # 22 | # Destination email address used solely for the interpolations in 23 | # jail.{conf,local} configuration files. 24 | destemail = {{ fail2ban_destemail }} 25 | 26 | # 27 | # Sender name and email address used solely for the interpolations in 28 | # jail.{conf,local} configuration files. 29 | sendername = {{ fail2ban_sendername }} 30 | {% if fail2ban_sender is defined %} 31 | sender = {{ fail2ban_sender }} 32 | {% endif %} 33 | 34 | # 35 | # ACTIONS 36 | # 37 | 38 | # Default banning action (e.g. iptables, iptables-new, 39 | # iptables-multiport, shorewall, etc) It is used to define 40 | # action_* variables. Can be overridden globally or per 41 | # section within jail.local file 42 | banaction = {{ fail2ban_banaction }} 43 | 44 | # email action. Since 0.8.1 upstream fail2ban uses sendmail 45 | # MTA for the mailing. Change mta configuration parameter to mail 46 | # if you want to revert to conventional 'mail'. 47 | mta = {{ fail2ban_mta }} 48 | 49 | # Default protocol 50 | protocol = {{ fail2ban_protocol }} 51 | 52 | # Specify chain where jumps would need to be added in iptables-* actions 53 | chain = {{ fail2ban_chain }} 54 | 55 | # 56 | # Action shortcuts. To be used to define action parameter 57 | 58 | # The simplest action to take: ban only 59 | action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] 60 | 61 | # ban & send an e-mail with whois report to the destemail. 62 | action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] 63 | %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"] 64 | 65 | # ban & send an e-mail with whois report and relevant log lines 66 | # to the destemail. 67 | action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] 68 | %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"] 69 | 70 | # Choose default action. To change, just override value of 'action' with the 71 | # interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local 72 | # globally (section [DEFAULT]) or per specific section 73 | action = {{ fail2ban_action }} 74 | 75 | # 76 | # JAILS 77 | # 78 | 79 | # Next jails corresponds to the standard configuration in Fail2ban 0.6 which 80 | # was shipped in Debian. Enable any defined here jail by including 81 | # 82 | # [SECTION_NAME] 83 | # enabled = true 84 | 85 | # 86 | # in /etc/fail2ban/jail.local. 87 | # 88 | # Optionally you may override any other parameter (e.g. banaction, 89 | # action, port, logpath, etc) in that section within jail.local 90 | 91 | 92 | {% for service in fail2ban_services %} 93 | [{{ service.name }}] 94 | enabled = {{ service.enabled | default(true) | bool | to_json }} 95 | {% for option, value in service.items() | sort %} 96 | {% if option not in ['name', 'enabled'] %} 97 | {{ option }} = {{ value }} 98 | {% endif %} 99 | {% endfor %} 100 | 101 | {% endfor %} 102 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/tests/test.yml: -------------------------------------------------------------------------------- 1 | # test file for fail2ban 2 | --- 3 | - hosts: localhost 4 | connection: local 5 | become: true 6 | roles: 7 | - ../../ 8 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/tests/vagrant.yml: -------------------------------------------------------------------------------- 1 | # test file for fail2ban 2 | --- 3 | - hosts: all 4 | remote_user: vagrant 5 | become: true 6 | roles: 7 | - ../../ 8 | -------------------------------------------------------------------------------- /ansible/roles/oefenweb.fail2ban/vars/main.yml: -------------------------------------------------------------------------------- 1 | # vars file for fail2ban 2 | --- 3 | fail2ban_dependencies: 4 | - fail2ban 5 | -------------------------------------------------------------------------------- /ansible/vars/default.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | docker_image: aaaguirrep/offensive-docker 3 | username: offensive -------------------------------------------------------------------------------- /digital-ocean/cloud-init.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | 3 | users: 4 | - name: ${username} 5 | lock_passwd: true 6 | shell: /bin/bash 7 | ssh_authorized_keys: 8 | - ${ssh_public_key} 9 | sudo: ALL=(ALL) NOPASSWD:ALL -------------------------------------------------------------------------------- /digital-ocean/firewall.tf: -------------------------------------------------------------------------------- 1 | resource "digitalocean_firewall" "traffic-ingress" { 2 | name = "traffic-ingress" 3 | 4 | droplet_ids = digitalocean_droplet.vm_instance.*.id 5 | 6 | inbound_rule { 7 | protocol = "tcp" 8 | port_range = "22" 9 | source_addresses = ["0.0.0.0/0", "::/0"] 10 | } 11 | 12 | inbound_rule { 13 | protocol = "tcp" 14 | port_range = "80" 15 | source_addresses = ["0.0.0.0/0", "::/0"] 16 | } 17 | 18 | inbound_rule { 19 | protocol = "tcp" 20 | port_range = "443" 21 | source_addresses = ["0.0.0.0/0", "::/0"] 22 | } 23 | 24 | inbound_rule { 25 | protocol = "tcp" 26 | port_range = "3128" 27 | source_addresses = ["0.0.0.0/0", "::/0"] 28 | } 29 | 30 | inbound_rule { 31 | protocol = "tcp" 32 | port_range = "8080" 33 | source_addresses = ["0.0.0.0/0", "::/0"] 34 | } 35 | 36 | outbound_rule { 37 | protocol = "tcp" 38 | port_range = "1-65535" 39 | destination_addresses = ["0.0.0.0/0", "::/0"] 40 | } 41 | 42 | outbound_rule { 43 | protocol = "udp" 44 | port_range = "1-65535" 45 | destination_addresses = ["0.0.0.0/0", "::/0"] 46 | } 47 | } -------------------------------------------------------------------------------- /digital-ocean/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | digitalocean = { 4 | source = "digitalocean/digitalocean" 5 | version = "1.23.0" 6 | } 7 | } 8 | } 9 | 10 | provider "digitalocean" { 11 | token = var.do_token 12 | } -------------------------------------------------------------------------------- /digital-ocean/network.tf: -------------------------------------------------------------------------------- 1 | resource "digitalocean_vpc" "vpc_network" { 2 | name = "vpc-network" 3 | region = var.region 4 | } 5 | -------------------------------------------------------------------------------- /digital-ocean/output.tf: -------------------------------------------------------------------------------- 1 | output "external_ip" { 2 | description = "Public IP address" 3 | value = digitalocean_droplet.vm_instance.*.ipv4_address 4 | } -------------------------------------------------------------------------------- /digital-ocean/server.tf: -------------------------------------------------------------------------------- 1 | // Terraform plugin for creating random ids 2 | resource "random_id" "instance_id" { 3 | count = var.vps_number 4 | byte_length = 8 5 | } 6 | 7 | resource "digitalocean_droplet" "vm_instance" { 8 | count = var.vps_number 9 | image = "ubuntu-18-04-x64" 10 | name = "offensive-docker-vm-${random_id.instance_id[count.index].hex}" 11 | region = var.region 12 | size = "s-2vcpu-4gb" 13 | vpc_uuid = digitalocean_vpc.vpc_network.id 14 | ssh_keys = [digitalocean_ssh_key.ssh_public_key.fingerprint] 15 | user_data = data.template_file.cloud_init_yaml.rendered 16 | } 17 | 18 | resource "digitalocean_ssh_key" "ssh_public_key" { 19 | name = "ssh_public_key" 20 | public_key = file(var.ssh_public_key) 21 | } 22 | 23 | data "template_file" "cloud_init_yaml" { 24 | template = file("cloud-init.yaml") 25 | vars = { 26 | ssh_public_key = file(var.ssh_public_key) 27 | username = var.username 28 | } 29 | } 30 | 31 | data "template_file" "dev_hosts" { 32 | template = file("${path.module}/templates/host.cfg") 33 | depends_on = [ 34 | digitalocean_droplet.vm_instance, 35 | ] 36 | vars= { 37 | externalIP = join("\n", digitalocean_droplet.vm_instance.*.ipv4_address) 38 | } 39 | } 40 | 41 | resource "null_resource" "sleep-before-ansible" { 42 | triggers = { 43 | template_rendered = data.template_file.dev_hosts.rendered 44 | } 45 | 46 | provisioner "local-exec" { 47 | command = "sleep 60" 48 | } 49 | } 50 | 51 | resource "null_resource" "dev-hosts" { 52 | depends_on = [ 53 | null_resource.sleep-before-ansible, 54 | ] 55 | provisioner "local-exec" { 56 | command = "echo '${data.template_file.dev_hosts.rendered}' > ../ansible/hosts.yaml" 57 | } 58 | provisioner "local-exec" { 59 | command = "cd ../ansible && ansible-playbook playbook.yaml " 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /digital-ocean/templates/host.cfg: -------------------------------------------------------------------------------- 1 | [lab] 2 | ${externalIP} 3 | -------------------------------------------------------------------------------- /digital-ocean/variables.tf: -------------------------------------------------------------------------------- 1 | variable "ssh_public_key" { 2 | description = "Public key" 3 | type = string 4 | default = "../credentials/offensive.pub" 5 | } 6 | 7 | variable "do_token" { 8 | description = "Digital Ocean Api Token" 9 | } 10 | 11 | variable "region" { 12 | description = "Digital Ocean Region" 13 | default = "nyc3" 14 | } 15 | 16 | variable "username" { 17 | description = "Username" 18 | type = string 19 | default = "offensive" 20 | } 21 | 22 | variable "vps_number" { 23 | description = "Number of VPS servers" 24 | type = string 25 | default = 1 26 | } -------------------------------------------------------------------------------- /gcp/firewall.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_firewall" "traffic-ingress" { 2 | name = "traffic-ingress" 3 | network = google_compute_network.vpc_network.name 4 | 5 | allow { 6 | protocol = "tcp" 7 | ports = ["22","8080","80","443","3128"] 8 | } 9 | 10 | source_ranges = ["0.0.0.0/0"] 11 | } -------------------------------------------------------------------------------- /gcp/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | google = { 4 | source = "hashicorp/google" 5 | version = "3.43.0" 6 | } 7 | } 8 | } 9 | 10 | // Configure the Google Cloud provider 11 | provider "google" { 12 | credentials = file("../credentials/gcp.json") 13 | project = "project-id" 14 | region = "us-central1" 15 | } -------------------------------------------------------------------------------- /gcp/network.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_network" "vpc_network" { 2 | name = "vpc-network" 3 | auto_create_subnetworks = true 4 | } -------------------------------------------------------------------------------- /gcp/output.tf: -------------------------------------------------------------------------------- 1 | output "external_ip" { 2 | description = "Public IP address" 3 | value = google_compute_instance.vm_instance.*.network_interface.0.access_config.0.nat_ip 4 | } -------------------------------------------------------------------------------- /gcp/server.tf: -------------------------------------------------------------------------------- 1 | // Terraform plugin for creating random ids 2 | resource "random_id" "instance_id" { 3 | count = var.vps_number 4 | byte_length = 8 5 | } 6 | 7 | // A single Compute Engine instance 8 | resource "google_compute_instance" "vm_instance" { 9 | count = var.vps_number 10 | name = "offensive-docker-vm-${random_id.instance_id[count.index].hex}" 11 | machine_type = "n1-standard-1" 12 | zone = "us-central1-a" 13 | 14 | boot_disk { 15 | initialize_params { 16 | image = "ubuntu-os-cloud/ubuntu-1804-lts" 17 | size = "30" 18 | } 19 | } 20 | 21 | network_interface { 22 | network = google_compute_network.vpc_network.self_link 23 | 24 | access_config { 25 | // Include this section to give the VM an external ip address 26 | } 27 | } 28 | 29 | metadata = { 30 | ssh-keys = "${var.username}:${file(var.ssh_public_key)}" 31 | } 32 | } 33 | 34 | data "template_file" "dev_hosts" { 35 | template = file("${path.module}/templates/host.cfg") 36 | depends_on = [ 37 | google_compute_instance.vm_instance, 38 | ] 39 | vars= { 40 | externalIP = join("\n", google_compute_instance.vm_instance.*.network_interface.0.access_config.0.nat_ip) 41 | } 42 | } 43 | 44 | resource "null_resource" "sleep-before-ansible" { 45 | triggers = { 46 | template_rendered = data.template_file.dev_hosts.rendered 47 | } 48 | 49 | provisioner "local-exec" { 50 | command = "sleep 60" 51 | } 52 | } 53 | 54 | resource "null_resource" "dev-hosts" { 55 | depends_on = [ 56 | null_resource.sleep-before-ansible, 57 | ] 58 | provisioner "local-exec" { 59 | command = "echo '${data.template_file.dev_hosts.rendered}' > ../ansible/hosts.yaml" 60 | } 61 | provisioner "local-exec" { 62 | command = "cd ../ansible && ansible-playbook playbook.yaml " 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /gcp/templates/host.cfg: -------------------------------------------------------------------------------- 1 | [lab] 2 | ${externalIP} 3 | -------------------------------------------------------------------------------- /gcp/variables.tf: -------------------------------------------------------------------------------- 1 | variable "ssh_public_key" { 2 | description = "Public key" 3 | type = string 4 | default = "../credentials/offensive.pub" 5 | } 6 | 7 | variable "username" { 8 | description = "Username" 9 | type = string 10 | default = "offensive" 11 | } 12 | 13 | variable "vps_number" { 14 | description = "Number of VPS servers" 15 | type = string 16 | default = 1 17 | } --------------------------------------------------------------------------------