การป้องกันความลับหลุดตอนที่ 2

🤔 การเก็บรหัสลับบนคลาว์ เขาทำกันยังไงนะ ?

😘 ทวนปัญหา

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

หมายเหตุ ผมขอใช้คำว่า Secret แทนคำว่า ความลับ นะ เพราะอ่านคำว่าความลับแล้วมันจั๊กจี้ยังไงก็ไม่รู้ แต่ให้เข้าใจตรงกันก็คือ มันเป็นของที่สำคัญที่ใช้ในการเข้าระบบอื่นๆ เช่น ฐานข้อมูล, API, Token บลาๆ นั่นเอง

💔 รายการที่ต้องแก้

  • การผัง Secret ไว้เป็น Hard code ทำให้เราต้อง Build & Deploy โปรเจคใหม่เท่านั้น

  • ใน Source code ของมี Secret ติดเข้าไปใน commit เสมอ

  • Developer บางคนอาจจะรู้ Secret ซึ่งเขาอาจจะเป็นคนร้ายในอนาคต หรือ เป็นจุดที่อันตรายถ้าเขาเก็บมันไว้ไม่ดี

  • (ยังไม่หมดนะ อ่านไปเรื่อยๆเดี๋ยวมันจะถูกเติมต่ออยู่)

ซึ่งจากรายการที่ลิสต์มาจะเหลืออยู่ข้อเดียว ดังนั้นเดี๋ยวเรามาลองแก้ปัญหาข้อนี้กัน (แล้วเราจะเพิ่มปัญหาถัดไปต่อ ฮี่ๆ)

แนะนำให้อ่าน บทความนี้เป็นส่วนหนึ่งของคอร์ส 🤠 Cloud Playground ที่จะพาเพื่อนๆแมวน้ำทั้งหลายได้ลองมาดูว่า การสร้างโปรเจคเพื่อทำงานบนคลาว์ โดยใช้มาตรฐานสากลจริงๆแล้วเขาทำกันยังไง ส่วนถ้าสนใจอยากอ่านต่อก็กดไปที่ลิงค์สีฟ้าๆได้เลย

ส่วนถ้าอยากอ่านบทความก่อนหน้าให้อ่านได้จากลิงค์นี้เบย การป้องกันความลับหลุดตอนที่ 1

😘 เข้าใจให้ตรงกันก่อน

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

❤️ หัวใจหลัก (สำคัญมากใช้ต่อหลายบทเลย)

แต่ในจุดนี้ผมอยากให้เข้าใจตรงกันก่อนว่า โดยปรกติเราจะไม่เขียนโค้ดสดต่อตรงเข้ากับตัว database ที่ใช้กับงานจริงมีลูกค้าใช้งานอยู่จริงนะจ๊ะ (ซึ่งหลายๆคนก็รู้ว่ามันไม่ดี แต่ในบางทีก็เลี่ยงไม่ได้ ... เดี๋ยวจะบอกวิธีแก้เรื่องนี้ในบทความถัดๆไปว่ามาตรฐานสากลเขาทำกันยังไง) เพราะ Developer ควรจะต้องทำงานกับ Development Environment หรือพูดง่ายๆก็คือของจำลองนั่นเอง เพราะเราจะเขียนโค้ดให้มันทำงานผิดๆถูกๆยังไงก็ได้ ก็จะไม่มีผลกับงานที่มีคนใช้จริงนั่นเอง ส่วนงานที่มีลูกค้าใช้อยู่จริงเราเรียกมันว่า Production Environment งุยล่ะ

จากที่ว่ามาถ้าเข้าใจ concept นี้แล้วเราก็จะมี Environment 2 แบบนั่นเอง ดังนั้นเราก็จะมี Secret 2 ตัว ตามนี้

  1. Development Secret - มีไว้แจกให้ developer ใช้งาน เช่น connection string เอาไว้ต่อ database ตัวทดสอบ

  2. Production Secret - มีไว้ให้เซิฟเวอร์รู้เท่านั้นไม่แจกให้ใครเด็ดขาด เพราะ ข้อมูลบนนั้นไม่ควรมีคนเข้าถึงได้

จากที่ร่ายยาวมาตัว Development Secret เราก็จะแจกให้ developer ที่เกี่ยวข้องเอาไปกำหนดใส่ Environment Variables ในเครื่องตัวเองเพื่อใช้เชื่อมต่อกับระบบทดสอบนั่นเอง

ดังนั้นเราก็จะมาลองดูกันว่าเจ้า Production Secret นั้นมันมีท่าในการจัดการยังไงบ้างนั่นเอง

🤠 เก็บ Secret ไว้บน Cloud Configuration

หลังจากที่เราได้ลองเก็บความลับไว้ใน Environment Variables ที่อยู่ภายในเครื่องของเราละ ซึ่งตัวเว็บ asp.net core มันจะอ่านค่าพวกนั้นเอาไปใช้งานผ่าน IConfiguration ตามตัวอย่างที่แล้ว (จำไม่ได้กดตรงนี้เพื่อกลับไปดู) แต่คราวนี้ถ้าเราเอาตัวเว็บของเราไป deploy ไว้บนคลาว์แล้วจะเกิดอะไรขึ้น ? ... ดังนั้นผมก็จะเอาตัวเว็บที่สร้างไว้ในบทที่แล้วลองเอาขึ้นคลาว์ดูบ้างนะ

แนะนำให้อ่าน สำหรับคนที่ไม่เคยเอาเว็บไปไว้บนคลาว์เลยก็สามารถลองทำตามได้ง่ายๆด้วยบทความนี้ครัช สร้างเว็บตัวแรกกัน

สำหรับคนที่อยากใช้ Visual Studio Code เอาเว็บขึ้นคลาว์ก็ไปติดตั้ง Extension ตัวนี้นะแล้ว Login ก็จะสามารถใช้คำสั่ง Deploy ขึ้นคลาว์ได้เลย

หลังจากที่เอาขึ้นคลาว์เรียบร้อยละ เราก็ลองเรียก api ของเราทดสอบกันดู ซึ่งสิ่งที่ได้ก็คือ

สาเหตุที่เราได้ ABCDEFG ก็เพราะว่าตัว asp.net core มันไปอ่าน Environment Variables แล้วมันไม่เจอตัวแปร DbConnectionString ยังไงล่ะ (เพราะเรายังไม่ได้กำหนดไว้บนคลาว์) มันเลยไปใช้ค่าจากไฟล์ appsettings.json แทนนั่นเอง

ดังนั้นคราวนี้เราก็จะลองไปกำหนดค่า Secret ไว้บนคลาว์กันดูบ้าง โดยที่เมนูด้านซ้ายของตัวเว็บของเรา มันจะมีเมนูที่ชื่อว่า Configuration อยู่นั่นเอง ให้จิ้มมันลงไปอย่างแผ่วเบา 1 ที

มันก็จะเปิดแสดง Configuration ที่เป็น Secret ที่สำคัญต่างๆออกมาให้เราดูทั้งหมดนั่นเอง ซึ่งในรอบนี้เราจะลองเพิ่ม Secret ใหม่ของเราไปลง ก็ทำการกดที่ปุ่ม + New application setting ลงไปอย่างแผ่วเบาเช่นเคย ตามรูปด้านล่าง

หลังจากนั้นก็ทำการกำหนดชื่อตัวแปรและค่าของมันลงไป (ตั้งชื่ออะไรไว้ก็ใช้ชื่อนั้นนะ ในตัวอย่างผมใช้ชื่อเป็น DbConnectionString นั่นเอง) หลังจากกำหนดเสร็จก็กดปุ่ม OK

สุดท้ายก็ทำการกดปุ่ม Save ก็จะเป็นการเสร็จสิ้นพิธีกรรม

ไหนลองเรียก api ตัวเดิมของเรากันดูดิ๊

ซึ่งตามรูปด้านบนเราก็จะเห็นว่าค่าที่ได้นั้นมันเป็นค่าที่อยู่บนคลาว์เท่านั้น ซึ่งค่านี้ Developer ที่ไม่มี access เข้าถึง service บนคลาว์ก็จะไม่มีทางเข้ามาเห็นนั่นเอง

🎯 สรุปคร่าวๆก่อนไปต่อ

ตอนนี้เราสามารถแยก Secret ออกเป็นแต่ละ Environment ได้อย่างง่ายๆแล้ว โดยที่ Developer ก็ไม่จำเป็นต้องมาคอยเปลี่ยน ConnectionString พวกนี้ไปๆมาๆละ (บางทีเปลี่ยนผิดสลับ Production secret กับ Development secret อีกจะบ้าตาย)

ซึ่งวิธีการในบทความนี้ก็ยังไม่สามารถแก้ปัญหาเรื่องนี้ได้ 100% เพราะว่า

  • ถ้ามีคนที่มี access เข้าถึง service บนคลาว์ตัวนั้นๆได้ เขาก็สามารถเข้ามาดู secret เหล่านั้นได้เหมือนเดิม

  • ถ้าเราไม่ให้ access เข้าถึง service ตัวนั้นๆ เราก็จะเอาแอพขึ้นคลาว์ไม่ได้

แต่เรื่องการ deploy งานขึ้นคลาว์นั้นเราสามารถแก้ไขได้ง่ายๆโดยการใช้ Build pipeline หรือ CI/CD นั่นเอง ดังนั้นปัญหาทั้งหมดของเราก็จะเหลือตามนี้

  • การผัง Secret ไว้เป็น Hard code ทำให้เราต้อง Build & Deploy โปรเจคใหม่เท่านั้น

  • ใน Source code ของมี Secret ติดเข้าไปใน commit เสมอ

  • Developer บางคนอาจจะรู้ Secret ซึ่งเขาอาจจะเป็นคนร้ายในอนาคต หรือ เป็นจุดที่อันตรายถ้าเขาเก็บมันไว้ไม่ดี

  • ถ้ามีคนที่มี access เข้าถึง service บนคลาว์ตัวนั้นๆได้ เขาก็สามารถเข้ามาดู secret เหล่านั้นได้เหมือนเดิม

  • ถ้าเราไม่ให้ access เข้าถึง service ตัวนั้นๆ เราก็จะเอาแอพขึ้นคลาว์ไม่ได้

ดังนั้นเดี๋ยวเราไปดูบทความถัดไปกันเลยดีกว่า ว่าเราจะแก้ปัญหาเรื่องนี้ต่อยังไงดี

แนะนำให้อ่าน สำหรับแมวน้ำท่านไหนสนใจบทความว่าการทำ Build pipeline หรือ CI/CD นั้นเขาทำกันยังไง ก็สามารถเข้าไปดูได้จากลิงค์ 2 ตัวนี้นะขอรับ Continuous Integration (CI) กับ Continuous Delivery (CD) ซึ่งทั้ง 2 บทความนั้นเป็นส่วนหนึ่งของ 👶 Azure DevOps ซึ่งจะสอนการใช้ DevOps ตั้งแต่ขั้นพื้นฐานให้เพื่อนๆนั่นเอง

ชอบ เกลียด โกรธ พบเนื้อหาผิด อ่านแล้ว งง อยากถาม ก็เข้ามาคุยกับ ดช.แมวน้ำ ได้ที่ Saladpuk Facebook นะฮ๊าฟ ฝากกดไลค์กดแชร์ด้วยก็ดีนะครับ 😍