การจัดเก็บ Secret/Password สำหรับ Python Script ให้ปลอดภัย
Securely Managing Secrets/Passwords for Python Scripts
— — — — — — — — — — — — — — —
สารบัญเนื้อหาทั้งหมด (My Contents)
— — — — — — — — — — — — — — —
เชื่อว่ามือใหม่บางท่านอาจจะเคยนำ secret, key หรือ password ไป hard-coded ไว้ใน Python script โต้ง ๆ แบบนี้
username = 'nopnithi'
password = 'P@ssw0rd'
print('-' * 20 + ' My Python Script ' + '-' * 20)
print(f'Username = {username}\nPassword = {password}')
ซึ่งไม่สมควรอย่างยิ่ง เพราะมีโอกาสที่ secret, key หรือ password ของเราจะหลุดออกสู่สาธารณะได้ ลองมาดูวิธีที่ปลอดภัยกันดีกว่า…
วิธีที่ 1: ใช้ getpass()
วิธีนี้เป็นการให้ user ป้อน secret ด้วยตัวเองขณะรัน Python script ซึ่งการใช้ getpass() จะช่วยให้ขณะที่เราพิมพ์จะไม่แสดงข้อความขึ้นมาบน terminal
ตัวอย่างไฟล์ 1-getpass.py
from getpass import getpass
username = input('Enter username: ')
password = getpass('Enter password: ')
print('-' * 20 + ' My Python Script ' + '-' * 20)
print(f'Username = {username}\nPassword = {password}')
รัน Python Script (1-getpass.py)
python3 1-getpass.py
จะได้
Enter username: nopnithi
Enter password:
-------------------- My Python Script --------------------
Username = nopnithi
Password = P@ssw0rd
ที่จริงวิธีการที่คล้ายกับการใช้ getpass() ยังมีอีกคือใช้ sys.argv ครับ แต่ผมไม่เขียนถึงเพราะส่วนตัวไม่ค่อยชอบเท่าไร ใครสนใจลอง Google หาดูตามคีย์เวิร์ดที่ให้ไปนะ
วิธีที่ 2: ใช้ Environment Variables
วิธีนี้เป็นการเก็บ secret เป็น variable environment ซึ่งทำให้โอกาสที่ secret จะหลุดออกไปในกรณีที่เราส่ง code ให้คนอื่นหรือเผลอ publish ขึ้น public ก็คงไม่มี
เพิ่ม Environment Variables
nano ~/.bashrc
หรือถ้าใช้ zshrc จะเป็น
nano ~/.zshrc
แล้วใส่ environment variable ด้านล่างนี้
export MYUSER=nopnithi
export MYPASS=P@ssw0rd
จากนั้นเซฟให้เรียบร้อยแล้วทำการรีโหลด shell setting ซะ
source ~/.bashrc
หรือ
source ~/.zshrc
ป.ล. ฝั่ง Windows ลองค้นหาวิธีใน Google ดูนะครับ
ตัวอย่างไฟล์ 2-environment-variables.py
import osusername = os.environ['MYUSER']
password = os.environ['MYPASS']
print('-' * 20 + ' My Python Script ' + '-' * 20)
print(f'Username = {username}\nPassword = {password}')
รัน Python Script
python3 2-environment-variables.py
จะได้
-------------------- My Python Script --------------------
Username = nopnithi
Password = P@ssw0rd
วิธีที่ 3: ใช้ GPG Encryption
วิธีนี้ปลอดภัยกว่าวิธีที่ 2 เพราะต่อให้มีใครใช้งานคอมพิวเตอร์ของเราก็ไม่สามารถเข้าถึง secret ได้อยู่ดี (encrypt ไว้)
ติดตั้ง GPG
pip3 install python-gnupg
brew install gpg
หรือถ้าท่านใช้ Ubuntu ก็เปลี่ยน brew install gpg เป็น apt install gpg
สร้างไฟล์ mysecret.txt
MYUSER=nopnithi
MYPASS=P@ssw0rd
Encrypt ไฟล์ mysecret.txt
gpg --symmetric -o encrypted.mysecret.gpg mysecret.txt
จากนั้นมันจะให้เรากำหนด passphrase (ผมกำหนดเป็น nopnithi)
เมื่อเสร็จเรียบร้อยแล้วเราจะได้ไฟล์ encrypted.mysecret.gpg ที่ถูก encrypt เอาไว้เรียบร้อย ก็ให้เราลบ mysecret.txt ทิ้งไปเลย (ไม่ได้ใช้แล้ว)
rm mysecret.txt
ลอง Decrypt ไฟล์ encrypted.mysecret.gpg
gpg --decrypt encrypted.mysecret.gpg
จะได้
gpg: AES256.CFB encrypted data
gpg: encrypted with 1 passphrase
MYUSER=nopnithi
MYPASS=P@ssw0rd
ตัวอย่างไฟล์ 3-gpg-encryption.py
import osusername = os.getenv('MYUSER')
password = os.getenv('MYPASS')
print('-' * 20 + ' My Python Script ' + '-' * 20)
print(f'Username = {username}\nPassword = {password}')
รัน Python Script
env $(gpg --decrypt encrypted.mysecret.gpg) python3 3-gpg-encrytion.py
จะได้
gpg: AES256.CFB encrypted data
gpg: encrypted with 1 passphrase
-------------------- My Python Script --------------------
Username = nopnithi
Password = P@ssw0rd
ระวัง! Flush Session ทิ้งด้วย
สังเกตว่าหลังจากที่เรากรอก passphrase ไป เราจะสามารถ decrypt ได้เรื่อย ๆ เพราะมันเก็บ session เอาไว้ ดังนั้นเราควร flush session ทิ้งด้วย
echo RELOADAGENT | gpg-connect-agent
ถ้าคิดว่าบทความนี้มีประโยชน์ ฝากกด clap, follow และ share บทความนี้ให้ผมด้วยนะครับ ขอบคุณมากครับ ^_^