From b6e4d0fa4179b5005b4d1aa3782b4c355cdf79c8 Mon Sep 17 00:00:00 2001 From: jo Date: Thu, 7 Jul 2022 15:42:53 +0200 Subject: [PATCH] feat: ansible infra setup --- infra/.gitignore | 5 + infra/Makefile | 17 +++ infra/ansible.cfg | 26 ++++ infra/hcloud.yml | 5 + infra/host_vars/prod1.yml | 14 ++ infra/hosts.yml | 8 ++ infra/infra.yml | 38 ++++++ infra/requirements.txt | 5 + infra/requirements.yml | 10 ++ infra/roles/common/defaults/main.yml | 4 + infra/roles/common/tasks/main.yml | 41 ++++++ infra/roles/docker/defaults/main.yml | 2 + infra/roles/docker/handlers/main.yml | 5 + infra/roles/docker/tasks/main.yml | 44 ++++++ .../docker/templates/docker/daemon.json.j2 | 5 + infra/roles/firewall/handlers/main.yml | 5 + infra/roles/firewall/tasks/main.yml | 24 ++++ .../firewall/templates/firewalld/zone.xml.j2 | 10 ++ infra/roles/root/files/.bash_aliases | 1 + infra/roles/root/files/.bashrc | 114 ++++++++++++++++ infra/roles/root/tasks/main.yml | 16 +++ infra/roles/ssh/handlers/main.yml | 5 + infra/roles/ssh/tasks/main.yml | 19 +++ infra/roles/ssh/tasks/motd.yml | 28 ++++ infra/roles/ssh/templates/scripts/motd.sh | 18 +++ infra/roles/ssh/templates/ssh/sshd_config.j2 | 126 ++++++++++++++++++ infra/roles/web/handlers/main.yml | 5 + infra/roles/web/tasks/main.yml | 35 +++++ .../roles/web/templates/nginx/custom.conf.j2 | 12 ++ infra/site.yml | 18 +++ infra/tools/vault-password | 3 + 31 files changed, 668 insertions(+) create mode 100644 infra/.gitignore create mode 100644 infra/Makefile create mode 100644 infra/ansible.cfg create mode 100644 infra/hcloud.yml create mode 100644 infra/host_vars/prod1.yml create mode 100644 infra/hosts.yml create mode 100644 infra/infra.yml create mode 100644 infra/requirements.txt create mode 100644 infra/requirements.yml create mode 100644 infra/roles/common/defaults/main.yml create mode 100644 infra/roles/common/tasks/main.yml create mode 100644 infra/roles/docker/defaults/main.yml create mode 100644 infra/roles/docker/handlers/main.yml create mode 100644 infra/roles/docker/tasks/main.yml create mode 100644 infra/roles/docker/templates/docker/daemon.json.j2 create mode 100644 infra/roles/firewall/handlers/main.yml create mode 100644 infra/roles/firewall/tasks/main.yml create mode 100644 infra/roles/firewall/templates/firewalld/zone.xml.j2 create mode 100644 infra/roles/root/files/.bash_aliases create mode 100644 infra/roles/root/files/.bashrc create mode 100644 infra/roles/root/tasks/main.yml create mode 100644 infra/roles/ssh/handlers/main.yml create mode 100644 infra/roles/ssh/tasks/main.yml create mode 100644 infra/roles/ssh/tasks/motd.yml create mode 100755 infra/roles/ssh/templates/scripts/motd.sh create mode 100644 infra/roles/ssh/templates/ssh/sshd_config.j2 create mode 100644 infra/roles/web/handlers/main.yml create mode 100644 infra/roles/web/tasks/main.yml create mode 100644 infra/roles/web/templates/nginx/custom.conf.j2 create mode 100644 infra/site.yml create mode 100755 infra/tools/vault-password diff --git a/infra/.gitignore b/infra/.gitignore new file mode 100644 index 0000000..b73a748 --- /dev/null +++ b/infra/.gitignore @@ -0,0 +1,5 @@ +## Ansible .gitignore +################################################################################ + +.cache/ +.venv/ diff --git a/infra/Makefile b/infra/Makefile new file mode 100644 index 0000000..a7977d8 --- /dev/null +++ b/infra/Makefile @@ -0,0 +1,17 @@ +SHELL = bash +VENV = .venv + +all: $(VENV) + +install: $(VENV) +$(VENV): + python3 -m venv $(VENV) --upgrade-deps + $(VENV)/bin/pip install wheel + $(VENV)/bin/pip install -r requirements.txt + $(VENV)/bin/ansible-galaxy install -r requirements.yml + +lint: $(VENV) + $(VENV)/bin/ansible-lint --force-color + +clean: + git clean -xdf -e .vault diff --git a/infra/ansible.cfg b/infra/ansible.cfg new file mode 100644 index 0000000..4fc3919 --- /dev/null +++ b/infra/ansible.cfg @@ -0,0 +1,26 @@ +# Config file for ansible -- https://ansible.com/ +# =============================================== + +[defaults] +inventory = hcloud.yml, hosts.yml +host_key_checking = False + +stdout_callback = community.general.yaml + +fact_caching = memory + +retry_files_enabled = False + +interpreter_python = /usr/bin/python3 + +ask_vault_pass = False +vault_password_file = tools/vault-password + +[inventory] +enable_plugins = yaml, hetzner.hcloud.hcloud + +[privilege_escalation] +become_ask_pass = False + +[ssh_connection] +pipelining = True diff --git a/infra/hcloud.yml b/infra/hcloud.yml new file mode 100644 index 0000000..74b0c25 --- /dev/null +++ b/infra/hcloud.yml @@ -0,0 +1,5 @@ +--- +plugin: hetzner.hcloud.hcloud +keyed_groups: + - key: labels + separator: "" diff --git a/infra/host_vars/prod1.yml b/infra/host_vars/prod1.yml new file mode 100644 index 0000000..2dd7150 --- /dev/null +++ b/infra/host_vars/prod1.yml @@ -0,0 +1,14 @@ +--- +ansible_user: root + +# firewall +firewalld_zones: + public: + head: | + + + + + + + diff --git a/infra/hosts.yml b/infra/hosts.yml new file mode 100644 index 0000000..594ad8d --- /dev/null +++ b/infra/hosts.yml @@ -0,0 +1,8 @@ +--- +web: + hosts: + prod1: + +docker: + hosts: + prod1: diff --git a/infra/infra.yml b/infra/infra.yml new file mode 100644 index 0000000..6cbe041 --- /dev/null +++ b/infra/infra.yml @@ -0,0 +1,38 @@ +--- +- name: Setup servers + hosts: localhost + connection: local + vars: + ansible_python_interpreter: .venv/bin/python3 + tasks: + - name: Create server + hetzner.hcloud.hcloud_server: + name: prod1 + server_type: cx11 + image: debian-11 + location: fsn1 + labels: + production: "" + ssh_keys: + - jooola + state: present + + - name: Ensure the server is started + hetzner.hcloud.hcloud_server: + name: prod1 + state: started + register: server + + - name: Create server domain name + community.general.gandi_livedns: + api_key: "{{ lookup('ansible.builtin.env', 'GANDI_TOKEN') }}" + domain: libretime.org + record: prod1 + type: A + values: + - "{{ server.hcloud_server.ipv4_address }}" + ttl: 360 + state: present + + - name: Refresh inventory + ansible.builtin.meta: refresh_inventory diff --git a/infra/requirements.txt b/infra/requirements.txt new file mode 100644 index 0000000..762fe3f --- /dev/null +++ b/infra/requirements.txt @@ -0,0 +1,5 @@ +## Ansible +ansible-core>=2.14,<2.15 +ansible-lint>=6.14.4,<6.15 + +hcloud>=1.19.0,<1.20 diff --git a/infra/requirements.yml b/infra/requirements.yml new file mode 100644 index 0000000..f99f507 --- /dev/null +++ b/infra/requirements.yml @@ -0,0 +1,10 @@ +collections: + - name: community.general + source: git+https://github.com/ansible-collections/community.general + type: git + version: 6.5.0 + + - name: hetzner.hcloud + source: git+https://github.com/ansible-collections/hetzner.hcloud + type: git + version: 1.11.0 diff --git a/infra/roles/common/defaults/main.yml b/infra/roles/common/defaults/main.yml new file mode 100644 index 0000000..df2ff23 --- /dev/null +++ b/infra/roles/common/defaults/main.yml @@ -0,0 +1,4 @@ +--- +lang: en_US.UTF-8 +language: en_US:en +timezone: Europe/Berlin diff --git a/infra/roles/common/tasks/main.yml b/infra/roles/common/tasks/main.yml new file mode 100644 index 0000000..b98088f --- /dev/null +++ b/infra/roles/common/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: Set timezone + community.general.timezone: + name: "{{ timezone }}" + +- name: Install locale + community.general.locale_gen: + name: "{{ lang }}" + state: present + +- name: Check default locale + ansible.builtin.lineinfile: + dest: /etc/default/locale + line: "{{ item }}" + check_mode: true + with_items: + - "LANG={{ lang }}" + - "LANGUAGE={{ language }}" + register: default_locale + +- name: Set locale # noqa no-handler no-changed-when + when: default_locale is changed + ansible.builtin.command: update-locale LANG="{{ lang }}" LANGUAGE="en_US:en" + +- name: Install common packages + ansible.builtin.apt: + state: present + update_cache: true + name: + - apt-transport-https + - bzip2 + - curl + - git + - gpg + - rsync + - sudo + - unzip + - vim + - wget + - zip + - zsh diff --git a/infra/roles/docker/defaults/main.yml b/infra/roles/docker/defaults/main.yml new file mode 100644 index 0000000..764068a --- /dev/null +++ b/infra/roles/docker/defaults/main.yml @@ -0,0 +1,2 @@ +--- +docker_bridge_ip: 172.17.0.1/16 diff --git a/infra/roles/docker/handlers/main.yml b/infra/roles/docker/handlers/main.yml new file mode 100644 index 0000000..37b5807 --- /dev/null +++ b/infra/roles/docker/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart docker + ansible.builtin.systemd: + name: docker + state: restarted diff --git a/infra/roles/docker/tasks/main.yml b/infra/roles/docker/tasks/main.yml new file mode 100644 index 0000000..dbcffd5 --- /dev/null +++ b/infra/roles/docker/tasks/main.yml @@ -0,0 +1,44 @@ +--- +- name: Ensure apt keyrings directory exists + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + owner: root + group: root + mode: "0755" + +- name: Deploy apt repository key for docker # noqa command-instead-of-module risky-shell-pipe + ansible.builtin.shell: > + curl -sSL https://download.docker.com/linux/debian/gpg + | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg + args: + creates: /etc/apt/keyrings/docker-archive-keyring.gpg + +- name: Deploy apt repository for docker + ansible.builtin.apt_repository: + repo: > + deb + [signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] + https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable + state: present + +- name: Install docker + ansible.builtin.apt: + name: [docker-ce, docker-compose-plugin, docker-buildx-plugin] + state: present + +- name: Deploy docker daemon conf + ansible.builtin.template: + src: docker/daemon.json.j2 + dest: /etc/docker/daemon.json + owner: root + group: root + mode: "0644" + backup: true + notify: Restart docker + +- name: Enable/start docker daemon + ansible.builtin.systemd: + name: docker + state: started + enabled: true diff --git a/infra/roles/docker/templates/docker/daemon.json.j2 b/infra/roles/docker/templates/docker/daemon.json.j2 new file mode 100644 index 0000000..691a1ca --- /dev/null +++ b/infra/roles/docker/templates/docker/daemon.json.j2 @@ -0,0 +1,5 @@ +{ + "ipv6": false, + "bip": "{{ docker_bridge_ip }}", + "ip": "127.0.0.1" +} diff --git a/infra/roles/firewall/handlers/main.yml b/infra/roles/firewall/handlers/main.yml new file mode 100644 index 0000000..69b3a07 --- /dev/null +++ b/infra/roles/firewall/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart firewalld + ansible.builtin.systemd: + name: firewalld + state: reloaded diff --git a/infra/roles/firewall/tasks/main.yml b/infra/roles/firewall/tasks/main.yml new file mode 100644 index 0000000..a7c0381 --- /dev/null +++ b/infra/roles/firewall/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- name: Install firewalld + ansible.builtin.apt: + name: firewalld + state: present + +- name: Enable/start firewalld + ansible.builtin.systemd: + name: firewalld + state: started + enabled: true + +- name: Deploy firewalld conf + ansible.builtin.template: + src: firewalld/zone.xml.j2 + dest: /etc/firewalld/zones/{{ zone.key }}.xml + owner: root + group: root + mode: "0644" + with_dict: "{{ firewalld_zones }}" + loop_control: + loop_var: zone + label: "{{ zone.key }}" + notify: Restart firewalld diff --git a/infra/roles/firewall/templates/firewalld/zone.xml.j2 b/infra/roles/firewall/templates/firewalld/zone.xml.j2 new file mode 100644 index 0000000..eeee5d3 --- /dev/null +++ b/infra/roles/firewall/templates/firewalld/zone.xml.j2 @@ -0,0 +1,10 @@ + + + {{ zone.value.head | indent(2) }} +{% if zone.value.rules is defined %} +{% for rule in zone.value.rules %} + + {{ zone.value.rules[rule] | indent(2) }} +{% endfor %} +{% endif %} + diff --git a/infra/roles/root/files/.bash_aliases b/infra/roles/root/files/.bash_aliases new file mode 100644 index 0000000..ace2cc2 --- /dev/null +++ b/infra/roles/root/files/.bash_aliases @@ -0,0 +1 @@ +alias dc="docker compose" diff --git a/infra/roles/root/files/.bashrc b/infra/roles/root/files/.bashrc new file mode 100644 index 0000000..bfb2d72 --- /dev/null +++ b/infra/roles/root/files/.bashrc @@ -0,0 +1,114 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +case $- in + *i*) ;; + *) return ;; +esac + +# don't put duplicate lines or lines starting with space in the history. +# See bash(1) for more options +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# If set, the pattern "**" used in a pathname expansion context will +# match all files and zero or more directories and subdirectories. +#shopt -s globstar + +# make less more friendly for non-text input files, see lesspipe(1) +#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color | *-256color) color_prompt=yes ;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]: \[\033[01;34m\]\w\[\033[00m\] \$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h: \w \$ ' +fi +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in + xterm* | rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; + *) ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + alias dir='dir --color=auto' + alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# colored GCC warnings and errors +#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + +# some more ls aliases +alias ll='ls -l' +#alias la='ls -A' +#alias l='ls -CF' +alias lla='ls -al' +alias llr='ls -Rl' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi diff --git a/infra/roles/root/tasks/main.yml b/infra/roles/root/tasks/main.yml new file mode 100644 index 0000000..89c9028 --- /dev/null +++ b/infra/roles/root/tasks/main.yml @@ -0,0 +1,16 @@ +--- +- name: Create root user + ansible.builtin.user: + name: root + shell: /bin/bash + +- name: Deploy root files + ansible.builtin.copy: + src: "{{ item }}" + dest: "/root/{{ item }}" + owner: root + group: root + mode: "0644" + with_items: + - .bashrc + - .bash_aliases diff --git a/infra/roles/ssh/handlers/main.yml b/infra/roles/ssh/handlers/main.yml new file mode 100644 index 0000000..d76899b --- /dev/null +++ b/infra/roles/ssh/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart ssh + ansible.builtin.systemd: + name: ssh + state: restarted diff --git a/infra/roles/ssh/tasks/main.yml b/infra/roles/ssh/tasks/main.yml new file mode 100644 index 0000000..375b25e --- /dev/null +++ b/infra/roles/ssh/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: Deploy sshd_config + ansible.builtin.template: + src: "ssh/sshd_config.j2" + dest: /etc/ssh/sshd_config + owner: root + group: root + mode: "0644" + backup: true + notify: Restart ssh + +- name: Enable/start ssh + ansible.builtin.systemd: + name: ssh + state: started + enabled: true + +- name: Setup motd + ansible.builtin.import_tasks: motd.yml diff --git a/infra/roles/ssh/tasks/motd.yml b/infra/roles/ssh/tasks/motd.yml new file mode 100644 index 0000000..16cea58 --- /dev/null +++ b/infra/roles/ssh/tasks/motd.yml @@ -0,0 +1,28 @@ +--- +- name: Remove old motd files + ansible.builtin.file: + path: "{{ item }}" + state: absent + with_items: + - /etc/motd + - /etc/motd.tail + - /etc/update-motd.d/10-uname + +- name: Deploy motd files + ansible.builtin.template: + src: scripts/motd.sh + dest: /etc/update-motd.d/50-body + owner: root + group: root + mode: "0755" + +- name: Clear motd issue + ansible.builtin.copy: + content: "" + dest: "{{ item }}" + owner: root + group: root + mode: "0644" + with_items: + - /etc/issue + - /etc/issue.net diff --git a/infra/roles/ssh/templates/scripts/motd.sh b/infra/roles/ssh/templates/scripts/motd.sh new file mode 100755 index 0000000..4f61298 --- /dev/null +++ b/infra/roles/ssh/templates/scripts/motd.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# Colors +dark='\e[30m' +# red='\e[31m' +# green='\e[32m' +# purple='\e[35m' +cyan='\e[36m' +reset='\e[39m' + +# Data +hostname=$(hostname) +distrib=$(lsb_release -s -d) +kernel_version=$(uname -r) + +echo +echo -e "Welcome on $cyan$hostname$reset $dark($distrib $kernel_version)$reset" +echo diff --git a/infra/roles/ssh/templates/ssh/sshd_config.j2 b/infra/roles/ssh/templates/ssh/sshd_config.j2 new file mode 100644 index 0000000..bc80cda --- /dev/null +++ b/infra/roles/ssh/templates/ssh/sshd_config.j2 @@ -0,0 +1,126 @@ +# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options override the +# default value. + +Include /etc/ssh/sshd_config.d/*.conf + +#Port 22 +#AddressFamily any +#ListenAddress 0.0.0.0 +#ListenAddress :: + +#HostKey /etc/ssh/ssh_host_rsa_key +#HostKey /etc/ssh/ssh_host_ecdsa_key +#HostKey /etc/ssh/ssh_host_ed25519_key + +# Ciphers and keying +#RekeyLimit default none + +# Logging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 2m +PermitRootLogin prohibit-password +#StrictModes yes +#MaxAuthTries 6 +#MaxSessions 10 + +#PubkeyAuthentication yes + +# Expect .ssh/authorized_keys2 to be disregarded by default in future. +#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 + +#AuthorizedPrincipalsFile none + +#AuthorizedKeysCommand none +#AuthorizedKeysCommandUser nobody + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +#HostbasedAuthentication no +# Change to yes if you don't trust ~/.ssh/known_hosts for +# HostbasedAuthentication +#IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# To disable tunneled clear text passwords, change to no here! +#PasswordAuthentication yes +PasswordAuthentication no +#PermitEmptyPasswords no + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication no + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes +#GSSAPIStrictAcceptorCheck yes +#GSSAPIKeyExchange no + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM yes + +#AllowAgentForwarding yes +#AllowTcpForwarding yes +#GatewayPorts no +#X11Forwarding yes +X11Forwarding no +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PermitTTY yes +PrintMotd no +#PrintLastLog yes +PrintLastLog no +#TCPKeepAlive yes +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS no +#PidFile /var/run/sshd.pid +#MaxStartups 10:30:100 +#PermitTunnel no +#ChrootDirectory none +#VersionAddendum none + +# no default banner path +#Banner none + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +# override default of no subsystems +Subsystem sftp /usr/lib/openssh/sftp-server + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# PermitTTY no +# ForceCommand cvs server diff --git a/infra/roles/web/handlers/main.yml b/infra/roles/web/handlers/main.yml new file mode 100644 index 0000000..4cbd8de --- /dev/null +++ b/infra/roles/web/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart nginx + ansible.builtin.systemd: + name: nginx + state: restarted diff --git a/infra/roles/web/tasks/main.yml b/infra/roles/web/tasks/main.yml new file mode 100644 index 0000000..e0fcf83 --- /dev/null +++ b/infra/roles/web/tasks/main.yml @@ -0,0 +1,35 @@ +--- +- name: Install nginx + ansible.builtin.apt: + name: [nginx] + state: present + +- name: Install certbot + ansible.builtin.apt: + name: [certbot, python3-certbot-nginx] + state: present + +- name: Deploy nginx files + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "0644" + backup: true + with_items: + - src: nginx/custom.conf.j2 + dest: /etc/nginx/conf.d/custom.conf + notify: Restart nginx + +- name: Disable default vhost + ansible.builtin.file: + path: /etc/nginx/sites-enabled/default + state: absent + notify: Restart nginx + +- name: Enable/start nginx + ansible.builtin.systemd: + name: nginx + state: started + enabled: true diff --git a/infra/roles/web/templates/nginx/custom.conf.j2 b/infra/roles/web/templates/nginx/custom.conf.j2 new file mode 100644 index 0000000..2a98f82 --- /dev/null +++ b/infra/roles/web/templates/nginx/custom.conf.j2 @@ -0,0 +1,12 @@ +## +# Custom Settings +## + +# Prevent redirecting url with port +port_in_redirect off; + +# Remove X-Powered-By, which is an information leak +fastcgi_hide_header X-Powered-By; + +# Remove server information +server_tokens off; diff --git a/infra/site.yml b/infra/site.yml new file mode 100644 index 0000000..13f13cc --- /dev/null +++ b/infra/site.yml @@ -0,0 +1,18 @@ +--- +- name: Install servers + hosts: production + roles: + - common + - root + - ssh + - firewall + +- name: Install webservers + hosts: web + roles: + - web + +- name: Install docker + hosts: docker + roles: + - docker diff --git a/infra/tools/vault-password b/infra/tools/vault-password new file mode 100755 index 0000000..95fe5d2 --- /dev/null +++ b/infra/tools/vault-password @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +echo "$ANSIBLE_VAULT_PASSWORD"