Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
69334da
Add role to deploy test helpers repo
LDiazN Aug 22, 2025
cc15c5e
Change test helpers url
LDiazN Aug 25, 2025
0904fea
Set up echo and jsonth services
LDiazN Aug 25, 2025
620d5a1
Fix bad comment
LDiazN Aug 25, 2025
b1ee5cc
fix certificate deadlock issue
LDiazN Aug 28, 2025
3beab5d
Routing test helper traffic with nginx
LDiazN Aug 28, 2025
d0a9298
nginx config for test helpers
LDiazN Aug 28, 2025
4c5fcc6
Creating echo machine
LDiazN Aug 28, 2025
61d705e
Creating host for each th
LDiazN Aug 28, 2025
91bfe43
Fix bad module name
LDiazN Aug 28, 2025
1f08b62
Set up ansible for each test helper
LDiazN Aug 28, 2025
b773393
Run prometheus without dehydrated when no https is required
LDiazN Aug 29, 2025
ed6f3a2
removing unused listen 80 entry in prometheus config
LDiazN Aug 29, 2025
94b24cd
Allow services to run on port 80
LDiazN Aug 29, 2025
393803e
Add port parameters to use a different port for test helpers metrics
LDiazN Aug 29, 2025
f5f5819
Remove unused firewall rules
LDiazN Sep 1, 2025
901639d
Updated comment
LDiazN Sep 1, 2025
e45f173
Add checksum for test helpers tar download
LDiazN Sep 4, 2025
7ca3083
Merge conflict
LDiazN Nov 4, 2025
1ef7431
update with main
LDiazN Aug 11, 2026
335152a
Add test helpers machines; build th from scratch since we don't have …
LDiazN Aug 11, 2026
61c8f79
Fix edge case where service won't be properly restarted if a new vers…
LDiazN Aug 11, 2026
9e27329
Merge branch 'main' into test-helpers-machine
LDiazN Aug 12, 2026
824a2bf
Point oonimeasurements to the temp branch
LDiazN Aug 12, 2026
7d85944
remove test helpers from dev env; point ooniprobe to dev branch
LDiazN Aug 12, 2026
41a344c
Pull binaries from ooniprobe-rs repo
LDiazN Aug 12, 2026
8f74d5d
Merge branch 'main' into test-helpers-machine
LDiazN Aug 13, 2026
abf93a2
Get monitoring ip by digging it
LDiazN Aug 13, 2026
cd7d168
Add oonidevops ssh key to digitalocean hosts
LDiazN Aug 14, 2026
b8b458b
Fix small issues on playbooks for debian
LDiazN Aug 14, 2026
a40258f
Add simpler test helper module
LDiazN Aug 14, 2026
f88a07f
Fix test helper restart
LDiazN Aug 14, 2026
0e057b4
merge conflict
LDiazN Aug 14, 2026
01214d6
rename binaries; do checksum on download
LDiazN Aug 14, 2026
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
23 changes: 23 additions & 0 deletions ansible/deploy-echo-test-helper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
- name: Deploy test helpers
hosts:
- echo.th.dev.ooni.io
- echo.th.prod.ooni.io
become: true
roles:
- role: bootstrap
- role: prometheus_node_exporter
vars:
node_exporter_port: 9100
node_exporter_host: "0.0.0.0"
prometheus_nginx_proxy_config:
- location: /metrics/node_exporter
proxy_pass: http://127.0.0.1:9100/metrics
use_https: false
http_port: 8080 # if we leave port 80, it's taken by nginx
- role: test_helpers
vars:
helper: ooechohelpd
# sha256 of https://github.com/ooni/ooniprobe-rs/releases/download/v0.1.6/ooechohelpd
test_helpers_checksum: 10511a8b918c2244eba9e17c32f3cec9efbc5ffa51d6ad7f59fe648cd0986615
port: 80
23 changes: 23 additions & 0 deletions ansible/deploy-json-test-helper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
- name: Deploy test helpers
hosts:
- json.th.dev.ooni.io
- json.th.prod.ooni.io
become: true
roles:
- role: bootstrap
- role: prometheus_node_exporter
vars:
node_exporter_port: 9100
node_exporter_host: "0.0.0.0"
prometheus_nginx_proxy_config:
- location: /metrics/node_exporter
proxy_pass: http://127.0.0.1:9100/metrics
use_https: false
http_port: 8080 # if we leave port 80, it's taken by nginx
- role: test_helpers
vars:
helper: oojsonhelpd
# sha256 of https://github.com/ooni/ooniprobe-rs/releases/download/v0.1.6/oojsonhelpd
test_helpers_checksum: 3d977e1418ea398f520dff3de951e36010a294dc3d1b564c961542cc3729a224
port: 80
4 changes: 4 additions & 0 deletions ansible/inventory
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ openvpn2.htz-fsn.prod.ooni.nu
[aws-backend]
fastpath.dev.ooni.io
fastpath.prod.ooni.io
json.th.dev.ooni.io
echo.th.dev.ooni.io
json.th.prod.ooni.io
echo.th.prod.ooni.io
fastpath2.prod.ooni.io
reuploaderfastpath.prod.ooni.io
anonc.dev.ooni.io
Expand Down
2 changes: 1 addition & 1 deletion ansible/requirements/ansible-galaxy.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
roles:
- src: nginxinc.nginx
version: 0.24.3
version: 0.26.0
- src: geerlingguy.certbot
version: 5.2.0
- src: https://github.com/idealista/clickhouse_role
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ server {
ssl_certificate_key /var/lib/dehydrated/certs/{{ inventory_hostname }}/privkey.pem;
ssl_trusted_certificate /var/lib/dehydrated/certs/{{ inventory_hostname }}/chain.pem;
{% else %}
listen 80;
listen {{http_port}};

server_name {{ inventory_hostname }};
server_name {{inventory_hostname}};
{% endif %}

{% for config in prometheus_nginx_proxy_config %}
Expand Down
4 changes: 2 additions & 2 deletions ansible/roles/ssh_users/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
path: /etc/sudoers.d/adm
state: absent

- name: reload sshd
- name: reload ssh
tags: ssh_users
ansible.builtin.systemd_service:
name: sshd
name: ssh
state: reloaded
5 changes: 5 additions & 0 deletions ansible/roles/test_helpers/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
test_helpers_version: v0.1.6
test_helpers_base_url: "https://github.com/ooni/ooniprobe-rs/releases/download/{{ test_helpers_version }}"
Comment thread
hellais marked this conversation as resolved.

# monitoring server IP
monitoring_server_ip: "{{ lookup('dig', 'monitoring.ooni.org') }}"
10 changes: 10 additions & 0 deletions ansible/roles/test_helpers/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- name: reload nftables
tags: nftables
ansible.builtin.systemd_service:
name: nftables
state: reloaded

- name: reload nginx
service:
name: nginx
state: reloaded
76 changes: 76 additions & 0 deletions ansible/roles/test_helpers/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---

# For prometheus scrape requests.
- name: Allow traffic on port 9100 from the monitoring host only
become: true
tags: prometheus-proxy
blockinfile:
path: /etc/ooni/nftables/tcp/9100.nft
create: yes
block: |
add rule inet filter input ip saddr {{ monitoring_server_ip }} tcp dport 9100 counter accept comment "node exporter"
notify:
- reload nftables

- name: Allow traffic on the {{ helper }} test helper port
become: true
tags: test-helpers
blockinfile:
path: "/etc/ooni/nftables/tcp/{{ port }}.nft"
create: yes
block: |
add rule inet filter input tcp dport {{ port }} counter accept comment "{{ helper }} test helper"
notify:
- reload nftables

# Create test helpers user
- name: Create the testhelpers user
ansible.builtin.user:
name: "testhelpers"
shell: "/bin/bash"
create_home: no
system: yes
become: yes

# Install test helpers
- name: Download the {{ helper }} test helper binary
ansible.builtin.get_url:
url: "{{ test_helpers_base_url }}/{{ helper }}"
dest: "/usr/local/bin/{{ helper }}"
checksum: "sha256:{{ test_helpers_checksum }}"
mode: '0755'
force: yes
become: yes
register: helper_binary

# Create systemd units

- name: Create <helper>.service file
tags: test-helpers
ansible.builtin.template:
src: templates/{{helper}}.service
dest: /etc/systemd/system/{{helper}}.service
mode: '0755'
owner: root
register: helper_unit

- name: reload systemd
tags: test-helpers
ansible.builtin.systemd_service:
daemon_reload: yes
when: helper_unit.changed

- name: Start helper
tags: test-helpers
systemd:
name: "{{helper}}.service"
state: started
enabled: yes

- name: Restart helper if its binary or unit file changed
tags: test-helpers
ansible.builtin.systemd_service:
name: "{{ helper }}.service"
state: restarted
become: yes
when: helper_binary.changed or helper_unit.changed
22 changes: 22 additions & 0 deletions ansible/roles/test_helpers/templates/ooechohelpd.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[Unit]
Description=Test helper that will start an echo session on request
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
ExecStart=/usr/local/bin/ooechohelpd --port {{port}}
Restart=on-failure
RestartSec=5
User=testhelpers
Group=testhelpers
ProtectSystem=full
ProtectHome=yes
NoNewPrivileges=yes
PrivateTmp=yes
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
22 changes: 22 additions & 0 deletions ansible/roles/test_helpers/templates/oojsonhelpd.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[Unit]
Description=Test helper that will respond with a json showing the headers it received
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
ExecStart=/usr/local/bin/oojsonhelpd --port {{port}}
Restart=on-failure
RestartSec=5
User=testhelpers
Group=testhelpers
ProtectSystem=full
ProtectHome=yes
NoNewPrivileges=yes
PrivateTmp=yes
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
4 changes: 4 additions & 0 deletions ansible/roles/test_helpers/vars/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

# choices: oojsonhelpd, ooechohelpd
helper: "oojsonhelpd"
port: "80"
39 changes: 39 additions & 0 deletions tf/environments/prod/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,45 @@ module "fastpath_builder" {
codepipeline_bucket = aws_s3_bucket.ooniapi_codepipeline_bucket.bucket
}


#### Test Helpers Machines
#

# Registers the same oonidevops keypair used for the EC2 instances (see
# module.adm_iam_roles) as a DigitalOcean account key, so it can be installed
# on droplets via their ssh_keys argument too.
resource "digitalocean_ssh_key" "oonidevops" {
name = "oonidevops"
public_key = jsondecode(data.aws_secretsmanager_secret_version.deploy_key.secret_string)["public_key"]
}

module "ooni_test_helpers_json" {
source = "../../modules/ooni_th_binary_droplet"

stage = local.environment
name = "oonijsonth"
hostname = "json.th"

ssh_keys = [digitalocean_ssh_key.oonidevops.fingerprint]

dns_zone_ooni_io = local.dns_zone_ooni_io
}

# Echo test helper requires a dedicated machine bc it's a tcp server,
# not an HTTP server. It's impossible to reroute using nginx
module "ooni_test_helpers_echo" {
source = "../../modules/ooni_th_binary_droplet"

stage = local.environment
name = "ooniechoth"
hostname = "echo.th"

ssh_keys = [digitalocean_ssh_key.oonidevops.fingerprint]

dns_zone_ooni_io = local.dns_zone_ooni_io
}


module "reuploader_builder" {
source = "../../modules/ooni_docker_build"
trigger_tag = ""
Expand Down
31 changes: 31 additions & 0 deletions tf/modules/ooni_th_binary_droplet/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}

resource "digitalocean_droplet" "ooni_th" {
image = "debian-13-x64"
name = "${var.name}-${var.stage}"
region = var.instance_location
size = var.instance_size
ipv6 = true
ssh_keys = var.ssh_keys

lifecycle {
create_before_destroy = true
ignore_changes = all
}
}

resource "aws_route53_record" "ooni_th" {
zone_id = var.dns_zone_ooni_io
name = "${var.hostname}.${var.stage}.ooni.io"
type = "A"
ttl = 60

records = [digitalocean_droplet.ooni_th.ipv4_address]
}
7 changes: 7 additions & 0 deletions tf/modules/ooni_th_binary_droplet/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "droplet_ipv4_address" {
value = digitalocean_droplet.ooni_th.ipv4_address
}

output "fqdn" {
value = aws_route53_record.ooni_th.fqdn
}
33 changes: 33 additions & 0 deletions tf/modules/ooni_th_binary_droplet/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
variable "stage" {
type = string
}

variable "name" {
description = "Name of the droplet (will be suffixed with -<stage>)"
type = string
}

variable "hostname" {
description = "DNS label for the helper, e.g. \"json.th\" or \"echo.th\". The record is created as <hostname>.<stage>.ooni.io"
type = string
}

variable "instance_location" {
type = string
default = "fra1"
}

variable "instance_size" {
type = string
default = "s-1vcpu-1gb"
}

variable "ssh_keys" {
description = "Fingerprints of the DigitalOcean account SSH keys to grant root access to"
type = list(string)
}

variable "dns_zone_ooni_io" {
description = "id of the DNS zone for ooni_io"
type = string
}
Loading