commit 099943f324ac8f8d2194bb57d73c8d7d34aa0929 Author: Brandon Shipley Date: Fri May 27 16:27:40 2022 -0700 first commit diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..eac4e27 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Brandon1811 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100755 index 0000000..89e0a63 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,3 @@ +--- +# harden by default +harden_os: true diff --git a/example.docker-compose.yml b/example.docker-compose.yml new file mode 100644 index 0000000..76a6635 --- /dev/null +++ b/example.docker-compose.yml @@ -0,0 +1,81 @@ +version: '2' + +services: + rocketchat: + image: registry.rocket.chat/rocketchat/rocket.chat:latest + command: > + bash -c + "for i in `seq 1 30`; do + node main.js && + s=$$? && break || s=$$?; + echo \"Tried $$i times. Waiting 5 secs...\"; + sleep 5; + done; (exit $$s)" + restart: unless-stopped + volumes: + - ./uploads:/app/uploads + environment: + - PORT=3000 + - ROOT_URL=http://localhost:3000 + - MONGO_URL=mongodb://mongo:27017/rocketchat + - MONGO_OPLOG_URL=mongodb://mongo:27017/local + - REG_TOKEN=${REG_TOKEN} +# - MAIL_URL=smtp://smtp.email +# - HTTP_PROXY=http://proxy.domain.com +# - HTTPS_PROXY=http://proxy.domain.com + depends_on: + - mongo + ports: + - 3000:3000 + labels: + - "traefik.backend=rocketchat" + - "traefik.frontend.rule=Host: your.domain.tld" + + mongo: + image: mongo:4.0 + restart: unless-stopped + volumes: + - ./data/db:/data/db + #- ./data/dump:/dump + command: mongod --smallfiles --oplogSize 128 --replSet rs0 --storageEngine=mmapv1 + labels: + - "traefik.enable=false" + + # this container's job is just run the command to initialize the replica set. + # it will run the command and remove himself (it will not stay running) + mongo-init-replica: + image: mongo:4.0 + command: > + bash -c + "for i in `seq 1 30`; do + mongo mongo/rocketchat --eval \" + rs.initiate({ + _id: 'rs0', + members: [ { _id: 0, host: 'localhost:27017' } ]})\" && + s=$$? && break || s=$$?; + echo \"Tried $$i times. Waiting 5 secs...\"; + sleep 5; + done; (exit $$s)" + depends_on: + - mongo + + #traefik: + # image: traefik:latest + # restart: unless-stopped + # command: > + # traefik + # --docker + # --acme=true + # --acme.domains='your.domain.tld' + # --acme.email='your@email.tld' + # --acme.entrypoint=https + # --acme.storagefile=acme.json + # --defaultentrypoints=http + # --defaultentrypoints=https + # --entryPoints='Name:http Address::80 Redirect.EntryPoint:https' + # --entryPoints='Name:https Address::443 TLS.Certificates:' + # ports: + # - 80:80 + # - 443:443 + # volumes: + # - /var/run/docker.sock:/var/run/docker.sock diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..009f249 --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,12 @@ +--- +dependencies: [] + +galaxy_info: + author: "Brandon Shipley" + description: "Ansible role to install/run rocket chat via docker-compose on a hardened Ubuntu 20.04 server" + company: "none" + license: MIT + min_anisble_version: 2.9 + role_name: ansible-rocketchat-role + galaxy_tags: + - rocketchat diff --git a/tasks/docker.yml b/tasks/docker.yml new file mode 100644 index 0000000..b6af838 --- /dev/null +++ b/tasks/docker.yml @@ -0,0 +1,26 @@ +--- + +# install docker using geerlingguy docker role +- name: 'Use geerlingguy.docker role' + include_role: + name: ansible-role-docker + tags: docker + +- name: 'Use geerlingguy.pip role to install docker via pip' + vars: + pip_install_packages: + - name: docker + - name: docker-compose + + include_role: + name: ansible-role-pip + tags: docker + +- name: Add adminstrator to docker group + user: + name: "{{ main_user }}" + groups: docker + append: yes + +- name: reset ssh connection to allow user changes to affect 'current login user' + meta: reset_connection diff --git a/tasks/harden.yml b/tasks/harden.yml new file mode 100644 index 0000000..a6a9b28 --- /dev/null +++ b/tasks/harden.yml @@ -0,0 +1,11 @@ +--- + +# harden the ubuntu server via ubuntu2004_cis +- name: 'Use ubuntu2004_cis role' + include_role: + name: ubuntu2004_cis + tags: harden + +- name: 'Include fail2ban/install using apt' + apt: name=fail2ban state=latest update_cache=yes force_apt_get=yes + tags: harden diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..80a9198 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,20 @@ +--- +# tasks file for setting up an assetto server on ubuntu20.04 +- include: ssh_port_fallback.yml +- include: harden.yml +# become: true +# apply tags,become +# when: harden_os +# tags: harden + +- include: docker.yml +# become: true +# apply tags,become +# when: harden_os +# tags: harden + +- include: rocketchat.yml +# become: true +# apply tags,become +# when: harden_os +# tags: harden diff --git a/tasks/rocketchat.yml b/tasks/rocketchat.yml new file mode 100644 index 0000000..3738373 --- /dev/null +++ b/tasks/rocketchat.yml @@ -0,0 +1,55 @@ +--- +- name: Install unzip using apt + apt: name=unzip state=latest update_cache=yes force_apt_get=yes + +- name: "NOTSCORED | 3.5.1.6 | PATCH | Ensure firewall rules exist for all open ports" + ufw: + rule: allow + proto: tcp + port: "{{ item }}" + loop: + - '3000' + - '80' + - '443' + - '22' + +- name: Creates directory structure for assetto content + file: + path: /home/{{ main_user }}/data + state: directory + owner: "{{ main_user }}" + group: "{{ main_user }}" + mode: 0775 + +- name: bring down server-manager docker-compose + become_user: "{{ main_user }}" + docker_compose: + project_src: /home/{{ main_user }}/server-manager/ + state: absent + register: __remove_assetto_server_manager + tags: + - bring-down + +- name: update permissions + file: + path: /home/{{ main_user }} + state: directory + recurse: yes + owner: "{{ main_user }}" + group: "{{ main_user }}" + mode: 0775 + +- name: docker compose up + become_user: "{{ main_user }}" + docker_compose: + project_src: /home/{{ main_user }}/server-manager/ + state: present + register: __assetto_server_manager + +- name: debug docker compose down + debug: + var: __remove_assetto_server_manager + +- name: debug docker compose up + debug: + var: __assetto_server_manager diff --git a/tasks/ssh_port_fallback.yml b/tasks/ssh_port_fallback.yml new file mode 100644 index 0000000..785e53e --- /dev/null +++ b/tasks/ssh_port_fallback.yml @@ -0,0 +1,55 @@ +--- +# +# https://gist.github.com/triplepoint/1ad6c6060c0f12112403d98180bcf0b4 +# +# This task list is intended to be imported by playbooks, before any +# other tasks are performed. It lets us determine whether the configured SSH +# port is available, and lets us fall back to the default port if necessary. +# +# The use case here is when a role in the playbook is configured to change the +# sshd port, but the first time the role is executed the host is still +# listening on the default port. With this check in place, we can fall back +# to the default port on the first run, and then on subsequent runs use the +# configured port. +# +# Be advised that running this task list in a `gather_facts: false` state as +# required means simple failures can go unexplained. For example, if python2 +# is not available, the `wait_for_connection` calls will just time out without +# explanation. +# +# Execute these tasks as the first thing in a playbook like so: +# - hosts: some-host-group +# gather_facts: false +# tasks: +# - import_tasks: _sshd_port_juggling.yml + +- name: SSH Port Juggle | define the fallback default SSH port + set_fact: + _default_ssh_port: 22 + +- name: SSH Port Juggle | Try configured ansible_port {{ ansible_port }} + wait_for_connection: + timeout: 10 + ignore_errors: true + register: _ssh_port_result + +- name: SSH Port Juggle | Set the ansible_port to the fallback default port {{ _default_ssh_port }} + set_fact: + ansible_port: "{{ _default_ssh_port }}" + when: + - _ssh_port_result is failed + +- name: SSH Port Juggle | Check fallback default port {{ ansible_port }} + wait_for_connection: + timeout: 10 + ignore_errors: true + register: _ssh_port_default_result + when: + - _ssh_port_result is failed + +- name: SSH Port Juggle | Fail + fail: msg="Neither the configured ansible_port {{ ansible_port }} nor the fallback port {{ _default_ssh_port }} were reachable" + when: + - _ssh_port_result is failed + - _ssh_port_default_result is defined + - _ssh_port_default_result is failed