initial commit

This commit is contained in:
HgO
2020-04-13 14:46:45 +02:00
commit 961498e32b
76 changed files with 2715 additions and 0 deletions

38
roles/common/README.md Normal file
View File

@@ -0,0 +1,38 @@
Role Name
=========
A brief description of the role goes here.
Requirements
------------
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
Role Variables
--------------
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
Dependencies
------------
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
Example Playbook
----------------
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
- hosts: servers
roles:
- { role: username.rolename, x: 42 }
License
-------
BSD
Author Information
------------------
An optional section for the role authors to include contact information, or a website (HTML is not allowed).

View File

@@ -0,0 +1,11 @@
---
# defaults file for common
node_exporter_path: /
node_exporter_port: 9100
node_exporter_public_port: "9180"
nginx_config_dir: /etc/nginx/conf.d
nginx_ssl_dir: /etc/nginx/ssl
ssh_config_dir: ~/.ssh
backup_targets: []

View File

@@ -0,0 +1,8 @@
- name: restart openssh
service:
name: ssh
state: restarted
- name: reload nginx
include_tasks: ../handlers/nginx.yml
when: nginx_started is not changed

View File

@@ -0,0 +1,7 @@
- name: Validate Nginx config
command: nginx -t
- name: Reload Nginx server
service:
name: nginx
state: reloaded

View File

@@ -0,0 +1,16 @@
- import_tasks: repos.yml
tags: repos
- import_tasks: users.yml
tags: users
- import_tasks: openssh.yml
tags: openssh
- import_tasks: ufw.yml
tags: firewall
- import_tasks: msmtp.yml
tags: smtp
- import_tasks: nginx.yml
tags: nginx
- import_tasks: node_exporter.yml
tags: node_exporter
#- import_tasks: backup.yml
# tags: backup

View File

@@ -0,0 +1,18 @@
---
# Install and configure SMTP relay
- name: Install msmtp
apt:
name:
- msmtp
- msmtp-mta
state: present
- name: Copy msmtp configuration
template:
src: msmtp/msmtprc.j2
dest: /etc/msmtprc
- name: Copy aliases
template:
src: msmtp/aliases.j2
dest: /etc/aliases

View File

@@ -0,0 +1,101 @@
---
# Install and configure Nginx
- name: Install htpasswd dependencies
apt:
name: python-passlib
state: present
- name: Install SSL dependencies
apt:
name: ssl-cert
state: present
- name: Install Nginx
apt:
name: nginx-full
state: present
- name: Create Nginx configuration directories
file:
path: "{{ config_dir }}"
state: directory
owner: root
group: www-data
mode: "755"
loop:
- "{{ nginx_config_dir }}"
- "{{ nginx_ssl_dir }}"
loop_control:
loop_var: config_dir
- name: Generate Diffie-Hellman parameters
# This can take a long time... So we are doing it in async mode
openssl_dhparam:
path: "{{ nginx_ssl_dir }}/dhparam.pem"
size: 3072
owner: root
group: www-data
async: 3600
poll: 0
register: nginx_dh
- name: Use snakoil cert key as Nginx's default private key
file:
src: "/etc/ssl/private/ssl-cert-snakeoil.key"
path: "{{ nginx_ssl_dir }}/nginx.key"
state: link
owner: root
group: www-data
mode: "750"
force: yes
- name: Use snakoil cert as Nginx's default certificate
file:
src: "/etc/ssl/certs/ssl-cert-snakeoil.pem"
path: "{{ nginx_ssl_dir }}/nginx.crt"
state: link
owner: root
group: www-data
mode: "755"
force: yes
- name: Copy default Nginx config
template:
src: nginx/default.conf.j2
dest: /etc/nginx/sites-available/default
owner: root
group: www-data
mode: "755"
notify: reload nginx
- name: Enable default Nginx config
file:
src: /etc/nginx/sites-available/default
dest: /etc/nginx/sites-enabled/default
owner: root
group: www-data
mode: "755"
notify: reload nginx
- name: Allow default Nginx ports
ufw:
rule: allow
name: "Nginx Full"
- name: Waiting for Diffie-Hellman task to complete…
async_status:
jid: "{{ nginx_dh.ansible_job_id }}"
register: nginx_dh_job
retries: 60
delay: 30 # will retry every 30s for 30min (60 retries)
until: nginx_dh_job.finished
- name: Start Nginx server
service:
name: nginx
state: started
enabled: yes
register: nginx_started
- name: "Trigger Nginx handlers"
meta: flush_handlers

View File

@@ -0,0 +1,30 @@
---
# Install and configure node-exporter
- name: Include role for installing node-exporter
include_role:
name: cloudalchemy.node-exporter
public: yes
vars:
node_exporter_web_listen_address: "0.0.0.0:{{ node_exporter_port }}"
- name: Configure Nginx for node-exporter
import_role:
name: nginx
vars:
nginx_config_file: node-exporter.conf
nginx_server:
name: "{{ inventory_hostname }}"
port: "{{ node_exporter_public_port }}"
locations:
- path: "{{ node_exporter_path }}"
basic_auth:
file: .htpasswd.node-exporter
password: "{{ node_exporter_password }}"
proxy_pass:
port: "{{ node_exporter_port }}"
path: /metrics
- name: Allow node-exporter port {{ node_exporter_public_port }}
ufw:
rule: allow
port: "{{ node_exporter_public_port }}"

View File

@@ -0,0 +1,19 @@
---
# Configure OpenSSH server
- name: Configure OpenSSH server
template:
src: openssh/sshd_config.j2
dest: /etc/ssh/sshd_config
backup: yes
owner: "0"
group: "0"
mode: "0644"
validate: '/usr/sbin/sshd -T -f %s'
notify: restart openssh
- name: Trigger Ansible handlers
meta: flush_handlers
- name: Change Ansible SSH port to {{ openssh_port }}
set_fact:
ansible_port: "{{ openssh_port }}"

View File

@@ -0,0 +1,12 @@
---
# Configure APT repositories and automatic upgrades
- name: Safely upgrade the server
apt:
upgrade: safe
update_cache: yes
cache_valid_time: "3600"
- name: Install unattend-upgrades for automatic upgrades
apt:
name: unattended-upgrades
state: present

View File

@@ -0,0 +1,15 @@
---
# Install and configure UFW, the uncomplicated firewall
- name: Install UFW, the uncomplicated firewall
apt:
name: ufw
state: present
- name: Allow OpenSSH port {{ openssh_port }}
ufw:
rule: allow
port: "{{ openssh_port }}"
- name: Enable UFW config
ufw:
state: enabled

View File

@@ -0,0 +1,22 @@
---
# Create an user and add their SSH public keys
- name: Create user {{ user.name }} with no password
user:
name: "{{ user.name }}"
shell: /bin/bash
# See https://unix.stackexchange.com/questions/193066/how-to-unlock-account-for-public-key-ssh-authorization-but-not-for-password-aut/193131#193131
password: '*'
groups:
- sudo
append: yes
state: present
update_password: on_create
- name: Add SSH public keys for user {{ user.name }}
authorized_key:
user: "{{ user.name }}"
state: present
# we can pass multiple SSH keys, but they must be separated by newlines
key: "{{ user.ssh_keys | join('\n') }}"
# remove obsolete keys
exclusive: yes

View File

@@ -0,0 +1,28 @@
---
# Create users and add their SSH public keys
- name: Install sudo package
package:
name: sudo
state: present
tags: sudo
- name: Remove password to become root with sudo
lineinfile:
path: /etc/sudoers
state: present
regexp: '^%sudo'
line: '%sudo ALL=(ALL) NOPASSWD: ALL'
validate: 'visudo -cf %s'
tags: sudo
- name: Remove password for root user
user:
name: root
shell: /bin/bash
state: present
- name: Create users and add their SSH public keys
include_tasks: user.yml
loop: "{{ users }}"
loop_control:
loop_var: user

View File

@@ -0,0 +1 @@
default: {{ smtp_default_contact }}

View File

@@ -0,0 +1,19 @@
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log
{% for account in smtp_accounts %}
account {{ account.name }}
host {{ account.host }}
port 587
from {{ account.from }}
user {{ account.user | default(account.from) }}
password {{ account.password }}
{% endfor %}
account default : {{ smtp_default_account }}
aliases /etc/aliases

View File

@@ -0,0 +1,62 @@
{{ ansible_managed | comment }}
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/default;
server_name _;
location ^~ /.well-known/acme-challenge/ {
allow all;
root /var/www/acme;
try_files $uri =404;
}
location / {
try_files $uri $uri/ =404;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
expires 7d;
log_not_found off;
access_log off;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location ~ /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
server {
listen 443 default_server;
listen [::]:443 default_server;
server_name _;
include snippets/snakeoil.conf;
return 444;
}

View File

@@ -0,0 +1,31 @@
{{ ansible_managed | comment }}
{% if nginx_server_name is defined %}
server {
listen {{ nginx_port }};
server_name {{ nginx_server_name }};
{% endif %}
{% for location in nginx_locations %}
location {{ location }} {
{% if location.proxy_pass is defined %}
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
{% endif %}
{% if location.basic_auth_file is defined %}
auth_basic "Authentication required";
auth_basic_user_file /etc/nginx/{{ location.basic_auth_file }};
{% endif %}
{% if location.proxy_pass is defined %}
proxy_pass http://localhost:{{ location.proxy_pass.port | default('80') }}{{ location.proxy_pass.path }};
{% endif %}
}
{% endif %}
{% if nginx_server_name is defined %}
}
{% endif %}

View File

@@ -0,0 +1,17 @@
# {{ ansible_managed }}
Port {{ openssh_port }}
PermitRootLogin no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server

View File

@@ -0,0 +1,2 @@
---
# vars file for common