On Firewall & VPN

ช่วงปีที่ผ่านมา evaluate firewall อยู่ หลักๆ ที่สนใจจะเป็นฟีเจอร์พวก VPN มากกว่าเพราะ AWS มันก็มี firewall อยู่แล้ว และพวก L7 firewall มันคือ security as a product ซึ่งไม่ได้ทำให้เกิด security (มันมีประโยชน์ถ้า security debt เยอะจนไม่ไหวแล้วและคุณอยากจะจ่ายดอกกู้นอกระบบ)

BeyondCorp

ที่ต้องใช้ VPN คือถึงโลกมันจะไป BeyondCorp กันแล้ว แต่เอาจริงๆ ecosystem ของ BeyondCorp มันห่วยมาก คือถ้าจะหวัง open source คิดว่ารอไปอีกนาน อาจจะต้องรอดู HashiCorp Boundary
แล้วพวก product พวกนี้เอามาลงเสร็จไม่ใช่จะเป็น BeyondCorp เลย เพราะ key สำคัญของ BeyondCorp คือ zero trust เอา auth มาปิดหน้าแต่ service ด้านหลังไม่ได้ auth ใคร port forward มาก็ปลอมเป็นใครก็ได้ แบบนี้ไม่ใช่ zero trust แต่คนน่าจะเข้าใจกันผิดเยอะว่าซื้อ product มา มี auth เรียบร้อยคือปลอดภัยตามแบบใหม่

ที่มันเป็นอย่างนี้เพราะไม่มี validator ที่ดีพอว่าคุณเป็น zero trust แล้วหรือยัง ไปซื้อ product มาตัว product เองมันก็ไม่ได้ require หรือ warn ว่าข้างหลังคุณต้องทำ mTLS นะ หรือ auth ท่าอื่นก็ว่ากันไป พวกนี้ดันไปอยู่ใน service mesh ซึ่งก็ยังไม่พร้อมใช้สักที แถมเรื่อง identity กับ service mesh ยังคิดว่าเป็นเรื่องอีกยาวไกลเพราะมันยังไม่ถึง MVP เลย

แต่จุดตายจริงๆ ของพวก Authenticating HTTPS proxy as a service ผมว่าคือพวก application ที่ไม่ใช่ HTTP ซึ่งไม่มีใครมีคำตอบดีๆ (ผมว่า LD_PRELOAD คือคำตอบ แต่ไม่มีใครทำ) ผมถาม Google กับ Cloudflare ไปว่า git push ssh ผ่าน solution ที่เค้าขายทำยังไง คำตอบก็คือต้องไปแก้ config บนเครื่องของ Git ให้มันเรียกผ่าน proxy เค้าซึ่งมันก็คือ VPN ดีๆ นี่แหละ แถมเอาออกมาได้ทีละ port

มันก็กลายเป็นปัญหาว่าโปรแกรมทุกตัวที่ไม่ใช่ HTTP เราก็ต้องไปหาวิธีก่อนถึงจะ deploy ได้ แล้วถ้าโปรแกรมมันไม่รองรับ proxy command เลยเช่น npm หรือ pypi จะทำยังไง ทาง vendor เองก็ไม่มี document เก็บไว้ว่าแอพแต่ละตัวใช้ยังไงบ้าง ถึงแม้จะบอกว่าภายในบริษัทของ vendor เองก็ใช้ product ตัวเองในการ develop อยู่แต่ก็ไม่ได้แชร์วิธีมาให้ลูกค้าด้วย

ทั้งหมดทั้งปวงเลยคิดว่าสำหรับ development team แล้ว BeyondCorp ยังไม่ใช่ solution ที่จะเวิร์คไปอีกสักพัก และถึงมันจะ work มันก็มีโอกาส footgun สูงมากๆ

พอเป็นแบบนี้แล้วผมก็เลยไม่มีทางเลือกนอกจากถอยกลับไป VPN ซึ่งพอไปค้นดูจริงๆ ก็พบว่าส่วนมากมันจะมาพ่วงกับ firewall แพงๆ

Next Gen Firewall

Keyword ของ firewall แพงๆ ตอนนี้คือ Next Gen Firewall ตอนแรกที่ผมเลือกทีมก็ยังลังเลอยู่ว่าทำไมผมต้องอยากซื้อ firewall แพงๆ ทั้งๆ ที่ใช้ OpenVPN ก็ได้ ไม่ว่าตัวฟรีหรือตัวเสียเงิน ผมก็อยากรู้เหมือนกันว่าทำไมคนยอมซื้อ firewall เป็นล้าน

ประเด็นสำคัญของ OpenVPN คือมันไม่ได้มากับ firewall แล้วผมก็ต้องไปนั่งเซต iptables อีกต่อหนึ่ง ซึ่งในเลเวลผมแล้วผมยัง prefer firewall gui มากกว่า config as code หรือ command line นะ

ทีนี้ก็ลองไปเลือกมาดูว่าเราจะใช้ใครดี

เจ้าแรกที่คิดถึงเลยคือ Pulse Secure เพราะที่บริษัทใช้อยู่แล้ว แต่พบว่ามันรัน 2 tunnel พร้อมกันไม่ได้ ก็เลยต้องแบน

ถัดมาก็ลองไปค้นดูว่าใครมี Linux client บ้าง ก็ได้ short list มาประมาณหนึ่งว่า

  • Citrix
  • Sophos
  • Barracuda
  • Fortigate
  • Palo Alto Networks

ซึ่งมันตัดตัวใหญ่ๆ ในตลาดไปเยอะเลย ทั้ง Checkpoint, Zscaler ต่างๆ

Citrix

ผมไม่ถนัดซื้อของประเภท contact us มากๆ คือ dev product ที่ขาย dev ตรงๆ มักจะมีราคาแล้ว tier แพงสุดถึงเป็น contact us แต่ product พวกนี้คือจะไม่มีราคาในหน้าเว็บเลย ซึ่งปกติผมจะตัดหมดไปดูเฉพาะเจ้าที่มีราคา แต่พอทุกเจ้าไม่มีราคาหมดก็เลยต้องยอมส่ง lead ไป

การส่ง lead ก็เป็นอีกอันนึงที่น่ารำคาญ คือมันแปลว่าช่วยติดต่อมาหน่อยจะซื้อของ แต่เอาเข้าจริงคิดว่าบริษัทหลายที่มักจะเก็บไปทำ remarketing หรือไม่ก็เก็บไว้ใน sales database แล้วมาขายเรื่อยๆ ซึ่งไม่ได้ consent ขนาดนั้น

Citrix เล่นตัวไม่คุยกับผมอยู่เดือนหนึ่งแล้วถึงส่งเซลมาคุย ก็เลยตัดจบ บาย

Sophos

ผมถือ vendor นึงอยู่ที่ผมจะดู ก็เลยลองคุยกับเซลดูว่าสนใจ bid project นี้มั้ย เค้าก็แนะนำ Sophos มาให้คุยดู

ปรากฏว่าจาก requirement ต่างๆ Sophos ยังไม่ตอบโจทย์ คือผมฟังแล้วรู้สึกว่าในมุม firewall ผมใช้ Mikrotik ที่บ้านยังดีกว่า แต่ Sophos จะไปเน้นเรื่อง internet security (เช่น antivirus) มากกว่าซึ่งก็ไม่ใช่แบรนด์ที่คนคิดถึงอยู่ดีถ้าจะซื้อของพวกนั้น

Barracuda

ผมส่ง lead ให้ Barracuda ก็สักพักติดต่อเข้ามาจากฮ่องกง แต่ผมถามก็บอกว่ามีตัวแทน local นะ

Barracuda เพิ่ง acquire Fyde เข้ามากลายเป็น Barracuda CloudGen Access ซึ่งผมว่าไอเดียมันโคตรดีเลยนะ แต่มันไม่ work

ไอเดียของ CGA คือมันไม่ใช่ VPN แต่มันคือ glorified SOCKS proxy โดยที่จะมี cloud ของ CGA เองเป็น directory service + authentication service

บน network ของเราเองเราจะต้องลง Envoy ที่เค้า customize มาแล้วและเปิด port ซึ่งมัน lightweight มากเพราะมาเป็น container ไม่ใช่ VM เหมือนกับ tranditional VPN

Magic ของ CGA อยู่ที่ client ซึ่งเท่าที่เห็นคือ UI มันเป็น webview ด้วยซ้ำ (ตามสไตล์ app สมัยใหม่) ด้านหลังมันจะ override DNS server บนเครื่องเรา พอมี DNS resolve บน CGA server จะ check ว่าเว็บนี้ IT admin allow หรือเปล่า และถ้ามันเป็น domain ที่ config ไว้ว่าต้องเข้าผ่าน VPN ตัว CGA client จะออก IP ใหม่ในวง 224.0.0.0/16 คืนให้

บน Application พอ connect ไปที่ 224.0.0.0/16 ที่ให้มาแล้ว CGA client ที่ listen อยู่บน IP นั้นจะ proxy กลับไปหา Envoy ตัวที่ directory บอก และเนื่องจาก Envoy มันเป็น L4 proxy มันเลยใช้กับ protocol ได้ทุกประเภท (ผมสงสัยมากว่าบน client ก็รัน Envoy หรือเปล่านะ มันอาจจะเป็น Envoy on client ตัวแรกที่ผมเห็นเลย)

ข้อดีของวิธีนี้คือมัน route by DNS ไม่ได้ route by subnet ทำให้ flexible กว่ามาก และถ้ามีหลาย site ที่ต้อง VPN ไปก็ไม่ต้องสลับไปสลับมา

ข้อเสียของวิธีนี้คือเนื่องจากมันเป็น proxy ทำให้ server ปลายทางไม่รู้ว่าใครเป็นคน connect เข้ามา เวลามีปัญหาดู access log ที่ service จะเห็นแต่ IP proxy ไม่รู้ว่าใคร (ต้องไปทำ audit log ให้หมด) และบน CGA server เองเนื่องจาก operate บน L4 ก็จะ log ให้แต่ว่าคนนี้เข้า service นี้แต่ถ้าเข้าพร้อมกันแล้วเอา log มาเทียบก็ยังไม่รู้ว่าใคร

ผมขอ Barracuda ลอง Firewall ธรรมดาๆ ต่อ แต่ดูท่าเซลจะพยายามดันตัวนี้ก็เลยตัดสินใจว่าไม่คุยต่อ

Fortigate

หลังจากเซลเค้าขาย Sophos ให้ไม่ได้ ก็เลยเลือก Fortigate เข้ามาคุย

ผมใช้ Fortigate แล้วก็ค่อนข้างประทับใจดี คือ UI มันลื่นไหล ใช้งานง่าย และดู modern ดี

แต่ในทางกลับกันฝั่ง VPN client (FortiClient) UI กลับดูโบราณเหมือนออกมาจากยุค 2010 ปลายๆ Windows XP อะไรแบบนั้น

ที่ไม่ชอบ Fortigate คือ product เค้าเยอะมีหลายตัว (FortiGate, FortiEMS, FortiClient, FortiAuthenticator) จนมันงงว่าต้องซื้ออะไรบ้าง และมันรู้สึกเหมือนซื้อเกมที่มันตัด content ไปทำ DLC เสียมากกว่า

สองคือ requirement ผมจะมีเรื่อง device check ต่างๆ ซึ่งมันไปอยู่ใน FortiEMS และ FortiEMS รันได้เฉพาะบน Windows Server เท่านั้น ซึ่งทีมไม่มีใครดู และเนื่องจาก FortiEMS มันวางตัวเป็น internet security ด้วยเลยขายแบบนับหัวซึ่งแพงมาก และถ้าไม่ซื้อ EMS แล้ว FortiClient ตัวที่ใช้จะโดนตัดฟีเจอร์ไปเยอะแถมมี nag ด้วยว่าต้องซื้อตัวแพง

คือขายของ enterprise แบบ EA ขายเกมนี่ไม่เอาอ่ะ

ในฝั่งของ product เองก็เจอบั๊กน่ารำคาญกับ SAML กับ LDAP คือ SAML มันบังคับเปิดใน embedded browser ซึ่ง Google เค้าจะแบนอยู่แล้ว และ login Google ค่อนข้างน่ารำคาญก็เลยไม่เอา

ส่วน LDAP ก็มีปัญหาว่ามัน fetch group แบบ lazy มากๆ คือ fetch เฉพาะ group ที่มีการใช้ใน firewall rule และ VPN access control มันเลยกลายเป็นว่าใช้ group ที่ไม่ได้ control สิทธิ์เข้าถึง VPN ใน firewall rule ไม่ได้

Palo Alto Network

สุดท้ายก็เลยเหลือแต่ Palo Alto…

ผมเกริ่นไว้นานมากว่าแล้ว firewall พวกนี้มันต่างกับ iptables ยังไง ประเด็นสำคัญของ NGFW คือวิธี match rule มันจะต่างกับ iptables ไปเลย (แต่ถ้าอยากเขียนแบบ iptables ก็ยังทำได้นะ) คือมันสามารถ match

  • Incoming/Outgoing zone (คือ group of interface)
  • Source/Destination IP address
  • Source user/group
  • Source computer settings
  • Application type
  • DNS name

ซึ่งมันทำให้เราทำ firewall rule ได้ล้ำมากๆ เพราะถ้าอยากจะแบ่งตาม user group โดยใช้ subnet เราอาจจะต้องแบ่งเช่น 10.1.0.0/16 = Dev, 10.2.0.0/16 = บัญชี, 10.3.0.0/16 = HR เป็นต้น แต่มันอาจจะมีกรณีที่ user หนึ่งอยู่หลาย group เช่น dev ที่เขียน ERP ต้องใช้งานระบบบัญชีด้วย มันก็จะทำให้ combination มันโตออกไปมากขึ้นเรื่อยๆ

แต่พอมัน match rule ตาม group ได้แล้วเราแจก 10.0.0.0/8 ได้เลยโดยไม่ต้องแบ่งแยกแผนก แต่ได้ access control ที่ละเอียดกว่าแบบแบ่ง subnet ซะอีก และมันเลยเป็นเหตุผลว่า firewall เลยเป็น VPN software ที่ดีด้วยเพราะข้อมูลการ login มันจะผูกกลับไปที่ firewall เอง (นอกจาก VPN client แล้ว Palo Alto ยังมีท่าที่ยิง log/API ให้มัน match แล้วรับรู้ว่า IP นี้ user อะไรอีกด้วย แต่เคสที่เห็นโหดๆ คือ clientless VPN ซึ่ง 1 source IP มีหลาย user มันก็ยังแยกได้ด้วย)

ในส่วนของ Match by computer settings ผมว่าเป็นข้อได้เปรียบของ closed source software หน่อยที่มันมีฟีเจอร์แบบ security by obscurity ได้ประมาณหนึ่ง โดยที่ตัว client มันจะเป็น spyware ให้เราดูดข้อมูล settings ของเครื่องส่งไปที่ firewall แล้วบน firewall match กับ rule บางอย่าง (ซึ่งแน่นอนในความเป็นจริง client fake report ได้ แต่ต้อง bypass client หรือไปแก้ source ที่มันอ่าน) ตัวอย่างเช่นถ้าเครื่องไม่ได้ลง Baidu Antivirus ไม่อนุญาตให้ใช้ VPN หรือไม่ให้ใช้บาง service เป็นต้น รวมถึง match serial number ของเครื่องเข้ากับ device inventory เพื่อเช็คว่าเป็นเครื่องบริษัทจริง

พวกนี้ถ้าเป็น open source ก็แก้ client แล้ว recompile ใหม่ ง่ายมาก แต่พอเป็น proprietary แล้วต้องทำ reverse engineering

ส่วนสุดท้ายคือ Application type และ URL คือการ match บน layer 7 โดย firewall จะเข้าใจ protocol บางตัวเช่น SSL SNI เพื่อ match กับ DNS name ที่กำหนด (โดยไม่ต้องทำ SSL interception) หรือเข้าใจ pattern ของ application โดยตรงถึงขนาดที่ว่าถ้ายอมทำ SSL interception แล้วสามารถเขียน rule แยกได้เลยว่าใช้ Slack คุยได้แต่ห้ามอัพไฟล์หรือ call

สำหรับ Palo Alto เอง client ทำออกมาได้ค่อนข้างดี อาจจะยกเว้น Linux ไว้หน่อยหนึ่งซึ่งถ้าเป็น distro ที่ support ก็รันได้ดีแต่เป็น distro ที่เก่าหน่อยคนอาจจะไม่ได้เอามาใช้เป็น desktop แล้ว ถ้าใ้ช distro ใหม่ๆ อาจจะต้องเล่นท่ายากพอสมควร

บนตัว Firewall เองผมยังไม่เจออะไรกวนใจนอกจาก UI ที่ค่อนข้างช้ามาก ก็ไม่แน่ใจว่ามันติดอะไรเหมือนกัน

เขียนมายาวแล้วเดี๋ยวจะไม่ได้ publish เอาเป็นว่าไว้ค่อยเล่าเรื่อง config

On Kubernetes Node Sizing

เหมือนเคยเขียนใน Facebook แต่ไม่แน่ใจ จริงๆ ก็อยากเขียนให้มัน scientific ดีๆ ลง blog บริษัท

คำถามที่ไม่มีใครตอบได้อันนึงของ Kubernetes คือ node ใช้ size อะไรดี โดยเฉพาะใน cloud ที่

  • m5.xlarge 4vCPU RAM 16GB ราคา $0.24/hr
  • m5.4xlarge 16vCPU RAM 64GB ราคา $0.96/hr

ซึ่งถ้าซื้อ m5.xlarge 4 เครื่องให้สเปคเท่ากัน มันก็ $0.96/hr อยู่ดี เลยไม่ต่างกันแล้วจะเลือกยังไง…

Fault isolation

ใน design cluster เดิมผมใช้ m5.xlarge รันอยู่

ข้อดีของวิธีนี้คือเครื่องจะเป็น single point of failure น้อย

ข้อเสียคือสมมุติว่าทุกเครื่องมันจะเหลือ CPU ประมาณ 200m เพราะมันไม่มี workload size ที่ลงได้ สมมุติว่าเรามี 10 เครื่องที่เหลือรวมกันก็ 2000m แล้ว ยังไ่มรวม memory

อีกปัญหาหนึ่งคือ workload ที่มัน burst เกิน cpu request ต่อเนื่องจะกลายเป็น noisy neighbour ให้กับ pod ข้างๆ ซึ่งแก้ไม่ได้เพราะบางทีมันก็ burst แป๊บเดียวจริงๆ เช่นตอน start อาจจะโหลดหนักมากแต่ตอนรันใช้ cpu แค่ 20m ถ้าเราใส่ cpu cap ให้มันเป็น 20m ทีนี้ start ทีนึงหลายนาที เผลอๆ connection timeout แล้ว start ไม่ติด (cloud ต่างๆ ใช้ burst model เป็นแบบเป็น credit ซึ่ง Kubernetes ไม่มี)

Bigger the better

ใน cluster ใหม่ ผมกับ director คิดกันว่าควรจะเลือกเครื่อง size ใหญ่ขึ้น

เหตุผลของผมคือเราใช้ AWS ENI ต่อเข้า pod แล้วพอเครื่องใหญ่ขึ้นจะได้ ENI มากขึ้น คิดว่าประมาณ m5.4xlarge กำลังเหมาะเพราะมันจะได้ 234 pod ซึ่งคิดว่า average case แล้วมันไม่น่า่จะอัดกันเครื่องเดียวได้ 234 pod แต่ก็มีบ้างถ้าเครื่องโดน assign แต่ workload เล็กๆ

เหตุผลของ Director ผมคือถ้าเราไปใช้ m5.8xlarge ขึ้นไป เราจะได้การันตี 10Gbps network (ต่ำกว่านี้เป็น up to) ซึ่งคิดว่ามันน่าจะช่วยให้ network เสถียรขึ้น แต่ก็คงใช้เฉพาะใน production เท่านั้น

ข้อเสียคือถ้าเครื่องมันดับ impact จะใหญ่ขึ้นมากๆ และเวลา scale up เครื่องมันจะเหลือ

จากที่ใช้งานมาจริง ก็พบว่า

  • Network มันน่าจะนิ่งและเร็วขึ้น เพราะเครื่องใหญ่แล้วโอกาสที่ workload จะรันอยู่บนเครื่องเดียวกันจะมากขึ้น
  • ส่วนมากคนจะเขียน resource request เป็น p80 ขึ้นไปแต่เวลาใช้งานจริงส่วนมากจะไม่ถึง และ workload บนเครื่องที่หลากหลายขึ้น คิดว่าน่าจะทำให้ในทางปฏิบัติทุก pod สามารถ burst ชน cpu limit ได้ตลอดเวลา เพราะไม่น่าจะมีโอกาสที่ทุก pod จะอยาก burst พร้อมกัน ซึ่งก็จะลดปัญหา noisy neighbor ไปได้
    • Google มี finding คล้ายๆ กันว่าถ้าเครื่องมันใหญ่กว่าขนาดของ workload มากๆ ทุกคนน่าจะสามารถ burst พร้อมกันได้ถ้ามันกระจายตัวดีพอ
  • rolling reboot เร็วขึ้น แต่ก่อน reboot ทั้ง cluster หลายชั่วโมง
  • resource request ส่วนที่เหลือทิ้งของเครื่องที่เต็มยังเท่าเดิมจริง แต่เครื่องมักจะไม่เต็มเพราะ Kubernetes จะเน้นกระจายมากกว่าพยายามอัดให้เต็มเป็นเครื่องๆ ไป ก็เลยเหลือทิ้งอยู่ดี

ไว้ prod เอาขึ้นแล้วน่าจะได้รู้ผลของทฤษฎีกันจริงๆ ว่าจะ work แค่ไหน