Browse Source

Add Ansible PoC stuff

Clément Gibaud 2 years ago
parent
commit
e6e5ae9d2f

+ 6
- 0
.gitignore View File

@@ -0,0 +1,6 @@
1
+/.vault_password
2
+/.vagrant
3
+/roles/ansible-*
4
+*.retry
5
+/ubuntu-*.log
6
+/.terraform*

+ 13
- 1
README.md View File

@@ -1,2 +1,14 @@
1
-# ansible
1
+# Ansible Netfreaks stream
2 2
 
3
+## Bootstrap on lab
4
+
5
+```bash
6
+./playbooks/00_bootstrap.yml -uroot -i inventories/lab/ -e 'apt_get_upgrade=true'
7
+./playbooks/01_baseline.yml -uroot -i inventories/lab/
8
+```
9
+
10
+## Deploy stack on lab
11
+
12
+```bash
13
+./playbooks/03_stream_stack.yml -i inventories/lab/
14
+```

+ 119
- 0
ansible.cfg View File

@@ -0,0 +1,119 @@
1
+# config file for ansible -- http://ansible.github.com
2
+# nearly all parameters can be overridden in ansible-playbook or with command line flags
3
+# ansible will read ~/.ansible.cfg or /etc/ansible/ansible.cfg, whichever it finds first
4
+
5
+[defaults]
6
+
7
+# location of inventory file, eliminates need to specify -i
8
+inventory = ./inventories/
9
+
10
+roles_path = ./roles:./local
11
+#gathering = smart
12
+fact_caching = memory
13
+fact_caching_timeout = 86400
14
+
15
+vault_password_file = ./.vault_password
16
+retry_files_enabled = False
17
+
18
+# location of ansible library, eliminates need to specify --module-path
19
+# library = /usr/share/ansible
20
+# hash_behaviour = merge
21
+
22
+# default module name used in /usr/bin/ansible when -m is not specified
23
+module_name = command
24
+
25
+# home directory where temp files are stored on remote systems.  Should
26
+# almost always contain $HOME or be a directory writeable by all users
27
+#remote_tmp = $HOME/.ansible/tmp
28
+remote_tmp = /tmp
29
+
30
+# the default pattern for ansible-playbooks ("hosts:")
31
+pattern = *
32
+
33
+# the default number of forks (parallelism) to be used.  Usually you
34
+# can crank this up.
35
+forks=20
36
+
37
+# the timeout used by various connection types.  Usually this corresponds
38
+# to an SSH timeout
39
+timeout=10
40
+
41
+# when using --poll or "poll:" in an ansible playbook, and not specifying
42
+# an explicit poll interval, use this interval
43
+poll_interval=15
44
+
45
+# when specifying --sudo to /usr/bin/ansible or "sudo:" in a playbook,
46
+# and not specifying "--sudo-user" or "sudo_user" respectively, sudo
47
+# to this user account
48
+become_user=root
49
+
50
+# the following forces ansible to always ask for the sudo password (instead of having
51
+# to add -K to the commandline). Or you can use the environment variable (ANSIBLE_ASK_SUDO_PASS)
52
+#ask_sudo_pass=True
53
+become_ask_pass=True
54
+
55
+# the following forces ansible to always ask for the ssh-password (-k)
56
+# can also be set by the environment variable ANSIBLE_ASK_PASS
57
+#ask_pass=True
58
+
59
+# connection to use when -c <connection_type> is not specified
60
+#transport=paramiko
61
+transport=ssh
62
+
63
+# remote SSH port to be used when --port or "port:" or an equivalent inventory
64
+# variable is not specified.
65
+remote_port=22
66
+
67
+# if set, always run /usr/bin/ansible commands as this user, and assume this value
68
+# if "user:" is not set in a playbook.  If not set, use the current Unix user
69
+# as the default
70
+remote_user=netfreaks
71
+
72
+# if set, always use this private key file for authentication, same as if passing
73
+# --private-key to ansible or ansible-playbook
74
+#private_key_file=/path/to/file
75
+
76
+host_key_checking=false
77
+
78
+jinja2_extensions=jinja2.ext.do
79
+
80
+error_on_undefined_vars=True
81
+# format of string $ansible_managed available within Jinja2 templates, replacing
82
+# {file}, {host} and {uid} with template filename, host and owner respectively.
83
+# The resulting string is passed through strftime(3) so it may contain any
84
+# time-formatting specifiers.
85
+#
86
+# Example: ansible_managed = DONT TOUCH {file}: call {uid} at {host} for changes
87
+ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
88
+
89
+# additional plugin paths for non-core plugins
90
+
91
+#action_plugins     = /usr/share/ansible_plugins/action_plugins
92
+#callback_plugins   = /usr/share/ansible_plugins/callback_plugins
93
+#connection_plugins = /usr/share/ansible_plugins/connection_plugins
94
+#lookup_plugins     = /usr/share/ansible_plugins/lookup_plugins
95
+#vars_plugins       = /usr/share/ansible_plugins/vars_plugins
96
+#callback_whitelist = profile_tasks,grafana_annotations
97
+#callback_whitelist = profile_roles
98
+#allow_world_readable_tmpfiles = True
99
+
100
+[paramiko_connection]
101
+
102
+# nothing to configure yet
103
+
104
+[ssh_connection]
105
+
106
+# if uncommented, sets the ansible ssh arguments to the following.  Leaving off ControlPersist
107
+# will result in poor performance, so use transport=paramiko on older platforms rather than
108
+# removing it
109
+
110
+#ssh_args=-o PasswordAuthentication=no -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r
111
+ssh_args=-o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r
112
+
113
+# the following makes ansible use scp if the connection type is ssh (default is sftp)
114
+
115
+pipelining=True
116
+
117
+scp_if_ssh=True
118
+
119
+

+ 63
- 0
inventories/common.yml View File

@@ -0,0 +1,63 @@
1
+# Netfreaks
2
+
3
+admin_mail: letsencrypt@gibaud.info
4
+
5
+# External roles
6
+
7
+## baseline users
8
+
9
+baseline_users:
10
+  - name: netfreaks
11
+    group: netfreaks
12
+    groups:
13
+      - sudo
14
+  - name: clement
15
+    group: netfreaks
16
+    groups:
17
+      - sudo
18
+
19
+## Certbot
20
+certbot_create_if_missing: true
21
+certbot_create_method: standalone
22
+certbot_admin_email: "{{ admin_mail }}"
23
+certbot_certs:
24
+  - email: "{{ certbot_admin_email }}"
25
+    domains:
26
+      - "{{ inventory_hostname }}"
27
+
28
+## Haproxy
29
+
30
+haproxy_filter_allow_stats:
31
+  - 89.234.140.140
32
+haproxy_global_stats_socket: /var/run/haproxy/admin.sock
33
+haproxy_stats_username: netfreaks
34
+haproxy_stats_password: !vault |
35
+  $ANSIBLE_VAULT;1.1;AES256
36
+  30366161343735333632646630386336353566653736326162343064616232333632396433346531
37
+  3164663235373463313638396532343937303436363365610a363230623139356539646163656130
38
+  31356465363663333535663830326430613030613665653732616532326332623166623438303761
39
+  6630306561613137610a336130316230636338326163323837313762653239306232646665363535
40
+  39366262303063333532373865626338333665333137333339366164633862616633
41
+haproxy_stats_port: 9090
42
+haproxy_pem_path: "/etc/haproxy/certs/{{ inventory_hostname }}.pem"
43
+
44
+## SSH
45
+
46
+ssh_allow:
47
+  - 89.234.140.140 
48
+ssh_allow_users:
49
+  - netfreaks
50
+  - clement
51
+ssh_keys:
52
+  - { name: clement_eddsa, user: clement, key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICYF0x4D7h6rFybKWg798gTTDKfcjVGq/ucMxjOk956c clement@silicium" }
53
+  - { name: clement_eddsa, user: netfreaks, key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICYF0x4D7h6rFybKWg798gTTDKfcjVGq/ucMxjOk956c clement@silicium" }
54
+  - { name: netfreaks_ecdsa_passhport, user: netfreaks, key: "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFr7CkskGwOcLV0F8b14xLfmPjG42mPGDp4jn0ZexMkeTiMJbo393BPrOt8RWvi7YcZmPilJJtkDUxFltqbB90gFgDE7NoLE+aV5mDo1WkkEyeBkkcntH+qYgTDJ/KZAZaUGaTErAczaI1q0/6vCb3krMmrAQ36LZAOI7YfhXdiM0G/hA== passhport@vps809106" }
55
+ssh_port: 22
56
+ferm_enabled: false
57
+
58
+## Local role
59
+
60
+### Frontstream
61
+
62
+frontstream_nginx_port: 8099
63
+frontstream_deploy_path: "/home/netfreaks/frontstream/"

+ 1
- 0
inventories/lab/group_vars/all/00_common.yml View File

@@ -0,0 +1 @@
1
+../../../common.yml

+ 0
- 0
inventories/lab/group_vars/all/99_all.yml View File


+ 0
- 0
inventories/lab/group_vars/all/frontstream/vars.yml View File


+ 0
- 0
inventories/lab/group_vars/all/stream/vars.yml View File


+ 10
- 0
inventories/lab/hosts View File

@@ -0,0 +1,10 @@
1
+frontstream.netfreaks.lab.gibaud.info
2
+stream0.netfreaks.lab.gibaud.info
3
+stream1.netfreaks.lab.gibaud.info
4
+
5
+[frontstream]
6
+frontstream.netfreaks.lab.gibaud.info
7
+
8
+[stream]
9
+stream0.netfreaks.lab.gibaud.info
10
+stream1.netfreaks.lab.gibaud.info

+ 1
- 0
inventories/prod/group_vars/all/00_common.yml View File

@@ -0,0 +1 @@
1
+../../../common.yml

+ 0
- 0
inventories/prod/group_vars/all/99_all.yml View File


+ 0
- 0
inventories/prod/group_vars/all/frontstream/vars.yml View File


+ 0
- 0
inventories/prod/group_vars/all/stream/vars.yml View File


+ 12
- 0
inventories/prod/hosts View File

@@ -0,0 +1,12 @@
1
+frontstream.netfreaks.fr
2
+stream1.netfreaks.fr
3
+stream2.netfreaks.fr
4
+stream3.netfreaks.fr
5
+
6
+[frontstream]
7
+frontstream.netfreaks.fr
8
+
9
+[stream]
10
+stream1.netfreaks.fr
11
+stream2.netfreaks.fr
12
+stream3.netfreaks.fr

+ 4
- 0
local/role-frontstream/handlers/main.yml View File

@@ -0,0 +1,4 @@
1
+- name: Reload nginx
2
+  service:
3
+    name: nginx
4
+    state: reloaded

+ 10
- 0
local/role-frontstream/tasks/certificates.yml View File

@@ -0,0 +1,10 @@
1
+- name: Create HAproxy cert directory if it doesn't exist
2
+  file:
3
+    path: /etc/haproxy/certs/
4
+    state: directory
5
+
6
+- name: Create PEM bundle for HAproxy
7
+  assemble:
8
+    src: /etc/letsencrypt/live/{{ inventory_hostname }}
9
+    dest: /etc/haproxy/certs/{{ inventory_hostname }}.pem
10
+    regexp: 'privkey.*|fullchain.*'

+ 5
- 0
local/role-frontstream/tasks/demo.yml View File

@@ -0,0 +1,5 @@
1
+- name: Adds demo homepage
2
+  template:
3
+    src: demo.index.html.j2
4
+    dest: "{{ frontstream_deploy_path }}/current/index.html"
5
+    backup: yes

+ 61
- 0
local/role-frontstream/tasks/glue.yml View File

@@ -0,0 +1,61 @@
1
+- name: Ensure frontstream directory exist
2
+  file:
3
+    path: "{{ frontstream_deploy_path }}/current"
4
+    state: directory
5
+
6
+- name: Deploys fronstream nginx config
7
+  template:
8
+    src: nginx-frontstream.conf.j2
9
+    dest: /etc/nginx/sites-available/frontstream.conf
10
+    mode: 0644
11
+    backup: yes
12
+  notify: Reload nginx
13
+  tags:
14
+    - nginx
15
+    - nginx:config
16
+
17
+- name: Symlinks frontstream nginx config
18
+  file:
19
+    src: /etc/nginx/sites-available/frontstream.conf
20
+    dest: /etc/nginx/sites-enabled/frontstream
21
+    state: link
22
+  tags:
23
+    - nginx
24
+    - nginx:config
25
+  notify: Reload nginx
26
+
27
+- name: Deploys stream nginx config
28
+  template:
29
+    src: nginx-stream.conf.j2
30
+    dest: /etc/nginx/sites-available/stream.conf
31
+    mode: 0644
32
+    backup: yes
33
+  notify: Reload nginx
34
+  tags:
35
+    - nginx
36
+    - nginx:config
37
+
38
+- name: Symlinks stream nginx config
39
+  file:
40
+    src: /etc/nginx/sites-available/stream.conf
41
+    dest: /etc/nginx/sites-enabled/stream
42
+    state: link
43
+  tags:
44
+    - nginx
45
+    - nginx:config
46
+  notify: Reload nginx
47
+
48
+- name: Adds haproxy config
49
+  template:
50
+    src: haproxy.conf.j2
51
+    dest: /etc/haproxy/conf.d/netfreaks.cfg
52
+    backup: yes
53
+  notify: Reload haproxy
54
+  tags:
55
+    - haproxy
56
+
57
+# - name: Adds telegraf to haproxy group
58
+#   user:
59
+#     name: telegraf
60
+#     append: yes
61
+#     groups: haproxy

+ 15
- 0
local/role-frontstream/tasks/main.yml View File

@@ -0,0 +1,15 @@
1
+# Glue configurations
2
+- include: certificates.yml
3
+  become: true
4
+  tags:
5
+    - certs
6
+
7
+- include: glue.yml
8
+  become: true
9
+  tags:
10
+    - config
11
+
12
+- include: demo.yml
13
+  become: true
14
+  tags:
15
+    - demo

+ 3
- 0
local/role-frontstream/templates/demo.index.html.j2 View File

@@ -0,0 +1,3 @@
1
+<h1>Hello, i'm {{ inventory_hostname }} !</h1>
2
+
3
+<a href="/stream">Give me to stream !</a>

+ 163
- 0
local/role-frontstream/templates/haproxy.conf.j2 View File

@@ -0,0 +1,163 @@
1
+{% macro dos_protection() -%}
2
+  # ~~~ DoS protection ~~~
3
+  # HAproxy tracks client IPs into a global stick table. Each IP is
4
+  # stored for a limited amount of time, with several counters attached
5
+  # to it. When a new connection comes in, the stick table is evaluated
6
+  # to verify that the new connection from this client is allowed to
7
+  # continue.
8
+
9
+  # Stick Table Definitions
10
+  #  - conn_cur: count active connections
11
+  #  - conn_rate(3s): average incoming connection rate over 3 seconds
12
+  #  - http_err_rate(10s): Monitors the number of errors generated by an IP over a period of 10 seconds
13
+  #  - http_req_rate(10s): Monitors the number of request sent by an IP over a period of 10 seconds
14
+  stick-table type ip size 500k expire 1m store gpc0,conn_cur,conn_rate(3s),http_req_rate(10s),http_err_rate(10s)
15
+  tcp-request connection track-sc1 src
16
+
17
+  # Whitelist friends
18
+  acl rate_limit_whitelist src -f /etc/haproxy/whitelist
19
+  http-request allow if rate_limit_whitelist
20
+
21
+  # TARPIT the new connection if the client already has N opened
22
+  http-request tarpit if { src_conn_cur ge {{ frontstream_haproxy_ip_max_open_connections | default(10) }} }
23
+
24
+  # TARPIT the new connection if the client has opened more than N connections in 3 seconds
25
+  http-request tarpit if { src_conn_rate ge {{ frontstream_haproxy_ip_max_connection_rate_3s | default(20) }} }
26
+
27
+  # TARPIT the connection if the client has passed the HTTP error rate (10s)
28
+  http-request tarpit if { sc0_http_err_rate() gt {{ frontstream_haproxy_ip_max_error_rate_10s | default(10) }} }
29
+
30
+  # TARPIT the connection if the client has passed the HTTP request rate (10s)
31
+  http-request tarpit if { sc0_http_req_rate() gt {{ frontstream_haproxy_ip_max_http_request_rate_10s | default(300) }} }
32
+{%- endmacro %}
33
+
34
+{% macro block_bad_requests() -%}
35
+  # ~~~ Bad Requests protection ~~~
36
+
37
+  acl FORBIDDEN_HDR hdr_cnt(host) gt 1
38
+  acl FORBIDDEN_HDR hdr_cnt(content-length) gt 1
39
+  acl FORBIDDEN_HDR hdr_val(content-length) lt 0
40
+  acl FORBIDDEN_HDR hdr_cnt(proxy-authorization) gt 0
41
+  acl FORBIDDEN_HDR hdr_cnt(x-xsrf-token) gt 1
42
+  acl FORBIDDEN_HDR hdr_len(x-xsrf-token) gt 36
43
+  http-request tarpit if FORBIDDEN_HDR
44
+
45
+  acl FORBIDDEN_URI url_reg -i .*(\.|%2e)(\.|%2e)(%2f|%5c|/|\\\\)
46
+  acl FORBIDDEN_URI url_sub -i %00 <script xmlrpc.php
47
+  acl FORBIDDEN_URI path_beg /_search /_nodes /send_mail_ami /wp-login
48
+  acl FORBIDDEN_URI path_end -i .ida .asp .dll .exe .sh .pl .py .so .htaccess
49
+  acl FORBIDDEN_URI path_dir -i chat phpbb sumthin horde _vti_bin MSOffice
50
+  http-request tarpit if FORBIDDEN_URI
51
+
52
+  # TARPIT requests with more than 10 Range headers
53
+  acl WEIRD_RANGE_HEADERS hdr_cnt(Range) gt 10
54
+  http-request tarpit if WEIRD_RANGE_HEADERS
55
+
56
+  # Just keep GET HEAD POST OPTIONS methods
57
+  http-request tarpit unless METH_GET or METH_POST or METH_OPTIONS or METH_HEAD
58
+
59
+  # Drop POST without content-length
60
+  acl MISSING_CONTENT_LENGTH hdr_cnt(content-length) eq 0
61
+  http-request tarpit if MISSING_CONTENT_LENGTH METH_POST
62
+
63
+  # Drop urls star without OPTIONS
64
+  http-request tarpit if HTTP_URL_STAR !METH_OPTIONS
65
+{%- endmacro %}
66
+
67
+{% macro block_httpoxy() -%}
68
+  # ~~~ Block HTTPoxy ~~~
69
+  # https://www.digitalocean.com/community/tutorials/how-to-protect-your-server-against-the-httpoxy-vulnerability
70
+
71
+  http-request del-header Proxy
72
+{%- endmacro %}
73
+
74
+{% macro block_slowloris(timeout) -%}
75
+  # ~~~ Block SlowLoris ~~~
76
+  # The timing only applies to headers
77
+  timeout http-request {{ timeout }}s
78
+{%- endmacro %}
79
+
80
+{% macro block_slowpost() -%}
81
+  # ~~~ Block Slow Post ~~~
82
+  # NOT AVAILABLE IN 1.5.x
83
+
84
+  # Buffer request so timeout http-request works on whole request
85
+  option http-buffer-request
86
+  timeout http-request 10s
87
+{%- endmacro %}
88
+
89
+#######################################
90
+#                                     #
91
+#          Ansible Managed            #
92
+#          role-frontstream           #
93
+#      templates/haproxy.conf.j2      #
94
+#                                     #
95
+#######################################
96
+
97
+global
98
+  tune.ssl.default-dh-param 2048
99
+
100
+  ssl-default-bind-options no-sslv3 no-tls-tickets
101
+  ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
102
+
103
+  ssl-default-server-options no-sslv3 no-tls-tickets
104
+  ssl-default-server-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
105
+
106
+userlist netfreaks
107
+  group netfreaks users {{ haproxy_stats_username }}
108
+  user {{ haproxy_stats_username }} insecure-password {{ haproxy_stats_password }}
109
+
110
+frontend netfreaks
111
+  mode http
112
+
113
+  # HTTP
114
+  bind *:80
115
+
116
+  # HTTPS
117
+  bind *:443 ssl crt {{ haproxy_pem_path }}
118
+
119
+  maxconn 4000
120
+
121
+  option http-server-close
122
+  option forwardfor
123
+
124
+  # errorfile 503 /etc/haproxy/errors/503.http
125
+
126
+  {# dos_protection() #}
127
+
128
+  {{ block_bad_requests() }}
129
+
130
+  {{ block_httpoxy() }}
131
+
132
+  {{ block_slowloris(5) }}
133
+
134
+  {{ block_slowpost() }}
135
+
136
+  http-request set-header X-Forwarded-Proto https if { ssl_fc }
137
+
138
+  redirect scheme https code 301 if !{ ssl_fc }
139
+
140
+  
141
+  acl is_stream path -i -m beg /stream
142
+  use_backend bk_stream if is_stream
143
+  use_backend bk_frontstream
144
+
145
+backend bk_frontstream
146
+  balance leastconn
147
+  timeout connect 15s
148
+  timeout server 5s
149
+  http-response del-header Server
150
+  server nginx_frontstream 127.0.0.1:{{ frontstream_nginx_port }} check weight 200 inter 5s backup
151
+
152
+{% set port = [8080] %}
153
+
154
+backend bk_stream
155
+  balance roundrobin
156
+  timeout connect 15s
157
+  timeout server 5s
158
+  http-response del-header Server
159
+{% for stream in groups['stream'] %}
160
+  server {{ stream }} 127.0.0.1:{{ port | replace(']', '') | replace('[', '')}} check weight 200 inter 5s backup
161
+{% if port.append(port.pop() + 1) %}{% endif %}
162
+
163
+{% endfor %}

+ 79
- 0
local/role-frontstream/templates/nginx-frontstream.conf.j2 View File

@@ -0,0 +1,79 @@
1
+log_format netfreaks '"$http_x_forwarded_for" $remote_addr $remote_user $host [$time_local] '
2
+                     '"$request" $status $body_bytes_sent '
3
+                     'rt=$request_time uct=$upstream_connect_time uht=$upstream_header_time '
4
+                     'urt=$upstream_response_time ucs=$upstream_cache_status '
5
+                     '"$sent_http_content_type" "$http_referer" "$http_user_agent"';
6
+
7
+map $request $dolog {
8
+    ~*health 0;
9
+    default 1;
10
+}
11
+
12
+server {
13
+    server_name {{ inventory_hostname }};
14
+    listen 127.0.0.1:{{ frontstream_nginx_port }};
15
+    root {{ frontstream_deploy_path }}/current/;
16
+
17
+    real_ip_header X-Forwarded-For;
18
+    real_ip_recursive on;
19
+
20
+    set_real_ip_from 127.0.0.1;
21
+
22
+    location = /favicon.ico {
23
+        log_not_found off;
24
+        access_log off;
25
+    }
26
+
27
+    location = /robots.txt {
28
+        allow all;
29
+        log_not_found off;
30
+        access_log off;
31
+    }
32
+
33
+    location ~* \.(txt|log)$ {
34
+        deny all;
35
+    }
36
+
37
+    location ~ \..*/.*\.php$ {
38
+        return 403;
39
+    }
40
+
41
+    # Allow "Well-Known URIs" as per RFC 5785
42
+    location ^~ /.well-known/acme-challenge/ {
43
+        allow all;
44
+        root /var/www/html;
45
+        default_type "text/plain";
46
+    }
47
+
48
+    # Block access to "hidden" files
49
+    location ~ (^|/)\. {
50
+        return 403;
51
+    }
52
+
53
+    location / {
54
+        expires 15m;
55
+        try_files $uri /index.html?$query_string;
56
+    }
57
+
58
+    location /nginx_status {
59
+        access_log off;
60
+        allow 127.0.0.1;
61
+        deny all;
62
+        stub_status;
63
+    }
64
+
65
+    location ~* \.(js|css)$ {
66
+        try_files $uri @rewrite;
67
+        expires 2w;
68
+        log_not_found off;
69
+    }
70
+
71
+    location ~* \.(png|jpg|jpeg|gif|ico|svg|otf)$ {
72
+        try_files $uri @rewrite;
73
+        expires 1w;
74
+        log_not_found off;
75
+    }
76
+
77
+    access_log /var/log/nginx/frontstream_access.log;
78
+    error_log /var/log/nginx/frontstream_error.log;
79
+}

+ 23
- 0
local/role-frontstream/templates/nginx-stream.conf.j2 View File

@@ -0,0 +1,23 @@
1
+{% set port = [8080] %}
2
+
3
+{% for stream in groups['stream'] %}
4
+
5
+server {
6
+    server_name {{ inventory_hostname }};
7
+    listen 127.0.0.1:{{ port | replace(']', '') | replace('[', '')}};
8
+    root {{ frontstream_deploy_path }}/current/;
9
+
10
+    real_ip_header X-Forwarded-For;
11
+    real_ip_recursive on;
12
+
13
+    set_real_ip_from 127.0.0.1;
14
+
15
+    rewrite ^/(.*)$ https://{{ stream }}/$1 redirect;
16
+
17
+    access_log /var/log/nginx/stream_access.log;
18
+    error_log /var/log/nginx/stream_error.log;
19
+}
20
+
21
+{% if port.append(port.pop() + 1) %}{% endif %}
22
+
23
+{% endfor %}

+ 0
- 0
local/role-letsencrypt/tasks/main.yml View File


+ 50
- 0
playbooks/00_bootstrap.yml View File

@@ -0,0 +1,50 @@
1
+#!/usr/bin/env ansible-playbook
2
+#
3
+# @description Bootstraps host to install basic ansible requirements
4
+#
5
+# If your key is NOT on the server and you have to sudo from 'devopsworks' user:
6
+# ./playbooks/00_bootstrap.yml -bku devopsworks -c paramiko -vvv --ask-become-pass -e 'ansible_ssh_port=22'
7
+#
8
+# If your key is already on the server for devopsworks user:
9
+# ./playbooks/00_bootstrap.yml -bu devopsworks -c paramiko -vvv --ask-become-pass -e 'ansible_ssh_port=22'
10
+#
11
+# If your key is already on the server for root:
12
+# ./playbooks/00_bootstrap.yml -vvv -e 'ansible_ssh_port=22'
13
+#
14
+# If you need to install python:
15
+# ./playbooks/00_bootstrap.yml -vvv -e 'ansible_ssh_port=22' -e apt_get_upgrade=true
16
+#
17
+# You might have to add path to inventory (-i inventories.prod/)
18
+
19
+# Real stuff
20
+
21
+- hosts: all
22
+  gather_facts: no
23
+  tasks:
24
+    - name: Updates packages
25
+      become: true
26
+      become_user: root
27
+      raw: apt-get update
28
+      when: apt_get_upgrade is defined and apt_get_upgrade
29
+
30
+    - name: Installs python 3
31
+      become: true
32
+      become_user: root
33
+      raw: apt-get install -y python3 python3-pip
34
+      when: apt_get_upgrade is defined and apt_get_upgrade
35
+
36
+    - name: Gather facts
37
+      setup:
38
+                    
39
+    - name: Installs aptitude (required)
40
+      become: true
41
+      become_user: root
42
+      apt: pkg=aptitude state=present
43
+      when: apt_get_upgrade is defined and apt_get_upgrade
44
+
45
+    - name: Upgrades all packages
46
+      become: true
47
+      become_user: root
48
+      apt: upgrade=safe update_cache=yes
49
+      when: apt_get_upgrade is defined and apt_get_upgrade
50
+

+ 15
- 0
playbooks/01_baseline.yml View File

@@ -0,0 +1,15 @@
1
+#!/usr/bin/env ansible-playbook
2
+#
3
+# @description Deploys baseline system configuration (users, ssh, ..)
4
+#
5
+# Run with:
6
+# ./playbooks/01_baseline.yml
7
+#
8
+
9
+# Real stuff
10
+- hosts: all
11
+  become: true
12
+  roles:
13
+    - ansible-baseline
14
+    - ansible-sshd
15
+#    - ansible-telegraf

+ 22
- 0
playbooks/03_stream_stack.yml View File

@@ -0,0 +1,22 @@
1
+#!/usr/bin/env ansible-playbook
2
+#
3
+# @description Deploys webserver configuration
4
+#
5
+# Run with:
6
+# ./playbooks/03_stream_stack.yml
7
+#
8
+
9
+# Real stuff
10
+- hosts: frontstream
11
+  become: true
12
+  roles:
13
+    - ansible-role-certbot
14
+    - ansible-nginx
15
+    - ansible-haproxy
16
+    - role-frontstream
17
+
18
+- hosts: stream
19
+  become: true
20
+  roles:
21
+    - ansible-role-certbot
22
+    - ansible-nginx

+ 36
- 0
requirements.txt View File

@@ -0,0 +1,36 @@
1
+ansible==2.9.9
2
+appdirs==1.4.3
3
+bcrypt==3.1.7
4
+CacheControl==0.12.6
5
+certifi==2019.11.28
6
+cffi==1.14.0
7
+chardet==3.0.4
8
+colorama==0.4.3
9
+contextlib2==0.6.0
10
+cryptography==2.9.2
11
+distlib==0.3.0
12
+distro==1.4.0
13
+html5lib==1.0.1
14
+idna==2.8
15
+ipaddr==2.2.0
16
+ipaddress==1.0.23
17
+Jinja2==2.11.2
18
+lockfile==0.12.2
19
+MarkupSafe==1.1.1
20
+msgpack==0.6.2
21
+netaddr==0.7.19
22
+packaging==20.3
23
+paramiko==2.7.1
24
+pep517==0.8.2
25
+progress==1.5
26
+pycparser==2.20
27
+PyNaCl==1.3.0
28
+pyparsing==2.4.6
29
+pytoml==0.1.21
30
+PyYAML==5.3.1
31
+redis==3.5.1
32
+requests==2.22.0
33
+retrying==1.3.3
34
+six==1.14.0
35
+urllib3==1.25.8
36
+webencodings==0.5.1

+ 14
- 0
roles/requirements.yml View File

@@ -0,0 +1,14 @@
1
+- src: http://github.com/devops-works/ansible-baseline.git
2
+  version: 4.0.0
3
+- src: http://github.com/devops-works/ansible-haproxy.git
4
+  version: 1.3.2
5
+- src: http://github.com/devops-works/ansible-netplan.git
6
+  version: 1.0.1
7
+- src: http://github.com/leucos/ansible-nginx.git
8
+  version: 1.1.2
9
+- src: http://github.com/devops-works/ansible-sshd.git
10
+  version: 2.2.0
11
+- src: http://github.com/leucos/ansible-telegraf.git
12
+  version: 4.0.0
13
+- src: http://github.com/geerlingguy/ansible-role-certbot.git
14
+  version: 3.1.0

+ 29
- 0
tf/providers/do/lab/.gitignore View File

@@ -0,0 +1,29 @@
1
+# Local .terraform directories
2
+**/.terraform/*
3
+
4
+# .tfstate files
5
+*.tfstate
6
+*.tfstate.*
7
+
8
+# Crash log files
9
+crash.log
10
+
11
+# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
12
+# .tfvars files are managed as part of configuration and so should be included in
13
+# version control.
14
+#
15
+# example.tfvars
16
+
17
+# Ignore override files as they are usually used to override resources locally and so
18
+# are not checked in
19
+override.tf
20
+override.tf.json
21
+*_override.tf
22
+*_override.tf.json
23
+
24
+# Include override files you do wish to add to version control using negated pattern
25
+#
26
+# !example_override.tf
27
+
28
+# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
29
+# example: *tfplan*

+ 60
- 0
tf/providers/do/lab/netfreaks.tf View File

@@ -0,0 +1,60 @@
1
+variable "region" {
2
+  default = "fra1"
3
+}
4
+
5
+resource "digitalocean_ssh_key" "cgibaud-ssh-key" {
6
+  name       = "Clément @ Silicium ed25519 ssh key"
7
+  public_key = "${file("../../../vars/ssh-keys/devops-cgibaud.pub")}"
8
+}
9
+
10
+variable "domain" {
11
+  default = "netfreaks.lab.gibaud.info"
12
+}
13
+
14
+#
15
+# Streams resources
16
+#
17
+
18
+variable "stream-count" {
19
+  default = "2"
20
+}
21
+
22
+resource "digitalocean_droplet" "stream" {
23
+  image              = "ubuntu-18-04-x64"
24
+  name               = "stream-${count.index}"
25
+  region             = "${var.region}"
26
+  size               = "s-1vcpu-1gb"
27
+  private_networking = "true"
28
+  ssh_keys           = ["${digitalocean_ssh_key.cgibaud-ssh-key.fingerprint}"]
29
+  count              = "${var.stream-count}"
30
+}
31
+
32
+resource "digitalocean_record" "stream-record" {
33
+  domain = "${var.domain}"
34
+  type   = "A"
35
+  ttl    = "60"
36
+  name   = "stream${count.index}"
37
+  value  = "${element(digitalocean_droplet.stream.*.ipv4_address, count.index)}"
38
+  count  = "${var.stream-count}"
39
+}
40
+
41
+#
42
+# FrontStream resources
43
+#
44
+
45
+resource "digitalocean_droplet" "frontstream" {
46
+  image              = "ubuntu-18-04-x64"
47
+  name               = "frontstream"
48
+  region             = "${var.region}"
49
+  size               = "s-1vcpu-1gb"
50
+  private_networking = "true"
51
+  ssh_keys           = ["${digitalocean_ssh_key.cgibaud-ssh-key.fingerprint}"]
52
+}
53
+
54
+resource "digitalocean_record" "frontstream-record" {
55
+  domain = "${var.domain}"
56
+  type   = "A"
57
+  ttl    = "60"
58
+  name   = "frontstream"
59
+  value  = "${digitalocean_droplet.frontstream.ipv4_address}"
60
+}

+ 1
- 0
tf/vars/ssh-keys/devops-cgibaud.pub View File

@@ -0,0 +1 @@
1
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICYF0x4D7h6rFybKWg798gTTDKfcjVGq/ucMxjOk956c clement@silicium

Loading…
Cancel
Save