diff --git a/group_vars/all.yml b/group_vars/all.yml index d852cd4..67f1fb3 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -1,2 +1,4 @@ +architecture_mapping: { "armv6l": "armhf", "armv7l": "armhf", "aarch64": "arm64", "x86_64": "amd64", "i386": "i386" } + sshd_port: 22 ipfs_port: 4001 diff --git a/handbook.yml b/handbook.yml index 6263672..df9fee9 100644 --- a/handbook.yml +++ b/handbook.yml @@ -13,14 +13,14 @@ tags: [firewall, ips, ids] - role: iptables-webserver tags: [firewall, webserver] - - role: iptables-ipfs - tags: [firewall, ipfs] - role: fail2ban-basic tags: [fail2ban, ips, ids] - - yggdrasil + - role: ipfs + tags: [ipfs] + - role: yggdrasil + tags: [yggdrasil] - role: snort-community tags: [snort, ips, ids] - diff --git a/roles/hardening-basic/README.md b/roles/hardening-basic/README.md index 95d63a1..dcfc840 100644 --- a/roles/hardening-basic/README.md +++ b/roles/hardening-basic/README.md @@ -19,6 +19,8 @@ Role Variables - **hardening_sysctl_vm_swappiness** (integer): Set the value for sysctl vm.swappiness - **hardening_sysctl_disable_ipv6** (boolean): Enable or disable ipv6 though sysctl - **hardening_modprobe_disable_list** (dict): Array of sections. Each section contains an array of string: modules, protocols and so on that can be disabled through modprobe +- **hardening_journald_system_max_use** (string): Example 250M +- **hardening_journald_system_max_file_size** (string): Example 50M Dependencies ------------ diff --git a/roles/hardening-basic/defaults/main.yml b/roles/hardening-basic/defaults/main.yml index 7b3bbbe..8437d8f 100644 --- a/roles/hardening-basic/defaults/main.yml +++ b/roles/hardening-basic/defaults/main.yml @@ -16,3 +16,6 @@ hardening_modprobe_disable_list: rare_filesystems: [cramfs,freevxfs,jffs2,hfs,hfsplus,squashfs,udf] rare_protocols: [dccp,sctp,rds,tipc,n-hdlc,ax25,netrom,x25,rose,decnet,econet,af_802154,ipx,appletalk,psnap,p8023,p8022,can,atm] vivid: [vivid] + +hardening_journald_system_max_use: 250M +hardening_journald_system_max_file_size: 50M diff --git a/roles/hardening-basic/tasks/harden_systemd.yml b/roles/hardening-basic/tasks/harden_systemd.yml new file mode 100644 index 0000000..a44247b --- /dev/null +++ b/roles/hardening-basic/tasks/harden_systemd.yml @@ -0,0 +1,14 @@ +- name: Create directory tree if not exists + ansible.builtin.file: + path: '/etc/{{ item.path }}' + state: directory + mode: '{{ item.mode }}' + with_community.general.filetree: '../templates/systemd/etc/' + when: item.state == 'directory' + +- name: Create and copy files + ansible.builtin.template: + src: '{{ item.src }}' + dest: '/etc/{{ item.path }}' + with_community.general.filetree: '../templates/systemd/etc/' + when: item.state == 'file' diff --git a/roles/hardening-basic/tasks/main.yml b/roles/hardening-basic/tasks/main.yml index 6a5c355..9754d8c 100644 --- a/roles/hardening-basic/tasks/main.yml +++ b/roles/hardening-basic/tasks/main.yml @@ -7,12 +7,18 @@ ansible.builtin.template: src: '{{ item.src }}' dest: '/etc/{{ item.path }}' - with_community.general.filetree: '../templates/etc/' + with_community.general.filetree: '../templates/basic/etc/' when: item.state == 'file' - name: Harden SSH Config when: 'hardening_sshd_enabled is true' block: + - name: Create and copy hardening files + ansible.builtin.template: + src: '{{ item.src }}' + dest: '/etc/{{ item.path }}' + with_community.general.filetree: '../templates/ssh/etc/' + when: item.state == 'file' - name: Give 1700 permissions to .ssh folder ansible.builtin.file: @@ -33,3 +39,7 @@ ansible.builtin.systemd: state: restarted name: sshd + + - name: Harden Service Manager (like Systemd) + block: + - include_tasks: "harden_{{ ansible_service_mgr }}.yml" diff --git a/roles/hardening-basic/templates/etc/modprobe.d/hardening.conf b/roles/hardening-basic/templates/basic/etc/modprobe.d/hardening.conf similarity index 100% rename from roles/hardening-basic/templates/etc/modprobe.d/hardening.conf rename to roles/hardening-basic/templates/basic/etc/modprobe.d/hardening.conf diff --git a/roles/hardening-basic/templates/etc/sysctl.d/99-hardening.conf b/roles/hardening-basic/templates/basic/etc/sysctl.d/99-hardening.conf similarity index 100% rename from roles/hardening-basic/templates/etc/sysctl.d/99-hardening.conf rename to roles/hardening-basic/templates/basic/etc/sysctl.d/99-hardening.conf diff --git a/roles/hardening-basic/templates/etc/ssh/sshd_config.d/99-hardening.conf b/roles/hardening-basic/templates/ssh/etc/ssh/sshd_config.d/99-hardening.conf similarity index 98% rename from roles/hardening-basic/templates/etc/ssh/sshd_config.d/99-hardening.conf rename to roles/hardening-basic/templates/ssh/etc/ssh/sshd_config.d/99-hardening.conf index 8692650..128a1a7 100644 --- a/roles/hardening-basic/templates/etc/ssh/sshd_config.d/99-hardening.conf +++ b/roles/hardening-basic/templates/ssh/etc/ssh/sshd_config.d/99-hardening.conf @@ -1,5 +1,3 @@ -{% if hardening_sshd_enabled %} - Protocol 2 # Protocol 1 is fundamentally broken StrictModes yes # Protects from misconfiguration @@ -54,5 +52,3 @@ MaxStartups 2 # Max concurrent TCPKeepAlive yes # Do not use TCP keep-alive AcceptEnv LANG LC_* # Allow client to pass locale environment variables - -{% endif %} diff --git a/roles/hardening-basic/templates/systemd/etc/systemd/journald.conf.d/size.conf b/roles/hardening-basic/templates/systemd/etc/systemd/journald.conf.d/size.conf new file mode 100644 index 0000000..2374c9c --- /dev/null +++ b/roles/hardening-basic/templates/systemd/etc/systemd/journald.conf.d/size.conf @@ -0,0 +1,3 @@ +[Journal] +SystemMaxUse={{ hardening_journald_system_max_use }} +SystemMaxFileSize={{ hardening_journald_system_max_file_size }} diff --git a/roles/ipfs/.travis.yml b/roles/ipfs/.travis.yml new file mode 100644 index 0000000..36bbf62 --- /dev/null +++ b/roles/ipfs/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/roles/ipfs/README.md b/roles/ipfs/README.md new file mode 100644 index 0000000..74b22e1 --- /dev/null +++ b/roles/ipfs/README.md @@ -0,0 +1,38 @@ +ipfs +========= + +This role setup ipfs-update and ipfs, systemd related files and start iptables-ipfs role + +Requirements +------------ + +. + +Role Variables +-------------- + +- **ipfs_enabled** (boolean): Enable or disable IPFS support +- **ipfs_setup** (boolean): If true will setup IPFS installation with updater for the first time +- **ipfs_updater_version**: ipfs-update version +- **ipfs_group**: IPFS dedicated group +- **ipfs_user**: IPFS dedicated user + +Dependencies +------------ + +. + +Example Playbook +---------------- + +ansible-playbook -i inventory/example.yml handbook.yml --extra-vars="target=your_target ipfs_version=latest" --tags ipfs + +License +------- + +GPLv3 + +Author Information +------------------ + +- [Claudio Maradonna](https://social.unitoo.it/claudio) diff --git a/roles/ipfs/defaults/main.yml b/roles/ipfs/defaults/main.yml new file mode 100644 index 0000000..8aa048a --- /dev/null +++ b/roles/ipfs/defaults/main.yml @@ -0,0 +1,9 @@ +--- +# defaults file for ipfs + +ipfs_enabled: false +ipfs_setup: false +ipfs_updater_version: 1.9.0 + +ipfs_group: ipfs +ipfs_user: ipfs diff --git a/roles/ipfs/handlers/main.yml b/roles/ipfs/handlers/main.yml new file mode 100644 index 0000000..50db67b --- /dev/null +++ b/roles/ipfs/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for ipfs diff --git a/roles/ipfs/meta/main.yml b/roles/ipfs/meta/main.yml new file mode 100644 index 0000000..c572acc --- /dev/null +++ b/roles/ipfs/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/ipfs/tasks/install_systemd_service.yml b/roles/ipfs/tasks/install_systemd_service.yml new file mode 100644 index 0000000..7b556b4 --- /dev/null +++ b/roles/ipfs/tasks/install_systemd_service.yml @@ -0,0 +1,16 @@ +- name: Install systemd service for ipfs + become: true + become_user: root + block: + - name: Create and copy systemd files + ansible.builtin.template: + src: '{{ item.src }}' + dest: '/{{ item.path }}' + with_community.general.filetree: '../templates/systemd/' + when: item.state == 'file' + + - name: Reload systemd services + ansible.builtin.systemd: + name: ipfs + state: started + daemon_reload: yes diff --git a/roles/ipfs/tasks/main.yml b/roles/ipfs/tasks/main.yml new file mode 100644 index 0000000..0ba7ce1 --- /dev/null +++ b/roles/ipfs/tasks/main.yml @@ -0,0 +1,77 @@ +--- +# tasks file for ipfs + +- name: Install IPFS if enabled + when: + - 'ipfs_enabled is true' + block: + - name: Setup ipfs-update + when: 'ipfs_setup is true' + block: + - name: Create ipfs group + group: + name: "{{ ipfs_group }}" + state: present + + - name: Create ipfs user + user: + name: "{{ ipfs_user }}" + state: present + shell: /sbin/nologin + group: "{{ ipfs_group }}" + + - name: Create working dir + ansible.builtin.file: + path: '/mnt/ipfs' + state: directory + owner: '{{ ipfs_user }}' + group: '{{ ipfs_group }}' + + - name: Download ipfs-update for IPFS version control + ansible.builtin.unarchive: + src: 'https://dist.ipfs.tech/ipfs-update/v{{ ipfs_updater_version }}/ipfs-update_v{{ ipfs_updater_version }}_linux-{{ architecture_mapping[ansible_architecture] }}.tar.gz' + dest: /tmp + remote_src: yes + owner: root + group: root + + - name: Install ipfs-update + ansible.builtin.copy: + src: /tmp/ipfs-update/ipfs-update + dest: /usr/local/bin/ipfs-update + owner: ipfs + group: ipfs + mode: '1750' + remote_src: yes + + - name: Install ipfs version specified + when: 'ipfs_version is defined' + become: true + become_user: '{{ ipfs_user }}' + block: + - name: Create directory tree if not exists + ansible.builtin.file: + path: '~/{{ item.path }}' + state: directory + mode: '{{ item.mode }}' + with_community.general.filetree: '../templates/ipfs/' + when: item.state == 'directory' + + - name: Create and copy hardening files + ansible.builtin.template: + src: '{{ item.src }}' + dest: '~/{{ item.path }}' + with_community.general.filetree: '../templates/ipfs/' + when: item.state == 'file' + + - name: Update ipfs-update version + ansible.builtin.shell: PATH=$PATH:$HOME/.local/bin ipfs-update versions + + - name: Install version + ansible.builtin.shell: PATH=$PATH:$HOME/.local/bin ipfs-update install {{ ipfs_version }} + + - include_tasks: "install_{{ ansible_service_mgr }}_service.yml" + + - name: Setup firewall + ansible.builtin.include_role: + name: iptables-ipfs diff --git a/roles/ipfs/templates/ipfs/.ipfs/api b/roles/ipfs/templates/ipfs/.ipfs/api new file mode 100644 index 0000000..e69de29 diff --git a/roles/ipfs/templates/systemd/lib/systemd/system/ipfs.service b/roles/ipfs/templates/systemd/lib/systemd/system/ipfs.service new file mode 100644 index 0000000..e256157 --- /dev/null +++ b/roles/ipfs/templates/systemd/lib/systemd/system/ipfs.service @@ -0,0 +1,57 @@ +[Unit] +Description=IPFS Daemon +Documentation=https://docs.ipfs.io/ +After=network.target + +[Service] +# hardening +ReadWritePaths=/home/ipfs /mnt/ipfs +NoNewPrivileges=true +ProtectSystem=strict +ProtectKernelTunables=true +ProtectKernelModules=true +ProtectKernelLogs=true +PrivateDevices=true +DevicePolicy=closed +ProtectControlGroups=true +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK +ProtectHostname=true +PrivateTmp=true +ProtectClock=true +LockPersonality=true +RestrictNamespaces=true +RestrictRealtime=true +MemoryDenyWriteExecute=true +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=~@privileged +#ProtectHome=true +RemoveIPC=true +RestrictSUIDSGID=true +CapabilityBoundingSet=CAP_NET_BIND_SERVICE + +LimitNOFILE=8192 +#LimitNice=10 +MemoryAccounting=true +#MemoryHigh=768M +#MemoryMax=1024M +MemorySwapMax=0 +CPUAccounting=true +CPUQuota=40% +TimeoutStartSec=infinity + +Type=notify +Environment="IPFS_PATH=/mnt/ipfs" +Environment=IPFS_LOGGING="error" +Environment=IPFS_FD_MAX=8192 +ExecStart=/home/ipfs/.local/bin/ipfs daemon --init --enable-gc --migrate +User=ipfs +Group=ipfs +StateDirectory=ipfs +Restart=always +RestartSec=60 +KillMode=process +KillSignal=SIGINT + +[Install] +WantedBy=multi-user.target diff --git a/roles/ipfs/tests/inventory b/roles/ipfs/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/roles/ipfs/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/ipfs/tests/test.yml b/roles/ipfs/tests/test.yml new file mode 100644 index 0000000..6c352bd --- /dev/null +++ b/roles/ipfs/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - ipfs diff --git a/roles/ipfs/vars/main.yml b/roles/ipfs/vars/main.yml new file mode 100644 index 0000000..32a3988 --- /dev/null +++ b/roles/ipfs/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for ipfs diff --git a/roles/iptables-ipfs/README.md b/roles/iptables-ipfs/README.md index 9615f30..27710bd 100644 --- a/roles/iptables-ipfs/README.md +++ b/roles/iptables-ipfs/README.md @@ -11,7 +11,7 @@ Requirements Role Variables -------------- -- **iptables_ipfs_enabled** (boolean): Enable or disable IPFS rules +- **ipfs_enabled** (boolean): Enable or disable IPFS rules Dependencies ------------ diff --git a/roles/iptables-ipfs/defaults/main.yml b/roles/iptables-ipfs/defaults/main.yml index ad7c494..9533535 100644 --- a/roles/iptables-ipfs/defaults/main.yml +++ b/roles/iptables-ipfs/defaults/main.yml @@ -1,4 +1,2 @@ --- # defaults file for iptables-ipfs - -iptables_ipfs_enabled: false diff --git a/roles/iptables-ipfs/tasks/main.yml b/roles/iptables-ipfs/tasks/main.yml index 29898a5..de56cc8 100644 --- a/roles/iptables-ipfs/tasks/main.yml +++ b/roles/iptables-ipfs/tasks/main.yml @@ -4,7 +4,7 @@ - name: setup iptables for IPFS when: - "is_docker is not true" - - "iptables_ipfs_enabled is true" + - "ipfs_enabled is true" block: - name: Allow new, established packets on TCP/UDP port 4001 (IPFS) ansible.builtin.iptables: