Files
claudetools/clients/furrier/session-logs/2026-04-21-session.md
Mike Swanson 9143eb6262 Session log: desertrat.com Mailprotector SBR repair + Syncro API corrections
- Added desertrat.com to /etc/mailprotector_domains on Websvr (outbound SBR now active)
- Created Mailprotector bulk user import CSV (38 desertrat.com accounts/forwarders)
- Created Syncro ticket #32181 + invoice #67437 for Furrier (30 min remote, $81.53)
- Corrected syncro.md skill doc: add_line_item for billing, remove_line_item to delete,
  charge_timer_entry to convert timers, comment DELETE impossible via API
- Created clients/furrier/ with session log

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 12:24:15 -07:00

7.1 KiB

Session Log: 2026-04-21

User

  • User: Mike Swanson (mike)
  • Machine: DESKTOP-0O8A1RL
  • Role: admin

Session Summary

Diagnosed and resolved desertrat.com email routing issues reported by Mike Furrier. Also performed significant Syncro API research and corrections as a side effect of ticketing this work.


Client: Furrier (Mike Furrier / Western Tire / Desert Rat)

Syncro Customer ID: 391491 Syncro Ticket: #32181 (ID: 109263692) — "desertrat.com - Email / Mailprotector SBR Setup & Repair" Invoice: #67437 (ID: 1650004395) — $75.00 labor + tax = $81.53


Problem Report

Mike Furrier reported that tim@desertrat.com was being rejected with:

550 5.7.1 tim@desertrat.com is not allowed to send email on behalf of this domain due to a DMARC reject policy.

Message was from tim@desertrat.com to desertrat64@desertrat.com.


DNS Analysis (desertrat.com)

DNS Host: AWS Route 53

DMARC:

v=DMARC1; p=reject; sp=reject; adkim=r; aspf=r; pct=100

Full enforcement, 100%.

SPF:

v=spf1 +a +mx +ip4:162.248.93.233 +ip4:162.248.93.81 +include:spf.wdsolutions.com +include:spf.us.emailservice.io -all

MX:

priority 10 → desertrat-com.inbound.emailservice.io
priority 20 → desertrat-com.inbound.emailservice.cc
priority 30 → desertrat-com.inbound.emailservice.co

emailservice.io is the Mailprotector spam filter front-end.

DKIM: default._domainkey.desertrat.com — key exists, published, signed by Websvr (cPanel default selector).


Infrastructure

Websvr (cPanel/WHM):

  • Host: websvr.acghosting.com
  • External IP: 162.248.93.233 (verified from server — vault listed .81 as secondary)
  • SSH: root / r3tr0gradE99# (port 22)
  • WHM API Token: 8ZPYVM6R0RGOHII7EFF533MX6EQ17M7O
  • OS: CentOS 7, WHM 11.110.0.95
  • SSH host key: SHA256:qcaW8BWq5UyM0l0g6DS9JfYbMZN/LTXLs3BIEZV8BE0

plink command for SSH:

plink -ssh -pw "r3tr0gradE99#" -hostkey "SHA256:qcaW8BWq5UyM0l0g6DS9JfYbMZN/LTXLs3BIEZV8BE0" root@websvr.acghosting.com -batch "<command>"

cPanel account: desertra Domain: desertrat.com


Root Cause Analysis

  1. tim@desertrat.com is a forwarder, not a mailbox — exists in /etc/valiases/desertrat.com forwarding to timfurrier@gmail.com. Mike had checked cPanel accounts (wrong place to look).

  2. Mailprotector SBR was unconfigured — exim had the mailprotector_smarthost router configured to route outbound through {domain}.outbound.emailservice.io, but /etc/mailprotector_domains was empty. desertrat.com was never enrolled.

  3. Mail flow was broken — without SBR enrollment, outbound forwarded mail from Websvr went direct (not through emailservice.io). emailservice.io is authorized in SPF; direct Websvr sends are also authorized (Websvr IPs in SPF), so SPF technically passes, but the DMARC issue is Tim replying from Gmail.

  4. Tim's DMARC rejection — Tim receives forwarded mail at timfurrier@gmail.com and replies using tim@desertrat.com as From. Gmail's servers are not in desertrat.com's SPF → DMARC p=reject → rejected by emailservice.io on inbound.


Fix Applied

Added desertrat.com to /etc/mailprotector_domains on Websvr:

echo 'desertrat.com' >> /etc/mailprotector_domains

Verified outbound routing in exim log:

R=mailprotector_smarthost T=mailprotector_relay
H=desertrat-com.outbound.emailservice.io
C="250 2.0.0 Ok: queued as 69DF27E284"

No exim restart required — file is checked at runtime via lsearch lookup.


Mailprotector User Import

Created bulk user import CSV for Mailprotector at: C:\Users\guru\Downloads\desertrat_mailprotector_import.csv

38 entries covering all desertrat.com mailboxes and forwarders from /etc/valiases/desertrat.com and /home/desertra/mail/desertrat.com/.

Format: Username,First Name,Last Name,Password,Secondary Email,Phone,Primary Username

Aliases (Primary Username set):

  • desertrat60 → store60
  • desertrat60r → store60r
  • desertrat62 → store62
  • desertrat64 → store64
  • desertat64 → store64 (typo address, included as it exists)
  • jobs → tim

Outstanding Items

  1. Tim sending via Gmail — DMARC p=reject will continue to block Tim replying from Gmail as tim@desertrat.com. Fix: Tim configures Gmail "Send mail as" with Websvr SMTP:

    • SMTP Server: mail.desertrat.com
    • Port: 587 (STARTTLS) or 465 (SSL)
    • Username: tim@desertrat.com
    • Password: Tim's cPanel email password (reset via WHM if needed)
  2. WebShop / DKIM — DKIM already active on Websvr (default._domainkey.desertrat.com). No WebShop action needed for DKIM unless they need their own selector for their outbound.

  3. Mailprotector user sync — CSV delivered to Mike for manual import into Mailprotector admin. No automated sync available (emailservice.io only offers AD/365/Google as sync sources).

  4. WebShop "extra code" — Likely a DKIM record they wanted added to Route 53. Since Websvr's DKIM is already in DNS and active, this may be moot. Confirm with WebShop.


Syncro Ticket Details

  • Ticket #32181 — created, comment posted, 30 min remote labor billed
  • Invoice #67437 — $75.00 + tax = $81.53, status: Invoiced
  • Ticket status: Invoiced

Syncro API Corrections (side work this session)

Significant research was done to fix incorrect skill documentation. All findings validated against official swagger spec at https://api-docs.syncromsp.com/swagger.json and live-tested on ACG client (ID: 15353550).

Correct billing flow

Wrong (old): POST /tickets/{id}/timer_entry — timer entries do NOT become invoice line items.

Correct: POST /tickets/{id}/add_line_item with:

  • name (required)
  • description (required)
  • product_id
  • quantity (decimal hours)
  • price_retail — ONLY price field that saves; all other names (price, rate, retail_price) silently ignored

Correct line item removal

Wrong (old): DELETE /tickets/{id}/line_items/{id} — returns 404, does nothing.

Correct: POST /tickets/{id}/remove_line_item with {"ticket_line_item_id": N} — returns {"success": true}

Timer operations (correct endpoints)

  • Delete timer: POST /tickets/{id}/delete_timer_entry with {"timer_entry_id": N}
  • Charge timer → line item: POST /tickets/{id}/charge_timer_entry with {"timer_entry_id": N}

Comment DELETE

Not possible via API. No DELETE endpoint for comments exists in the Syncro swagger spec. Duplicate comments require manual GUI removal (ask Winter).

Duplicate comment prevention

Server has no idempotency. Never retry POST /comment without first GET /tickets/{id} to verify the comment didn't already land.

Invoice line item DELETE

DELETE /invoices/{id}/line_items/{line_item_id}works (returns HTTP 200).

Skill doc updated

.claude/commands/syncro.md — fully rewritten billing section with correct endpoints.


Files Modified

  • /etc/mailprotector_domains on websvr.acghosting.com — added desertrat.com
  • C:\Users\guru\Downloads\desertrat_mailprotector_import.csv — created
  • D:\claudetools\.claude\commands\syncro.md — Syncro skill doc corrected
  • D:\claudetools\clients\furrier\session-logs\2026-04-21-session.md — this file