ConnMan ทำงานได้ช่วงบ่ายแล้วก็ปฏิเสธ และบรรทัดในบันทึกกล่าวถึงการตรวจสอบใบรับรอง บรรทัดนั้นทำให้คนไปยุ่งกับชุด CA ที่ไม่เคยเสียหาย ความผิดพลาดสองแบบให้รูปร่างของความล้มเหลวเกือบเหมือนกัน คือคุกกี้เซสชันหมดอายุ หรือใบรับรองของเซิร์ฟเวอร์เปลี่ยนจริง แยกได้ภายในประมาณหนึ่งนาที และมีเพียงแบบเดียวที่เกี่ยวกับลายนิ้วมือ

สองความผิดพลาด หนึ่งบรรทัดบันทึกที่สับสน

แยกได้ด้วยการสังเกตสองอย่าง และไม่ต้องอ่านซ้ำ อย่างแรกคือเวลาเริ่มล้มเหลว คุกกี้ที่หมดอายุมาหลังทำงานหลายชั่วโมงหรือหลายวัน และ ใบรับรองที่ถูกเปลี่ยนจะมาทันทีหลังการเปลี่ยนเกตเวย์

SignalExpired cookieChanged certificate
When it startedafter hours or days of workingright after a gateway change
Fingerprint from a fresh authenticateunchangeddifferent value
Usual log tailHTTP CONNECT 401 / unauthorizedsigner not found / verify failed
Repairreplace the cookie, restartre-pin deliberately, then restart

การทดสอบหนึ่งนาทีคือการรัน authenticate ด้านล่าง เปรียบเทียบ FINGERPRINT กับ OpenConnect.ServerCert ในไฟล์ ลายนิ้วมือเหมือนกันแต่ COOKIE ต่างกันหมายถึงเปลี่ยนเฉพาะคุกกี้ ลายนิ้วมือต่างกันหมายถึงใบรับรองเซิร์ฟเวอร์เปลี่ยนจริง จึงปักหมุดใหม่โดยตั้งใจและบันทึกว่าใครอนุมัติ

สร้างวัสดุแทนการพิมพ์เอง

ConnMan ไม่มีขั้นตอนนำเข้าโปรไฟล์ OpenConnect ต่างจาก NetworkManager มันอ่านไฟล์จัดเตรียมที่ค่าต้องถูกสร้างล่วงหน้า และวิธีที่รองรับในการสร้างคือโหมด authenticate ของ OpenConnect

sudo openconnect --csd-wrapper=/home/user/.cisco/csd-wrapper.sh \
  --authenticate --user myuser vpn.example.com

เอาต์พุตพิมพ์สี่ค่า คือ POST, COOKIE, HOST และ FINGERPRINT ลายนิ้วมือที่นำหน้าด้วย sha256: คือการปักหมุดเซิร์ฟเวอร์ คุกกี้คือสิ่งที่เกิดจากเซสชันซึ่งมีอายุการใช้งานที่เกตเวย์กำหนด มองทั้งสองเป็นความลับคนละชนิด เพราะหมดอายุตามกำหนดเวลาต่างกัน และคาดว่ามีเพียงอันเดียวที่เปลี่ยน

ไฟล์เก็บทั้งสองอย่าง และทั้งสองแก่ต่างกัน

ไฟล์จัดเตรียมอยู่ใต้ /var/lib/connman-vpn/ และถูกอ่านต่อการเชื่อมต่อโดยเดมอน VPN ไม่ใช่แอปเพล็ตในถาดระบบ เก็บชื่อการเชื่อมต่อไว้ในส่วนกลาง และรายละเอียดโปรโตคอลในส่วนผู้ให้บริการ

[global]
Name = Company VPN

[provider_openconnect]
Type = OpenConnect
Name = Company Cisco VPN
Host = vpn.example.com
Domain = corp.example
OpenConnect.ServerCert = sha256:...
OpenConnect.Cookie = ...

ใช้ชื่อโฮสต์ที่พอร์ทัลให้บริการจริง ที่อยู่ IP เปล่า ๆ อาจผ่านการตรวจใบรับรองและยังล้มเหลวได้ เพราะอุปกรณ์กำหนดเส้นทางตามโฮสต์เสมือนและคาดหวังชื่อ

systemctl status connman-vpn --no-pager   # is the daemon even installed and running
sudo systemctl restart connman-vpn       # after the file edit
journalctl -u connman-vpn --since '1 hour ago'  # after the connection attempt

บันทึกแสดงอะไรจริง ๆ

คำแนะนำในถาดระบบไม่บอกว่าคุณมีความผิดพลาดแบบไหน บันทึกจะบอกถ้าคุณอ่านลำดับแทนที่จะอ่านบรรทัดน่าตกใจบรรทัดแรก คุกกี้เก่ามักแสดงว่า TLS เจรจาเสร็จแล้วและชั้น HTTP ปฏิเสธภายหลัง นั่นคือเหตุผลที่คำเกี่ยวกับใบรับรองอยู่ข้างความล้มเหลวในการอนุญาต

เปรียบเทียบการรัน authenticate ใหม่กับค่าในไฟล์ ถ้าลายนิ้วมือตรงและต่างกันเพียงคุกกี้ คุณได้คำตอบแล้วโดยไม่ต้องแตะการตั้งค่าความเชื่อถือ

รีเฟรชฟิลด์ที่หมดอายุ

ทำคำสั่ง authenticate ซ้ำ เปลี่ยน OpenConnect.Cookie แล้วรีสตาร์ตเดมอน ปล่อยลายนิ้วมือไว้ เว้นแต่เอาต์พุตใหม่จะแสดงค่าต่าง ในกรณีนั้นใบรับรองเซิร์ฟเวอร์ถูกเปลี่ยนจริง และการปักหมุดใหม่เป็นการตัดสินใจที่ใครคนหนึ่งควรบันทึก ไม่ใช่การวางจากข้อความผิดพลาด

การทำให้การรีเฟรชอัตโนมัติเป็นเรื่องสมเหตุสมผล สคริปต์เล็กอ่านรหัสผ่านจากอินพุตมาตรฐาน รันโหมด authenticate และเขียนใหม่เฉพาะบรรทัดคุกกี้ เก็บข้อมูลรับรองไว้นอกสคริปต์และให้บัญชีที่รันอ่านได้เท่านั้น และทำให้การเขียนใหม่เป็นแบบอะตอม เพื่อการรันที่ล้มเหลวจะไม่ทิ้งไฟล์ที่เขียนค้างไว้

ถ้าต้องรีเฟรชทุกสองสามชั่วโมง ให้จดช่วงเวลาไว้ มันเป็นคุณสมบัติของนโยบายเซสชันของเกตเวย์ และเป็นตัวตัดสินว่าจะทำรีเฟรชอัตโนมัติหรือขอเซสชันที่ยาวขึ้น

บทความที่เกี่ยวข้อง