Compare commits
5 commits
908f96b51a
...
da087a74c7
Author | SHA1 | Date | |
---|---|---|---|
da087a74c7 | |||
f7206d721c | |||
3002808f92 | |||
c8a34a6e7b | |||
eb586633ec |
15 changed files with 632 additions and 13 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -159,3 +159,5 @@ cython_debug/
|
||||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
ansible/credentials/
|
||||||
|
terraform/mcaptcha/mcaptcha
|
||||||
|
|
29
Makefile
29
Makefile
|
@ -24,6 +24,12 @@ define configure_cache
|
||||||
ansible-playbook -i $(INVENTORY) -f 10 ./ansible/cache.yml
|
ansible-playbook -i $(INVENTORY) -f 10 ./ansible/cache.yml
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define configure_mcaptcha
|
||||||
|
. ./venv/bin/activate && \
|
||||||
|
ansible-playbook -i $(INVENTORY) -f 10 ./ansible/mcaptcha.yml
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
define test_base
|
define test_base
|
||||||
. ./venv/bin/activate && \
|
. ./venv/bin/activate && \
|
||||||
|
@ -49,6 +55,19 @@ define test_cache
|
||||||
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define test_mcaptcha
|
||||||
|
. ./venv/bin/activate && \
|
||||||
|
cd tests/mcaptcha/ && \
|
||||||
|
ANSIBLE_REMOTE_USER=root \
|
||||||
|
py.test --hosts='ansible://mcaptcha_hosts' \
|
||||||
|
-n 10 \
|
||||||
|
--verbose \
|
||||||
|
--ansible-inventory="../../${INVENTORY}" \
|
||||||
|
base.py
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
define test_locust
|
define test_locust
|
||||||
. ./venv/bin/activate && \
|
. ./venv/bin/activate && \
|
||||||
|
@ -88,6 +107,13 @@ conf.dos: ## Configure all DoS VMs
|
||||||
conf.cache: ## Configure all cache VMs
|
conf.cache: ## Configure all cache VMs
|
||||||
$(call configure_cache)
|
$(call configure_cache)
|
||||||
|
|
||||||
|
# ```bash
|
||||||
|
# INVENTORY=./terraform/dos/hosts.ini make conf.mcaptcha
|
||||||
|
# ```
|
||||||
|
conf.mcaptcha: ## Configure all mcaptcha VMs
|
||||||
|
$(call configure_mcaptcha)
|
||||||
|
|
||||||
|
|
||||||
# ```bash
|
# ```bash
|
||||||
# INVENTORY=./terraform/dos/hosts.ini make conf.ping
|
# INVENTORY=./terraform/dos/hosts.ini make conf.ping
|
||||||
# ```
|
# ```
|
||||||
|
@ -105,7 +131,8 @@ test.base: ## Test base configuration on all VMs
|
||||||
test.cache: ## Test cache configuration
|
test.cache: ## Test cache configuration
|
||||||
$(call test_cache)
|
$(call test_cache)
|
||||||
|
|
||||||
|
test.mcaptcha: ## Test mcaptcha configuration
|
||||||
|
$(call test_mcaptcha)
|
||||||
|
|
||||||
help: ## Prints help for targets with comments
|
help: ## Prints help for targets with comments
|
||||||
@cat $(MAKEFILE_LIST) | grep -E '^[a-zA-Z_-].+:.*?## .*$$' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@cat $(MAKEFILE_LIST) | grep -E '^[a-zA-Z_-].+:.*?## .*$$' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
29
ansible/artifacts/mcaptcha/mcaptcha.service
Normal file
29
ansible/artifacts/mcaptcha/mcaptcha.service
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
[Unit]
|
||||||
|
Description=mCaptcha: PoW CAPTCHA system
|
||||||
|
After=syslog.target
|
||||||
|
After=network.target
|
||||||
|
###
|
||||||
|
# Don't forget to add the database service dependencies
|
||||||
|
###
|
||||||
|
#
|
||||||
|
#Wants=mariadb.service
|
||||||
|
#After=mariadb.service
|
||||||
|
#
|
||||||
|
Wants=postgresql.service
|
||||||
|
After=postgresql.service
|
||||||
|
#
|
||||||
|
#Wants=redis.service
|
||||||
|
#After=redis.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
RestartSec=2s
|
||||||
|
Type=simple
|
||||||
|
User=mcaptcha
|
||||||
|
Group=mcaptcha
|
||||||
|
WorkingDirectory=/home/mcaptcha/
|
||||||
|
ExecStart=/usr/local/bin/mcaptcha
|
||||||
|
Restart=always
|
||||||
|
Environment=USER=mcaptcha HOME=/home/mcaptcha
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
98
ansible/mcaptcha.yml
Normal file
98
ansible/mcaptcha.yml
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
#---
|
||||||
|
- name: Base configuration
|
||||||
|
ansible.builtin.import_playbook: base.yml
|
||||||
|
|
||||||
|
- name: Install and configure postgres
|
||||||
|
hosts: mcaptcha_hosts
|
||||||
|
become: yes
|
||||||
|
vars_files:
|
||||||
|
- vars/mcaptcha/vars.yml
|
||||||
|
- vars/mcaptcha/db-common.yml
|
||||||
|
- vars/mcaptcha/postgresql.yml
|
||||||
|
tasks:
|
||||||
|
- ansible.builtin.include_role:
|
||||||
|
name: geerlingguy.postgresql
|
||||||
|
when:
|
||||||
|
database_type == "postgres"
|
||||||
|
|
||||||
|
- name: Install and configure mariadb
|
||||||
|
hosts: mcaptcha_hosts
|
||||||
|
become: yes
|
||||||
|
vars_files:
|
||||||
|
- vars/mcaptcha/vars.yml
|
||||||
|
- vars/mcaptcha/db-common.yml
|
||||||
|
- vars/mcaptcha/mariadb.yml.yml
|
||||||
|
tasks:
|
||||||
|
- ansible.builtin.include_role:
|
||||||
|
name: geerlingguy.mysql
|
||||||
|
when:
|
||||||
|
database_type == "mariadb"
|
||||||
|
|
||||||
|
- name: Install and configure cache
|
||||||
|
hosts: mcaptcha_hosts
|
||||||
|
become: yes
|
||||||
|
vars_files:
|
||||||
|
- vars/mcaptcha/vars.yml
|
||||||
|
tasks:
|
||||||
|
- name: conditionally install redis cache
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: cache
|
||||||
|
when: cache_type == "redis"
|
||||||
|
|
||||||
|
- name: Install mCaptcha binary
|
||||||
|
hosts: mcaptcha_hosts
|
||||||
|
remote_user: atm
|
||||||
|
vars_files:
|
||||||
|
- vars/mcaptcha/vars.yml
|
||||||
|
- vars/mcaptcha/db-common.yml
|
||||||
|
- vars/mcaptcha/mcaptcha.yml
|
||||||
|
roles:
|
||||||
|
- mcaptcha
|
||||||
|
tasks:
|
||||||
|
- name: restart mcaptcha
|
||||||
|
debug:
|
||||||
|
msg: "mCaptcha successfully deployed to {{ mcaptcha_server_hostname }}"
|
||||||
|
notify: restart mcaptcha
|
||||||
|
|
||||||
|
- name: Install git, zip, nginx, wget, curl & other utils
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
cache_valid_time: 3600
|
||||||
|
pkg:
|
||||||
|
- nginx
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
- name: Copy nginx vhost
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: ./templates/mcaptcha/nginx.vhost.j2
|
||||||
|
dest: "/etc/nginx/sites-available/{{ mcaptcha_server_hostname }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
force: true
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Copy nginx vhost
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "/etc/nginx/sites-available/{{ mcaptcha_server_hostname }}"
|
||||||
|
dest: "/etc/nginx/sites-enabled/{{ mcaptcha_server_hostname }}"
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Restart nginx
|
||||||
|
become: true
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: nginx
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: Allow port 80 and enable UFW
|
||||||
|
become: true
|
||||||
|
community.general.ufw:
|
||||||
|
state: enabled
|
||||||
|
rule: allow
|
||||||
|
proto: tcp
|
||||||
|
port: "80"
|
16
ansible/roles/cache/tasks/main.yml
vendored
16
ansible/roles/cache/tasks/main.yml
vendored
|
@ -72,15 +72,7 @@
|
||||||
force: true
|
force: true
|
||||||
mode: "0755"
|
mode: "0755"
|
||||||
|
|
||||||
# - name: Delete download dir
|
- name: Delete download dir
|
||||||
# ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
# path: /tmp/cache-lib
|
path: /tmp/cache-lib
|
||||||
# state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Allow port 6379 for redis
|
|
||||||
become: true
|
|
||||||
community.general.ufw:
|
|
||||||
state: enabled
|
|
||||||
rule: allow
|
|
||||||
proto: tcp
|
|
||||||
port: "6379"
|
|
||||||
|
|
7
ansible/roles/mcaptcha/handlers/main.yml
Normal file
7
ansible/roles/mcaptcha/handlers/main.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
- name: restart mcaptcha
|
||||||
|
listen: restart mcaptcha
|
||||||
|
become: true
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: mcaptcha
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
82
ansible/roles/mcaptcha/tasks/main.yml
Normal file
82
ansible/roles/mcaptcha/tasks/main.yml
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
---
|
||||||
|
- name: Create mCaptcha systemd user
|
||||||
|
become: true
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: mcaptcha
|
||||||
|
state: present
|
||||||
|
system: true
|
||||||
|
comment: mCaptcha systemd user
|
||||||
|
|
||||||
|
- name: Create download dir
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /tmp/mcaptcha-dl
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Download binary
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://dl.mcaptcha.org/mcaptcha/mCaptcha/master/mcaptcha-master-linux-amd64.tar.gz
|
||||||
|
dest: /tmp/mcaptcha-dl
|
||||||
|
checksum: sha256:https://dl.mcaptcha.org/mcaptcha/mCaptcha/master/mcaptcha-master-linux-amd64.tar.gz.sha256
|
||||||
|
|
||||||
|
- name: Extract mcaptcha-master-linux-amd64.tar.gz into /var/lib/foo
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: /tmp/mcaptcha-dl/mcaptcha-master-linux-amd64.tar.gz
|
||||||
|
remote_src: true
|
||||||
|
dest: /tmp/mcaptcha-dl/
|
||||||
|
|
||||||
|
- name: Install binary
|
||||||
|
become: true
|
||||||
|
notify: restart mcaptcha
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: /tmp/mcaptcha-dl/mcaptcha-master-linux-amd64/mcaptcha
|
||||||
|
remote_src: true
|
||||||
|
dest: /usr/local/bin/mcaptcha
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
force: true
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Copy mCaptcha systemd servicefile
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ./artifacts/mcaptcha/mcaptcha.service
|
||||||
|
dest: /etc/systemd/system/
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
force: true
|
||||||
|
mode: "0777"
|
||||||
|
|
||||||
|
- name: Create mCaptcha config dir
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/mcaptcha
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Copy mCaptcha systemd servicefile
|
||||||
|
become: true
|
||||||
|
notify: restart mcaptcha
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: ./templates/mcaptcha/config.toml.j2
|
||||||
|
dest: /etc/mcaptcha/config.toml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
force: true
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Run mCaptcha as a systemd service
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: mcaptcha
|
||||||
|
daemon_reload: true
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: Delete download dir
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /tmp/mcaptcha-dl
|
||||||
|
state: absent
|
81
ansible/templates/mcaptcha/config.toml.j2
Normal file
81
ansible/templates/mcaptcha/config.toml.j2
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
{% if database_type == 'postgres' %}
|
||||||
|
{% set mcaptcha_database_url = "postgres://" ~ database_owner ~ ":" ~ database_password ~ "@" ~ "localhost:5432/" ~ database_name %}
|
||||||
|
{% else %}
|
||||||
|
{% set mcaptcha_database_url = "mysql://" ~ database_owner ~ ":" ~ database_password ~ "@" ~ "localhost/" ~ database_name %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
debug = "{{ mcaptcha_debug | default('false') }}"
|
||||||
|
source_code = "{{ mcaptcha_source_code | default('https://github.com/mCaptcha/mCaptcha') }}"
|
||||||
|
commercial = "{{ mcaptcha_commercial | default('false') }}"
|
||||||
|
allow_demo = "{{ mcaptcha_allow_demo | default('false') }}"
|
||||||
|
allow_registration = "{{ mcaptcha_allow_registration | default('true') }}"
|
||||||
|
|
||||||
|
[server]
|
||||||
|
# Please set a unique value, your mCaptcha instance's security depends on this being
|
||||||
|
# unique
|
||||||
|
cookie_secret = "{{ mcaptcha_server_cookie_secret }}"
|
||||||
|
# The port at which you want authentication to listen to
|
||||||
|
# takes a number, choose from 1000-10000 if you dont know what you are doing
|
||||||
|
port = "{{ mcaptcha_server_port | default(7000) }}"
|
||||||
|
#IP address. Enter 0.0.0.0 to listen on all available addresses
|
||||||
|
ip= "{{ mcaptcha_server_bind | default('127.0.0.1') }}"
|
||||||
|
# enter your hostname, eg: example.com
|
||||||
|
domain = "{{ mcaptcha_server_hostname }}"
|
||||||
|
# Set true if you have setup TLS with a reverse proxy like Nginx.
|
||||||
|
# Does HTTPS redirect and sends additional headers that can only be used if
|
||||||
|
# HTTPS available to improve security
|
||||||
|
proxy_has_tls = "{{ mcaptcha_proxy_has_tls | default('false') }}"
|
||||||
|
|
||||||
|
[captcha]
|
||||||
|
# Please set a unique value, your mCaptcha instance's security depends on this being
|
||||||
|
# unique
|
||||||
|
salt = "{{ mcaptcha_captcha_salt }}"
|
||||||
|
# garbage collection period to manage mCaptcha system
|
||||||
|
# leave untouched if you don't know what you are doing
|
||||||
|
gc = "{{ mcaptcha_captcha_gc | default(30) }}" #30
|
||||||
|
runners = "{{ mcaptcha_captcha_runners | default(4) }}" #4
|
||||||
|
queue_length = "{{ mcaptcha_captcha_queue_length | default(2000) }}" #2000
|
||||||
|
enable_stats = "{{ mcaptcha_captcha_enable_stats | default('true') }}" #true
|
||||||
|
|
||||||
|
[captcha.default_difficulty_strategy]
|
||||||
|
avg_traffic_difficulty = "{{ mcaptcha_captcha_default_difficulty_strategy_avg_traffic_difficulty | default(50000) }}" # 50000 # almost instant solution
|
||||||
|
peak_sustainable_traffic_difficulty = "{{ mcaptcha_captcha_default_difficulty_strategy_peak_sustainable_traffic_difficulty | default(3000000) }}" # 3000000 # roughly 1.5s
|
||||||
|
broke_my_site_traffic_difficulty = "{{ mcaptcha_captcha_default_difficulty_strategy_broke_my_site_traffic_difficulty | default(5000000) }}" # 5000000 # greater than 3.5s
|
||||||
|
# cooldown period in seconds
|
||||||
|
duration = "{{ mcaptcha_captcha_default_difficulty_strategy_avg_duration | default(30) }}" # 30
|
||||||
|
|
||||||
|
[database]
|
||||||
|
# This section deals with the database location and how to access it
|
||||||
|
# Please note that at the moment, we have support for only postgresqa.
|
||||||
|
# Example, if you are Batman, your config would be:
|
||||||
|
# url = "postgres://batman:password@batcave.org:5432/batcave"
|
||||||
|
# database_type = "postgres"
|
||||||
|
# pool = 4
|
||||||
|
url = "{{ mcaptcha_database_url }}" # "postgres://example.org" # hack for tests to run successfully
|
||||||
|
|
||||||
|
pool = "{{ mcaptcha_database_pool | default(4) }}" #4
|
||||||
|
|
||||||
|
|
||||||
|
{% if cache_type == 'redis' %}
|
||||||
|
[redis]
|
||||||
|
# This section deals with the database location and how to access it
|
||||||
|
# Please note that at the moment, we have support for only postgresqa.
|
||||||
|
# Example, if you are Batman, your config would be:
|
||||||
|
url = "{{ mcaptcha_redis_url }}" #"redis://127.0.0.1"
|
||||||
|
pool = "{{ mcaptcha_redis_pool | default(4) }}" #4
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
[smtp]
|
||||||
|
from = "{{ mcaptcha_smtp_from }}" # "admin@localhost"
|
||||||
|
reply = "{{ mcaptcha_smtp_reply }}" #"admin@localhost"
|
||||||
|
url = "{{ mcaptcha_smtp_url }}" #"127.0.0.1"
|
||||||
|
port = "{{ mcaptcha_smtp_port }}" #10025
|
||||||
|
username = "{{ mcaptcha_smtp_username }}" #"admin"
|
||||||
|
password = "{{ mcaptcha_smtp_password }}" #"password"
|
||||||
|
|
||||||
|
#[survey]
|
||||||
|
#nodes = ["http://localhost:7001"]
|
||||||
|
#rate_limit = 10 # upload every hour
|
||||||
|
#instance_root_url = "http://localhost:7000"
|
12
ansible/templates/mcaptcha/nginx.vhost.j2
Normal file
12
ansible/templates/mcaptcha/nginx.vhost.j2
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name {{ mcaptcha_server_hostname }};
|
||||||
|
error_log /var/log/nginx/"{{ mcaptcha_server_hostname }}".error.log;
|
||||||
|
access_log /var/log/nginx/"{{ mcaptcha_server_hostname }}".access.log;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://{{ mcaptcha_server_bind }}:{{ mcaptcha_server_port }};
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
}
|
||||||
|
}
|
3
ansible/vars/mcaptcha/db-common.yml
Normal file
3
ansible/vars/mcaptcha/db-common.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
database_owner: "mcaptcha"
|
||||||
|
database_name: "mcaptcha"
|
||||||
|
database_password: "{{ lookup('ansible.builtin.password', 'credentials/database_password', chars=['ascii_leters', 'digits'], length=32) }}"
|
136
ansible/vars/mcaptcha/mariadb.yml
Normal file
136
ansible/vars/mcaptcha/mariadb.yml
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
---
|
||||||
|
# Set this to the user ansible is logging in as - should have root
|
||||||
|
# or sudo access
|
||||||
|
mysql_user_home: /home/atm
|
||||||
|
mysql_user_name: atm
|
||||||
|
|
||||||
|
# The default root user installed by mysql - almost always root
|
||||||
|
mysql_root_home: /root
|
||||||
|
mysql_root_username: root
|
||||||
|
mysql_root_password: root
|
||||||
|
|
||||||
|
# Set this to `true` to forcibly update the root password.
|
||||||
|
mysql_root_password_update: true
|
||||||
|
mysql_user_password_update: true
|
||||||
|
|
||||||
|
mysql_enabled_on_startup: true
|
||||||
|
|
||||||
|
# Whether my.cnf should be updated on every run.
|
||||||
|
overwrite_global_mycnf: true
|
||||||
|
|
||||||
|
# The following variables have a default value depending on operating system.
|
||||||
|
# mysql_config_file: /etc/my.cnf
|
||||||
|
# mysql_config_include_dir: /etc/my.cnf.d
|
||||||
|
|
||||||
|
# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). Used only
|
||||||
|
# for RedHat systems (and derivatives).
|
||||||
|
mysql_enablerepo: ""
|
||||||
|
|
||||||
|
# Define a custom list of packages to install; if none provided, the default
|
||||||
|
# package list from vars/[OS-family].yml will be used.
|
||||||
|
# mysql_packages:
|
||||||
|
# - mysql
|
||||||
|
# - mysql-server
|
||||||
|
# - MySQL-python
|
||||||
|
|
||||||
|
mysql_python_package_debian: python3-mysqldb
|
||||||
|
|
||||||
|
# MySQL connection settings.
|
||||||
|
mysql_port: "3306"
|
||||||
|
mysql_bind_address: '0.0.0.0'
|
||||||
|
mysql_skip_name_resolve: false
|
||||||
|
mysql_datadir: /var/lib/mysql
|
||||||
|
mysql_sql_mode: ~
|
||||||
|
# The following variables have a default value depending on operating system.
|
||||||
|
# mysql_pid_file: /var/run/mysqld/mysqld.pid
|
||||||
|
# mysql_socket: /var/lib/mysql/mysql.sock
|
||||||
|
|
||||||
|
# Log file settings.
|
||||||
|
mysql_log_file_group: mysql
|
||||||
|
|
||||||
|
# Slow query log settings.
|
||||||
|
mysql_slow_query_log_enabled: false
|
||||||
|
mysql_slow_query_time: "2"
|
||||||
|
# The following variable has a default value depending on operating system.
|
||||||
|
# mysql_slow_query_log_file: /var/log/mysql-slow.log
|
||||||
|
|
||||||
|
# Memory settings (default values optimized ~512MB RAM).
|
||||||
|
mysql_key_buffer_size: "256M"
|
||||||
|
mysql_max_allowed_packet: "64M"
|
||||||
|
mysql_table_open_cache: "256"
|
||||||
|
mysql_sort_buffer_size: "1M"
|
||||||
|
mysql_read_buffer_size: "1M"
|
||||||
|
mysql_read_rnd_buffer_size: "4M"
|
||||||
|
mysql_myisam_sort_buffer_size: "64M"
|
||||||
|
mysql_thread_cache_size: "8"
|
||||||
|
mysql_query_cache_type: "0"
|
||||||
|
mysql_query_cache_size: "16M"
|
||||||
|
mysql_query_cache_limit: "1M"
|
||||||
|
mysql_max_connections: "151"
|
||||||
|
mysql_tmp_table_size: "16M"
|
||||||
|
mysql_max_heap_table_size: "16M"
|
||||||
|
mysql_group_concat_max_len: "1024"
|
||||||
|
mysql_join_buffer_size: "262144"
|
||||||
|
|
||||||
|
# Other settings.
|
||||||
|
mysql_lower_case_table_names: "0"
|
||||||
|
mysql_wait_timeout: "28800"
|
||||||
|
mysql_event_scheduler_state: "OFF"
|
||||||
|
|
||||||
|
# InnoDB settings.
|
||||||
|
mysql_innodb_file_per_table: "1"
|
||||||
|
# Set .._buffer_pool_size up to 80% of RAM but beware of setting too high.
|
||||||
|
mysql_innodb_buffer_pool_size: "256M"
|
||||||
|
# Set .._log_file_size to 25% of buffer pool size.
|
||||||
|
mysql_innodb_log_file_size: "64M"
|
||||||
|
mysql_innodb_log_buffer_size: "8M"
|
||||||
|
mysql_innodb_flush_log_at_trx_commit: "1"
|
||||||
|
mysql_innodb_lock_wait_timeout: "50"
|
||||||
|
|
||||||
|
# These settings require MySQL > 5.5.
|
||||||
|
mysql_innodb_large_prefix: "1"
|
||||||
|
mysql_innodb_file_format: "barracuda"
|
||||||
|
|
||||||
|
# mysqldump settings.
|
||||||
|
mysql_mysqldump_max_allowed_packet: "64M"
|
||||||
|
|
||||||
|
# Logging settings.
|
||||||
|
mysql_log: ""
|
||||||
|
# The following variables have a default value depending on operating system.
|
||||||
|
# mysql_log_error: /var/log/mysql/mysql.err
|
||||||
|
# mysql_syslog_tag: mysql
|
||||||
|
|
||||||
|
mysql_config_include_files: []
|
||||||
|
# - src: path/relative/to/playbook/file.cnf
|
||||||
|
# - { src: path/relative/to/playbook/anotherfile.cnf, force: yes }
|
||||||
|
|
||||||
|
# Databases.
|
||||||
|
mysql_databases:
|
||||||
|
- name: mcaptcha
|
||||||
|
collation: utf8_general_ci
|
||||||
|
encoding: utf8
|
||||||
|
replicate: 1
|
||||||
|
|
||||||
|
# Users.
|
||||||
|
mysql_users:
|
||||||
|
- name: mcaptcha
|
||||||
|
priv: "mcaptcha.*:ALL"
|
||||||
|
password: "{{ database_password }}"
|
||||||
|
|
||||||
|
mysql_disable_log_bin: false
|
||||||
|
|
||||||
|
# Replication settings (replication is only enabled if master/user have values).
|
||||||
|
mysql_server_id: "1"
|
||||||
|
mysql_max_binlog_size: "100M"
|
||||||
|
mysql_binlog_format: "ROW"
|
||||||
|
mysql_expire_logs_days: "10"
|
||||||
|
mysql_replication_role: ''
|
||||||
|
mysql_replication_master: ''
|
||||||
|
mysql_replication_master_inventory_host: "{{ mysql_replication_master }}"
|
||||||
|
|
||||||
|
# Same keys as `mysql_users` above.
|
||||||
|
mysql_replication_user:
|
||||||
|
- name: mcaptcha
|
||||||
|
host: 127.0.0.1
|
||||||
|
|
||||||
|
mysql_hide_passwords: false
|
61
ansible/vars/mcaptcha/mcaptcha.yml
Normal file
61
ansible/vars/mcaptcha/mcaptcha.yml
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
mcaptcha_debug: false
|
||||||
|
# mcaptcha_source_code: 'https://github.com/mCaptcha/mCaptcha'
|
||||||
|
mcaptcha_commercial: false
|
||||||
|
mcaptcha_allow_demo: false
|
||||||
|
mcaptcha_allow_registration: false
|
||||||
|
|
||||||
|
# Please set a unique value, your mCaptcha instance's security depends on this being
|
||||||
|
# unique
|
||||||
|
mcaptcha_server_cookie_secret: "{{ lookup('ansible.builtin.password', 'credentials/mcaptcha_server_cookie_secret', chars=['ascii_leters', 'digits'], length=32) }}"
|
||||||
|
mcaptcha_server_port: 7000
|
||||||
|
mcaptcha_server_bind: "127.0.0.1"
|
||||||
|
mcaptcha_server_hostname: "mcaptcha.local"
|
||||||
|
# Set true if you have setup TLS with a reverse proxy like Nginx.
|
||||||
|
# Does HTTPS redirect and sends additional headers that can only be used if
|
||||||
|
# HTTPS available to improve security
|
||||||
|
#mcaptcha_proxy_has_tls: false
|
||||||
|
|
||||||
|
# Please set a unique value, your mCaptcha instance's security depends on this being
|
||||||
|
# unique
|
||||||
|
mcaptcha_captcha_salt: "{{ lookup('ansible.builtin.password', 'credentials/mcaptcha_captha_salt', chars=['ascii_leters', 'digits'], length=32) }}"
|
||||||
|
# garbage collection period to manage mCaptcha system
|
||||||
|
# leave untouched if you don't know what you are doing
|
||||||
|
# mcaptcha_captcha_gc: 30
|
||||||
|
# mcaptcha_captcha_runners: 4
|
||||||
|
# mcaptcha_captcha_queue_length: 2000
|
||||||
|
mcaptcha_captcha_enable_stats: true
|
||||||
|
|
||||||
|
#mcaptcha_captcha_default_difficulty_strategy_avg_traffic_difficulty: 50000 # almost instant solution
|
||||||
|
#mcaptcha_captcha_default_difficulty_strategy_peak_sustainable_traffic_difficulty: 3000000 # roughly 1.5s
|
||||||
|
#mcaptcha_captcha_default_difficulty_strategy_broke_my_site_traffic_difficulty: 5000000 # greater than 3.5s
|
||||||
|
# cooldown period in seconds
|
||||||
|
mcaptcha_captcha_default_difficulty_strategy_avg_duration: 30
|
||||||
|
|
||||||
|
#{% if database_type == 'postgres' %}
|
||||||
|
# {% set mcaptcha_database_url = "postgres://{{ database_owner }}:{{ database_password }}@localhost:5432/{{ database_name }}" %}
|
||||||
|
#{% else %}
|
||||||
|
# {% set mcaptcha_database_url = "mysql://{{ database_owner }}:{{ database_password }}@localhost/{{ database_name }}" %}
|
||||||
|
#{% endif %}
|
||||||
|
#mcaptcha_database_url: "mysql://{{ database_owner }}:{{ database_password }}@localhost/{{ database_name }}"
|
||||||
|
#mcaptcha_database_url: "postgres://{{ database_owner }}:{{ database_password }}@localhost:5432/{{ database_name }}"
|
||||||
|
# mysql://mcaptcha:password@localhost/mcaptcha"
|
||||||
|
mcaptcha_database_pool: 4
|
||||||
|
#mcaptcha_database_url: "{{ mcaptcha_database_url }}"
|
||||||
|
|
||||||
|
mcaptcha_redis_url: "redis://127.0.0.1"
|
||||||
|
mcaptcha_redis_pool: 4
|
||||||
|
|
||||||
|
mcaptcha_redis_url: "redis://127.0.0.1"
|
||||||
|
mcaptcha_redis_pool: 4
|
||||||
|
|
||||||
|
|
||||||
|
mcaptcha_smtp_from: "admin@localhost"
|
||||||
|
mcaptcha_smtp_reply: "admin@localhost"
|
||||||
|
mcaptcha_smtp_url: "127.0.0.1"
|
||||||
|
mcaptcha_smtp_port: 10025
|
||||||
|
mcaptcha_smtp_username: "admin"
|
||||||
|
mcaptcha_smtp_password: "password"
|
||||||
|
#[survey]
|
||||||
|
#nodes = ["http://localhost:7001"]
|
||||||
|
#rate_limit = 10 # upload every hour
|
||||||
|
#instance_root_url = "http://localhost:7000"
|
48
ansible/vars/mcaptcha/postgresql.yml
Normal file
48
ansible/vars/mcaptcha/postgresql.yml
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
# Set postgresql state when configuration changes are made. Recommended values:
|
||||||
|
# `restarted` or `reloaded`
|
||||||
|
postgresql_restarted_state: "restarted"
|
||||||
|
|
||||||
|
postgresql_python_library: python-psycopg2
|
||||||
|
postgresql_user: postgres
|
||||||
|
postgresql_group: postgres
|
||||||
|
|
||||||
|
# `md5` or `scram-sha-256` (https://www.postgresql.org/docs/10/auth-methods.html)
|
||||||
|
postgresql_auth_method: "md5"
|
||||||
|
|
||||||
|
postgresql_unix_socket_directories:
|
||||||
|
- /var/run/postgresql
|
||||||
|
|
||||||
|
postgresql_service_state: started
|
||||||
|
postgresql_service_enabled: true
|
||||||
|
|
||||||
|
# Global configuration options that will be set in postgresql.conf.
|
||||||
|
postgresql_global_config_options:
|
||||||
|
- option: unix_socket_directories
|
||||||
|
value: '{{ postgresql_unix_socket_directories | join(",") }}'
|
||||||
|
- option: log_directory
|
||||||
|
value: 'log'
|
||||||
|
|
||||||
|
# Host based authentication (hba) entries to be added to the pg_hba.conf. This
|
||||||
|
# variable's defaults reflect the defaults that come with a fresh installation.
|
||||||
|
postgresql_hba_entries:
|
||||||
|
- {type: local, database: all, user: postgres, auth_method: peer}
|
||||||
|
- {type: local, database: all, user: all, auth_method: peer}
|
||||||
|
- {type: host, database: all, user: all, address: '127.0.0.1/32', auth_method: "{{ postgresql_auth_method }}"}
|
||||||
|
- {type: host, database: all, user: all, address: '::1/128', auth_method: "{{ postgresql_auth_method }}"}
|
||||||
|
|
||||||
|
# Debian only. Used to generate the locales used by PostgreSQL databases.
|
||||||
|
postgresql_locales:
|
||||||
|
- 'en_US.UTF-8'
|
||||||
|
|
||||||
|
# Users to ensure exist.
|
||||||
|
postgresql_users:
|
||||||
|
- name: "{{ database_owner }}" #required; the rest are optional
|
||||||
|
password: "{{ database_password }}"
|
||||||
|
|
||||||
|
# Databases to ensure exist.
|
||||||
|
postgresql_databases:
|
||||||
|
- name: "{{ database_name }}" # required; the rest are optional
|
||||||
|
owner: "{{ database_owner }}"
|
||||||
|
|
||||||
|
# Whether to output user data when managing users.
|
||||||
|
postgres_users_no_log: true
|
2
ansible/vars/mcaptcha/vars.yml
Normal file
2
ansible/vars/mcaptcha/vars.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
database_type: "postgres" # options: "mariadb", "postgres"
|
||||||
|
cache_type: "redis" # options: "embedded", "redis"
|
39
tests/mcaptcha/base.py
Normal file
39
tests/mcaptcha/base.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
def test_mcaptcha_nginx_is_listening(host):
|
||||||
|
socket = host.socket(f"tcp://127.0.0.1:80")
|
||||||
|
assert socket.is_listening
|
||||||
|
|
||||||
|
|
||||||
|
def test_mcaptcha_config_exists(host):
|
||||||
|
config = host.file("/etc/mcaptcha/config.toml")
|
||||||
|
assert config.exists
|
||||||
|
assert config.is_file
|
||||||
|
|
||||||
|
|
||||||
|
def test_mcaptcha_health(host):
|
||||||
|
url = f"http://{host.interface.default().addresses[0]}/api/v1/meta/health"
|
||||||
|
resp = requests.get(url, headers={"Host": "mcaptcha.local"})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
if "redis" in data:
|
||||||
|
assert data["redis"] is True
|
||||||
|
assert data["db"] is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_nginx_service_running_and_enabled(host):
|
||||||
|
service = host.service("nginx")
|
||||||
|
assert service.is_running
|
||||||
|
assert service.is_enabled
|
||||||
|
|
||||||
|
|
||||||
|
def test_mcaptcha_service_running_and_enabled(host):
|
||||||
|
service = host.service("mcaptcha")
|
||||||
|
assert service.is_running
|
||||||
|
assert service.is_enabled
|
Loading…
Reference in a new issue