From 3002808f923bae6b8556f5cb471770be14b271d1 Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Sat, 9 Dec 2023 02:56:13 +0530 Subject: [PATCH] feat: optionally redis, mariadb and postgres and proxy mcaptcha w nginx --- ansible/artifacts/mcaptcha/mcaptcha.service | 29 +++++ ansible/mcaptcha.yml | 98 ++++++++++++++ ansible/templates/mcaptcha/config.toml.j2 | 81 ++++++++++++ ansible/templates/mcaptcha/nginx.vhost.j2 | 12 ++ ansible/vars/mcaptcha/db-common.yml | 3 + ansible/vars/mcaptcha/mariadb.yml | 136 ++++++++++++++++++++ ansible/vars/mcaptcha/postgresql.yml | 48 +++++++ ansible/vars/mcaptcha/vars.yml | 2 + 8 files changed, 409 insertions(+) create mode 100644 ansible/artifacts/mcaptcha/mcaptcha.service create mode 100644 ansible/mcaptcha.yml create mode 100644 ansible/templates/mcaptcha/config.toml.j2 create mode 100644 ansible/templates/mcaptcha/nginx.vhost.j2 create mode 100644 ansible/vars/mcaptcha/db-common.yml create mode 100644 ansible/vars/mcaptcha/mariadb.yml create mode 100644 ansible/vars/mcaptcha/postgresql.yml create mode 100644 ansible/vars/mcaptcha/vars.yml diff --git a/ansible/artifacts/mcaptcha/mcaptcha.service b/ansible/artifacts/mcaptcha/mcaptcha.service new file mode 100644 index 0000000..9889943 --- /dev/null +++ b/ansible/artifacts/mcaptcha/mcaptcha.service @@ -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 diff --git a/ansible/mcaptcha.yml b/ansible/mcaptcha.yml new file mode 100644 index 0000000..314f3d5 --- /dev/null +++ b/ansible/mcaptcha.yml @@ -0,0 +1,98 @@ +# SPDX-FileCopyrightText: 2023 Aravinth Manivannan +# +# 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" diff --git a/ansible/templates/mcaptcha/config.toml.j2 b/ansible/templates/mcaptcha/config.toml.j2 new file mode 100644 index 0000000..704e576 --- /dev/null +++ b/ansible/templates/mcaptcha/config.toml.j2 @@ -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" diff --git a/ansible/templates/mcaptcha/nginx.vhost.j2 b/ansible/templates/mcaptcha/nginx.vhost.j2 new file mode 100644 index 0000000..a16e8d6 --- /dev/null +++ b/ansible/templates/mcaptcha/nginx.vhost.j2 @@ -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; + } +} diff --git a/ansible/vars/mcaptcha/db-common.yml b/ansible/vars/mcaptcha/db-common.yml new file mode 100644 index 0000000..8146b87 --- /dev/null +++ b/ansible/vars/mcaptcha/db-common.yml @@ -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) }}" diff --git a/ansible/vars/mcaptcha/mariadb.yml b/ansible/vars/mcaptcha/mariadb.yml new file mode 100644 index 0000000..e142d47 --- /dev/null +++ b/ansible/vars/mcaptcha/mariadb.yml @@ -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 diff --git a/ansible/vars/mcaptcha/postgresql.yml b/ansible/vars/mcaptcha/postgresql.yml new file mode 100644 index 0000000..e379950 --- /dev/null +++ b/ansible/vars/mcaptcha/postgresql.yml @@ -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 diff --git a/ansible/vars/mcaptcha/vars.yml b/ansible/vars/mcaptcha/vars.yml new file mode 100644 index 0000000..2bc8542 --- /dev/null +++ b/ansible/vars/mcaptcha/vars.yml @@ -0,0 +1,2 @@ +database_type: "postgres" # options: "mariadb", "postgres" +cache_type: "redis" # options: "embedded", "redis"