diff options
| author | Miguel Dalberto Pedro <miguel.pedro@precisioninno.com> | 2026-10-29 12:48:06 -0300 |
|---|---|---|
| committer | Miguel Dalberto Pedro <miguel.pedro@precisioninno.com> | 2026-10-29 12:48:06 -0300 |
| commit | 4b7379914a1865f07b2c54252234cc90158fc253 (patch) | |
| tree | a476c7e08bb994034d7d04b5b1cdfce216f49c43 /roles | |
| download | my-infra-4b7379914a1865f07b2c54252234cc90158fc253.tar.gz my-infra-4b7379914a1865f07b2c54252234cc90158fc253.zip | |
feat(iac): establish Ansible baseline for Nginx, SearXNG, Valkey, and Certbot
- Reverse-engineer live Debian 13 (trixie) VPS state at miguelpedro.xyz.br
- Add modular Ansible roles: common, certbot, valkey, searxng, and nginx
- Encrypt SearXNG secret_key using ansible-vault in group_vars/all/vault.yml
- Cleanly remove unused example.com Nginx stub symlink (sites-enabled/miguelpedro.xyz.br)
- Scaffold cgit + fcgiwrap role (cgit_enabled: false) for upcoming deployment
- Add DISCOVERY_REPORT.md, COMMAND_LOG.md, README.md, and AGENT_INSTRUCTIONS.md with Self-Updating Protocol
Diffstat (limited to 'roles')
| -rw-r--r-- | roles/certbot/tasks/main.yml | 23 | ||||
| -rw-r--r-- | roles/cgit/tasks/main.yml | 47 | ||||
| -rw-r--r-- | roles/cgit/templates/cgitrc.j2 | 26 | ||||
| -rw-r--r-- | roles/cgit/templates/site-cgit.conf.j2 | 21 | ||||
| -rw-r--r-- | roles/common/tasks/main.yml | 26 | ||||
| -rw-r--r-- | roles/nginx/handlers/main.yml | 11 | ||||
| -rw-r--r-- | roles/nginx/tasks/main.yml | 87 | ||||
| -rw-r--r-- | roles/nginx/templates/default-app-searxng.conf.j2 | 23 | ||||
| -rw-r--r-- | roles/nginx/templates/nginx.conf.j2 | 84 | ||||
| -rw-r--r-- | roles/nginx/templates/site-default.conf.j2 | 173 | ||||
| -rw-r--r-- | roles/nginx/templates/site-searxng.conf.j2 | 47 | ||||
| -rw-r--r-- | roles/searxng/handlers/main.yml | 5 | ||||
| -rw-r--r-- | roles/searxng/tasks/main.yml | 84 | ||||
| -rw-r--r-- | roles/searxng/templates/limiter.toml.j2 | 49 | ||||
| -rw-r--r-- | roles/searxng/templates/settings.yml.j2 | 25 | ||||
| -rw-r--r-- | roles/searxng/templates/uwsgi-searxng.ini.j2 | 78 | ||||
| -rw-r--r-- | roles/valkey/tasks/main.yml | 12 |
17 files changed, 821 insertions, 0 deletions
diff --git a/roles/certbot/tasks/main.yml b/roles/certbot/tasks/main.yml new file mode 100644 index 0000000..02e8c0b --- /dev/null +++ b/roles/certbot/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: Ensure Certbot and Nginx plugin are installed + ansible.builtin.apt: + name: + - certbot + - python3-certbot-nginx + state: present + +- name: Ensure certbot renewal timer is enabled and active + ansible.builtin.systemd: + name: certbot.timer + enabled: true + state: started + +- name: Verify primary domain TLS certificate exists + ansible.builtin.stat: + path: "/etc/letsencrypt/live/{{ primary_domain }}/fullchain.pem" + register: primary_cert + +- name: Verify SearXNG domain TLS certificate exists + ansible.builtin.stat: + path: "/etc/letsencrypt/live/{{ searxng_domain }}/fullchain.pem" + register: searxng_cert diff --git a/roles/cgit/tasks/main.yml b/roles/cgit/tasks/main.yml new file mode 100644 index 0000000..44f9459 --- /dev/null +++ b/roles/cgit/tasks/main.yml @@ -0,0 +1,47 @@ +--- +- name: Install cgit and FastCGI dependencies + ansible.builtin.apt: + name: + - cgit + - fcgiwrap + - python3-pygments + - python3-markdown + state: present + +- name: Ensure Git repositories root directory exists + ansible.builtin.file: + path: "{{ cgit_repos_path }}" + state: directory + owner: www-data + group: www-data + mode: "0755" + +- name: Deploy /etc/cgitrc configuration + ansible.builtin.template: + src: cgitrc.j2 + dest: /etc/cgitrc + owner: root + group: root + mode: "0644" + +- name: Ensure fcgiwrap socket/service is enabled and running + ansible.builtin.systemd: + name: fcgiwrap.socket + enabled: true + state: started + +- name: Deploy Nginx virtual host for cgit + ansible.builtin.template: + src: site-cgit.conf.j2 + dest: /etc/nginx/sites-available/cgit.conf + owner: root + group: root + mode: "0644" + notify: Reload nginx + +- name: Enable Nginx virtual host for cgit + ansible.builtin.file: + src: /etc/nginx/sites-available/cgit.conf + dest: /etc/nginx/sites-enabled/cgit.conf + state: link + notify: Reload nginx diff --git a/roles/cgit/templates/cgitrc.j2 b/roles/cgit/templates/cgitrc.j2 new file mode 100644 index 0000000..0cae2ab --- /dev/null +++ b/roles/cgit/templates/cgitrc.j2 @@ -0,0 +1,26 @@ +# /etc/cgitrc - Managed by Ansible +css=/cgit-css/cgit.css +logo=/cgit-css/cgit.png +favicon=/cgit-css/favicon.ico + +root-title={{ cgit_title }} +root-desc={{ cgit_description }} +virtual-root=/ + +enable-index-links=1 +enable-index-owner=0 +enable-commit-graph=1 +enable-log-filecount=1 +enable-log-linecount=1 +snapshots=tar.gz zip + +about-filter=/usr/lib/cgit/filters/about-formatting.sh +source-filter=/usr/lib/cgit/filters/syntax-highlighting.py + +readme=:README.md +readme=:readme.md +readme=:README.rst +readme=:README.txt +readme=:README + +scan-path={{ cgit_repos_path }} diff --git a/roles/cgit/templates/site-cgit.conf.j2 b/roles/cgit/templates/site-cgit.conf.j2 new file mode 100644 index 0000000..557c364 --- /dev/null +++ b/roles/cgit/templates/site-cgit.conf.j2 @@ -0,0 +1,21 @@ +server { + listen 80; + listen [::]:80; + server_name {{ cgit_domain }}; + + root /usr/share/cgit; + try_files $uri @cgit; + + location ~* ^/cgit-css/(.*)$ { + alias /usr/share/cgit/$1; + } + + location @cgit { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi; + fastcgi_param PATH_INFO $uri; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $server_name; + fastcgi_pass unix:/run/fcgiwrap.socket; + } +} diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml new file mode 100644 index 0000000..413a3dd --- /dev/null +++ b/roles/common/tasks/main.yml @@ -0,0 +1,26 @@ +--- +- name: Ensure base system and build dependencies are installed + ansible.builtin.apt: + name: + - build-essential + - ca-certificates + - curl + - git + - libffi-dev + - libssl-dev + - libxslt1-dev + - nftables + - python-is-python3 + - python3 + - python3-babel + - python3-dev + - python3-venv + - screen + - shellcheck + - uwsgi + - uwsgi-plugin-python3 + - vim + - wget + - zlib1g-dev + state: present + update_cache: false diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml new file mode 100644 index 0000000..3940edb --- /dev/null +++ b/roles/nginx/handlers/main.yml @@ -0,0 +1,11 @@ +--- +- name: Validate and reload nginx + ansible.builtin.command: /usr/sbin/nginx -t + changed_when: false + notify: Reload nginx service + +- name: Reload nginx service + ansible.builtin.systemd: + name: nginx.service + state: reloaded + listen: Reload nginx diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml new file mode 100644 index 0000000..c4f55b6 --- /dev/null +++ b/roles/nginx/tasks/main.yml @@ -0,0 +1,87 @@ +--- +- name: Ensure nginx is installed + ansible.builtin.apt: + name: + - nginx + state: present + +- name: Ensure Nginx directories exist + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: root + group: root + mode: "0755" + loop: + - /etc/nginx/sites-available + - /etc/nginx/sites-enabled + - /etc/nginx/default.apps-available + - /etc/nginx/default.d + - "{{ default_web_root }}" + +- name: Deploy /etc/nginx/nginx.conf + ansible.builtin.template: + src: nginx.conf.j2 + dest: /etc/nginx/nginx.conf + owner: root + group: root + mode: "0644" + validate: "/usr/sbin/nginx -t -c %s" + notify: Reload nginx + +- name: Deploy /etc/nginx/default.apps-available/searxng.conf + ansible.builtin.template: + src: default-app-searxng.conf.j2 + dest: /etc/nginx/default.apps-available/searxng.conf + owner: root + group: root + mode: "0644" + notify: Reload nginx + +- name: Enable /etc/nginx/default.d/searxng.conf symlink + ansible.builtin.file: + src: /etc/nginx/default.apps-available/searxng.conf + dest: /etc/nginx/default.d/searxng.conf + state: link + notify: Reload nginx + +- name: Deploy /etc/nginx/sites-available/default + ansible.builtin.template: + src: site-default.conf.j2 + dest: /etc/nginx/sites-available/default + owner: root + group: root + mode: "0644" + notify: Reload nginx + +- name: Deploy /etc/nginx/sites-available/searxng.conf + ansible.builtin.template: + src: site-searxng.conf.j2 + dest: /etc/nginx/sites-available/searxng.conf + owner: root + group: root + mode: "0644" + notify: Reload nginx + +- name: Enable active Nginx sites + ansible.builtin.file: + src: "/etc/nginx/sites-available/{{ item }}" + dest: "/etc/nginx/sites-enabled/{{ item }}" + state: link + loop: + - default + - searxng.conf + notify: Reload nginx + +- name: Remove unused/stub Nginx site symlinks (clean tracking) + ansible.builtin.file: + path: "/etc/nginx/sites-enabled/{{ item }}" + state: absent + loop: "{{ nginx_remove_unused_sites | default([]) }}" + notify: Reload nginx + +- name: Ensure nginx service is enabled and running + ansible.builtin.systemd: + name: nginx.service + enabled: true + state: started diff --git a/roles/nginx/templates/default-app-searxng.conf.j2 b/roles/nginx/templates/default-app-searxng.conf.j2 new file mode 100644 index 0000000..66b1f86 --- /dev/null +++ b/roles/nginx/templates/default-app-searxng.conf.j2 @@ -0,0 +1,23 @@ +location /searxng { + + uwsgi_pass unix://{{ searxng_socket_path }}; + + include uwsgi_params; + + uwsgi_param HTTP_HOST $host; + uwsgi_param HTTP_CONNECTION $http_connection; + + # see flaskfix.py + uwsgi_param HTTP_X_FORWARDED_PROTO $scheme; + uwsgi_param HTTP_X_SCRIPT_NAME /searxng; + + # see botdetection/trusted_proxies.py + uwsgi_param HTTP_X_REAL_IP $remote_addr; + uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; +} + +# To serve the static files via the HTTP server +# +# location /searxng/static/ { +# alias /usr/local/searxng/searxng-src/searx/static/; +# } diff --git a/roles/nginx/templates/nginx.conf.j2 b/roles/nginx/templates/nginx.conf.j2 new file mode 100644 index 0000000..68a8fd4 --- /dev/null +++ b/roles/nginx/templates/nginx.conf.j2 @@ -0,0 +1,84 @@ +user www-data; +worker_processes auto; +worker_cpu_affinity auto; +pid /run/nginx.pid; +error_log /var/log/nginx/error.log; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + types_hash_max_size 2048; + server_tokens off; # Recommended practice is to turn this off + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3 (POODLE), TLS 1.0, 1.1 + ssl_prefer_server_ciphers off; # Don't force server cipher order. + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + + ## + # Gzip Settings + ## + + gzip on; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} + + +#mail { +# # See sample authentication script at: +# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript +# +# # auth_http localhost/auth.php; +# # pop3_capabilities "TOP" "USER"; +# # imap_capabilities "IMAP4rev1" "UIDPLUS"; +# +# server { +# listen localhost:110; +# protocol pop3; +# proxy on; +# } +# +# server { +# listen localhost:143; +# protocol imap; +# proxy on; +# } +#} diff --git a/roles/nginx/templates/site-default.conf.j2 b/roles/nginx/templates/site-default.conf.j2 new file mode 100644 index 0000000..2542a3a --- /dev/null +++ b/roles/nginx/templates/site-default.conf.j2 @@ -0,0 +1,173 @@ +## +# You should look at the following URL's in order to grasp a solid understanding +# of Nginx configuration files in order to fully unleash the power of Nginx. +# https://www.nginx.com/resources/wiki/start/ +# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/ +# https://wiki.debian.org/Nginx/DirectoryStructure +# +# In most cases, administrators will remove this file from sites-enabled/ and +# leave it as reference inside of sites-available where it will continue to be +# updated by the nginx packaging team. +# +# This file will automatically load configuration files provided by other +# applications, such as Drupal or Wordpress. These applications will be made +# available underneath a path with that package name, such as /drupal8. +# +# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. +## + +# Default server configuration +# +server { + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + listen 80 default_server; + listen [::]:80 default_server; + + # SSL configuration + # + # listen 443 ssl default_server; + # listen [::]:443 ssl default_server; + # + # Note: You should disable gzip for SSL traffic. + # See: https://bugs.debian.org/773332 + # + # Read up on ssl_ciphers to ensure a secure configuration. + # See: https://bugs.debian.org/765782 + # + # Self signed certs generated by the ssl-cert package + # Don't use them in a production server! + # + # include snippets/snakeoil.conf; + + root {{ default_web_root }}; + + # Add index.php to the list if you are using PHP + index index.html index.htm index.nginx-debian.html; + + server_name _; + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + # pass PHP scripts to FastCGI server + # + #location ~ \.php$ { + # include snippets/fastcgi-php.conf; + # + # # With php-fpm (or other unix sockets): + # fastcgi_pass unix:/run/php/php7.4-fpm.sock; + # # With php-cgi (or other tcp sockets): + # fastcgi_pass 127.0.0.1:9000; + #} + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} +} + + +# Virtual Host configuration for example.com +# +# You can move that to a different file under sites-available/ and symlink that +# to sites-enabled/ to enable it. +# +#server { +# listen 80; +# listen [::]:80; +# +# server_name example.com; +# +# root /var/www/example.com; +# index index.html; +# +# location / { +# try_files $uri $uri/ =404; +# } +#} + +server { + + # SSL configuration + # + # listen 443 ssl default_server; + # listen [::]:443 ssl default_server; + # + # Note: You should disable gzip for SSL traffic. + # See: https://bugs.debian.org/773332 + # + # Read up on ssl_ciphers to ensure a secure configuration. + # See: https://bugs.debian.org/765782 + # + # Self signed certs generated by the ssl-cert package + # Don't use them in a production server! + # + # include snippets/snakeoil.conf; + + root {{ default_web_root }}; + + # Add index.php to the list if you are using PHP + index index.html index.htm index.nginx-debian.html; + server_name {{ primary_domain_aliases | join(' ') }} {{ primary_domain }}; # managed by Certbot + + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + # pass PHP scripts to FastCGI server + # + #location ~ \.php$ { + # include snippets/fastcgi-php.conf; + # + # # With php-fpm (or other unix sockets): + # fastcgi_pass unix:/run/php/php7.4-fpm.sock; + # # With php-cgi (or other tcp sockets): + # fastcgi_pass 127.0.0.1:9000; + #} + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} + + + listen 443 ssl; # managed by Certbot + listen [::]:443 ssl ipv6only=on; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/{{ primary_domain }}/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/{{ primary_domain }}/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot + + + +} +server { +{% for alias in primary_domain_aliases %} + if ($host = {{ alias }}) { + return 301 https://$host$request_uri; + } # managed by Certbot + + +{% endfor %} + if ($host = {{ primary_domain }}) { + return 301 https://$host$request_uri; + } # managed by Certbot + + + listen 80 ; + listen [::]:80 ; + server_name {{ primary_domain_aliases | join(' ') }} {{ primary_domain }}; + return 404; # managed by Certbot +} diff --git a/roles/nginx/templates/site-searxng.conf.j2 b/roles/nginx/templates/site-searxng.conf.j2 new file mode 100644 index 0000000..67a5a2d --- /dev/null +++ b/roles/nginx/templates/site-searxng.conf.j2 @@ -0,0 +1,47 @@ +server { + server_name {{ searxng_domain }}; + + # Disable logging for user privacy + access_log /dev/null; + error_log /dev/null; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + uwsgi_pass unix://{{ searxng_socket_path }}; + + include uwsgi_params; + + uwsgi_param HTTP_HOST $host; + uwsgi_param HTTP_CONNECTION $http_connection; + + # see flaskfix.py + uwsgi_param HTTP_X_SCHEME $scheme; + + # see limiter.py + uwsgi_param HTTP_X_REAL_IP $remote_addr; + uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for; + } + + listen 443 ssl; # managed by Certbot + listen [::]:443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/{{ searxng_domain }}/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/{{ searxng_domain }}/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot +} + +server { + if ($host = {{ searxng_domain }}) { + return 301 https://$host$request_uri; + } # managed by Certbot + + listen 80; + listen [::]:80; + server_name {{ searxng_domain }}; + return 404; # managed by Certbot +} diff --git a/roles/searxng/handlers/main.yml b/roles/searxng/handlers/main.yml new file mode 100644 index 0000000..e049618 --- /dev/null +++ b/roles/searxng/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart uwsgi + ansible.builtin.service: + name: uwsgi + state: restarted diff --git a/roles/searxng/tasks/main.yml b/roles/searxng/tasks/main.yml new file mode 100644 index 0000000..c7d45d4 --- /dev/null +++ b/roles/searxng/tasks/main.yml @@ -0,0 +1,84 @@ +--- +- name: Ensure searxng system group exists + ansible.builtin.group: + name: "{{ searxng_group }}" + gid: "{{ searxng_gid }}" + system: true + state: present + +- name: Ensure searxng system user exists + ansible.builtin.user: + name: "{{ searxng_user }}" + uid: "{{ searxng_uid }}" + group: "{{ searxng_group }}" + groups: sudo + append: true + comment: "Privacy-respecting metasearch engine" + home: "{{ searxng_home }}" + shell: /bin/bash + system: true + state: present + +- name: Ensure SearXNG directories exist + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + owner: "{{ item.owner }}" + group: "{{ item.group }}" + mode: "{{ item.mode }}" + loop: + - { path: "{{ searxng_home }}", owner: "{{ searxng_user }}", group: "{{ searxng_group }}", mode: "0755" } + - { path: "{{ searxng_home }}/.ansible/tmp", owner: "{{ searxng_user }}", group: "{{ searxng_group }}", mode: "0700" } + - { path: "{{ searxng_run_dir }}", owner: "{{ searxng_user }}", group: "{{ searxng_group }}", mode: "0755" } + - { path: "/etc/searxng", owner: "root", group: "root", mode: "0755" } + - { path: "/etc/uwsgi/apps-available", owner: "root", group: "root", mode: "0755" } + - { path: "/etc/uwsgi/apps-enabled", owner: "root", group: "root", mode: "0755" } + +- name: Clone or update SearXNG source repository + ansible.builtin.git: + repo: "{{ searxng_git_repo }}" + dest: "{{ searxng_src_dir }}" + version: "{{ searxng_git_version }}" + update: false + become: true + become_user: "{{ searxng_user }}" + +- name: Deploy /etc/searxng/settings.yml + ansible.builtin.template: + src: settings.yml.j2 + dest: /etc/searxng/settings.yml + owner: "{{ searxng_user }}" + group: "{{ searxng_group }}" + mode: "0640" + notify: Restart uwsgi + +- name: Deploy /etc/searxng/limiter.toml + ansible.builtin.template: + src: limiter.toml.j2 + dest: /etc/searxng/limiter.toml + owner: "{{ searxng_user }}" + group: "{{ searxng_group }}" + mode: "0644" + notify: Restart uwsgi + +- name: Deploy uWSGI app configuration for SearXNG + ansible.builtin.template: + src: uwsgi-searxng.ini.j2 + dest: /etc/uwsgi/apps-available/searxng.ini + owner: root + group: root + mode: "0644" + notify: Restart uwsgi + +- name: Enable uWSGI SearXNG app symlink + ansible.builtin.file: + src: /etc/uwsgi/apps-available/searxng.ini + dest: /etc/uwsgi/apps-enabled/searxng.ini + state: link + notify: Restart uwsgi + +- name: Ensure uwsgi service is enabled and running + ansible.builtin.service: + name: uwsgi + enabled: true + state: started diff --git a/roles/searxng/templates/limiter.toml.j2 b/roles/searxng/templates/limiter.toml.j2 new file mode 100644 index 0000000..0b40bf8 --- /dev/null +++ b/roles/searxng/templates/limiter.toml.j2 @@ -0,0 +1,49 @@ +[botdetection] + +# The prefix defines the number of leading bits in an address that are compared +# to determine whether or not an address is part of a (client) network. + +ipv4_prefix = 32 +ipv6_prefix = 48 + +# If the request IP is in trusted_proxies list, the client IP address is +# extracted from the X-Forwarded-For and X-Real-IP headers. This should be +# used if SearXNG is behind a reverse proxy or load balancer. + +trusted_proxies = [ + '127.0.0.0/8', + '::1', + # '192.168.0.0/16', + # '172.16.0.0/12', + # '10.0.0.0/8', + # 'fd00::/8', +] + +[botdetection.ip_limit] + +# To get unlimited access in a local network, by default link-local addresses +# (networks) are not monitored by the ip_limit +filter_link_local = false + +# activate link_token method in the ip_limit method +link_token = false + +[botdetection.ip_lists] + +# In the limiter, the ip_lists method has priority over all other methods -> if +# an IP is in the pass_ip list, it has unrestricted access and it is also not +# checked if e.g. the "user agent" suggests a bot (e.g. curl). + +block_ip = [ + # '93.184.216.34', # IPv4 of example.org + # '257.1.1.1', # invalid IP --> will be ignored, logged in ERROR class +] + +pass_ip = [ + # '192.168.0.0/16', # IPv4 private network + # 'fe80::/10' # IPv6 linklocal / wins over botdetection.ip_limit.filter_link_local +] + +# Activate passlist of (hardcoded) IPs from the SearXNG organization, +# e.g. `check.searx.space`. +pass_searxng_org = true diff --git a/roles/searxng/templates/settings.yml.j2 b/roles/searxng/templates/settings.yml.j2 new file mode 100644 index 0000000..ae23d6f --- /dev/null +++ b/roles/searxng/templates/settings.yml.j2 @@ -0,0 +1,25 @@ +# SearXNG settings + +use_default_settings: true + +general: + debug: false + instance_name: "{{ searxng_instance_name }}" + +search: + safe_search: 0 + autocomplete: "duckduckgo" + formats: + - html + - json + +server: + # Is overwritten by ${SEARXNG_SECRET} + secret_key: "{{ searxng_secret_key }}" + limiter: true + image_proxy: true + base_url: {{ searxng_base_url }} + +valkey: + # URL to connect valkey database. Is overwritten by ${SEARXNG_VALKEY_URL}. + url: {{ searxng_valkey_url }} diff --git a/roles/searxng/templates/uwsgi-searxng.ini.j2 b/roles/searxng/templates/uwsgi-searxng.ini.j2 new file mode 100644 index 0000000..87e333f --- /dev/null +++ b/roles/searxng/templates/uwsgi-searxng.ini.j2 @@ -0,0 +1,78 @@ +# -*- mode: conf; coding: utf-8 -*- +[uwsgi] + +# uWSGI core +# ---------- +# +# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core + +# Who will run the code / Hint: in emperor-tyrant mode uid & gid setting will be +# ignored [1]. Mode emperor-tyrant is the default on fedora (/etc/uwsgi.ini). +# +# [1] https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html#tyrant-mode-secure-multi-user-hosting +# +uid = {{ searxng_user }} +gid = {{ searxng_group }} + +# set (python) default encoding UTF-8 +env = LANG=C.UTF-8 +env = LANGUAGE=C.UTF-8 +env = LC_ALL=C.UTF-8 + +# chdir to specified directory before apps loading +chdir = {{ searxng_src_dir }}/searx + +# SearXNG configuration (settings.yml) +env = SEARXNG_SETTINGS_PATH=/etc/searxng/settings.yml + +# disable logging for privacy +disable-logging = true + +# The right granted on the created socket +chmod-socket = 666 + +# Plugin to use and interpreter config +single-interpreter = true + +# enable master process +master = true + +# load apps in each worker instead of the master +lazy-apps = true + +# load uWSGI plugins +plugin = python3,http + +# By default the Python plugin does not initialize the GIL. This means your +# app-generated threads will not run. If you need threads, remember to enable +# them with enable-threads. Running uWSGI in multithreading mode (with the +# threads options) will automatically enable threading support. This *strange* +# default behaviour is for performance reasons. +enable-threads = true + +# Number of workers (usually CPU count) +workers = %k +threads = 4 + +# plugin: python +# -------------- +# +# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python + +# load a WSGI module +module = searx.webapp + +# set PYTHONHOME/virtualenv +virtualenv = {{ searxng_venv_dir }} + +# add directory (or glob) to pythonpath +pythonpath = {{ searxng_src_dir }} + + +# speak to upstream +# ----------------- + +socket = {{ searxng_socket_path }} +buffer-size = 8192 + +offload-threads = %k diff --git a/roles/valkey/tasks/main.yml b/roles/valkey/tasks/main.yml new file mode 100644 index 0000000..553869a --- /dev/null +++ b/roles/valkey/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Ensure valkey-server is installed + ansible.builtin.apt: + name: + - valkey-server + state: present + +- name: Ensure valkey-server is enabled and running + ansible.builtin.systemd: + name: valkey-server.service + enabled: true + state: started |
