From 4cc72da4da22474fef301d41a710ff65ee6320d3 Mon Sep 17 00:00:00 2001 From: counterweight Date: Mon, 15 Dec 2025 23:33:08 +0100 Subject: [PATCH 1/2] knots is publicly reachable --- .../deploy_bitcoin_knots_playbook.yml | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) diff --git a/ansible/services/bitcoin-knots/deploy_bitcoin_knots_playbook.yml b/ansible/services/bitcoin-knots/deploy_bitcoin_knots_playbook.yml index 47c4f58..2684965 100644 --- a/ansible/services/bitcoin-knots/deploy_bitcoin_knots_playbook.yml +++ b/ansible/services/bitcoin-knots/deploy_bitcoin_knots_playbook.yml @@ -722,3 +722,195 @@ name: bitcoind state: restarted + +- name: Setup public Bitcoin P2P forwarding on vipy via systemd-socket-proxyd + hosts: vipy + become: yes + vars_files: + - ../../infra_vars.yml + - ../../services_config.yml + - ../../infra_secrets.yml + - ./bitcoin_knots_vars.yml + vars: + bitcoin_tailscale_hostname: "knots-box" + uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}" + + tasks: + - name: Create Bitcoin P2P proxy socket unit + copy: + dest: /etc/systemd/system/bitcoin-p2p-proxy.socket + content: | + [Unit] + Description=Bitcoin P2P Proxy Socket + + [Socket] + ListenStream={{ bitcoin_p2p_port }} + + [Install] + WantedBy=sockets.target + owner: root + group: root + mode: '0644' + notify: Restart bitcoin-p2p-proxy socket + + - name: Create Bitcoin P2P proxy service unit + copy: + dest: /etc/systemd/system/bitcoin-p2p-proxy.service + content: | + [Unit] + Description=Bitcoin P2P Proxy to {{ bitcoin_tailscale_hostname }} + Requires=bitcoin-p2p-proxy.socket + After=network.target + + [Service] + Type=notify + ExecStart=/lib/systemd/systemd-socket-proxyd {{ bitcoin_tailscale_hostname }}:{{ bitcoin_p2p_port }} + owner: root + group: root + mode: '0644' + + - name: Reload systemd daemon + systemd: + daemon_reload: yes + + - name: Enable and start Bitcoin P2P proxy socket + systemd: + name: bitcoin-p2p-proxy.socket + enabled: yes + state: started + + - name: Allow Bitcoin P2P port through UFW + ufw: + rule: allow + port: "{{ bitcoin_p2p_port | string }}" + proto: tcp + comment: "Bitcoin P2P public access" + + - name: Verify connectivity to knots-box via Tailscale + wait_for: + host: "{{ bitcoin_tailscale_hostname }}" + port: "{{ bitcoin_p2p_port }}" + timeout: 10 + ignore_errors: yes + + - name: Display public endpoint + debug: + msg: "Bitcoin P2P public endpoint: {{ ansible_host }}:{{ bitcoin_p2p_port }}" + + # =========================================== + # Uptime Kuma TCP Monitor for Public P2P + # =========================================== + - name: Create Uptime Kuma TCP monitor setup script for Bitcoin P2P + delegate_to: localhost + become: no + copy: + dest: /tmp/setup_bitcoin_p2p_tcp_monitor.py + content: | + #!/usr/bin/env python3 + import sys + import traceback + import yaml + from uptime_kuma_api import UptimeKumaApi, MonitorType + + try: + with open('/tmp/ansible_bitcoin_p2p_config.yml', 'r') as f: + config = yaml.safe_load(f) + + url = config['uptime_kuma_url'] + username = config['username'] + password = config['password'] + monitor_host = config['monitor_host'] + monitor_port = config['monitor_port'] + monitor_name = config['monitor_name'] + + api = UptimeKumaApi(url, timeout=30) + api.login(username, password) + + monitors = api.get_monitors() + + # Find or create "services" group + group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None) + if not group: + api.add_monitor(type='group', name='services') + monitors = api.get_monitors() + group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None) + + # Check if monitor already exists + existing = next((m for m in monitors if m.get('name') == monitor_name), None) + + # Get ntfy notification ID + notifications = api.get_notifications() + ntfy_notification_id = None + for notif in notifications: + if notif.get('type') == 'ntfy': + ntfy_notification_id = notif.get('id') + break + + if existing: + print(f"Monitor '{monitor_name}' already exists (ID: {existing['id']})") + print("Skipping - monitor already configured") + else: + print(f"Creating TCP monitor '{monitor_name}'...") + api.add_monitor( + type=MonitorType.PORT, + name=monitor_name, + hostname=monitor_host, + port=monitor_port, + parent=group['id'], + interval=60, + maxretries=3, + retryInterval=60, + notificationIDList={ntfy_notification_id: True} if ntfy_notification_id else {} + ) + + api.disconnect() + print("SUCCESS") + + except Exception as e: + print(f"ERROR: {str(e)}", file=sys.stderr) + traceback.print_exc(file=sys.stderr) + sys.exit(1) + mode: '0755' + + - name: Create temporary config for TCP monitor setup + delegate_to: localhost + become: no + copy: + dest: /tmp/ansible_bitcoin_p2p_config.yml + content: | + uptime_kuma_url: "{{ uptime_kuma_api_url }}" + username: "{{ uptime_kuma_username }}" + password: "{{ uptime_kuma_password }}" + monitor_host: "{{ ansible_host }}" + monitor_port: {{ bitcoin_p2p_port }} + monitor_name: "Bitcoin Knots P2P Public" + mode: '0644' + + - name: Run Uptime Kuma TCP monitor setup + command: python3 /tmp/setup_bitcoin_p2p_tcp_monitor.py + delegate_to: localhost + become: no + register: tcp_monitor_setup + changed_when: "'SUCCESS' in tcp_monitor_setup.stdout" + ignore_errors: yes + + - name: Display TCP monitor setup output + debug: + msg: "{{ tcp_monitor_setup.stdout_lines }}" + when: tcp_monitor_setup.stdout is defined + + - name: Clean up TCP monitor temporary files + delegate_to: localhost + become: no + file: + path: "{{ item }}" + state: absent + loop: + - /tmp/setup_bitcoin_p2p_tcp_monitor.py + - /tmp/ansible_bitcoin_p2p_config.yml + + handlers: + - name: Restart bitcoin-p2p-proxy socket + systemd: + name: bitcoin-p2p-proxy.socket + state: restarted From 859cd2d8b7ccae3ac8c00beb3787675ab77a3470 Mon Sep 17 00:00:00 2001 From: counterweight Date: Mon, 15 Dec 2025 23:33:20 +0100 Subject: [PATCH 2/2] small memos stuff --- ansible/services/memos/memos_vars.yml | 11 +++++------ ansible/services/memos/setup_backup_memos_to_lapy.yml | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ansible/services/memos/memos_vars.yml b/ansible/services/memos/memos_vars.yml index dcd0aac..99618db 100644 --- a/ansible/services/memos/memos_vars.yml +++ b/ansible/services/memos/memos_vars.yml @@ -14,12 +14,11 @@ memos_tailscale_ip: "100.64.0.4" # (caddy_sites_dir and subdomain in services_config.yml) -# Remote access (for backup from lapy) -backup_host_name: "memos_box_local" -backup_host: "{{ hostvars.get(backup_host_name, {}).get('ansible_host', backup_host_name) }}" -backup_user: "{{ hostvars.get(backup_host_name, {}).get('ansible_user', 'counterweight') }}" -backup_key_file: "{{ hostvars.get(backup_host_name, {}).get('ansible_ssh_private_key_file', '') }}" -backup_port: "{{ hostvars.get(backup_host_name, {}).get('ansible_port', 22) }}" +# Remote access (for backup from lapy via Tailscale) +backup_host: "{{ memos_tailscale_hostname }}" +backup_user: "counterweight" +backup_key_file: "~/.ssh/counterganzua" +backup_port: 22 # Local backup local_backup_dir: "{{ lookup('env', 'HOME') }}/memos-backups" diff --git a/ansible/services/memos/setup_backup_memos_to_lapy.yml b/ansible/services/memos/setup_backup_memos_to_lapy.yml index 3e3718e..6d9c161 100644 --- a/ansible/services/memos/setup_backup_memos_to_lapy.yml +++ b/ansible/services/memos/setup_backup_memos_to_lapy.yml @@ -46,7 +46,7 @@ SSH_CMD="ssh -p {{ backup_port }}" {% endif %} - rsync -az -e "$SSH_CMD" --delete {{ backup_user }}@{{ backup_host }}:{{ backup_data_path }}/ "$BACKUP_DIR/" + rsync -az -e "$SSH_CMD" --rsync-path="sudo rsync" --delete {{ backup_user }}@{{ backup_host }}:{{ backup_data_path }}/ "$BACKUP_DIR/" # Rotate old backups (keep 14 days) # Calculate cutoff date (14 days ago) and delete backups older than that