DevOps

Fix GlobalProtect Certificate Error di macOS, Akhirnya Kelar

Asep Alazhari

GlobalProtect tiba-tiba error Failed to verify certificate di beberapa Mac doang, padahal Windows aman? Ini akar masalah aslinya plus fix permanennya.

Fix GlobalProtect Certificate Error di macOS, Akhirnya Kelar

Hari VPN Gue Berhenti Percaya Sama Dirinya Sendiri

GlobalProtect VPN gue konek mulus banget dari home office. Beberapa jam kemudian gue duduk di meja lain, buka GlobalProtect, klik Connect, eh malah kena ini:

Connection Failed
Failed to verify certificate
Portal: vpn.yourcompany.com

Dialog GlobalProtect Connection Failed yang menunjukkan error Failed to verify certificate

Error GlobalProtect yang bikin gue mulai investigasi ini. Field portal-nya gue blur, tapi pesan errornya sama persis kayak yang lo liat sekarang.

Laptop sama. VPN client sama. Portal kantor sama. 10 menit sebelumnya lancar jaya. Sekarang error mulu. Gue klik Connect lagi, error. Restart GlobalProtect, error juga. Restart Mac, tetep error.

Terus gue ganti Wi-Fi ke hotspot HP, klik Connect, langsung konek di percobaan pertama.

Detail kecil itu yang bikin gue sadar ini bukan soal certificate beneran. Kalau certificate-nya emang rusak, harusnya gagal di mana aja, kapan aja. Tapi ini cuma gagal di network tertentu doang, dan lancar di network lain. Makin aneh lagi, temen kantor yang pake Windows, duduk di meja yang sama, di Wi-Fi yang sama, konek tanpa masalah sama sekali.

Kalau lo pernah ketemu error “Failed to verify certificate” dari GlobalProtect di macOS, dan ini cuma kejadian di network tertentu, Mac tertentu, atau hari tertentu, artikel ini buat lo. Gue udah investigasi penuh soal ini, dan ternyata fix-nya hampir gak ada hubungannya sama certificate. Biangnya adalah DNS. Ini penjelasan lengkap apa yang terjadi dan gimana gue benerin permanen.

Error yang Gak Masuk Akal

Sebelum ngubek log, gue petain dulu pola yang muncul selama beberapa minggu.

KondisiHasil
Wi-Fi kantor tertentuSelalu gagal “Failed to verify certificate”
Ganti ke hotspot HPKonek di percobaan pertama
Flush DNS cache dan restart mDNSResponderKadang bantu, kadang gak ngaruh
Append CA certificate ke cert store GlobalProtectGak konsisten, error balik lagi setelah restart
Wi-Fi sama, laptop WindowsSelalu konek lancar

Gue udah punya beberapa shell alias dari percobaan fix sebelumnya, kayak flush DNS dan nge-patch certificate file GlobalProtect. Gak ada satupun yang reliable. Kadang bantu, kadang gak, dan errornya selalu balik lagi cepat atau lambat. Ketidakkonsistenan itu sebenernya clue penting. Fix yang beneran permanen harusnya kerja sama setiap kali. Punya gue gak gitu, artinya gue lagi nanganin symptom, bukan penyakit aslinya.

”Certificate Error” Itu Sering Cuma Bohong

Cek DNS Duluan

Hal pertama yang gue cek, apakah Mac gue resolve hostname portal VPN ke alamat yang benar.

dig vpn.yourcompany.com +short

Di network yang lancar, ini balikin IP publik portal yang asli, semacam 203.0.113.10. Di network yang gagal, hasilnya beda total. Buat mastiin jawaban yang seharusnya benar, gue query langsung ke public resolver, bukan DNS yang dikasih router.

dig @1.1.1.1 vpn.yourcompany.com +short

Hasilnya selalu 203.0.113.10, di network manapun. System resolver sama public resolver beda jawaban, dan ini cuma kejadian di network yang GlobalProtect-nya gagal.

Cek TLS Chain

Selanjutnya gue cek apakah certificate chain-nya beneran valid dengan ngomong langsung ke server pake OpenSSL.

openssl s_client -connect 203.0.113.10:443 -servername vpn.yourcompany.com -legacy_renegotiation

Output-nya diakhiri Verify return code: 0 (ok), dan certificate chain-nya nunjukin issuer yang bener, punya gue DigiCert Global G2 TLS RSA SHA256 2020 CA1 yang root-nya DigiCert Global Root G2. Server asli, di IP asli, ngasih certificate yang valid sempurna.

Baca Juga: Kenapa Sertifikat SSL Lo Sekarang Cuma 6 Bulan?

Jadi certificate di IP yang benar itu fine. DNS answer di network yang gagal itu yang salah. Dua fakta yang kelihatannya gak nyambung, tapi kalau digabung, ngarah langsung ke masalah aslinya.

Akar Masalah Asli: DNS Dimanipulasi Router Wi-Fi

Ini rantai kejadian yang bikin muncul “Failed to verify certificate” padahal masalah aslinya DNS.

  1. Lo konek ke Wi-Fi yang router-nya ngasih DNS server sendiri lewat DHCP.
  2. DNS server itu resolve vpn.yourcompany.com ke IP yang bukan VPN gateway kantor lo yang asli.
  3. GlobalProtect konek ke IP yang salah itu dan minta certificate-nya.
  4. Server yang salah ngasih certificate yang gak match sama trusted chain yang diharapkan GlobalProtect.
  5. GlobalProtect gak bisa verify certificate itu, jadi dia lapor satu-satunya error yang ada: “Failed to verify certificate.”

Errornya soal certificate karena di situ lah koneksinya akhirnya putus. Akar masalahnya dua langkah sebelumnya, di DNS.

Gue konfirmasi ini dengan cek setting DNS di semua network interface Mac gue sekaligus.

networksetup -listallnetworkservices | while read svc; do
  echo "$svc: $(networksetup -getdnsservers "$svc")"
done

Semua interface, Wi-Fi, USB Ethernet adapter, sampai iPhone yang lagi mode tethering USB, balikin “There aren’t any DNS Servers set.” Semua interface ngandelin sepenuhnya DNS dari network yang konek. Di network yang router-nya resolve hal normal, semua jalan lancar. Di network yang router-nya rewrite atau hijack hostname tertentu, GlobalProtect konek ke tempat yang salah dan gagal dengan certificate error.

Ini juga ngejelasin kenapa ganti ke hotspot HP langsung benerin masalahnya. DNS hotspot resolve portal-nya dengan benar, jadi GlobalProtect konek ke IP yang benar dan dapet certificate yang benar.

Soal kenapa temen-temen Windows gue gak pernah ngalamin ini di Wi-Fi yang sama, gue gak bisa kasih jawaban pasti dari sisi Windows-nya. Tapi ini perbedaan praktis yang gue liat. Mac gue sering punya 4 sampai 5 network service aktif barengan, Wi-Fi, dua USB Ethernet adapter, Thunderbolt bridge, dan iPhone mode tethering, masing-masing ngambil konfigurasi DNS sendiri dari DHCP. Laptop Windows di sebelah gue cuma konek satu Wi-Fi doang, gak ada yang lain. Makin banyak network interface yang aktif dan rebutan resolve DNS, makin gede kemungkinan salah satunya ngasih jawaban salah buat satu hostname tertentu. Kalau setup lo, Mac atau bukan, cuma pernah pake satu interface aja dalam satu waktu, kemungkinan lo emang gak akan ketemu failure mode ini.

Masalah Kedua: GlobalProtect Selalu Reset Certificate File-nya Sendiri

Sambil ngubek-ngubek file GlobalProtect, gue nemu masalah kedua yang numpuk di atas masalah DNS. GlobalProtect nyimpen certificate store kecil:

/Library/Application Support/PaloAltoNetworks/GlobalProtect/tca.cer

Gue punya beberapa backup file ini dari percobaan fix sebelumnya, dan semuanya persis 1208 bytes.

-rw-------  1 root  admin  1208 Jun  6 08:34  tca.cer
-rw-------  1 root  admin  1208 May 25 08:15  tca.cer.bak
-rw-------  1 root  admin  1208 May 25 12:30  tca.cer.bak2
-rw-------  1 root  admin  1208 May 25 12:34  tca.cer.bak3

Ukuran yang sama persis itu yang jadi tanda. Setiap kali background service GlobalProtect restart, atau Mac reboot, file ini ditulis ulang ke default factory-nya. Percobaan fix gue sebelumnya nyoba nambahin certificate chain tambahan ke file ini pake >>. Pendekatan itu ada dua masalah. Pertama, nambahin certificate format PEM ke file format DER bikin file yang gak murni format apapun, ada tool yang bisa baca, ada yang gak. Kedua, dan ini lebih penting, GlobalProtect nimpa lagi file itu setiap kali service-nya restart, jadi fix-nya kebatalin diam-diam. Pantes aja errornya balik lagi random.

Fix Permanennya

Ini bagian yang paling penting. Lima perubahan, diurutin dari “langsung kelar di network manapun” sampai “gak usah dipikirin lagi selamanya”.

Fix 1: Pin VPN Portal di /etc/hosts

Satu baris ini yang beneran nyelesain masalah aslinya. File /etc/hosts dicek sebelum DNS resolver manapun, termasuk DNS apapun yang dikasih router lo.

sudo bash -c 'echo -e "\n# Pin GlobalProtect VPN portal to prevent DNS hijacking\n203.0.113.10    vpn.yourcompany.com" >> /etc/hosts'

Ganti 203.0.113.10 dengan IP VPN gateway kantor lo yang asli, yang sama dengan yang lo konfirmasi pake dig @1.1.1.1 sebelumnya, dan ganti vpn.yourcompany.com dengan hostname portal asli lo. Mulai dari sini, network Wi-Fi apapun gak akan bisa ngerusak resolusi hostname ini, mau DNS-nya dikasih apa aja.

Satu catatan penting. Kalau VPN gateway kantor lo ada di belakang load balancer atau traffic manager yang IP-nya bisa berubah, lo mungkin perlu update entry ini sesekali. Tapi kejadiannya jarang banget, dan /etc/hosts tetep fix paling kuat karena kerjanya sama persis di network manapun yang lo konek.

Fix 2: Benerin Alias DNS buat Semua Network Interface

Alias vpndns lama gue cuma set DNS server di interface Wi-Fi doang. Itu gak ada gunanya begitu gue konek lewat USB Ethernet adapter atau tethering iPhone. Fix-nya loop ke semua interface yang relevan.

alias vpndns='for _svc in "Wi-Fi" "USB 10/100 LAN" "USB 10/100/1000 LAN" "iPhone USB"; do
  networksetup -setdnsservers "$_svc" 1.1.1.1 8.8.8.8 2>/dev/null
done && sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder'

alias vpndnsreset='for _svc in "Wi-Fi" "USB 10/100 LAN" "USB 10/100/1000 LAN" "iPhone USB"; do
  networksetup -setdnsservers "$_svc" "Empty" 2>/dev/null
done && sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder'

Jalanin networksetup -listallnetworkservices sekali buat dapetin nama interface yang pas di Mac lo, terus update daftarnya di kedua alias. vpndns maksa semua interface pake resolver yang udah jelas bagus, dan vpndnsreset ngembaliin semuanya ke DHCP otomatis kalau lo udah gak butuh override-nya.

Fix 3: Satu Command buat Diagnosa Semuanya

Gue bikin satu alias diagnostic yang cek semua bagian chain sekaligus, jadi gue gak perlu nebak-nebak lagi.

alias vpncheck='
  echo "=== Portal DNS (harusnya match 203.0.113.10) ===" && dig vpn.yourcompany.com +short
  echo "=== DNS via 1.1.1.1 (ground truth) ===" && dig @1.1.1.1 vpn.yourcompany.com +short
  echo "=== TLS cert check ===" && echo | openssl s_client -connect vpn.yourcompany.com:443 \
    -servername vpn.yourcompany.com -legacy_renegotiation 2>&1 \
    | grep -E "subject|issuer|Verify return code|error" | head -6
  echo "=== OCSP reachable ===" && curl -s --max-time 3 -o /dev/null -w "ocsp.digicert.com: HTTP %{http_code}\n" http://ocsp.digicert.com
  echo "=== Active network interface ===" && route get 1.1.1.1 2>/dev/null | grep interface
'

Ini cara baca output-nya.

OutputArtinyaYang Harus Dilakukan
Portal DNS match sama hasil 1.1.1.1DNS resolve dengan benarKonek normal aja
Portal DNS beda sama hasil 1.1.1.1Network sekarang rewrite DNSJalanin vpndns, atau andelin pin /etc/hosts
TLS nunjukin Verify return code: 0 (ok)Certificate chain validGak perlu ngapa-ngapain
TLS error atau no peer certificateCert store GlobalProtect gak lengkapJalanin gpfix
OCSP balikin HTTP 200Cek revocation bisa nyampe internetGak perlu ngapa-ngapain
OCSP timeoutNetwork ini block OCSPGanti network kalau bisa

Fix 4: Tulis Ulang gpfix, Replace Bukan Append

Alias gpfix lama gue nambahin certificate chain format PEM ke file tca.cer yang udah ada pake >>. Itu bikin file format campuran, dan seperti yang udah dibahas, GlobalProtect nimpa file itu lagi setiap kali service-nya restart. Versi baru download intermediate certificate yang fresh, replace tca.cer sepenuhnya, baru append chain-nya, terus restart background service GlobalProtect biar perubahannya langsung kepake.

alias gpfix='
  echo "Downloading CA intermediate certificate..."
  if curl -s --max-time 10 "https://your-ca-cert-url/intermediate.crt" -o /tmp/_int.crt 2>/dev/null && [ -s /tmp/_int.crt ]; then
    sudo cp "/Library/Application Support/PaloAltoNetworks/GlobalProtect/tca.cer" \
      "/Library/Application Support/PaloAltoNetworks/GlobalProtect/tca.cer.bak-$(date +%Y%m%d)" 2>/dev/null
    sudo bash -c "cp /tmp/_int.crt \"/Library/Application Support/PaloAltoNetworks/GlobalProtect/tca.cer\" \
      && cat ~/Documents/ca-chain.pem >> \"/Library/Application Support/PaloAltoNetworks/GlobalProtect/tca.cer\""
    echo "tca.cer updated"
  else
    echo "Download failed, falling back to local chain only"
    sudo bash -c "cat ~/Documents/ca-chain.pem > \"/Library/Application Support/PaloAltoNetworks/GlobalProtect/tca.cer\""
  fi
  launchctl bootout gui/$(id -u) /Library/LaunchAgents/com.paloaltonetworks.gp.pangpa.plist 2>/dev/null
  launchctl bootout gui/$(id -u) /Library/LaunchAgents/com.paloaltonetworks.gp.pangps.plist 2>/dev/null
  sleep 2
  launchctl bootstrap gui/$(id -u) /Library/LaunchAgents/com.paloaltonetworks.gp.pangps.plist
  launchctl bootstrap gui/$(id -u) /Library/LaunchAgents/com.paloaltonetworks.gp.pangpa.plist
  echo "Done. Try connecting GlobalProtect now."
'

Ganti URL certificate dan path chain file-nya sesuai CA lo sendiri. Kalau certificate chain portal lo nyambung ke DigiCert, sama kayak punya gue, DigiCert publish intermediate certificate-nya secara publik, jadi lo bisa download yang cocok langsung.

Baca Juga: Kenapa Gue Tinggalin Termius Demi WebSSH: SSH Client Terbaik untuk Apple

Fix 5 (Opsional): LaunchDaemon yang Benerin Dirinya Sendiri

Fix 4 kerja, sampai Mac lo restart dan GlobalProtect nulis ulang tca.cer balik ke default 1208 byte-nya. Jawaban jangka panjang yang paling rapi adalah LaunchDaemon yang ngawasin file itu dan otomatis nge-apply fix lagi, setiap kali filenya berubah.

Pertama, watcher script-nya, simpen di /usr/local/bin/gp-certfix.sh:

#!/bin/sh
TCACER="/Library/Application Support/PaloAltoNetworks/GlobalProtect/tca.cer"
CHAINPEM="/path/to/ca-chain.pem"
INTCRT="/tmp/gp-int.crt"

if ! grep -q "BEGIN CERTIFICATE" "$TCACER" 2>/dev/null; then
    if [ ! -s "$INTCRT" ]; then
        curl -s --max-time 10 "https://your-ca-cert-url/intermediate.crt" -o "$INTCRT" 2>/dev/null
    fi
    if [ -s "$INTCRT" ]; then
        cp "$INTCRT" "$TCACER"
    fi
    if [ -f "$CHAINPEM" ]; then
        cat "$CHAINPEM" >> "$TCACER"
    fi
fi

Terus definisi LaunchDaemon-nya, simpen di /Library/LaunchDaemons/com.user.gp-certfix.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.user.gp-certfix</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/gp-certfix.sh</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Library/Application Support/PaloAltoNetworks/GlobalProtect/tca.cer</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Install dua-duanya dengan tiga command:

sudo cp gp-certfix.sh /usr/local/bin/gp-certfix.sh
sudo chmod 755 /usr/local/bin/gp-certfix.sh
sudo cp com.user.gp-certfix.plist /Library/LaunchDaemons/com.user.gp-certfix.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/com.user.gp-certfix.plist

Mulai sekarang, setiap kali GlobalProtect reset tca.cer, macOS nyadar perubahannya lewat WatchPaths dan jalanin script-nya dalam hitungan detik, naro lagi certificate chain yang bener sebelum lo sempet klik Connect.

Hasilnya: Konek di Network Manapun

Setelah nambahin pin /etc/hosts doang, semua network yang sebelumnya gagal dengan “Failed to verify certificate” mulai konek normal. Alias DNS dan gpfix yang ditulis ulang nutup sisa edge case, yang berhubungan sama tethering USB dan cert store yang basi. LaunchDaemon bikin gue gak pernah perlu jalanin fix-fix ini manual lagi, termasuk setelah full restart.

Masalah ini gak pernah kejadian di semua Mac, dan gak pernah kejadian di laptop Windows di network yang sama sama sekali. Ini cuma muncul di Mac yang sering gonta-ganti antar network interface dan konek ke Wi-Fi yang router-nya diem-diem rewrite DNS buat hostname tertentu. Kalau itu mirip setup lo, fix-fix di atas harusnya bikin lo kelar juga.

Tabel Referensi Cepat

SymptomKemungkinan SebabFix
Gagal di Wi-Fi tertentu, lancar di hotspot HPDNS dihijack router ituFix 1, pin /etc/hosts
Gagal saat konek lewat USB Ethernet atau tethering HPDNS di interface itu gak pernah di-overrideFix 2, vpndns semua interface
vpncheck nunjukin TLS error atau no peer certificatetca.cer kehilangan CA chainFix 4, gpfix yang udah ditulis ulang
Fix 4 kerja, terus rusak lagi setelah rebootGlobalProtect reset tca.cer saat startupFix 5, LaunchDaemon self healing
Windows lancar, cuma Mac yang gagalMac punya lebih banyak network interface yang rebutan DNSFix 1 plus Fix 2

Penutup

Pelajaran paling berguna dari investigasi ini, “Failed to verify certificate” sering cuma domino terakhir dari rantai kejadian yang mulainya dari tempat yang sama sekali berbeda. GlobalProtect lapor di langkah dia nyerah, bukan di langkah masalahnya beneran mulai. Sebelum lo mulai ganti-ganti certificate file atau install ulang VPN client, coba jalanin dig biasa ke hostname portal lo, lewat resolver normal dan lewat public resolver kayak 1.1.1.1, terus bandingin hasilnya. Kalau beda, lo udah nemu masalah aslinya, dan satu baris di /etc/hosts mungkin udah cukup buat benerin semuanya.

Back to Blog

Related Posts

View All Posts »
Commit Langsung ke master Bakal Nyiksa Lo di Hari Deploy
DevOps

Commit Langsung ke master Bakal Nyiksa Lo di Hari Deploy

Satu refactor Swagger yang di-commit langsung ke master bikin 3-way merge conflict, GitLab API diam-diam gagal, dan 30 menit operasi branch manual sebelum bisa deploy. Ini cerita lengkapnya dan satu aturan yang bisa mencegahnya.