Initial Commit
This commit is contained in:
parent
b8546a759e
commit
a1581e6c4f
24
ansible.cfg
Normal file
24
ansible.cfg
Normal file
@ -0,0 +1,24 @@
|
||||
[defaults]
|
||||
ansible_managed = Ansible managed - DO NOT EDIT HERE
|
||||
forks = 10
|
||||
host_key_checking = False
|
||||
inventory = environments/production
|
||||
retry_files_enabled = False
|
||||
roles_path = roles/
|
||||
vault_password_file = ansible_vault.key
|
||||
|
||||
[privilege_escalation]
|
||||
become = True
|
||||
become_user = root
|
||||
become_method = sudo
|
||||
|
||||
[persistent_connection]
|
||||
connect_interval = 1
|
||||
connect_retries = 30
|
||||
connect_timeout = 30
|
||||
|
||||
[ssh_connection]
|
||||
retries = 5
|
||||
pipelining = True
|
||||
ssh_args = "-o ControlMaster=auto -o ControlPersist=30m"
|
||||
control_path = "./ssh/ansible-%%C"
|
6
ansible_requirements.yaml
Normal file
6
ansible_requirements.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
collections:
|
||||
- name: 'ansible.posix'
|
||||
- name: 'community.docker'
|
||||
- name: 'community.general'
|
8
environments/production/group_vars/wafs.yaml
Normal file
8
environments/production/group_vars/wafs.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
#######################
|
||||
#### open-appsec ####
|
||||
#######################
|
||||
openappsec_advanced_model_url: 'https://some_internal_url/open-appsec-advanced-model.tgz'
|
||||
openappsec_advanced_model_sha: 'sha_of_the_advanced_model'
|
||||
openappsec_token: 'cp-some-long-token'
|
3
environments/production/hosts
Normal file
3
environments/production/hosts
Normal file
@ -0,0 +1,3 @@
|
||||
[wafs]
|
||||
waf0.example.local
|
||||
waf1.example.local
|
9
playbooks/production/wafs.yaml
Normal file
9
playbooks/production/wafs.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
|
||||
# wafs
|
||||
- name: 'ansible role for wafs'
|
||||
become: true
|
||||
hosts: 'wafs'
|
||||
serial: '1'
|
||||
roles:
|
||||
- 'openappsec'
|
15
roles/openappsec/files/dehydrated/config
Normal file
15
roles/openappsec/files/dehydrated/config
Normal file
@ -0,0 +1,15 @@
|
||||
# generic
|
||||
CHALLENGETYPE="http-01"
|
||||
CONTACT_EMAIL="info@example.com"
|
||||
IP_VERSION="4"
|
||||
RENEW_DAYS="30"
|
||||
|
||||
# dirs
|
||||
ACCOUNTDIR="/mnt/certs/accounts"
|
||||
CERTDIR="/mnt/certs/certs"
|
||||
CHAINCACHE="/mnt/certs/chains"
|
||||
WELLKNOWN="/mnt/certs/challenge"
|
||||
|
||||
# oscp
|
||||
OCSP_MUST_STAPLE="yes"
|
||||
OCSP_FETCH="no"
|
3
roles/openappsec/files/dehydrated/domains.txt
Normal file
3
roles/openappsec/files/dehydrated/domains.txt
Normal file
@ -0,0 +1,3 @@
|
||||
# example.com
|
||||
example.com
|
||||
subdomain.example.com
|
70
roles/openappsec/files/nginx/conf.d/example.com.conf
Normal file
70
roles/openappsec/files/nginx/conf.d/example.com.conf
Normal file
@ -0,0 +1,70 @@
|
||||
server {
|
||||
listen 80 default_server proxy_protocol;
|
||||
server_name example.com;
|
||||
|
||||
# proxy protocol settings
|
||||
set_real_ip_from 10.0.0.1/32;
|
||||
real_ip_header proxy_protocol;
|
||||
real_ip_recursive on;
|
||||
|
||||
# logging
|
||||
access_log syslog:server=log.example.local vhost;
|
||||
error_log syslog:server=log.example.local;
|
||||
|
||||
location ^~ /.well-known/acme-challenge {
|
||||
alias /mnt/certs/challenge;
|
||||
}
|
||||
|
||||
# health uri
|
||||
location /health {
|
||||
|
||||
# return 'rp-ok' in plain text
|
||||
add_header Content-Type text/plain;
|
||||
return 200 'waf-ok';
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 default_server http2 proxy_protocol ssl;
|
||||
server_name example.com;
|
||||
|
||||
# proxy protocol settings
|
||||
set_real_ip_from 10.0.0.1/32;
|
||||
real_ip_header proxy_protocol;
|
||||
real_ip_recursive on;
|
||||
|
||||
# logging
|
||||
access_log syslog:server=log.example.local vhost;
|
||||
error_log syslog:server=log.example.local;
|
||||
|
||||
# certificates
|
||||
ssl_certificate /mnt/certs/certs/example.com/fullchain.pem;
|
||||
ssl_certificate_key /mnt/certs/certs/example.com/privkey.pem;
|
||||
|
||||
# tls settings
|
||||
ssl_dhparam /etc/nginx/dhparam.pem;
|
||||
ssl_session_timeout 4h;
|
||||
ssl_session_tickets off;
|
||||
ssl_session_cache shared:SSL:20m;
|
||||
ssl_ecdh_curve secp384r1;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_protocols TLSv1.3 TLSv1.2;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
|
||||
# health uri
|
||||
location /health {
|
||||
|
||||
# return 'rp-ok' in plain text
|
||||
add_header Content-Type text/plain;
|
||||
return 200 'rp-ok';
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://example.com;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
upstream application01 {
|
||||
server 10.0.0.10:443;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 proxy_protocol;
|
||||
server_name subdomain.example.com;
|
||||
|
||||
# proxy protocol settings
|
||||
set_real_ip_from 10.0.0.1/32;
|
||||
real_ip_header proxy_protocol;
|
||||
real_ip_recursive on;
|
||||
|
||||
# logging
|
||||
access_log syslog:server=log.example.local vhost;
|
||||
error_log syslog:server=log.example.local;
|
||||
|
||||
location ^~ /.well-known/acme-challenge {
|
||||
alias /mnt/certs/challenge;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 proxy_protocol ssl http2;
|
||||
server_name subdomain.example.com;
|
||||
|
||||
# proxy protocol settings
|
||||
set_real_ip_from 10.0.0.1/32;
|
||||
real_ip_header proxy_protocol;
|
||||
real_ip_recursive on;
|
||||
|
||||
# logging
|
||||
access_log syslog:server=log.example.local vhost;
|
||||
error_log syslog:server=log.example.local;
|
||||
|
||||
# certificates
|
||||
ssl_certificate /mnt/certs/certs/subdomain.example.com/fullchain.pem;
|
||||
ssl_certificate_key /mnt/certs/certs/subdomain.example.com/privkey.pem;
|
||||
|
||||
# tls settings
|
||||
ssl_dhparam /etc/nginx/dhparam.pem;
|
||||
ssl_session_timeout 4h;
|
||||
ssl_session_tickets off;
|
||||
ssl_session_cache shared:SSL:20m;
|
||||
ssl_ecdh_curve secp384r1;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_protocols TLSv1.3 TLSv1.2;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
|
||||
location / {
|
||||
|
||||
# set headers
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $proxy_protocol_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# pass upstream
|
||||
proxy_pass https://application01;
|
||||
}
|
||||
}
|
5
roles/openappsec/files/nginx/dhparam.pem
Normal file
5
roles/openappsec/files/nginx/dhparam.pem
Normal file
@ -0,0 +1,5 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
...
|
||||
( openssl dhparam -out dhparam.pem 2048 )
|
||||
...
|
||||
-----END DH PARAMETERS-----
|
27
roles/openappsec/files/nginx/nginx.conf
Normal file
27
roles/openappsec/files/nginx/nginx.conf
Normal file
@ -0,0 +1,27 @@
|
||||
worker_processes 2;
|
||||
load_module /usr/lib/nginx/modules/ngx_cp_attachment_module.so;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
server_tokens off;
|
||||
|
||||
log_format vhost 'openappsec-waf "$host" "$proxy_protocol_addr" "$request" "$http_user_agent" "$status"';
|
||||
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
fastcgi_param HTTP_PROXY "";
|
||||
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
||||
|
||||
resolver 1.1.1.1 8.8.8.8;
|
||||
resolver_timeout 2s;
|
||||
|
||||
proxy_cache_valid 200 1d;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
13
roles/openappsec/handlers/main.yaml
Normal file
13
roles/openappsec/handlers/main.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
|
||||
# open-appsec agent
|
||||
- name: 'restart openappsec-agent'
|
||||
community.docker.docker_container:
|
||||
name: 'openappsec-agent'
|
||||
restart: 'true'
|
||||
|
||||
# open-appsec nginx
|
||||
- name: 'restart nginx'
|
||||
community.docker.docker_container:
|
||||
name: 'openappsec-nginx'
|
||||
restart: 'true'
|
28
roles/openappsec/tasks/main.yaml
Normal file
28
roles/openappsec/tasks/main.yaml
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
|
||||
# create network
|
||||
- name: 'create network'
|
||||
ansible.builtin.import_tasks: 'openappsec/network.yaml'
|
||||
|
||||
# install open-appsec
|
||||
- name: 'install open-appsec'
|
||||
ansible.builtin.import_tasks: 'openappsec/install.yaml'
|
||||
|
||||
|
||||
# configure nginx
|
||||
- name: 'configure nginx'
|
||||
ansible.builtin.import_tasks: 'nginx/config.yaml'
|
||||
|
||||
# loop vhosts
|
||||
- name: 'config - vhosts'
|
||||
ansible.builtin.import_tasks: 'nginx/vhosts.yaml'
|
||||
|
||||
|
||||
# import dehydrated
|
||||
- name: 'dehydrated'
|
||||
ansible.builtin.import_tasks: 'nginx/dehydrated.yaml'
|
||||
|
||||
|
||||
# cleanup docker
|
||||
- name: 'cleanup docker'
|
||||
ansible.builtin.import_tasks: 'openappsec/cleanup.yaml'
|
21
roles/openappsec/tasks/nginx/config.yaml
Normal file
21
roles/openappsec/tasks/nginx/config.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
|
||||
# configure dhparam file
|
||||
- name: 'configure - dhparam'
|
||||
ansible.builtin.copy:
|
||||
src: 'files/nginx/dhparam.pem'
|
||||
dest: '/etc/nginx/dhparam.pem'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
notify: 'restart nginx'
|
||||
|
||||
# configure nginx
|
||||
- name: 'config - configure nginx'
|
||||
ansible.builtin.copy:
|
||||
src: 'files/nginx/nginx.conf'
|
||||
dest: '/etc/nginx/nginx.conf'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
notify: 'restart nginx'
|
45
roles/openappsec/tasks/nginx/dehydrated.yaml
Normal file
45
roles/openappsec/tasks/nginx/dehydrated.yaml
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
|
||||
# install dehydrated
|
||||
- name: 'install - dehydrated'
|
||||
ansible.builtin.apt:
|
||||
name: 'dehydrated'
|
||||
state: 'present'
|
||||
cache_valid_time: '120'
|
||||
when: 'ansible_os_family == "Debian"'
|
||||
|
||||
|
||||
# copy dehydrated configuration file from template
|
||||
- name: 'revproxy - config - copy config from template'
|
||||
ansible.builtin.copy:
|
||||
src: 'files/dehydrated/config'
|
||||
dest: '/etc/dehydrated/config'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
|
||||
# copy dehydrated configuration file from template
|
||||
- name: 'revproxy - config - copy domains.txt from template'
|
||||
ansible.builtin.copy:
|
||||
src: 'files/dehydrated/domains.txt'
|
||||
dest: '/etc/dehydrated/domains.txt'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
|
||||
# create dehydrated folder
|
||||
- name: 'directory - dehydrated folder'
|
||||
ansible.builtin.file:
|
||||
path: '/mnt/certs/challenge'
|
||||
state: 'directory'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0755'
|
||||
|
||||
|
||||
# symlink archive folder
|
||||
- name: 'directory - dehydrated archive folder'
|
||||
ansible.builtin.file:
|
||||
src: '/mnt/certs/archive'
|
||||
dest: '/etc/dehydrated/archive'
|
||||
state: 'link'
|
13
roles/openappsec/tasks/nginx/vhosts.yaml
Normal file
13
roles/openappsec/tasks/nginx/vhosts.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
|
||||
# configure vhosts
|
||||
- name: 'config - vhosts'
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item }}"
|
||||
dest: '/etc/nginx/conf.d/'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0644'
|
||||
notify: 'restart nginx'
|
||||
with_fileglob:
|
||||
- "files/nginx/conf.d/*"
|
18
roles/openappsec/tasks/openappsec/cleanup.yaml
Normal file
18
roles/openappsec/tasks/openappsec/cleanup.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
|
||||
# cleanup
|
||||
- name: 'docker - prune all'
|
||||
community.docker.docker_prune:
|
||||
containers: true
|
||||
images: true
|
||||
networks: true
|
||||
volumes: true
|
||||
builder_cache: true
|
||||
|
||||
- name: 'docker - force prune'
|
||||
ansible.builtin.command:
|
||||
"docker system prune \
|
||||
--all \
|
||||
--force \
|
||||
--volumes"
|
||||
changed_when: false
|
102
roles/openappsec/tasks/openappsec/install.yaml
Normal file
102
roles/openappsec/tasks/openappsec/install.yaml
Normal file
@ -0,0 +1,102 @@
|
||||
---
|
||||
|
||||
# create open-appsec directories
|
||||
- name: 'create open-appsec directories'
|
||||
ansible.builtin.file:
|
||||
path: "/mnt/openappsec/{{ item }}"
|
||||
state: 'directory'
|
||||
mode: '0775'
|
||||
with_items:
|
||||
- 'conf'
|
||||
- 'data'
|
||||
- 'logs'
|
||||
- 'model'
|
||||
|
||||
# download advanced model
|
||||
- name: 'download advanced model'
|
||||
ansible.builtin.get_url:
|
||||
url: '{{ openappsec_advanced_model_url }}'
|
||||
dest: '/mnt/openappsec/model/advanced.tgz'
|
||||
checksum: "sha256:{{ openappsec_advanced_model_sha }}"
|
||||
notify: 'restart openappsec-agent'
|
||||
|
||||
|
||||
# docker pull open-appsec agent
|
||||
- name: 'run open-appsec agent'
|
||||
community.docker.docker_container:
|
||||
|
||||
# container_default_behavior
|
||||
auto_remove: 'no'
|
||||
container_default_behavior: 'no_defaults'
|
||||
detach: 'yes'
|
||||
init: 'no'
|
||||
interactive: 'no'
|
||||
memory: '0'
|
||||
paused: 'no'
|
||||
privileged: 'no'
|
||||
pull: 'yes'
|
||||
read_only: 'no'
|
||||
state: 'started'
|
||||
tty: 'no'
|
||||
ipc_mode: 'host'
|
||||
|
||||
# open-appsec - agent
|
||||
name: 'openappsec-agent'
|
||||
image: 'ghcr.io/openappsec/agent:1.1.4'
|
||||
restart_policy: 'unless-stopped'
|
||||
command: ["/cp-nano-agent", "--token", "{{ openappsec_token }}"]
|
||||
|
||||
networks:
|
||||
- name: 'openappsec'
|
||||
|
||||
volumes:
|
||||
- '/mnt/openappsec/conf:/etc/cp/conf'
|
||||
- '/mnt/openappsec/data:/etc/cp/data'
|
||||
- '/mnt/openappsec/logs:/var/log/nano_agent'
|
||||
- '/mnt/openappsec/model/advanced.tgz:/advanced-model/open-appsec-advanced-model.tgz:rw'
|
||||
|
||||
env:
|
||||
|
||||
# global
|
||||
TZ: '{{ timezone }}'
|
||||
|
||||
|
||||
# docker pull open-appsec nginx
|
||||
- name: 'run open-appsec nginx'
|
||||
community.docker.docker_container:
|
||||
|
||||
# container_default_behavior
|
||||
auto_remove: 'no'
|
||||
container_default_behavior: 'no_defaults'
|
||||
detach: 'yes'
|
||||
init: 'no'
|
||||
interactive: 'no'
|
||||
memory: '0'
|
||||
paused: 'no'
|
||||
privileged: 'no'
|
||||
pull: 'yes'
|
||||
read_only: 'no'
|
||||
state: 'started'
|
||||
tty: 'no'
|
||||
ipc_mode: 'host'
|
||||
|
||||
# open-appsec nginx
|
||||
name: 'openappsec-nginx'
|
||||
image: 'ghcr.io/openappsec/nginx-attachment:1.1.4'
|
||||
restart_policy: 'unless-stopped'
|
||||
|
||||
networks:
|
||||
- name: 'openappsec'
|
||||
|
||||
volumes:
|
||||
- '/etc/nginx:/etc/nginx'
|
||||
- '/mnt/certs:/mnt/certs'
|
||||
|
||||
ports:
|
||||
- '80:80/tcp' # http
|
||||
- '443:443/tcp' # https
|
||||
|
||||
env:
|
||||
|
||||
# global
|
||||
TZ: '{{ timezone }}'
|
6
roles/openappsec/tasks/openappsec/network.yaml
Normal file
6
roles/openappsec/tasks/openappsec/network.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
# create network
|
||||
- name: 'docker create openappsec network'
|
||||
community.docker.docker_network:
|
||||
name: 'openappsec'
|
Loading…
Reference in New Issue
Block a user