Skip to content

fix: Prevent sensitive information from being logged #14779

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions algo.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Metadata-Version: 2.4
Name: algo
Version: 2.0.0b0
Summary: Set up a personal IPSEC VPN in the cloud
Requires-Python: >=3.11
License-File: LICENSE
Requires-Dist: ansible==11.8.0
Requires-Dist: jinja2>=3.1.6
Requires-Dist: netaddr==1.3.0
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: pyopenssl>=0.15
Requires-Dist: segno>=1.6.0
Provides-Extra: aws
Requires-Dist: boto3>=1.34.0; extra == "aws"
Requires-Dist: boto>=2.49.0; extra == "aws"
Provides-Extra: azure
Requires-Dist: azure-identity>=1.15.0; extra == "azure"
Requires-Dist: azure-mgmt-compute>=30.0.0; extra == "azure"
Requires-Dist: azure-mgmt-network>=25.0.0; extra == "azure"
Requires-Dist: azure-mgmt-resource>=23.0.0; extra == "azure"
Requires-Dist: msrestazure>=0.6.4; extra == "azure"
Provides-Extra: gcp
Requires-Dist: google-auth>=2.28.0; extra == "gcp"
Requires-Dist: requests>=2.31.0; extra == "gcp"
Provides-Extra: hetzner
Requires-Dist: hcloud>=1.33.0; extra == "hetzner"
Provides-Extra: linode
Requires-Dist: linode-api4>=5.15.0; extra == "linode"
Provides-Extra: openstack
Requires-Dist: openstacksdk>=2.1.0; extra == "openstack"
Provides-Extra: cloudstack
Requires-Dist: cs>=3.0.0; extra == "cloudstack"
Requires-Dist: sshpubkeys>=3.3.1; extra == "cloudstack"
Dynamic: license-file
10 changes: 10 additions & 0 deletions algo.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
LICENSE
README.md
pyproject.toml
algo.egg-info/PKG-INFO
algo.egg-info/SOURCES.txt
algo.egg-info/dependency_links.txt
algo.egg-info/requires.txt
algo.egg-info/top_level.txt
tests/test_cloud_init_template.py
tests/test_package_preinstall.py
1 change: 1 addition & 0 deletions algo.egg-info/dependency_links.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

34 changes: 34 additions & 0 deletions algo.egg-info/requires.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
ansible==11.8.0
jinja2>=3.1.6
netaddr==1.3.0
pyyaml>=6.0.2
pyopenssl>=0.15
segno>=1.6.0

[aws]
boto3>=1.34.0
boto>=2.49.0

[azure]
azure-identity>=1.15.0
azure-mgmt-compute>=30.0.0
azure-mgmt-network>=25.0.0
azure-mgmt-resource>=23.0.0
msrestazure>=0.6.4

[cloudstack]
cs>=3.0.0
sshpubkeys>=3.3.1

[gcp]
google-auth>=2.28.0
requests>=2.31.0

[hetzner]
hcloud>=1.33.0

[linode]
linode-api4>=5.15.0

[openstack]
openstacksdk>=2.1.0
1 change: 1 addition & 0 deletions algo.egg-info/top_level.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

64 changes: 63 additions & 1 deletion config.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,69 @@ keys_clean_all: false

# StrongSwan log level
# https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration
strongswan_log_level: 2
# Privacy enhancement: Set to -1 to disable logging of VPN connection details
# Level 2 logs connection attempts and authentication which may reveal usage patterns
# Level -1 disables logging entirely for enhanced privacy
strongswan_log_level: -1

### Privacy Enhancements ###
# Additional privacy measures to reduce server-side traces of VPN usage
# These settings help protect user privacy by minimizing log retention and filtering sensitive data

# Enable enhanced privacy features
# Set to false to disable all privacy enhancements (useful for debugging)
privacy_enhancements_enabled: true

# Log rotation and retention settings
privacy_log_rotation:
# Maximum age for logs in days (shorter = more private, but less debugging info)
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 to save space
compress: true
# Force daily rotation
daily_rotation: true

# History clearing configuration
privacy_history_clearing:
# Clear bash/shell history after deployment
clear_bash_history: true
# Clear system command history logs
clear_system_history: true
# Disable persistent history for system users
disable_service_history: true

# Log filtering to exclude VPN-related entries
privacy_log_filtering:
# Filter out VPN connection logs (WireGuard, StrongSwan, etc.)
exclude_vpn_logs: true
# Filter out detailed authentication logs (reduces security logging - use with caution)
exclude_auth_logs: false
# Filter kernel messages related to VPN traffic
filter_kernel_vpn_logs: true

# Automatic cleanup policies
privacy_auto_cleanup:
# Enable automatic cleanup of old logs and temporary files
enabled: true
# Cleanup frequency: daily, weekly, or monthly
frequency: "daily"
# Remove temporary files older than N days
temp_files_max_age: 1
# Clean package manager cache
clean_package_cache: true

# Advanced privacy settings (use with caution)
privacy_advanced:
# Disable logging of successful SSH connections (keeps failures for security)
disable_ssh_success_logs: false
# Reduce kernel log verbosity to minimize VPN traces
reduce_kernel_verbosity: true
# Clear all logs on system shutdown (extreme privacy measure)
clear_logs_on_shutdown: false

# rightsourceip for ipsec
# ipv4
Expand Down
32 changes: 32 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -59,6 +60,37 @@ 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?

Algo was not originally designed for zero-logging, but recent updates have introduced privacy enhancements to significantly reduce the logging footprint. Here's what you need to know:

**Recent Privacy Enhancements:**
* **StrongSwan logging disabled by default** - Connection logs no longer record who connects, when, or from which IP
* **DNSCrypt syslog disabled** - DNS queries are not logged to system logs
* **Sensitive data protection** - All passwords, keys, and credentials are now hidden from Ansible logs
* **Aggressive log rotation** - Logs are automatically rotated and deleted after 7 days
* **Optional privacy features** - Bash history clearing, VPN log filtering, and more

**What May Still Be Logged:**
* System errors and security events (failed authentications, system updates)
* SSH administrative access for server management
* Cloud provider logs and metadata (outside Algo's control)
* Kernel messages and system diagnostics needed for troubleshooting

**How to Maximize Privacy:**
* Keep the default privacy settings enabled in `config.cfg`
* Use the privacy monitoring script: `sudo /usr/local/bin/privacy-monitor.sh`
* Deploy on ephemeral cloud instances that can be destroyed when needed
* Review the privacy settings in `config.cfg` for additional options

**Important Limitations:**
* WireGuard inherently shows last endpoint and handshake time via `sudo wg`
* Cloud providers maintain their own logs and traffic metadata
* Your ISP and destination websites can still observe traffic patterns
* Complete zero-logging may make troubleshooting difficult

The privacy enhancements are enabled by default but can be disabled if you need more detailed logging for debugging. See the `privacy_enhancements_enabled` setting in `config.cfg`.

## Wasn't IPSEC backdoored by the US government?

No.
Expand Down
1 change: 1 addition & 0 deletions roles/cloud-azure/tasks/prompts.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
- set_fact:
secret: "{{ azure_secret | default(lookup('env','AZURE_SECRET'), true) }}"

Check failure on line 3 in roles/cloud-azure/tasks/prompts.yml

View workflow job for this annotation

GitHub Actions / Linting

jinja[spacing]

Jinja2 spacing could be improved: {{ azure_client_id | default(lookup('env','AZURE_CLIENT_ID'), true) }} -> {{ azure_client_id | default(lookup('env', 'AZURE_CLIENT_ID'), true) }}
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
Expand Down
1 change: 1 addition & 0 deletions roles/cloud-cloudstack/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@
CLOUDSTACK_KEY: "{{ algo_cs_key }}"
CLOUDSTACK_SECRET: "{{ algo_cs_token }}"
CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}"
no_log: true
4 changes: 4 additions & 0 deletions roles/cloud-cloudstack/tasks/prompts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
when:
- cs_key is undefined
- lookup('env','CLOUDSTACK_KEY')|length <= 0
no_log: true

- pause:
prompt: |
Expand All @@ -17,6 +18,7 @@
when:
- cs_secret is undefined
- lookup('env','CLOUDSTACK_SECRET')|length <= 0
no_log: true

- pause:
prompt: |
Expand All @@ -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:
Expand All @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions roles/cloud-digitalocean/tasks/prompts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
1 change: 1 addition & 0 deletions roles/cloud-ec2/tasks/cloudformation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
tags:
Environment: Algo
register: stack
no_log: true
1 change: 1 addition & 0 deletions roles/cloud-ec2/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions roles/cloud-ec2/tasks/prompts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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 }}"
Expand Down
4 changes: 4 additions & 0 deletions roles/cloud-gce/tasks/prompts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions roles/cloud-hetzner/tasks/prompts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions roles/cloud-lightsail/tasks/cloudformation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
Environment: Algo
Lightsail: true
register: stack
no_log: true
4 changes: 4 additions & 0 deletions roles/cloud-lightsail/tasks/prompts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
when:
- aws_access_key is undefined
- lookup('env','AWS_ACCESS_KEY_ID')|length <= 0
no_log: true

- pause:
prompt: |
Expand All @@ -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
Expand All @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions roles/cloud-linode/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
script: |
{{ stackscript }}
register: _linode_stackscript
no_log: true

- name: Update the stackscript
uri:
Expand All @@ -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:
Expand All @@ -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] }}"
Expand Down
Loading
Loading