diff --git a/Linode/tracker.yml b/Linode/tracker.yml new file mode 100644 index 0000000..6b9e3b0 --- /dev/null +++ b/Linode/tracker.yml @@ -0,0 +1,132 @@ +--- +# Linode Tracker Deployment Playbook + +- name: Deploy Linode email tracking server + hosts: localhost + gather_facts: false + connection: local + vars_files: + - vars.yaml + vars: + # Default values + linode_region: "{{ linode_region | default(region_choices | random) }}" + plan: "{{ plan | default('g6-nanode-1') }}" # Use smallest plan for tracker + tracker_image: "linode/debian12" + + # Generate random instance name if not provided + tracker_name: "{{ tracker_name | default('t-' + 9999999999 | random | to_uuid | hash('md5') | truncate(8, True, '')) }}" + + tasks: + - name: Validate required Linode token + assert: + that: + - linode_token is defined and linode_token != "" + fail_msg: "Linode API token is required. Set linode_token in vars.yaml." + + - name: Create tracker Linode instance + community.general.linode_v4: + access_token: "{{ linode_token }}" + label: "{{ tracker_name }}" + type: "{{ plan }}" + region: "{{ linode_region }}" + image: "{{ tracker_image }}" + root_pass: "{{ lookup('password', '/dev/null length=16') }}" + authorized_keys: + - "{{ lookup('file', ssh_key_path) }}" + state: present + register: tracker_instance + + - name: Set tracker_ip for later use + set_fact: + tracker_ip: "{{ tracker_instance.instance.ipv4[0] }}" + tracker_instance_id: "{{ tracker_instance.instance.id }}" + + - name: Wait for tracker SSH to be available + wait_for: + host: "{{ tracker_ip }}" + port: 22 + delay: 60 + timeout: 300 + state: started + + - name: Add tracker to inventory + add_host: + name: "tracker" + groups: "trackers" + ansible_host: "{{ tracker_ip }}" + ansible_user: "root" + ansible_ssh_private_key_file: "{{ ssh_key_path | replace('.pub', '') }}" + ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" + +- name: Configure tracker server + hosts: trackers + become: true + gather_facts: true + vars_files: + - vars.yaml + vars: + tracker_domain: "{{ tracker_domain | default('track.' + domain) }}" + tasks: + - name: Update and install required packages + apt: + name: + - nginx + - certbot + - python3-certbot-nginx + - git + - curl + - python3-pip + update_cache: yes + state: present + + - name: Clone email tracker repository + git: + repo: https://github.com/Datalux/Osint-Tracker.git + dest: /opt/tracker + version: master + ignore_errors: yes + + - name: Install tracker dependencies + pip: + requirements: /opt/tracker/requirements.txt + ignore_errors: yes + + - name: Configure tracker settings + template: + src: "../templates/tracker-config.j2" + dest: /opt/tracker/config.py + mode: '0644' + ignore_errors: yes + + - name: Set up SSL if requested + block: + - name: Install Let's Encrypt certificate + shell: | + certbot --nginx -d {{ tracker_domain }} --non-interactive --agree-tos -m {{ tracker_email }} + args: + creates: /etc/letsencrypt/live/{{ tracker_domain }}/fullchain.pem + when: tracker_setup_ssl | default(true) | bool + ignore_errors: yes + + - name: Create systemd service for tracker + template: + src: "../templates/tracker.service.j2" + dest: /etc/systemd/system/tracker.service + mode: '0644' + ignore_errors: yes + + - name: Start and enable tracker service + systemd: + name: tracker + state: started + enabled: yes + daemon_reload: yes + ignore_errors: yes + + - name: Print deployment summary + debug: + msg: + - "Email Tracker Deployment Complete!" + - "------------------------------" + - "Tracker IP: {{ ansible_host }}" + - "Tracker Domain: {{ tracker_domain }} (Update DNS A record)" \ No newline at end of file diff --git a/deploy.py b/deploy.py index f11090c..fe08cf3 100644 --- a/deploy.py +++ b/deploy.py @@ -287,8 +287,12 @@ def interactive_setup(): # Domain configuration default_domain = vars_data.get('domain', 'example.com') config['domain'] = input(f"\nDomain name [default: {default_domain}]: ") or default_domain - - default_email = vars_data.get('letsencrypt_email', f"admin@{config['domain']}") + + # Always use the most up-to-date domain for the email default + default_email = vars_data.get('letsencrypt_email') + if not default_email or "example.com" in default_email: + default_email = f"admin@{config['domain']}" + config['letsencrypt_email'] = input(f"Email for Let's Encrypt [default: {default_email}]: ") or default_email # Security options diff --git a/templates/tracker-config.j2 b/templates/tracker-config.j2 new file mode 100644 index 0000000..bfa756c --- /dev/null +++ b/templates/tracker-config.j2 @@ -0,0 +1,33 @@ +# templates/tracker-config.j2 +""" +Email Tracker Configuration +""" + +# Basic Configuration +SECRET_KEY = '{{ lookup("password", "/dev/null chars=ascii_letters,digits length=32") }}' +DEBUG = False + +# Database settings +DB_NAME = 'tracker.db' + +# Domain configuration +DOMAIN = '{{ tracker_domain }}' +USE_HTTPS = {{ tracker_setup_ssl | default(true) | lower }} + +# Tracking pixel path +TRACKING_PATH = 'pixel.png' + +# API Keys +{% if tracker_ipinfo_token is defined and tracker_ipinfo_token != "" %} +IPINFO_TOKEN = '{{ tracker_ipinfo_token }}' +{% else %} +IPINFO_TOKEN = None +{% endif %} + +# Notification settings +ENABLE_NOTIFICATIONS = False +NOTIFICATION_EMAIL = '{{ tracker_email | default("admin@" + domain) }}' + +# Logger configuration +LOG_LEVEL = 'INFO' +LOG_FILE = '/var/log/tracker.log' \ No newline at end of file diff --git a/templates/tracker.service.j2 b/templates/tracker.service.j2 new file mode 100644 index 0000000..8053667 --- /dev/null +++ b/templates/tracker.service.j2 @@ -0,0 +1,20 @@ +# templates/tracker.service.j2 +[Unit] +Description=Email Tracking Server +After=network.target + +[Service] +User=root +Group=root +WorkingDirectory=/opt/tracker +ExecStart=/usr/bin/python3 /opt/tracker/app.py +Restart=always +RestartSec=10 + +# Security measures +PrivateTmp=true +ProtectSystem=full +NoNewPrivileges=true + +[Install] +WantedBy=multi-user.target \ No newline at end of file