fix: Prevent sensitive information from being logged (#14779)

* fix: Add no_log to tasks handling sensitive information

- Add no_log: true to OpenSSL commands that contain passwords/passphrases
- Add no_log: true to WireGuard key generation commands
- Add no_log: true to password/CA password generation tasks
- Add no_log: true to AWS credential handling tasks
- Add no_log: true to QR code generation that contains full configs

This prevents sensitive information like passwords, private keys, and
WireGuard configurations from being logged to syslog/journald.

Fixes #1617

* feat: Comprehensive privacy enhancements

- Add no_log directives to all cloud provider credential handling
- Set privacy-focused defaults (StrongSwan logging disabled, DNSCrypt syslog off)
- Implement privacy role with log rotation, history clearing, and log filtering
- Add Privacy Considerations section to README
- Make all privacy features configurable and enabled by default

This update significantly reduces Algo's logging footprint to enhance user privacy
while maintaining the ability to enable logging for debugging when needed.

* docs: Move privacy documentation from README to FAQ

- Remove Privacy Considerations section from README
- Add expanded 'Does Algo support zero logging?' question to FAQ
- Better placement alongside existing logging/monitoring questions
- More detailed explanation of privacy features and limitations

* fix: Remove invalid 'bool' filter from Jinja2 template

The privacy-monitor.sh.j2 template was using '| bool' which is not a valid
Jinja2 filter. The 'bool' is a built-in Python function, not a Jinja2 filter.

Fixed by removing the '| bool' filter and directly outputting the boolean
variables as they will be rendered correctly by Jinja2.

This resolves the template syntax error that was causing CI tests to fail:
"No filter named 'bool'" error in privacy monitoring script template.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix YAML linting issues in privacy role

* Fix linting warnings: shellcheck and ansible-lint issues

- Fixed all shellcheck warnings in test scripts:
  - Quoted variables to prevent word splitting
  - Replaced A && B || C constructs with proper if-then-else
  - Changed unused loop variable to _
  - Added shellcheck directives for FreeBSD rc.d script

- Fixed ansible-lint risky-file-permissions warnings:
  - Added explicit file permissions for sensitive files (mode 0600)
  - Added permissions for config files and certificates (mode 0644)
  - Set proper permissions for directories (mode 0755)

- Fixed yamllint compatibility with ansible-lint:
  - Added required octal-values configuration
  - Quoted all octal mode values to prevent YAML misinterpretation
  - Added comments-indentation: false as required

All tests pass and functionality remains unchanged.

* Remove algo.egg-info from version control

This directory is generated by Python package tools (pip/setuptools) and
should not be tracked in git. It's already listed in .gitignore but was
accidentally committed. The directory contains build metadata that is
regenerated when the package is installed.

* Restructure privacy documentation for clarity

- Simplified FAQ entry to be concise with link to README for details
- Added comprehensive Privacy and Logging section to README
- Clarified what IS logged by default vs what is not
- Explained two separate privacy settings (strongswan_log_level and privacy_enhancements_enabled)
- Added clear debugging instructions (need to change both settings)
- Removed confusing language about "enabling additional features"
- Made documentation more natural and less AI-generated sounding

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix Ubuntu 22.04 iptables deployment issues and simplify config.cfg

Issues fixed:
1. Added base 'iptables' package to batch installation list (was missing, only iptables-persistent was included)
2. Fixed alternatives configuration for Ubuntu 22.04+ - only configure main iptables/ip6tables alternatives, not save/restore (they're handled as slaves)

Config.cfg improvements:
- Reduced from 308 to 198 lines (35% reduction)
- Moved privacy settings above "Advanced users only" line for better accessibility
- Clarified algo_no_log is for Ansible output, not server privacy
- Simplified verbose comments throughout
- Moved experimental performance options to commented section at end
- Better organized into logical sections

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add privacy features to README and improve feature descriptions

- Added privacy-focused feature bullet highlighting minimal logging and privacy enhancements
- Simplified IKEv2 bullet (removed redundant platform list)
- Updated helper scripts description to be more comprehensive
- Specified Ubuntu 22.04 LTS and automatic security updates
- Made feature list more concise and accurate

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix logrotate duplicate entries error in privacy role

The privacy role was creating logrotate configs that duplicated the default
Ubuntu rsyslog logrotate rules, causing deployment failures with errors like
'duplicate log entry for /var/log/syslog'.

Changes:
- Disable default rsyslog logrotate config before applying privacy configs
- Consolidate system log rotation into single config file
- Add missingok flag to handle logs that may not exist on all systems
- Remove forced immediate rotation that was triggering the error

This ensures privacy-enhanced log rotation works without conflicts.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix 'history: not found' error in privacy role

The 'history -c' command was failing because history is a bash built-in
that doesn't exist in /bin/sh (Ubuntu's default shell for scripts).

Changes:
- Removed the 'Clear current session history' task since it's ineffective
  in Ansible context (each task runs in a new shell)
- History files are already cleared by the existing file removal tasks
- Added explanatory comment about why session history clearing is omitted

This fixes the deployment failure while maintaining all effective history
clearing functionality.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix BPF JIT sysctl error in privacy role

The net.core.bpf_jit_enable sysctl parameter was failing on some systems
because BPF JIT support is not available in all kernel configurations.

Changes:
- Separated BPF JIT setting into its own task with ignore_errors
- Made BPF JIT disabling optional since it's not critical for privacy
- Added explanatory comments about kernel support variability
- Both runtime sysctl and persistent config now handle missing parameter

This allows deployments to succeed on systems without BPF JIT support
while still applying the setting where available.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Dan Guido 2025-08-17 15:58:19 -04:00 committed by GitHub
parent 315898fafb
commit 454faa96b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
63 changed files with 1390 additions and 123 deletions

View file

@ -17,6 +17,10 @@ rules:
level: warning
comments:
min-spaces-from-content: 1
comments-indentation: false
octal-values:
forbid-implicit-octal: true
forbid-explicit-octal: true
braces:
max-spaces-inside: 1
truthy:

View file

@ -8,14 +8,15 @@ See our [release announcement](https://blog.trailofbits.com/2016/12/12/meet-algo
## Features
* Supports only IKEv2 with strong crypto (AES-GCM, SHA2, and P-256) for iOS, macOS, and Linux
* Supports only IKEv2 with strong crypto (AES-GCM, SHA2, and P-256) for iOS, MacOS, and Linux
* Supports [WireGuard](https://www.wireguard.com/) for all of the above, in addition to Android and Windows 11
* Generates .conf files and QR codes for iOS, macOS, Android, and Windows WireGuard clients
* Generates Apple profiles to auto-configure iOS and macOS devices for IPsec - no client software required
* Includes a helper script to add and remove users
* Includes helper scripts to add, remove, and manage users
* Blocks ads with a local DNS resolver (optional)
* Sets up limited SSH users for tunneling traffic (optional)
* Based on current versions of Ubuntu and strongSwan
* Privacy-focused with minimal logging, automatic log rotation, and configurable privacy enhancements
* Based on Ubuntu 22.04 LTS with automatic security updates
* Installs to DigitalOcean, Amazon Lightsail, Amazon EC2, Vultr, Microsoft Azure, Google Compute Engine, Scaleway, OpenStack, CloudStack, Hetzner Cloud, Linode, or [your own Ubuntu server (for advanced users)](docs/deploy-to-ubuntu.md)
## Anti-features
@ -175,6 +176,33 @@ To add or remove users, first edit the `users` list in your `config.cfg` file. A
After the process completes, new configuration files will be generated in the `configs` directory for any new users. The Algo VPN server will be updated to contain only the users listed in the `config.cfg` file. Removed users will no longer be able to connect, and new users will have fresh certificates and configuration files ready for use.
## Privacy and Logging
Algo takes a pragmatic approach to privacy. By default, we minimize logging while maintaining enough information for security and troubleshooting.
What IS logged by default:
* System security events (failed SSH attempts, firewall blocks, system updates)
* Kernel messages and boot diagnostics (with reduced verbosity)
* WireGuard client state (visible via `sudo wg` - shows last endpoint and handshake time)
* Basic service status (service starts/stops/errors)
* All logs automatically rotate and delete after 7 days
Privacy is controlled by two main settings in `config.cfg`:
* `strongswan_log_level: -1` - Controls StrongSwan connection logging (-1 = disabled, 2 = debug)
* `privacy_enhancements_enabled: true` - Master switch for log rotation, history clearing, log filtering, and cleanup
To enable full debugging when troubleshooting, set both `strongswan_log_level: 2` and `privacy_enhancements_enabled: false`. This will capture detailed connection logs and disable all privacy features. Remember to revert these changes after debugging.
After deployment, verify your privacy settings:
```bash
ssh -F configs/<server_ip>/ssh_config <hostname>
sudo /usr/local/bin/privacy-monitor.sh
```
Perfect privacy is impossible with any VPN solution. Your cloud provider sees and logs network traffic metadata regardless of your server configuration. And of course, your ISP knows you're connecting to a VPN server, even if they can't see what you're doing through it.
For the highest level of privacy, treat your Algo servers as disposable. Spin up a new instance when you need it, use it for your specific purpose, then destroy it completely. The ephemeral nature of cloud infrastructure can be a privacy feature if you use it intentionally.
## Additional Documentation
* [FAQ](docs/faq.md)
* [Troubleshooting](docs/troubleshooting.md)

View file

@ -12,106 +12,61 @@ users:
### Review these options BEFORE you run Algo, as they are very difficult/impossible to change after the server is deployed.
# Performance optimizations (reduces deployment time)
# Skip reboots unless kernel was updated (saves 0-5 minutes)
performance_skip_optional_reboots: false
# Use parallel key generation for certificates (saves 1-2 minutes)
performance_parallel_crypto: false
# Batch install all packages in one operation (saves 30-60 seconds)
performance_parallel_packages: false
# Pre-install universal packages via cloud-init (saves 30-90 seconds)
performance_preinstall_packages: false
# Configure VPN services in parallel (saves 1-2 minutes)
performance_parallel_services: false
# Change default SSH port for the cloud roles only
# It doesn't apply if you deploy to your existing Ubuntu Server
# SSH port for cloud deployments (doesn't apply to existing Ubuntu servers)
ssh_port: 4160
# Deploy StrongSwan to enable IPsec support
# VPN protocols to deploy
ipsec_enabled: true
# Deploy WireGuard
# WireGuard will listen on 51820/UDP. You might need to change to another port
# if your network blocks this one. Be aware that 53/UDP (DNS) is blocked on some
# mobile data networks.
wireguard_enabled: true
wireguard_port: 51820
wireguard_port: 51820 # Change if blocked by your network (avoid 53/UDP)
# This feature allows you to configure the Algo server to send outbound traffic
# through a different external IP address than the one you are establishing the VPN connection with.
# More info https://trailofbits.github.io/algo/cloud-alternative-ingress-ip.html
# Available for the following cloud providers:
# - DigitalOcean
# Use different IP for outbound traffic (DigitalOcean only)
alternative_ingress_ip: false
# Reduce the MTU of the VPN tunnel
# Some cloud and internet providers use a smaller MTU (Maximum Transmission
# Unit) than the normal value of 1500 and if you don't reduce the MTU of your
# VPN tunnel some network connections will hang. Algo will attempt to set this
# automatically based on your server, but if connections hang you might need to
# adjust this yourself.
# See: https://github.com/trailofbits/algo/blob/master/docs/troubleshooting.md#various-websites-appear-to-be-offline-through-the-vpn
# Reduce MTU if connections hang (0 = auto-detect)
# See: docs/troubleshooting.md#various-websites-appear-to-be-offline-through-the-vpn
reduce_mtu: 0
# Algo will use the following lists to block ads. You can add new block lists
# after deployment by modifying the line starting "BLOCKLIST_URLS=" at:
# /usr/local/sbin/adblock.sh
# If you load very large blocklists, you may also have to modify resource limits:
# /etc/systemd/system/dnsmasq.service.d/100-CustomLimitations.conf
# Ad blocking lists (modify /usr/local/sbin/adblock.sh after deployment to add more)
adblock_lists:
- "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
- "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
# Enable DNS encryption.
# If 'false', 'dns_servers' should be specified below.
# DNS encryption can not be disabled if DNS adblocking is enabled
# DNS encryption (required if using ad blocking)
dns_encryption: true
# Block traffic between connected clients. Change this to false to enable
# connected clients to reach each other, as well as other computers on the
# same LAN as your Algo server (i.e. the "road warrior" setup). In this
# case, you may also want to enable SMB/CIFS and NETBIOS traffic below.
# Client isolation (set false for "road warrior" setup where clients can reach each other)
BetweenClients_DROP: true
block_smb: true # Block SMB/CIFS traffic
block_netbios: true # Block NETBIOS traffic
# Block SMB/CIFS traffic
block_smb: true
# Block NETBIOS traffic
block_netbios: true
# Your Algo server will automatically install security updates. Some updates
# require a reboot to take effect but your Algo server will not reboot itself
# automatically unless you change 'enabled' below from 'false' to 'true', in
# which case a reboot will take place if necessary at the time specified (as
# HH:MM) in the time zone of your Algo server. The default time zone is UTC.
# Automatic reboot for security updates (time in server's timezone, default UTC)
unattended_reboot:
enabled: false
time: 06:00
### Privacy Settings ###
# StrongSwan connection logging (-1 = disabled, 2 = debug)
strongswan_log_level: -1
# Master switch for privacy enhancements (log rotation, history clearing, etc.)
# Set to false for debugging. For advanced privacy options, see roles/privacy/defaults/main.yml
privacy_enhancements_enabled: true
### Advanced users only below this line ###
# DNS servers which will be used if 'dns_encryption' is 'true'. Multiple
# providers may be specified, but avoid mixing providers that filter results
# (like Cisco) with those that don't (like Cloudflare) or you could get
# inconsistent results. The list of available public providers can be found
# here:
# https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v2/public-resolvers.md
# DNSCrypt providers (see https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v2/public-resolvers.md)
dnscrypt_servers:
ipv4:
- cloudflare
# - google
# - <YourCustomServer> # E.g., if using NextDNS, this will be something like NextDNS-abc123.
# You must also fill in custom_server_stamps below. You may specify
# multiple custom servers.
# - YourCustomServer # For NextDNS etc., add stamp below
ipv6:
- cloudflare-ipv6
custom_server_stamps:
# YourCustomServer: 'sdns://...'
# DNS servers which will be used if 'dns_encryption' is 'false'.
# Fallback resolvers for systemd-resolved
# The default is to use Cloudflare.
# DNS servers when encryption is disabled
dns_servers:
ipv4:
- 1.1.1.1
@ -120,37 +75,36 @@ dns_servers:
- 2606:4700:4700::1111
- 2606:4700:4700::1001
# Store the PKI in a ram disk. Enabled only if store_pki (retain the PKI) is set to false
# Supports on MacOS and Linux only (including Windows Subsystem for Linux)
# Store PKI in RAM disk when not retaining (MacOS/Linux only)
pki_in_tmpfs: true
# Set this to 'true' when running './algo update-users' if you want ALL users to get new certs, not just new users.
# Regenerate ALL user certs on update-users (not just new users)
keys_clean_all: false
# StrongSwan log level
# https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration
strongswan_log_level: 2
# rightsourceip for ipsec
# ipv4
### VPN Network Configuration ###
strongswan_network: 10.48.0.0/16
# ipv6
strongswan_network_ipv6: '2001:db8:4160::/48'
# If you're behind NAT or a firewall and you want to receive incoming connections long after network traffic has gone silent.
# This option will keep the "connection" open in the eyes of NAT.
# See: https://www.wireguard.com/quickstart/#nat-and-firewall-traversal-persistence
wireguard_PersistentKeepalive: 0
# WireGuard network configuration
wireguard_network_ipv4: 10.49.0.0/16
wireguard_network_ipv6: 2001:db8:a160::/48
# Keep NAT connections alive (0 = disabled)
wireguard_PersistentKeepalive: 0
### Experimental Performance Options ###
# These are experimental and may cause issues. Enable at your own risk.
# performance_skip_optional_reboots: false # Skip non-kernel reboots
# performance_parallel_crypto: false # Parallel key generation
# performance_parallel_packages: false # Batch package installation
# performance_preinstall_packages: false # Pre-install via cloud-init
# performance_parallel_services: false # Configure VPN services in parallel
# Randomly generated IP address for the local dns resolver
local_service_ip: "{{ '172.16.0.1' | ansible.utils.ipmath(1048573 | random(seed=algo_server_name + ansible_fqdn)) }}"
local_service_ipv6: "{{ 'fd00::1' | ansible.utils.ipmath(1048573 | random(seed=algo_server_name + ansible_fqdn)) }}"
# Hide sensitive data
# Hide sensitive data in Ansible output during deployment (passwords, keys, etc.)
# This is NOT related to privacy/logging on the VPN server itself
algo_no_log: true
congrats:
@ -218,11 +172,11 @@ cloud_providers:
image: Ubuntu 22.04 Jammy Jellyfish
arch: x86_64
hetzner:
server_type: cpx11
server_type: cpx11
image: ubuntu-22.04
openstack:
flavor_ram: ">=512"
image: Ubuntu-22.04
image: Ubuntu-22.04
cloudstack:
size: Micro
image: Linux Ubuntu 22.04 LTS 64-bit

View file

@ -10,6 +10,7 @@
* [I deployed an Algo server. Can you update it with new features?](#i-deployed-an-algo-server-can-you-update-it-with-new-features)
* [Where did the name "Algo" come from?](#where-did-the-name-algo-come-from)
* [Can DNS filtering be disabled?](#can-dns-filtering-be-disabled)
* [Does Algo support zero logging?](#does-algo-support-zero-logging)
* [Wasn't IPSEC backdoored by the US government?](#wasnt-ipsec-backdoored-by-the-us-government)
* [What inbound ports are used?](#what-inbound-ports-are-used)
* [How do I monitor user activity?](#how-do-i-monitor-user-activity)
@ -59,6 +60,10 @@ Algo is short for "Al Gore", the **V**ice **P**resident of **N**etworks everywhe
You can temporarily disable DNS filtering for all IPsec clients at once with the following workaround: SSH to your Algo server (using the 'shell access' command printed upon a successful deployment), edit `/etc/ipsec.conf`, and change `rightdns=<random_ip>` to `rightdns=8.8.8.8`. Then run `sudo systemctl restart strongswan`. DNS filtering for WireGuard clients has to be disabled on each client device separately by modifying the settings in the app, or by directly modifying the `DNS` setting on the `clientname.conf` file. If all else fails, we recommend deploying a new Algo server without the adblocking feature enabled.
## Does Algo support zero logging?
Yes, Algo includes privacy enhancements that minimize logging by default. StrongSwan connection logging is disabled, DNSCrypt syslog is turned off, and logs are automatically rotated after 7 days. However, some system-level logging remains for security and troubleshooting purposes. For detailed privacy configuration and limitations, see the [Privacy and Logging](#privacy-and-logging) section in the README.
## Wasn't IPSEC backdoored by the US government?
No.

View file

@ -45,11 +45,14 @@
dest: "{{ item.dest }}"
line: "{{ item.line }}"
create: true
mode: "{{ item.mode }}"
with_items:
- dest: "{{ configs_prefix }}/ipsec.conf"
line: include ipsec.{{ IP_subject_alt_name }}.conf
mode: '0644'
- dest: "{{ configs_prefix }}/ipsec.secrets"
line: include ipsec.{{ IP_subject_alt_name }}.secrets
mode: '0600'
notify:
- restart strongswan
@ -59,18 +62,22 @@
dest: "{{ configs_prefix }}/strongswan.d/relax-ca-constraints.conf"
owner: root
group: root
mode: 0644
mode: '0644'
- name: Setup the certificates and keys
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
with_items:
- src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/certs/{{ vpn_user }}.crt
dest: "{{ configs_prefix }}/ipsec.d/certs/{{ vpn_user }}.crt"
mode: '0644'
- src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/cacert.pem
dest: "{{ configs_prefix }}/ipsec.d/cacerts/{{ IP_subject_alt_name }}.pem"
mode: '0644'
- src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/private/{{ vpn_user }}.key
dest: "{{ configs_prefix }}/ipsec.d/private/{{ vpn_user }}.key"
mode: '0600'
notify:
- restart strongswan

View file

@ -4,6 +4,7 @@
tenant: "{{ azure_tenant | default(lookup('env', 'AZURE_TENANT'), true) }}"
client_id: "{{ azure_client_id | default(lookup('env', 'AZURE_CLIENT_ID'), true) }}"
subscription_id: "{{ azure_subscription_id | default(lookup('env', 'AZURE_SUBSCRIPTION_ID'), true) }}"
no_log: true
- block:
- name: Set the default region

View file

@ -57,3 +57,4 @@
CLOUDSTACK_KEY: "{{ algo_cs_key }}"
CLOUDSTACK_SECRET: "{{ algo_cs_token }}"
CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}"
no_log: true

View file

@ -8,6 +8,7 @@
when:
- cs_key is undefined
- lookup('env', 'CLOUDSTACK_KEY')|length <= 0
no_log: true
- pause:
prompt: |
@ -17,6 +18,7 @@
when:
- cs_secret is undefined
- lookup('env', 'CLOUDSTACK_SECRET')|length <= 0
no_log: true
- pause:
prompt: |
@ -34,6 +36,7 @@
{{ cs_url | default(_cs_url.user_input|default(None)) |
default(lookup('env', 'CLOUDSTACK_ENDPOINT'), true) |
default('https://api.exoscale.com/compute', true) }}
no_log: true
- name: Get zones on cloud
cs_zone_info:
@ -42,6 +45,7 @@
CLOUDSTACK_KEY: "{{ algo_cs_key }}"
CLOUDSTACK_SECRET: "{{ algo_cs_token }}"
CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}"
no_log: true
- name: Extract zones from output
set_fact:

View file

@ -7,10 +7,12 @@
when:
- do_token is undefined
- lookup('env', 'DO_API_TOKEN')|length <= 0
no_log: true
- name: Set the token as a fact
set_fact:
algo_do_token: "{{ do_token | default(_do_token.user_input | default(None)) | default(lookup('env', 'DO_API_TOKEN'), true) }}"
no_log: true
- name: Get regions
uri:
@ -21,6 +23,7 @@
Content-Type: application/json
Authorization: Bearer {{ algo_do_token }}
register: _do_regions
no_log: true
- name: Set facts about the regions
set_fact:

View file

@ -20,3 +20,4 @@
tags:
Environment: Algo
register: stack
no_log: true

View file

@ -15,6 +15,7 @@
architecture: "{{ cloud_providers.ec2.image.arch }}"
name: ubuntu/images/hvm-ssd/{{ cloud_providers.ec2.image.name }}-*64-server-*
register: ami_search
no_log: true
- name: Set the ami id as a fact
set_fact:

View file

@ -73,6 +73,7 @@
aws_session_token: "{{ session_token if session_token else omit }}"
region: us-east-1
register: _aws_regions
no_log: true
- name: Set facts about the regions
set_fact:
@ -114,6 +115,7 @@
aws_session_token: "{{ session_token if session_token else omit }}"
region: "{{ algo_region }}"
register: raw_eip_addresses
no_log: true
- set_fact:
available_eip_addresses: "{{ raw_eip_addresses.addresses | selectattr('association_id', 'undefined') | list }}"

View file

@ -7,19 +7,23 @@
when:
- gce_credentials_file is undefined
- lookup('env', 'GCE_CREDENTIALS_FILE_PATH')|length <= 0
no_log: true
- set_fact:
credentials_file_path: >-
{{ gce_credentials_file | default(_gce_credentials_file.user_input|default(None)) |
default(lookup('env', 'GCE_CREDENTIALS_FILE_PATH'), true) }}
ssh_public_key_lookup: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
no_log: true
- set_fact:
credentials_file_lookup: "{{ lookup('file', '{{ credentials_file_path }}') }}"
no_log: true
- set_fact:
service_account_email: "{{ credentials_file_lookup.client_email | default(lookup('env', 'GCE_EMAIL')) }}"
project_id: "{{ credentials_file_lookup.project_id | default(lookup('env', 'GCE_PROJECT')) }}"
no_log: true
- block:
- name: Get regions

View file

@ -7,10 +7,12 @@
when:
- hcloud_token is undefined
- lookup('env', 'HCLOUD_TOKEN')|length <= 0
no_log: true
- name: Set the token as a fact
set_fact:
algo_hcloud_token: "{{ hcloud_token | default(_hcloud_token.user_input | default(None)) | default(lookup('env', 'HCLOUD_TOKEN'), true) }}"
no_log: true
- name: Get regions
hetzner.hcloud.datacenter_info:

View file

@ -17,3 +17,4 @@
Environment: Algo
Lightsail: true
register: stack
no_log: true

View file

@ -8,6 +8,7 @@
when:
- aws_access_key is undefined
- lookup('env', 'AWS_ACCESS_KEY_ID')|length <= 0
no_log: true
- pause:
prompt: |
@ -17,10 +18,12 @@
when:
- aws_secret_key is undefined
- lookup('env', 'AWS_SECRET_ACCESS_KEY')|length <= 0
no_log: true
- set_fact:
access_key: "{{ aws_access_key | default(_aws_access_key.user_input | default(None)) | default(lookup('env', 'AWS_ACCESS_KEY_ID'), true) }}"
secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input | default(None)) | default(lookup('env', 'AWS_SECRET_ACCESS_KEY'), true) }}"
no_log: true
- block:
- name: Get regions
@ -29,6 +32,7 @@
aws_secret_key: "{{ secret_key }}"
region: us-east-1
register: _lightsail_regions
no_log: true
- name: Set facts about the regions
set_fact:

View file

@ -23,6 +23,7 @@
script: |
{{ stackscript }}
register: _linode_stackscript
no_log: true
- name: Update the stackscript
uri:
@ -36,6 +37,7 @@
Content-Type: application/json
Authorization: Bearer {{ algo_linode_token }}
when: (_linode_stackscript.stackscript.script | hash('md5')) != (stackscript | hash('md5'))
no_log: true
- name: Creating an instance...
linode_v4:
@ -48,6 +50,7 @@
authorized_keys: "{{ public_key }}"
stackscript_id: "{{ _linode_stackscript.stackscript.id }}"
register: _linode
no_log: true
- set_fact:
cloud_instance_ip: "{{ _linode.instance.ipv4[0] }}"

View file

@ -7,10 +7,12 @@
when:
- linode_token is undefined
- lookup('env', 'LINODE_API_TOKEN')|length <= 0
no_log: true
- name: Set the token as a fact
set_fact:
algo_linode_token: "{{ linode_token | default(_linode_token.user_input | default(None)) | default(lookup('env', 'LINODE_API_TOKEN'), true) }}"
no_log: true
- name: Get regions
uri:

View file

@ -7,6 +7,7 @@
when:
- scaleway_token is undefined
- lookup('env', 'SCW_TOKEN')|length <= 0
no_log: true
- pause:
prompt: |
@ -27,3 +28,4 @@
{% if region is defined %}{{ region }}
{%- elif _algo_region.user_input %}{{ scaleway_regions[_algo_region.user_input | int -1 ]['alias'] }}
{%- else %}{{ scaleway_regions.0.alias }}{% endif %}
no_log: true

View file

@ -7,10 +7,12 @@
when:
- vultr_config is undefined
- lookup('env', 'VULTR_API_CONFIG')|length <= 0
no_log: true
- name: Set the token as a fact
set_fact:
algo_vultr_config: "{{ vultr_config | default(_vultr_config.user_input) | default(lookup('env', 'VULTR_API_CONFIG'), true) }}"
no_log: true
- name: Set the Vultr API Key as a fact
set_fact:

View file

@ -16,6 +16,7 @@
template:
src: 99-algo-ipv6-egress.yaml.j2
dest: /etc/netplan/99-algo-ipv6-egress.yaml
mode: '0644'
when:
- ipv6_support
- ipv6_subnet_size|int > 1

View file

@ -3,11 +3,13 @@
set_fact:
p12_export_password: "{{ p12_password | default(lookup('password', '/dev/null length=9 chars=ascii_letters,digits,_,@')) }}"
tags: update-users
no_log: true
- name: Set facts
set_fact:
CA_password: "{{ ca_password | default(lookup('password', '/dev/null length=16 chars=ascii_letters,digits,_,@')) }}"
IP_subject_alt_name: "{{ IP_subject_alt_name }}"
no_log: true
- name: Set IPv6 support as a fact
set_fact:

View file

@ -5,7 +5,7 @@
dest: "{{ item.dest }}"
owner: root
group: root
mode: 0640
mode: '0640'
with_items:
- { src: rules.v4.j2, dest: /etc/iptables/rules.v4 }
notify:
@ -17,7 +17,7 @@
dest: "{{ item.dest }}"
owner: root
group: root
mode: 0640
mode: '0640'
when: ipv6_support
with_items:
- { src: rules.v6.j2, dest: /etc/iptables/rules.v6 }

View file

@ -77,6 +77,7 @@
section: Resolve
option: FallbackDNS
value: "{{ dns_servers.ipv4 | join(' ') }}"
mode: '0644'
notify:
- restart systemd-resolved
@ -84,6 +85,7 @@
template:
src: 10-algo-lo100.network.j2
dest: /etc/systemd/network/10-algo-lo100.network
mode: '0644'
notify:
- restart systemd-networkd
@ -121,6 +123,7 @@
- apparmor-utils
- uuid-runtime
- coreutils
- iptables
- iptables-persistent
- cgroup-tools
- openssl
@ -178,10 +181,6 @@
with_items:
- iptables
- ip6tables
- iptables-save
- iptables-restore
- ip6tables-save
- ip6tables-restore
when:
- ansible_distribution == "Ubuntu"
- ansible_distribution_version is version('22.04', '>=')

View file

@ -10,7 +10,7 @@
dest: /etc/apt/apt.conf.d/50unattended-upgrades
owner: root
group: root
mode: 0644
mode: '0644'
- name: Periodic upgrades configured
template:
@ -18,4 +18,4 @@
dest: /etc/apt/apt.conf.d/10periodic
owner: root
group: root
mode: 0644
mode: '0644'

View file

@ -5,7 +5,7 @@
dest: /usr/local/sbin/adblock.sh
owner: root
group: "{{ root_group | default('root') }}"
mode: 0755
mode: '0755'
- name: Adblock script added to cron
cron:

View file

@ -8,6 +8,7 @@
template:
src: ip-blacklist.txt.j2
dest: "{{ config_prefix | default('/') }}etc/dnscrypt-proxy/ip-blacklist.txt"
mode: '0644'
notify:
- restart dnscrypt-proxy
@ -15,6 +16,7 @@
template:
src: dnscrypt-proxy.toml.j2
dest: "{{ config_prefix | default('/') }}etc/dnscrypt-proxy/dnscrypt-proxy.toml"
mode: '0644'
notify:
- restart dnscrypt-proxy

View file

@ -16,7 +16,7 @@
dest: /etc/apt/apt.conf.d/50-dnscrypt-proxy-unattended-upgrades
owner: root
group: root
mode: 0644
mode: '0644'
when: ansible_facts['distribution_version'] is version('20.04', '<')
- name: Install dnscrypt-proxy (individual)
@ -33,7 +33,7 @@
dest: /etc/apparmor.d/usr.bin.dnscrypt-proxy
owner: root
group: root
mode: 0600
mode: '0600'
notify: restart dnscrypt-proxy
- name: Ubuntu | Enforce the dnscrypt-proxy AppArmor policy
@ -46,13 +46,14 @@
file:
path: /etc/systemd/system/dnscrypt-proxy.service.d/
state: directory
mode: 0755
mode: '0755'
owner: root
group: root
- name: Ubuntu | Add custom requirements to successfully start the unit
copy:
dest: /etc/systemd/system/dnscrypt-proxy.service.d/99-algo.conf
mode: '0644'
content: |
[Unit]
After=systemd-resolved.service
@ -93,7 +94,7 @@
SystemCallErrorNumber=EPERM
owner: root
group: root
mode: 0644
mode: '0644'
notify:
- daemon-reload
- restart dnscrypt-proxy

View file

@ -137,8 +137,11 @@ lb_strategy = 'p2'
## Log level (0-6, default: 2 - 0 is very verbose, 6 only contains fatal errors)
## Privacy enhancement: Set to 4 (warnings and errors only) to reduce information disclosure
## Lower levels may log DNS queries and connection details that could compromise privacy
## Level 4 provides essential error information while minimizing privacy-sensitive logging
log_level = 2
log_level = 4
## log file for the application
@ -147,8 +150,11 @@ log_level = 2
## Use the system logger (syslog on Unix, Event Log on Windows)
## Privacy enhancement: Disabled by default to prevent DNS query logging in system logs
## DNS queries logged to syslog can reveal browsing patterns and compromise privacy
## Enable only if required for debugging purposes
use_syslog = true
use_syslog = false
## Delay, in minutes, after which certificates are reloaded
@ -332,6 +338,9 @@ cache_neg_max_ttl = 600
###############################
## Log client queries to a file
## Privacy warning: Enabling query logging will record all DNS requests
## which can reveal detailed browsing patterns and compromise user privacy
## Only enable for debugging purposes and disable immediately after use
[query_log]
@ -358,6 +367,8 @@ cache_neg_max_ttl = 600
## Log queries for nonexistent zones
## These queries can reveal the presence of malware, broken/obsolete applications,
## and devices signaling their presence to 3rd parties.
## Privacy warning: This logging can still reveal browsing patterns and queried domains
## Only enable for security monitoring purposes when necessary
[nx_log]

205
roles/privacy/README.md Normal file
View file

@ -0,0 +1,205 @@
# Privacy Enhancements Role
This Ansible role implements additional privacy enhancements for Algo VPN to minimize server-side traces of VPN usage and reduce log retention. These measures help protect user privacy while maintaining system security.
## Features
### 1. Aggressive Log Rotation
- Configures shorter log retention periods (default: 7 days)
- Implements more frequent log rotation
- Compresses rotated logs to save space
- Automatically cleans up old log files
### 2. History Clearing
- Clears bash/shell history after deployment
- Disables persistent command history for system users
- Clears temporary files and caches
- Sets up automatic history clearing on user logout
### 3. VPN Log Filtering
- Filters out VPN connection logs from rsyslog
- Excludes WireGuard and StrongSwan messages from persistent storage
- Filters kernel messages related to VPN traffic
- Optional filtering of authentication logs (use with caution)
### 4. Automatic Cleanup
- Daily/weekly/monthly cleanup of old logs and temporary files
- Package cache cleaning
- Configurable retention policies
- Optional shutdown cleanup for extreme privacy
### 5. Advanced Privacy Settings
- Reduced kernel log verbosity
- Disabled successful SSH connection logging (optional)
- Volatile systemd journal storage
- Privacy monitoring script
## Configuration
All privacy settings are configured in `config.cfg` under the "Privacy Enhancements" section:
```yaml
# Enable/disable all privacy enhancements
privacy_enhancements_enabled: true
# Log rotation settings
privacy_log_rotation:
max_age: 7 # Days to keep logs
max_size: 10 # Max size per log file (MB)
rotate_count: 3 # Number of rotated files to keep
compress: true # Compress rotated logs
daily_rotation: true # Force daily rotation
# History clearing
privacy_history_clearing:
clear_bash_history: true
clear_system_history: true
disable_service_history: true
# Log filtering
privacy_log_filtering:
exclude_vpn_logs: true
exclude_auth_logs: false # Use with caution
filter_kernel_vpn_logs: true
# Automatic cleanup
privacy_auto_cleanup:
enabled: true
frequency: "daily" # daily, weekly, monthly
temp_files_max_age: 1
clean_package_cache: true
# Advanced settings
privacy_advanced:
disable_ssh_success_logs: false
reduce_kernel_verbosity: true
clear_logs_on_shutdown: false # Extreme measure
```
## Security Considerations
### Safe Settings (Default)
- `exclude_vpn_logs: true` - Safe, only filters VPN-specific messages
- `clear_bash_history: true` - Safe, improves privacy without affecting security
- `reduce_kernel_verbosity: true` - Safe, reduces noise in logs
### Use With Caution
- `exclude_auth_logs: true` - Reduces security logging, makes incident investigation harder
- `disable_ssh_success_logs: true` - Removes audit trail for successful connections
- `clear_logs_on_shutdown: true` - Extreme measure, makes debugging very difficult
## Files Created
### Configuration Files
- `/etc/logrotate.d/99-privacy-enhanced` - Main log rotation config
- `/etc/logrotate.d/99-auth-privacy` - Auth log rotation
- `/etc/logrotate.d/99-kern-privacy` - Kernel log rotation
- `/etc/rsyslog.d/49-privacy-vpn-filter.conf` - VPN log filtering
- `/etc/rsyslog.d/48-privacy-kernel-filter.conf` - Kernel log filtering
- `/etc/rsyslog.d/47-privacy-auth-filter.conf` - Auth log filtering (optional)
- `/etc/rsyslog.d/46-privacy-ssh-filter.conf` - SSH log filtering (optional)
- `/etc/rsyslog.d/45-privacy-minimal.conf` - Minimal logging config
### Scripts
- `/usr/local/bin/privacy-auto-cleanup.sh` - Automatic cleanup script
- `/usr/local/bin/privacy-log-cleanup.sh` - Initial log cleanup
- `/usr/local/bin/privacy-monitor.sh` - Privacy status monitoring
- `/etc/bash.bash_logout` - History clearing on logout
### Systemd Services
- `/etc/systemd/system/privacy-shutdown-cleanup.service` - Shutdown cleanup (optional)
## Usage
### Enable Privacy Enhancements
Privacy enhancements are enabled by default. To disable them:
```yaml
privacy_enhancements_enabled: false
```
### Run Specific Privacy Tasks
You can run specific privacy components using tags:
```bash
# Run only log rotation setup
ansible-playbook server.yml --tags privacy-logs
# Run only history clearing
ansible-playbook server.yml --tags privacy-history
# Run only log filtering
ansible-playbook server.yml --tags privacy-filtering
# Run only cleanup tasks
ansible-playbook server.yml --tags privacy-cleanup
# Run all privacy enhancements
ansible-playbook server.yml --tags privacy
```
### Monitor Privacy Status
Check the status of privacy enhancements:
```bash
sudo /usr/local/bin/privacy-monitor.sh
```
### Manual Cleanup
Run manual cleanup:
```bash
sudo /usr/local/bin/privacy-auto-cleanup.sh
```
## Debugging
If you need to debug VPN issues, temporarily disable privacy enhancements:
1. Set `privacy_enhancements_enabled: false` in `config.cfg`
2. Re-run the deployment: `./algo`
3. Debug your issues with full logging
4. Re-enable privacy enhancements when done
Alternatively, disable specific features:
- Set `exclude_vpn_logs: false` to see VPN connection logs
- Set `reduce_kernel_verbosity: false` for full kernel logging
- Check `/var/log/privacy-cleanup.log` for cleanup operation logs
## Impact on System
### Positive Effects
- Improved user privacy
- Reduced disk usage from logs
- Faster log searches
- Reduced attack surface
### Potential Drawbacks
- Limited debugging information
- Shorter audit trail
- May complicate troubleshooting
- Could hide security incidents
## Compatibility
- **Ubuntu 22.04**: Fully supported
- **FreeBSD**: Limited support (log rotation and history clearing only)
- **Other distributions**: May require adaptation
## Best Practices
1. **Start Conservative**: Use default settings initially
2. **Test Thoroughly**: Verify VPN functionality after enabling privacy features
3. **Monitor Logs**: Check that essential security logs are still being captured
4. **Document Changes**: Keep track of privacy settings for troubleshooting
5. **Regular Reviews**: Periodically review privacy settings and their effectiveness
## Privacy vs. Security Balance
This role aims to balance privacy with security by:
- Keeping security-critical logs (authentication failures, system errors)
- Filtering only VPN-specific operational logs
- Providing granular control over what gets filtered
- Maintaining essential audit trails while reducing VPN usage traces
For maximum privacy, consider running your own log analysis before enabling aggressive filtering options.

View file

@ -0,0 +1,57 @@
---
# Privacy enhancement configuration defaults
# These settings can be overridden in config.cfg
# Enable privacy enhancements (disabled for debugging when false)
privacy_enhancements_enabled: true
# Log rotation settings
privacy_log_rotation:
# Maximum age for system logs in days
max_age: 7
# Maximum size for individual log files in MB
max_size: 10
# Number of rotated files to keep
rotate_count: 3
# Compress rotated logs
compress: true
# Force daily rotation regardless of size
daily_rotation: true
# History clearing settings
privacy_history_clearing:
# Clear bash history after deployment
clear_bash_history: true
# Clear system command history
clear_system_history: true
# Disable bash history persistence for service users
disable_service_history: true
# Log filtering settings
privacy_log_filtering:
# Exclude VPN connection logs from persistent storage
exclude_vpn_logs: true
# Exclude authentication logs (be careful with this)
exclude_auth_logs: false
# Filter kernel logs related to VPN traffic
filter_kernel_vpn_logs: true
# Automatic cleanup settings
privacy_auto_cleanup:
# Enable automatic log cleanup
enabled: true
# Cleanup frequency (daily, weekly, monthly)
frequency: "daily"
# Clean up temporary files older than N days
temp_files_max_age: 1
# Clean up old package cache
clean_package_cache: true
# Advanced privacy settings
privacy_advanced:
# Disable logging of successful SSH connections
disable_ssh_success_logs: false
# Reduce kernel log verbosity
reduce_kernel_verbosity: true
# Clear logs on shutdown (use with caution)
clear_logs_on_shutdown: false

View file

@ -0,0 +1,29 @@
---
# Privacy role handlers
# These handlers are triggered by privacy configuration changes
- name: restart rsyslog
systemd:
name: rsyslog
state: restarted
daemon_reload: yes
become: yes
- name: restart systemd-journald
systemd:
name: systemd-journald
state: restarted
daemon_reload: yes
become: yes
- name: reload systemd
systemd:
daemon_reload: yes
become: yes
- name: enable privacy shutdown cleanup
systemd:
name: privacy-shutdown-cleanup.service
enabled: yes
daemon_reload: yes
become: yes

View file

@ -0,0 +1,99 @@
---
# Advanced privacy settings for enhanced anonymity
- name: Reduce kernel log verbosity for privacy
sysctl:
name: "{{ item.name }}"
value: "{{ item.value }}"
state: present
reload: yes
loop:
- { name: 'kernel.printk', value: '3 4 1 3' }
- { name: 'kernel.dmesg_restrict', value: '1' }
when: privacy_advanced.reduce_kernel_verbosity | bool
- name: Disable BPF JIT if available (optional security hardening)
sysctl:
name: net.core.bpf_jit_enable
value: '0'
state: present
reload: yes
when: privacy_advanced.reduce_kernel_verbosity | bool
ignore_errors: yes
- name: Configure kernel parameters for privacy
lineinfile:
path: /etc/sysctl.d/99-privacy.conf
line: "{{ item }}"
create: yes
mode: '0644'
loop:
- "# Privacy enhancements - reduce kernel logging"
- "kernel.printk = 3 4 1 3"
- "kernel.dmesg_restrict = 1"
- "# Note: net.core.bpf_jit_enable may not be available on all kernels"
when: privacy_advanced.reduce_kernel_verbosity | bool
- name: Add BPF JIT disable to sysctl config if kernel supports it
lineinfile:
path: /etc/sysctl.d/99-privacy.conf
line: "net.core.bpf_jit_enable = 0 # Disable BPF JIT to reduce attack surface"
create: yes
mode: '0644'
when: privacy_advanced.reduce_kernel_verbosity | bool
ignore_errors: yes
- name: Configure journal settings for privacy
lineinfile:
path: /etc/systemd/journald.conf
regexp: "^#?{{ item.key }}="
line: "{{ item.key }}={{ item.value }}"
backup: yes
loop:
- { key: 'MaxRetentionSec', value: '{{ privacy_log_rotation.max_age * 24 * 3600 }}' }
- { key: 'MaxFileSec', value: '1day' }
- { key: 'SystemMaxUse', value: '100M' }
- { key: 'SystemMaxFileSize', value: '{{ privacy_log_rotation.max_size }}M' }
- { key: 'ForwardToSyslog', value: 'no' }
notify: restart systemd-journald
- name: Disable persistent systemd journal
file:
path: /var/log/journal
state: absent
when: privacy_advanced.reduce_kernel_verbosity | bool
- name: Create journal configuration for volatile storage only
lineinfile:
path: /etc/systemd/journald.conf
regexp: "^#?Storage="
line: "Storage=volatile"
backup: yes
notify: restart systemd-journald
- name: Configure rsyslog for minimal logging
template:
src: privacy-rsyslog.conf.j2
dest: /etc/rsyslog.d/45-privacy-minimal.conf
mode: '0644'
owner: root
group: root
notify: restart rsyslog
- name: Set up privacy monitoring script
template:
src: privacy-monitor.sh.j2
dest: /usr/local/bin/privacy-monitor.sh
mode: '0755'
owner: root
group: root
- name: Display privacy configuration summary
debug:
msg:
- "Privacy enhancements applied:"
- " - Log retention: {{ privacy_log_rotation.max_age }} days"
- " - VPN log filtering: {{ privacy_log_filtering.exclude_vpn_logs | bool }}"
- " - History clearing: {{ privacy_history_clearing.clear_bash_history | bool }}"
- " - Auto cleanup: {{ privacy_auto_cleanup.enabled | bool }}"
- " - Kernel verbosity reduction: {{ privacy_advanced.reduce_kernel_verbosity | bool }}"

View file

@ -0,0 +1,70 @@
---
# Automatic cleanup tasks for enhanced privacy
- name: Create privacy cleanup script
template:
src: privacy-auto-cleanup.sh.j2
dest: /usr/local/bin/privacy-auto-cleanup.sh
mode: '0755'
owner: root
group: root
- name: Set up automatic privacy cleanup cron job
cron:
name: "Privacy auto cleanup"
job: "/usr/local/bin/privacy-auto-cleanup.sh"
minute: "30"
hour: "2"
user: root
state: "{{ 'present' if privacy_auto_cleanup.enabled else 'absent' }}"
when: privacy_auto_cleanup.frequency == 'daily'
- name: Set up weekly privacy cleanup cron job
cron:
name: "Privacy auto cleanup weekly"
job: "/usr/local/bin/privacy-auto-cleanup.sh"
minute: "30"
hour: "2"
weekday: "0"
user: root
state: "{{ 'present' if privacy_auto_cleanup.enabled else 'absent' }}"
when: privacy_auto_cleanup.frequency == 'weekly'
- name: Set up monthly privacy cleanup cron job
cron:
name: "Privacy auto cleanup monthly"
job: "/usr/local/bin/privacy-auto-cleanup.sh"
minute: "30"
hour: "2"
day: "1"
user: root
state: "{{ 'present' if privacy_auto_cleanup.enabled else 'absent' }}"
when: privacy_auto_cleanup.frequency == 'monthly'
- name: Create systemd service for privacy cleanup on shutdown
template:
src: privacy-shutdown-cleanup.service.j2
dest: /etc/systemd/system/privacy-shutdown-cleanup.service
mode: '0644'
owner: root
group: root
when: privacy_advanced.clear_logs_on_shutdown | bool
notify:
- reload systemd
- enable privacy shutdown cleanup
- name: Clean up temporary files immediately
shell: |
find /tmp -type f -mtime +{{ privacy_auto_cleanup.temp_files_max_age }} -delete
find /var/tmp -type f -mtime +{{ privacy_auto_cleanup.temp_files_max_age }} -delete
changed_when: false
when: privacy_auto_cleanup.enabled | bool
- name: Clean package cache immediately
shell: |
apt-get clean
apt-get autoclean
changed_when: false
when:
- privacy_auto_cleanup.enabled | bool
- privacy_auto_cleanup.clean_package_cache | bool

View file

@ -0,0 +1,59 @@
---
# Clear command history and disable persistent history for privacy
- name: Clear bash history for all users
shell: |
for user_home in /home/* /root; do
if [ -d "$user_home" ]; then
rm -f "$user_home/.bash_history"
rm -f "$user_home/.zsh_history"
rm -f "$user_home/.sh_history"
fi
done
when: privacy_history_clearing.clear_bash_history | bool
changed_when: false
- name: Clear system command history logs
file:
path: "{{ item }}"
state: absent
loop:
- /var/log/lastlog
- /var/log/wtmp.1
- /var/log/btmp.1
- /tmp/.X*
- /tmp/.font-unix
- /tmp/.ICE-unix
when: privacy_history_clearing.clear_system_history | bool
ignore_errors: true
- name: Configure bash to not save history for service users
lineinfile:
path: "{{ item }}/.bashrc"
line: "{{ history_disable_line }}"
create: true
mode: '0644'
loop:
- /root
- /home/ubuntu
vars:
history_disable_line: |
# Privacy enhancement: disable bash history
export HISTFILE=/dev/null
export HISTSIZE=0
export HISTFILESIZE=0
unset HISTFILE
when: privacy_history_clearing.disable_service_history | bool
ignore_errors: true
- name: Create history clearing script for logout
template:
src: clear-history-on-logout.sh.j2
dest: /etc/bash.bash_logout
mode: '0644'
owner: root
group: root
when: privacy_history_clearing.clear_bash_history | bool
# Note: We don't clear current session history as each Ansible task
# runs in its own shell session, making this operation ineffective

View file

@ -0,0 +1,61 @@
---
# Configure rsyslog to filter out VPN-related logs for privacy
- name: Create rsyslog privacy configuration directory
file:
path: /etc/rsyslog.d
state: directory
mode: '0755'
owner: root
group: root
- name: Configure rsyslog to exclude VPN-related logs
template:
src: 49-privacy-vpn-filter.conf.j2
dest: /etc/rsyslog.d/49-privacy-vpn-filter.conf
mode: '0644'
owner: root
group: root
notify: restart rsyslog
when: privacy_log_filtering.exclude_vpn_logs | bool
- name: Configure rsyslog to filter kernel VPN logs
template:
src: 48-privacy-kernel-filter.conf.j2
dest: /etc/rsyslog.d/48-privacy-kernel-filter.conf
mode: '0644'
owner: root
group: root
notify: restart rsyslog
when: privacy_log_filtering.filter_kernel_vpn_logs | bool
- name: Configure rsyslog to exclude detailed auth logs (optional)
template:
src: 47-privacy-auth-filter.conf.j2
dest: /etc/rsyslog.d/47-privacy-auth-filter.conf
mode: '0644'
owner: root
group: root
notify: restart rsyslog
when: privacy_log_filtering.exclude_auth_logs | bool
- name: Create rsyslog privacy filter for SSH success logs
template:
src: 46-privacy-ssh-filter.conf.j2
dest: /etc/rsyslog.d/46-privacy-ssh-filter.conf
mode: '0644'
owner: root
group: root
notify: restart rsyslog
when: privacy_advanced.disable_ssh_success_logs | bool
- name: Test rsyslog configuration
command: rsyslogd -N1
register: rsyslog_test
changed_when: false
failed_when: rsyslog_test.rc != 0
- name: Display rsyslog test results
debug:
msg: "Rsyslog configuration test passed"
when: rsyslog_test.rc == 0

View file

@ -0,0 +1,60 @@
---
# Aggressive log rotation configuration for privacy
# Reduces log retention time and implements more frequent rotation
- name: Check if default rsyslog logrotate config exists
stat:
path: /etc/logrotate.d/rsyslog
register: rsyslog_logrotate
- name: Disable default rsyslog logrotate to prevent conflicts
command: mv /etc/logrotate.d/rsyslog /etc/logrotate.d/rsyslog.disabled
when: rsyslog_logrotate.stat.exists
changed_when: rsyslog_logrotate.stat.exists
- name: Configure aggressive logrotate for system logs
template:
src: privacy-logrotate.j2
dest: /etc/logrotate.d/99-privacy-enhanced
mode: '0644'
owner: root
group: root
notify: restart rsyslog
- name: Configure logrotate for auth logs with shorter retention
template:
src: auth-logrotate.j2
dest: /etc/logrotate.d/99-auth-privacy
mode: '0644'
owner: root
group: root
notify: restart rsyslog
- name: Configure logrotate for kern logs with VPN filtering
template:
src: kern-logrotate.j2
dest: /etc/logrotate.d/99-kern-privacy
mode: '0644'
owner: root
group: root
notify: restart rsyslog
- name: Set more frequent logrotate execution
cron:
name: "Enhanced privacy log rotation"
job: "/usr/sbin/logrotate /etc/logrotate.conf"
minute: "0"
hour: "*/6"
user: root
state: present
- name: Create privacy log cleanup script
template:
src: privacy-log-cleanup.sh.j2
dest: /usr/local/bin/privacy-log-cleanup.sh
mode: '0755'
owner: root
group: root
# Note: We don't force immediate rotation as it can cause conflicts
# The new settings will apply on the next scheduled rotation

View file

@ -0,0 +1,36 @@
---
# Privacy enhancements for Algo VPN
# This role implements additional privacy measures to reduce log retention
# and minimize traces of VPN usage on the server
- name: Display privacy enhancements status
debug:
msg: "Privacy enhancements are {{ 'enabled' if privacy_enhancements_enabled else 'disabled' }}"
- name: Privacy enhancements block
block:
- name: Include log rotation tasks
include_tasks: log_rotation.yml
tags: privacy-logs
- name: Include history clearing tasks
include_tasks: clear_history.yml
tags: privacy-history
- name: Include log filtering tasks
include_tasks: log_filtering.yml
tags: privacy-filtering
- name: Include automatic cleanup tasks
include_tasks: auto_cleanup.yml
tags: privacy-cleanup
- name: Include advanced privacy tasks
include_tasks: advanced_privacy.yml
tags: privacy-advanced
- name: Display privacy enhancements completion
debug:
msg: "Privacy enhancements have been successfully applied"
when: privacy_enhancements_enabled | bool

View file

@ -0,0 +1,15 @@
# Privacy-enhanced SSH log filtering
# Filters successful SSH connections while keeping failures for security
# Generated by Algo VPN privacy role
{% if privacy_advanced.disable_ssh_success_logs %}
# Filter successful SSH connections (keep failures for security monitoring)
:msg, contains, "sshd.*Accepted" stop
:msg, contains, "sshd.*session opened" stop
:msg, contains, "sshd.*session closed" stop
# Filter SSH key-based authentication success
:msg, contains, "sshd.*publickey" stop
{% endif %}
# Continue processing SSH failure messages and other logs

View file

@ -0,0 +1,19 @@
# Privacy-enhanced authentication log filtering
# WARNING: Use with caution - this reduces security logging
# Only enable if you understand the security implications
# Generated by Algo VPN privacy role
{% if privacy_log_filtering.exclude_auth_logs %}
# Filter successful authentication messages (reduces audit trail)
:msg, contains, "authentication success" stop
:msg, contains, "session opened" stop
:msg, contains, "session closed" stop
# Filter sudo success messages (keep failures for security)
:msg, regex, "sudo.*COMMAND" stop
# Filter cron messages
:msg, contains, "CRON" stop
{% endif %}
# Continue processing other auth messages

View file

@ -0,0 +1,21 @@
# Privacy-enhanced kernel log filtering
# Filters kernel messages that may reveal VPN usage patterns
# Generated by Algo VPN privacy role
{% if privacy_log_filtering.filter_kernel_vpn_logs %}
# Filter iptables/netfilter messages related to VPN
:msg, contains, "iptables" stop
:msg, contains, "netfilter" stop
# Filter connection tracking messages
:msg, contains, "nf_conntrack" stop
# Filter network interface up/down messages for VPN interfaces
:msg, regex, "wg[0-9]+.*link" stop
:msg, regex, "ipsec[0-9]+.*link" stop
# Filter routing table changes
:msg, contains, "rtnetlink" stop
{% endif %}
# Continue processing non-filtered messages

View file

@ -0,0 +1,34 @@
# Privacy-enhanced rsyslog configuration
# Filters VPN-related log entries for enhanced privacy
# Generated by Algo VPN privacy role
# Stop processing VPN-related messages to prevent them from being logged
# This helps maintain user privacy by not storing VPN connection details
{% if privacy_log_filtering.exclude_vpn_logs %}
# Filter WireGuard messages
:msg, contains, "wireguard" stop
# Filter StrongSwan/IPsec messages
:msg, contains, "strongswan" stop
:msg, contains, "ipsec" stop
:msg, contains, "charon" stop
:msg, contains, "xl2tpd" stop
# Filter VPN interface messages
:msg, contains, "wg0" stop
:msg, contains, "ipsec0" stop
# Filter VPN-related kernel messages
:msg, regex, "IN=wg[0-9]+" stop
:msg, regex, "OUT=wg[0-9]+" stop
{% endif %}
{% if privacy_log_filtering.filter_kernel_vpn_logs %}
# Filter kernel messages related to VPN traffic
:msg, contains, "netfilter" stop
:msg, regex, "FORWARD.*DPT:(51820|500|4500)" stop
{% endif %}
# Continue processing other messages
& stop

View file

@ -0,0 +1,26 @@
# Privacy-enhanced auth log rotation
# Reduces retention time for authentication logs
# Generated by Algo VPN privacy role
/var/log/auth.log
{
# Shorter retention for auth logs (privacy)
rotate 2
maxage {{ privacy_log_rotation.max_age | int // 2 }}
size {{ privacy_log_rotation.max_size // 2 }}M
daily
missingok
notifempty
compress
delaycompress
create 0640 syslog adm
copytruncate
postrotate
if [ -f /var/run/rsyslogd.pid ]; then
kill -HUP `cat /var/run/rsyslogd.pid`
fi
endscript
}

View file

@ -0,0 +1,36 @@
#!/bin/bash
# Privacy-enhanced history clearing on logout
# This script clears command history when users log out
# Generated by Algo VPN privacy role
{% if privacy_history_clearing.clear_bash_history %}
# Clear bash history
if [ -f ~/.bash_history ]; then
> ~/.bash_history
fi
# Clear zsh history
if [ -f ~/.zsh_history ]; then
> ~/.zsh_history
fi
# Clear current session history
history -c
history -w
# Clear less history
if [ -f ~/.lesshst ]; then
rm -f ~/.lesshst
fi
# Clear vim history
if [ -f ~/.viminfo ]; then
rm -f ~/.viminfo
fi
{% endif %}
{% if privacy_history_clearing.clear_system_history %}
# Clear temporary files in user directory
find ~/tmp -type f -delete 2>/dev/null || true
find ~/.cache -type f -delete 2>/dev/null || true
{% endif %}

View file

@ -0,0 +1,37 @@
# Privacy-enhanced kernel log rotation
# Reduces retention time for kernel logs that may contain VPN traces
# Generated by Algo VPN privacy role
/var/log/kern.log
{
# Aggressive rotation for kernel logs
rotate {{ privacy_log_rotation.rotate_count }}
maxage {{ privacy_log_rotation.max_age }}
size {{ privacy_log_rotation.max_size }}M
daily
missingok
notifempty
compress
delaycompress
create 0640 syslog adm
copytruncate
# Pre-rotation script to filter VPN-related entries
prerotate
# Create filtered version excluding VPN traces
if [ -f /var/log/kern.log ]; then
grep -v -E "(wireguard|ipsec|strongswan|xl2tpd)" /var/log/kern.log > /tmp/kern.log.filtered || true
if [ -s /tmp/kern.log.filtered ]; then
mv /tmp/kern.log.filtered /var/log/kern.log
fi
fi
endscript
postrotate
if [ -f /var/run/rsyslogd.pid ]; then
kill -HUP `cat /var/run/rsyslogd.pid`
fi
endscript
}

View file

@ -0,0 +1,75 @@
#!/bin/bash
# Privacy auto-cleanup script
# Automatically cleans up logs and temporary files for enhanced privacy
# Generated by Algo VPN privacy role
set -euo pipefail
# Configuration
LOG_MAX_AGE={{ privacy_auto_cleanup.temp_files_max_age }}
SCRIPT_LOG="/var/log/privacy-cleanup.log"
# Logging function
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$SCRIPT_LOG"
}
log_message "Starting privacy cleanup"
{% if privacy_auto_cleanup.enabled %}
# Rotate log files to prevent the cleanup log from growing
if [ -f "$SCRIPT_LOG" ] && [ $(wc -l < "$SCRIPT_LOG") -gt 1000 ]; then
tail -n 500 "$SCRIPT_LOG" > "$SCRIPT_LOG.tmp"
mv "$SCRIPT_LOG.tmp" "$SCRIPT_LOG"
fi
# Clean temporary files
log_message "Cleaning temporary files older than ${LOG_MAX_AGE} days"
find /tmp -type f -mtime +${LOG_MAX_AGE} -delete 2>/dev/null || true
find /var/tmp -type f -mtime +${LOG_MAX_AGE} -delete 2>/dev/null || true
# Clean old log files that may have escaped rotation
log_message "Cleaning old rotated logs"
find /var/log -name "*.log.*" -type f -mtime +{{ privacy_log_rotation.max_age }} -delete 2>/dev/null || true
find /var/log -name "*.gz" -type f -mtime +{{ privacy_log_rotation.max_age }} -delete 2>/dev/null || true
# Clean systemd journal if it exists
if [ -d /var/log/journal ]; then
log_message "Cleaning systemd journal files"
journalctl --vacuum-time={{ privacy_log_rotation.max_age }}d 2>/dev/null || true
journalctl --vacuum-size=50M 2>/dev/null || true
fi
{% if privacy_auto_cleanup.clean_package_cache %}
# Clean package cache
log_message "Cleaning package cache"
apt-get clean 2>/dev/null || true
apt-get autoclean 2>/dev/null || true
{% endif %}
# Clean bash history files
log_message "Cleaning bash history files"
for user_home in /home/* /root; do
if [ -d "$user_home" ]; then
rm -f "$user_home/.bash_history" 2>/dev/null || true
rm -f "$user_home/.zsh_history" 2>/dev/null || true
rm -f "$user_home/.lesshst" 2>/dev/null || true
rm -f "$user_home/.viminfo" 2>/dev/null || true
fi
done
# Clean core dumps
log_message "Cleaning core dumps"
find /var/crash -type f -name "*.crash" -mtime +1 -delete 2>/dev/null || true
# Force log rotation
log_message "Forcing log rotation"
/usr/sbin/logrotate -f /etc/logrotate.conf 2>/dev/null || true
log_message "Privacy cleanup completed successfully"
{% else %}
log_message "Privacy cleanup is disabled"
{% endif %}
# Clean up old privacy cleanup logs
find /var/log -name "privacy-cleanup.log.*" -type f -mtime +7 -delete 2>/dev/null || true

View file

@ -0,0 +1,22 @@
#!/bin/bash
# Privacy log cleanup script
# Immediately cleans up existing logs and applies privacy settings
# Generated by Algo VPN privacy role
set -euo pipefail
echo "Starting privacy log cleanup..."
# Truncate existing log files to apply new rotation settings immediately
find /var/log -type f -name "*.log" -size +{{ privacy_log_rotation.max_size }}M -exec truncate -s {{ privacy_log_rotation.max_size }}M {} \; 2>/dev/null || true
# Remove old rotated logs that exceed our retention policy
find /var/log -type f \( -name "*.log.*" -o -name "*.gz" \) -mtime +{{ privacy_log_rotation.max_age }} -delete 2>/dev/null || true
# Clean up systemd journal to respect new settings
if [ -d /var/log/journal ]; then
journalctl --vacuum-time={{ privacy_log_rotation.max_age }}d 2>/dev/null || true
journalctl --vacuum-size={{ privacy_log_rotation.max_size * 10 }}M 2>/dev/null || true
fi
echo "Privacy log cleanup completed"

View file

@ -0,0 +1,53 @@
# Privacy-enhanced logrotate configuration
# This configuration enforces aggressive log rotation for privacy
# Generated by Algo VPN privacy role
# Replaces the default rsyslog logrotate configuration
# Main system logs (may not all exist on every system)
/var/log/syslog
/var/log/messages
/var/log/daemon.log
/var/log/debug
/var/log/user.log
/var/log/mail.log
/var/log/mail.err
/var/log/mail.warn
{
# Rotate {{ privacy_log_rotation.rotate_count }} times before deletion
rotate {{ privacy_log_rotation.rotate_count }}
# Maximum age in days
maxage {{ privacy_log_rotation.max_age }}
# Maximum size per file
size {{ privacy_log_rotation.max_size }}M
{% if privacy_log_rotation.daily_rotation %}
# Force daily rotation
daily
{% endif %}
{% if privacy_log_rotation.compress %}
# Compress rotated files
compress
delaycompress
{% endif %}
# Missing files are ok (not all systems have all logs)
missingok
# Don't rotate if empty
notifempty
# Create new files with specific permissions
create 0640 syslog adm
# Truncate original file after rotation
copytruncate
# Execute after rotation
postrotate
# Send SIGHUP to rsyslog
/usr/bin/killall -HUP rsyslogd 2>/dev/null || true
endscript
}

View file

@ -0,0 +1,85 @@
#!/bin/bash
# Privacy monitoring script
# Monitors and reports on privacy settings status
# Generated by Algo VPN privacy role
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}Algo VPN Privacy Status Monitor${NC}"
echo "========================================"
# Check log rotation settings
echo -e "\n${YELLOW}Log Rotation Status:${NC}"
if [ -f /etc/logrotate.d/99-privacy-enhanced ]; then
echo -e " ${GREEN}✓${NC} Privacy log rotation configured"
else
echo -e " ${RED}✗${NC} Privacy log rotation not found"
fi
# Check rsyslog filtering
echo -e "\n${YELLOW}Log Filtering Status:${NC}"
if [ -f /etc/rsyslog.d/49-privacy-vpn-filter.conf ]; then
echo -e " ${GREEN}✓${NC} VPN log filtering enabled"
else
echo -e " ${RED}✗${NC} VPN log filtering not configured"
fi
# Check history clearing
echo -e "\n${YELLOW}History Clearing Status:${NC}"
if [ -f /etc/bash.bash_logout ]; then
echo -e " ${GREEN}✓${NC} Logout history clearing configured"
else
echo -e " ${RED}✗${NC} Logout history clearing not configured"
fi
# Check auto cleanup
echo -e "\n${YELLOW}Auto Cleanup Status:${NC}"
if [ -f /usr/local/bin/privacy-auto-cleanup.sh ]; then
echo -e " ${GREEN}✓${NC} Auto cleanup script installed"
if crontab -l | grep -q "privacy-auto-cleanup"; then
echo -e " ${GREEN}✓${NC} Auto cleanup scheduled"
else
echo -e " ${YELLOW}!${NC} Auto cleanup script exists but not scheduled"
fi
else
echo -e " ${RED}✗${NC} Auto cleanup not configured"
fi
# Check current log sizes
echo -e "\n${YELLOW}Current Log Status:${NC}"
total_log_size=$(du -sh /var/log 2>/dev/null | cut -f1 || echo "Unknown")
echo " Total log directory size: $total_log_size"
if [ -f /var/log/auth.log ]; then
auth_size=$(du -h /var/log/auth.log | cut -f1)
echo " Auth log size: $auth_size"
fi
if [ -f /var/log/syslog ]; then
syslog_size=$(du -h /var/log/syslog | cut -f1)
echo " Syslog size: $syslog_size"
fi
# Check systemd journal status
echo -e "\n${YELLOW}Journal Status:${NC}"
if [ -d /var/log/journal ]; then
journal_size=$(du -sh /var/log/journal 2>/dev/null | cut -f1 || echo "Unknown")
echo " Journal size: $journal_size"
else
echo -e " ${GREEN}✓${NC} Persistent journal disabled (using volatile storage)"
fi
# Privacy configuration summary
echo -e "\n${YELLOW}Privacy Configuration Summary:${NC}"
echo " Log retention: {{ privacy_log_rotation.max_age }} days"
echo " Max log size: {{ privacy_log_rotation.max_size }}MB"
echo " VPN log filtering: {{ privacy_log_filtering.exclude_vpn_logs }}"
echo -e " History clearing: {{ privacy_history_clearing.clear_bash_history }}"
echo -e "\n${GREEN}Privacy monitoring complete${NC}"

View file

@ -0,0 +1,32 @@
# Privacy-enhanced rsyslog configuration
# Minimal logging configuration for enhanced privacy
# Generated by Algo VPN privacy role
# Global settings for privacy
$ModLoad imuxsock # provides support for local system logging
$ModLoad imklog # provides kernel logging support
# Reduce logging verbosity
$KLogPermitNonKernelFacility on
$SystemLogSocketName /run/systemd/journal/syslog
# Privacy-enhanced rules
{% if privacy_advanced.reduce_kernel_verbosity %}
# Reduce kernel message verbosity
kern.info;kern.!debug /var/log/kern.log
{% else %}
kern.* /var/log/kern.log
{% endif %}
# Essential system messages only
*.emerg :omusrmsg:*
*.alert /var/log/alert.log
*.crit /var/log/critical.log
*.err /var/log/error.log
# Compress and limit emergency logs
$template PrivacyTemplate,"%timegenerated% %hostname% %syslogtag%%msg%\n"
$ActionFileDefaultTemplate PrivacyTemplate
# Stop processing after essential logs to prevent detailed logging
& stop

View file

@ -0,0 +1,44 @@
# Privacy shutdown cleanup systemd service
# Clears logs and sensitive data on system shutdown
# Generated by Algo VPN privacy role
[Unit]
Description=Privacy Cleanup on Shutdown
DefaultDependencies=false
Before=shutdown.target reboot.target halt.target
Requires=-.mount
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/bin/bash -c '
# Clear all logs
find /var/log -type f -name "*.log" -exec truncate -s 0 {} \; 2>/dev/null || true;
# Clear rotated logs
find /var/log -type f \( -name "*.log.*" -o -name "*.gz" \) -delete 2>/dev/null || true;
# Clear systemd journal
if [ -d /var/log/journal ]; then
rm -rf /var/log/journal/* 2>/dev/null || true;
fi;
# Clear bash history
for user_home in /home/* /root; do
if [ -d "$user_home" ]; then
rm -f "$user_home"/.bash_history 2>/dev/null || true;
rm -f "$user_home"/.zsh_history 2>/dev/null || true;
fi;
done;
# Clear temporary files
rm -rf /tmp/* /var/tmp/* 2>/dev/null || true;
# Sync to ensure changes are written
sync;
'
TimeoutStopSec=30
[Install]
WantedBy=shutdown.target

View file

@ -23,7 +23,7 @@
file:
path: /var/jail/
state: directory
mode: 0755
mode: '0755'
owner: root
group: "{{ root_group | default('root') }}"
@ -87,7 +87,7 @@
template:
src: ssh_config.j2
dest: "{{ ssh_tunnels_config_path }}/{{ item }}.ssh_config"
mode: 0700
mode: '0700'
with_items: "{{ users }}"
delegate_to: localhost
become: false

View file

@ -19,7 +19,7 @@
template:
src: mobileconfig.j2
dest: "{{ ipsec_config_path }}/apple/{{ item.0 }}.mobileconfig"
mode: 0600
mode: '0600'
with_together:
- "{{ users }}"
- "{{ PayloadContent.results }}"
@ -29,7 +29,7 @@
template:
src: client_ipsec.conf.j2
dest: "{{ ipsec_config_path }}/manual/{{ item }}.conf"
mode: 0600
mode: '0600'
with_items:
- "{{ users }}"
@ -38,7 +38,7 @@
template:
src: client_ipsec.secrets.j2
dest: "{{ ipsec_config_path }}/manual/{{ item }}.secrets"
mode: 0600
mode: '0600'
with_items:
- "{{ users }}"
@ -46,4 +46,4 @@
file:
path: "{{ ipsec_config_path }}"
state: directory
mode: 0700
mode: '0700'

View file

@ -36,6 +36,7 @@
type: ECC
curve: secp384r1
mode: "0600"
no_log: true
# CA certificate with name constraints to prevent certificate misuse (Issue #75)
- name: Create certificate signing request (CSR) for CA certificate with security constraints
@ -91,11 +92,13 @@
privatekey_passphrase: "{{ CA_password }}"
provider: selfsigned
mode: "0644"
no_log: true
- name: Copy the CA certificate
copy:
src: "{{ ipsec_pki_path }}/cacert.pem"
dest: "{{ ipsec_config_path }}/manual/cacert.pem"
mode: '0644'
- name: Create private keys for users and server
community.crypto.openssl_privatekey:
@ -164,6 +167,7 @@
ownca_not_after: "+{{ certificate_validity_days }}d"
ownca_not_before: "-1d"
mode: "0644"
no_log: true
- name: Sign client certificates with CA
community.crypto.x509_certificate:
@ -178,6 +182,7 @@
mode: "0644"
with_items: "{{ client_csr_jobs.results }}"
register: client_sign_results
no_log: true
- name: Generate p12 files
community.crypto.openssl_pkcs12:
@ -189,6 +194,7 @@
mode: "0600"
encryption_level: "compatibility2022" # Apple device compatibility
with_items: "{{ users }}"
no_log: true
- name: Generate p12 files with CA certificate included
community.crypto.openssl_pkcs12:
@ -202,11 +208,13 @@
mode: "0600"
encryption_level: "compatibility2022" # Apple device compatibility
with_items: "{{ users }}"
no_log: true
- name: Copy the p12 certificates
copy:
src: "{{ ipsec_pki_path }}/private/{{ item }}.p12"
dest: "{{ ipsec_config_path }}/manual/{{ item }}.p12"
mode: '0600'
with_items:
- "{{ users }}"
@ -221,6 +229,7 @@
ansible.builtin.lineinfile:
path: "{{ ipsec_pki_path }}/all-users"
line: "{{ item }}"
mode: '0644'
create: true
with_items: "{{ users }}"
register: users_file
@ -255,6 +264,7 @@
issuer:
CN: "{{ IP_subject_alt_name }}"
revoked_certificates: "{{ revoked_certificates }}"
no_log: true
- name: Set CRL file permissions
file:
@ -270,5 +280,6 @@
copy:
src: "{{ ipsec_pki_path }}/crl.pem"
dest: "{{ config_prefix | default('/') }}etc/ipsec.d/crls/algo.root.pem"
mode: '0644'
notify:
- rereadcrls

View file

@ -25,7 +25,7 @@
content: " capability setpcap,"
owner: root
group: root
mode: 0644
mode: '0644'
notify: restart strongswan
- name: Ubuntu | Enforcing ipsec with apparmor
@ -49,7 +49,7 @@
file:
path: /etc/systemd/system/{{ strongswan_service }}.service.d/
state: directory
mode: 0755
mode: '0755'
owner: root
group: root
@ -57,6 +57,7 @@
template:
src: 100-CustomLimitations.conf.j2
dest: /etc/systemd/system/{{ strongswan_service }}.service.d/100-CustomLimitations.conf
mode: '0644'
notify:
- daemon-reload
- restart strongswan

View file

@ -5,14 +5,19 @@
# BEFORE: securelevel
# KEYWORD: shutdown
# shellcheck source=/dev/null
. /etc/rc.subr
name="wg"
# shellcheck disable=SC2034
rcvar=wg_enable
command="/usr/local/bin/wg-quick"
# shellcheck disable=SC2034
start_cmd=wg_up
# shellcheck disable=SC2034
stop_cmd=wg_down
# shellcheck disable=SC2034
status_cmd=wg_status
pidfile="/var/run/$name.pid"
load_rc_config "$name"

View file

@ -17,6 +17,7 @@
with_items:
- "{{ users }}"
- "{{ IP_subject_alt_name }}"
no_log: true
- name: Generate raw preshared keys
community.crypto.openssl_privatekey:
@ -36,6 +37,7 @@
with_items:
- "{{ users }}"
- "{{ IP_subject_alt_name }}"
no_log: true
- name: Generate public keys
x25519_pubkey:
@ -44,3 +46,13 @@
with_items:
- "{{ users }}"
- "{{ IP_subject_alt_name }}"
no_log: true
- name: Set permissions for public keys
file:
path: "{{ wireguard_pki_path }}/public/{{ item }}"
mode: '0644'
with_items:
- "{{ users }}"
- "{{ IP_subject_alt_name }}"
no_log: true

View file

@ -72,6 +72,7 @@
args:
chdir: "{{ wireguard_config_path }}"
executable: bash
no_log: true
become: false
delegate_to: localhost

View file

@ -15,7 +15,7 @@
file:
path: /etc/systemd/system/wg-quick@{{ wireguard_interface }}.service.d/
state: directory
mode: 0755
mode: '0755'
owner: root
group: root
@ -48,7 +48,7 @@
SystemCallErrorNumber=EPERM
owner: root
group: root
mode: 0644
mode: '0644'
notify:
- daemon-reload
- restart wireguard

View file

@ -177,10 +177,16 @@
- algo_ssh_tunneling
tags: ssh_tunneling
- import_role:
name: privacy
when: privacy_enhancements_enabled | default(true)
tags: privacy
- block:
- name: Dump the configuration
copy:
dest: configs/{{ IP_subject_alt_name }}/.config.yml
mode: '0644'
content: |
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
server_user: {{ ansible_ssh_user }}

View file

@ -8,9 +8,12 @@ CA_CONSTRAINTS="$(openssl verify -verbose \
-CAfile ./configs/10.0.8.100/ipsec/.pki/cacert.pem \
./configs/10.0.8.100/ipsec/.pki/certs/google-algo-test-pair.com.crt 2>&1)" || true
echo "$CA_CONSTRAINTS" | grep "permitted subtree violation" >/dev/null && \
echo "Name Constraints test passed" || \
(echo "Name Constraints test failed" && exit 1)
if echo "$CA_CONSTRAINTS" | grep "permitted subtree violation" >/dev/null; then
echo "Name Constraints test passed"
else
echo "Name Constraints test failed"
exit 1
fi
echo "$CA_CONSTRAINTS"

View file

@ -22,7 +22,7 @@ lxc profile set default raw.lxc 'lxc.apparmor.profile = unconfined'
lxc profile set default security.privileged true
lxc profile show default
lxc init ubuntu:${UBUNTU_VERSION} algo
lxc init ubuntu:"${UBUNTU_VERSION}" algo
lxc network attach lxdbr0 algo eth0 eth0
lxc config device set algo eth0 ipv4.address 10.0.8.100
lxc start algo

View file

@ -4,12 +4,18 @@ set -euxo pipefail
PASS=$(grep ^p12_password: configs/10.0.8.100/.config.yml | awk '{print $2}' | cut -f2 -d\')
ssh-keygen -p -P ${PASS} -N '' -f configs/10.0.8.100/ssh-tunnel/desktop.pem
ssh-keygen -p -P "${PASS}" -N '' -f configs/10.0.8.100/ssh-tunnel/desktop.pem
ssh -o StrictHostKeyChecking=no -D 127.0.0.1:1080 -f -q -C -N desktop@10.0.8.100 -i configs/10.0.8.100/ssh-tunnel/desktop.pem -F configs/10.0.8.100/ssh_config
git config --global http.proxy 'socks5://127.0.0.1:1080'
for i in {1..10}; do git clone -vv https://github.com/trailofbits/algo /tmp/ssh-tunnel-check && break || sleep 1; done
for _ in {1..10}; do
if git clone -vv https://github.com/trailofbits/algo /tmp/ssh-tunnel-check; then
break
else
sleep 1
fi
done
echo "SSH tunneling tests passed"