ฉันจะบันทึกคีย์ลับและรหัสผ่านอย่างปลอดภัยในระบบควบคุมเวอร์ชันของฉันได้อย่างไร


134

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

แต่ดูเหมือนว่ารหัสผ่านจะเหมือนกับการตั้งค่าอื่น ๆ แล้วไงเป็นวิธีการที่เหมาะสมในการเก็บรหัสผ่านควบคุมรุ่น?

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


ฉันถามคำถามโดยทั่วไป แต่ในกรณีเฉพาะของฉันฉันต้องการเก็บคีย์ลับและรหัสผ่านสำหรับไซต์Django / Pythonโดยใช้gitและgithub GitHub

นอกจากนี้ทางออกที่ดีจะทำสิ่งที่น่าอัศจรรย์เมื่อฉันกด / ดึงด้วยคอมไพล์เช่นหากไฟล์รหัสผ่านที่เข้ารหัสเปลี่ยนสคริปต์จะถูกเรียกใช้ซึ่งขอรหัสผ่านและถอดรหัสให้เข้าที่


แก้ไข: เพื่อความชัดเจนฉันกำลังถามเกี่ยวกับสถานที่เก็บความลับในการผลิต


1
จริงๆแล้วต้องสำรองเงินไว้เพื่อให้ repo ทั้งหมดเป็นแบบส่วนตัว
John Mee

29
@JohnMee ฉันจ่ายค่าพื้นที่เก็บข้อมูลส่วนตัวไปแล้ว แต่ประเด็นยังคงอยู่ - คุณไม่ควรเก็บข้อมูลที่ละเอียดอ่อนไว้ในที่เก็บของคุณ
Chris W.

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

4
ทำไม? มีค่า zilch ในเวอร์ชันควบคุมรหัสผ่านสำหรับบริการภายนอก มูลค่าหลักของการควบคุมเวอร์ชันคือการที่คุณสามารถตรวจสอบการแก้ไขประวัติศาสตร์ของแอพลิเคชันของคุณเป็นที่รู้จักกันจะเป็นเพื่อการทำงานและการใช้พวกเขา อย่างไรก็ตามรหัสผ่านเก่าไม่มีประโยชน์สำหรับคุณ หากถูกเพิกถอนก็จะไม่กลับมาทำงานอีก
พันเอก Panic

คำตอบ:


100

คุณมีสิทธิ์ที่ต้องการเข้ารหัสไฟล์การตั้งค่าที่ละเอียดอ่อนของคุณในขณะที่ยังคงรักษาไฟล์ไว้ในการควบคุมเวอร์ชัน ดังที่คุณกล่าวถึงทางออกที่ดีที่สุดคือ Git จะเข้ารหัสไฟล์ที่ละเอียดอ่อนบางไฟล์อย่างโปร่งใสเมื่อคุณผลักดันเพื่อให้ภายในเครื่อง (เช่นบนเครื่องใดก็ได้ที่มีใบรับรองของคุณ) คุณสามารถใช้ไฟล์การตั้งค่าได้ แต่ Git หรือ Dropbox หรือใครก็ตาม การจัดเก็บไฟล์ของคุณภายใต้ VC ไม่มีความสามารถในการอ่านข้อมูลในรูปแบบข้อความธรรมดา

บทช่วยสอนเกี่ยวกับการเข้ารหัส / ถอดรหัสแบบโปร่งใสระหว่างการกด / ดึง

ส่วนสำคัญนี้https://gist.github.com/873637แสดงบทช่วยสอนเกี่ยวกับวิธีใช้ไดรเวอร์ตัวกรอง smudge / clean ของ Git พร้อม openssl เพื่อเข้ารหัสไฟล์ที่พุชอย่างโปร่งใส คุณต้องทำการตั้งค่าเริ่มต้นบางอย่าง

สรุปวิธีการทำงาน

โดยพื้นฐานแล้วคุณจะสร้าง.gitencryptโฟลเดอร์ที่มี 3 bash scripts

clean_filter_openssl 
smudge_filter_openssl 
diff_filter_openssl 

ซึ่ง Git ใช้สำหรับถอดรหัสเข้ารหัสและรองรับ Git diff ข้อความรหัสผ่านหลักและเกลือ (แก้ไขแล้ว!) ถูกกำหนดไว้ในสคริปต์เหล่านี้และคุณต้องแน่ใจว่าไม่มีการผลักดัน. gitencrypt จริง ตัวอย่างclean_filter_opensslสคริปต์:

#!/bin/bash

SALT_FIXED=<your-salt> # 24 or less hex characters
PASS_FIXED=<your-passphrase>

openssl enc -base64 -aes-256-ecb -S $SALT_FIXED -k $PASS_FIXED

คล้ายกันสำหรับsmudge_filter_open_sslและdiff_filter_oepnssl . ดู Gist

repo ของคุณที่มีข้อมูลที่ละเอียดอ่อนควรมีไฟล์. gitattribute (ไม่ได้เข้ารหัสและรวมอยู่ใน repo) ซึ่งอ้างอิงถึงไดเร็กทอรี. gitencrypt (ซึ่งมีทุกสิ่งที่ Git ต้องการเพื่อเข้ารหัส / ถอดรหัสโปรเจ็กต์อย่างโปร่งใส) และมีอยู่ในเครื่องของคุณ

.gitattribute เนื้อหา:

* filter=openssl diff=openssl
[merge]
    renormalize = true

สุดท้ายคุณจะต้องเพิ่มเนื้อหาต่อไปนี้ใน.git/configไฟล์ของคุณ

[filter "openssl"]
    smudge = ~/.gitencrypt/smudge_filter_openssl
    clean = ~/.gitencrypt/clean_filter_openssl
[diff "openssl"]
    textconv = ~/.gitencrypt/diff_filter_openssl

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

หมายเหตุ

ฉันควรทราบว่าบทช่วยสอนนี้ไม่ได้อธิบายวิธีเข้ารหัสเฉพาะไฟล์การตั้งค่าที่ละเอียดอ่อนของคุณเท่านั้น การดำเนินการนี้จะเข้ารหัสที่เก็บทั้งหมดอย่างโปร่งใสที่ถูกพุชไปยังโฮสต์ VC ระยะไกลและถอดรหัสที่เก็บทั้งหมดเพื่อให้ถูกถอดรหัสในเครื่องทั้งหมด เพื่อให้บรรลุพฤติกรรมที่คุณต้องการคุณสามารถวางไฟล์ที่ละเอียดอ่อนสำหรับโครงการหนึ่งหรือหลายโครงการใน sensitive_settings_repo เดียว คุณสามารถตรวจสอบว่าเทคนิคการเข้ารหัสแบบโปร่งใสนี้ทำงานอย่างไรกับ Git submodules http://git-scm.com/book/en/Git-Tools-Submodulesหากคุณต้องการให้ไฟล์ที่ละเอียดอ่อนอยู่ในที่เก็บเดียวกันจริงๆ

การใช้ข้อความรหัสผ่านคงที่ในทางทฤษฎีอาจนำไปสู่ช่องโหว่ที่กำลังดุร้ายหากผู้โจมตีสามารถเข้าถึง repos / ไฟล์ที่เข้ารหัสจำนวนมาก IMO ความน่าจะเป็นของสิ่งนี้ต่ำมาก ดังหมายเหตุที่ด้านล่างของบทช่วยสอนนี้กล่าวถึงการไม่ใช้ข้อความรหัสผ่านคงที่จะส่งผลให้ repo เวอร์ชันท้องถิ่นบนเครื่องต่าง ๆ แสดงว่ามีการเปลี่ยนแปลงเกิดขึ้นกับ 'git status' เสมอ


1
โอ้น่าสนใจมาก ฟังดูเกือบจะเหมือนกับสิ่งที่ฉันต้องการ (ยกเว้นการเข้ารหัสที่เก็บทั้งหมด)
Chris W.

คุณสามารถเก็บไฟล์การตั้งค่าที่ละเอียดอ่อนทั้งหมดสำหรับหลาย ๆ แอปพลิเคชันไว้ในที่เก็บที่เข้ารหัสเดียวหรือเพิ่มที่เก็บที่เข้ารหัสด้วยการตั้งค่าที่ละเอียดอ่อนให้กับโปรเจ็กต์ของคุณเป็นโมดูลย่อย Git ตามที่อธิบายไว้ที่นี่git-scm.com/book/en/Git-Tools-Submodules .
dgh

การจัดเก็บรหัสผ่าน / การตั้งค่าการใช้งานจริงในโมดูลย่อย (เข้ารหัส) ไม่ใช่เรื่องแปลก stackoverflow.com/questions/11207284/… . มันจะทำให้ง่ายต่อการจัดการการตั้งค่าในโครงการต่างๆ
dgh

อาจคุ้มค่าที่จะตรวจสอบgithub.com/AGWA/git-cryptสำหรับโซลูชันที่อัปเดต มีข้อดีคืออนุญาตให้เข้ารหัสไฟล์แต่ละไฟล์ได้และอ้างว่า "ปลอดภัยทางความหมาย" ผู้เขียนสรุปสาระสำคัญของตัวเองบอกว่าเครื่องมือนี้จะดีกว่าที่github.com/shadowhand/git-encrypt
geekley

52

Heroku ผลักดันการใช้ตัวแปรสภาพแวดล้อมสำหรับการตั้งค่าและคีย์ลับ:

วิธีการดั้งเดิมในการจัดการ config vars ดังกล่าวคือการวางไว้ภายใต้ซอร์ส - ในไฟล์คุณสมบัติบางประเภท นี่เป็นกระบวนการที่เกิดข้อผิดพลาดได้ง่ายและมีความซับซ้อนเป็นพิเศษสำหรับแอปโอเพนซอร์สซึ่งมักจะต้องดูแลสาขาแยกต่างหาก (และส่วนตัว) ด้วยการกำหนดค่าเฉพาะแอป

ทางออกที่ดีกว่าคือการใช้ตัวแปรสภาพแวดล้อมและเก็บคีย์ไม่ให้อยู่ในโค้ด บนโฮสต์แบบดั้งเดิมหรือทำงานในพื้นที่คุณสามารถตั้งค่าสภาพแวดล้อม vars ใน bashrc ของคุณ ใน Heroku คุณใช้ config vars

ด้วย Foreman และ.envไฟล์ Heroku มอบ toolchain ที่น่าอิจฉาในการส่งออกนำเข้าและซิงโครไนซ์ตัวแปรสภาพแวดล้อม


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

ด้วยวิธีการ Heroku ด้านบนนักพัฒนาสามารถชำระเงินแอปของปีที่แล้วกำหนดค่าด้วยคีย์ของวันนี้และรันได้สำเร็จกับฐานข้อมูลของวันนี้


1
คำตอบนี้ไม่ได้รับความสนใจเพียงพอ แต่ส่วนใหญ่เกิดขึ้นพร้อมกับวิธี linux
Nikolay Fominyh

11
ดังนั้นหากสภาพแวดล้อม vars ถูกตั้งค่าใน bashrc ของคุณและคุณกำลังปรับใช้เซิร์ฟเวอร์ใหม่สิ่งที่สร้าง bashrc? นั่นไม่เพียงแค่ย้ายรหัสผ่านออกจากที่เก็บซอร์สโค้ดของคุณและไปยังการกำหนดค่าการปรับใช้ของคุณ (ซึ่งคาดว่าจะอยู่ใน repo ซอร์สโค้ดหรือใน repo ของตัวเอง)
Jonathan Hartley

@JonathanHartley. bashrc ของคุณไม่ควรอยู่ในรหัส repo สำหรับแอป Django ของคุณ
สตีฟ

4
ขออภัยความคิดเห็นของฉันไม่ชัดเจน แต่นั่นเป็นเพราะฉันสับสนจริงๆ ฉันชอบเสียงของมุมมองของคำตอบนี้ แต่ไม่เคยเข้าใจอย่างถ่องแท้ หากฉันปรับใช้กับสภาพแวดล้อมที่แตกต่างกันซึ่งแต่ละแห่งมีโฮสต์หลายโฮสต์และอาจมีโฮสต์หลายประเภทเห็นได้ชัดว่าฉันต้องสร้างไฟล์. bashrc โดยอัตโนมัติที่จะมีอยู่ในแต่ละโฮสต์เพื่อตั้งค่าตัวแปรสภาพแวดล้อม ดังนั้นคำตอบที่บอกว่าฉันควรมีrepo ที่สองแยกต่างหากจากแหล่งที่มาของฉันซึ่งมีการตั้งค่าทั้งหมดซึ่งจะกลายเป็นตัวแปรสภาพแวดล้อมใน. bashrc ในการปรับใช้?
Jonathan Hartley

1
จำเป็นต้องกำหนดค่าเพียงครั้งเดียวต่อเครื่องที่คุณปรับใช้ หากกระบวนการปรับใช้ของคุณคือ "หมุนเครื่องใหม่และทดสอบว่าใช้ได้ก่อนที่จะเปลี่ยนเส้นทางการรับส่งข้อมูลไปยังเครื่องนั้นจากนั้นจึงยิงเครื่องเก่าในหัว" ซึ่ง IMHO เป็นแนวทางปฏิบัติที่ดีที่สุดคุณจะต้องสร้างสิ่งที่กำหนดโดยอัตโนมัติ env vars.
Jonathan Hartley

17

วิธีที่สะอาดที่สุดในความคิดของฉันคือการใช้ตัวแปรสภาพแวดล้อม คุณจะไม่ต้องจัดการกับ. distไฟล์.และสถานะโปรเจ็กต์บนสภาพแวดล้อมการใช้งานจริงจะเหมือนกับของเครื่องในเครื่องของคุณ

ฉันขอแนะนำให้อ่านบท config ของแอปสิบสองปัจจัยอื่น ๆ ด้วยหากคุณสนใจ


6
ดูเหมือนว่าตัวแปรสภาพแวดล้อมจะเป็นวิธีที่ดีในการเรียกใช้แอปพลิเคชันด้วยการตั้งค่าความลับ ... แต่ก็ยังไม่ตอบคำถามว่าจะเก็บการตั้งค่าเหล่านั้นไว้ที่ใด
Chris W.

2
โดยปกติคุณควรมีไฟล์ README สำหรับแต่ละแอปของคุณ ในนั้นให้ระบุตัวแปรสภาพแวดล้อมที่ควรตั้งค่าและทุกครั้งที่คุณปรับใช้โครงการเพียงทำตามขั้นตอนและตั้งค่าแต่ละตัวแปร คุณยังสามารถสร้างเชลล์สคริปต์ที่มีจำนวนมากexport MY_ENV_VAR=และเมื่อคุณปรับใช้เพียงเติมค่าที่ถูกต้องsourceแล้วเติม หากให้คุณหมายถึงการตั้งค่าเวอร์ชันคุณไม่ควรทำเช่นนี้ตั้งแต่แรก
Samy Dindane

นอกจากนี้ยังโหวตให้แอป The Twelve-Factorซึ่งเป็นสิ่งที่ยอดเยี่ยมจริงๆ
Chris W.

4
@Samy: และถ้าคุณติดตั้งระบบอัตโนมัติล่ะ?
Jonathan Hartley

3
@Samy ฉันยังไม่เข้าใจว่าจะตั้งค่าตัวแปรสภาพแวดล้อมอย่างไร หน้าแอปปัจจัย 12 ก็ไม่ชัดเจนเช่นกัน (เว้นแต่คุณจะใช้ Heroku ซึ่งโครงการปัจจุบันของฉันไม่ใช่) เรากำลังบอกว่าสคริปต์ที่สร้างขึ้นจำเป็นต้องถามที่เก็บ config ส่วนกลาง "ฉันเป็นเครื่อง X โปรด ให้ข้อมูลการกำหนดค่าของฉัน” และตอบสนองด้วยค่าของตัวแปรสภาพแวดล้อมที่ควรตั้งค่า ในกรณีนั้นฉันไม่คิดว่าคุณต้องการสคริปต์ที่สร้างขึ้นอีกแล้ว ฉันคาดเดาอย่างดุเดือดที่นี่ฉันเห่าต้นไม้ใช่ไหม
Jonathan Hartley

10

ตัวเลือกคือใส่ข้อมูลประจำตัวที่ผูกกับโปรเจ็กต์ลงในคอนเทนเนอร์ที่เข้ารหัส (TrueCrypt หรือ Keepass) แล้วพุช

อัปเดตเป็นคำตอบจากความคิดเห็นของฉันด้านล่าง:

คำถามที่น่าสนใจ btw. ฉันเพิ่งพบสิ่งนี้: github.com/shadowhand/git-encryptซึ่งดูมีแนวโน้มมากสำหรับการเข้ารหัสอัตโนมัติ


คงจะดีไม่น้อยหากมีบางอย่างที่ทำให้เป็นอัตโนมัติได้ ดังนั้นหากไฟล์รหัสผ่านที่เข้ารหัสของฉันเปลี่ยนไประบบจะถอดรหัสไฟล์ใหม่โดยอัตโนมัติ
Chris W.

7
คำถามที่น่าสนใจ btw. ฉันเพิ่งพบสิ่งนี้: github.com/shadowhand/git-encryptซึ่งดูมีแนวโน้มมากสำหรับการเข้ารหัสอัตโนมัติ
schneck

1
ว้าวเยี่ยมมาก คำอธิบายของgit-encryptเสียงเหมือนกับสิ่งที่ฉันกำลังมองหา "เมื่อทำงานกับที่เก็บ git ระยะไกลซึ่งโฮสต์บนเซิร์ฟเวอร์หน่วยเก็บข้อมูลของบุคคลที่สามการรักษาความลับของข้อมูลบางครั้งก็เป็นเรื่องที่น่ากังวลบทความนี้จะอธิบายขั้นตอนการตั้งค่าที่เก็บ git ซึ่งไดเรกทอรีการทำงานในพื้นที่ของคุณเป็นไปตามปกติ (ไม่เข้ารหัส) แต่เนื้อหาที่ผูกมัดจะถูกเข้ารหัส (แน่นอนฉันต้องการเพียงบางส่วนของเนื้อหาที่เข้ารหัส ... )
Chris W.

@schneck โพสต์ความคิดเห็นของคุณเป็นคำตอบเพื่อให้คริสยอมรับ - ดูเหมือนว่าจะเป็นสิ่งที่เขากำลังมองหา
Tony Abou-Assaleh

9

ฉันขอแนะนำให้ใช้ไฟล์คอนฟิกูเรชันสำหรับสิ่งนั้นและไม่ใช่เวอร์ชัน

อย่างไรก็ตามคุณสามารถเวอร์ชันตัวอย่างของไฟล์ได้

ฉันไม่เห็นปัญหาในการแชร์การตั้งค่าการพัฒนา ตามคำจำกัดความไม่ควรมีข้อมูลที่มีค่า


1
แต่แล้วจะเก็บบันทึกรหัสผ่านมาตรฐานได้ที่ไหน? มันจะทำให้ฉันกังวลที่จะมีข้อมูลนั้นอยู่ในไฟล์คอนฟิกูเรชันบนเครื่องซึ่งอาจระเบิดขึ้นในสักวันหนึ่ง
Chris W.

@ChrisW. หากเครื่องระเบิดคุณไม่จำเป็นต้องใช้รหัสผ่านอีกต่อไป ... อย่างไรก็ตามหากคุณมีสำเนาข้อมูลเพียงชุดเดียวในเครื่องผลิตของคุณนั่นควรจะขึ้นธงสีแดง แต่ไม่ได้หมายความว่าควรอยู่ใน VCS ควรมี RAID การสำรองข้อมูลแบบเต็มเสริมด้วยการสำรองข้อมูลส่วนเพิ่มบนสื่อแม่เหล็กและออปติคัล บริษัท หลายแห่งมีขั้นตอนการควบคุมการเปลี่ยนแปลงซึ่งอาจกำหนดวิธีการและสถานที่ในการจัดเก็บรหัสผ่านและวัสดุที่ละเอียดอ่อนอื่น ๆ บนกระดาษด้วย
Steve Buzonas

@ChrisW ฉันไม่อยากพูดหยาบ แต่ดูเหมือนว่าคุณไม่ได้บอกความจริงกับเราและรหัสผ่านที่คุณต้องการจัดเก็บไม่ได้ใช้ในการพัฒนา แต่ในการผลิต นี่ไม่จริงเหรอ? มิฉะนั้นทำไมคุณถึงสนใจเครื่องพัฒนาหรือทดสอบและรหัสผ่านสำหรับการพัฒนา ไม่มีใครทำอย่างนั้น
tiktak

BTW ที่ บริษัท ของเรารหัสผ่านการพัฒนาทั้งหมดมีอยู่ในกระดาษและบนอินทราเน็ต เพราะพวกเขาไม่มีค่า พวกเขาอยู่ที่นั่นเนื่องจากซอฟต์แวร์ที่เราพัฒนาต้องการการตรวจสอบสิทธิ์
tiktak

@tiktak คุณถูกต้อง - คำถามของฉันเกี่ยวกับสิ่งที่เกี่ยวข้องกับรหัสผ่านการผลิต ฉันไม่สนใจเป็นพิเศษเกี่ยวกับการจัดเก็บรหัสผ่านการพัฒนาใน A VCS อย่างชัดเจน ขออภัยหากฉันยังไม่ชัดเจนพอ
Chris W.

7

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

จากคำอธิบายบนhttps://github.com/StackExchange/blackbox :

จัดเก็บความลับอย่างปลอดภัยใน VCS repo (เช่น Git หรือ Mercurial) คำสั่งเหล่านี้ทำให้ GPG เข้ารหัสไฟล์เฉพาะใน repo ได้อย่างง่ายดายดังนั้นจึง "เข้ารหัสที่เหลือ" ในที่เก็บของคุณ อย่างไรก็ตามสคริปต์ทำให้ง่ายต่อการถอดรหัสเมื่อคุณต้องการดูหรือแก้ไขและถอดรหัสเพื่อใช้ในการผลิต


7

ตั้งแต่ถามคำถามนี้ฉันได้ตัดสินวิธีแก้ปัญหาซึ่งฉันใช้ในการพัฒนาแอปพลิเคชันขนาดเล็กกับทีมงานขนาดเล็ก

git-crypt

git-crypt ใช้ GPG เพื่อเข้ารหัสไฟล์อย่างโปร่งใสเมื่อชื่อตรงกับรูปแบบบางอย่าง สำหรับความตั้งใจถ้าคุณเพิ่มลงใน.gitattributesไฟล์ของคุณ...

*.secret.* filter=git-crypt diff=git-crypt

... แล้วไฟล์เช่น config.secret.jsonจะถูกผลักไปยัง repos ระยะไกลด้วยการเข้ารหัสเสมอ แต่จะยังคงไม่ได้เข้ารหัสในระบบไฟล์ภายในของคุณ

ถ้าผมต้องการที่จะเพิ่มคีย์จีพีจีใหม่ (บุคคล) เพื่อ repo git-crypt add-gpg-user <gpg_user_key>ของคุณที่สามารถถอดรหัสไฟล์ที่มีการป้องกันจากนั้นก็วิ่ง สิ่งนี้จะสร้างคอมมิตใหม่ ผู้ใช้ใหม่จะสามารถถอดรหัสการกระทำที่ตามมาได้


6

โดยทั่วไปฉันถามคำถามนี้ แต่ในกรณีเฉพาะของฉันฉันต้องการเก็บคีย์ลับและรหัสผ่านสำหรับไซต์ Django / Python โดยใช้ git และ github

ไม่เพียง แต่อย่าแม้ว่าจะเป็น repo ส่วนตัวของคุณและคุณไม่เคยตั้งใจที่จะแบ่งปันก็อย่า

คุณควรสร้าง local_settings.py วางไว้บน VCS ละเว้นและใน settings.py ของคุณทำสิ่งที่ชอบ

from local_settings import DATABASES, SECRET_KEY
DATABASES = DATABASES

SECRET_KEY = SECRET_KEY

หากการตั้งค่าความลับของคุณนั้นมีประโยชน์มากมายฉันอยากจะบอกว่าคุณทำอะไรผิดพลาด


9
แต่ฉันยังคงต้องติดตามความลับเหล่านั้นอยู่ที่ไหนสักแห่ง เช่นคีย์พาสหรืออะไรบางอย่างตามเส้นเหล่านั้นใช่ไหม?
Chris W.

กฎระเบียบและการดำเนินการจัดเก็บข้อมูลส่วนตัวขึ้นอยู่กับนโยบายของ บริษัท ที่ทำโครงการ ฉันสงสัยอย่างมากว่าซอร์สโค้ดของโครงการเป็นสถานที่ที่เหมาะสมเนื่องจากผู้ทดสอบหรือโปรแกรมเมอร์บุคคลที่สามสามารถเห็นสิ่งเหล่านี้
Hedde van der Heide

4

แก้ไข: ฉันคิดว่าคุณต้องการติดตามรหัสผ่านรุ่นก่อนหน้าของคุณเช่นสำหรับสคริปต์ที่จะป้องกันไม่ให้ใช้รหัสผ่านซ้ำ

ฉันคิดว่า GnuPG เป็นวิธีที่ดีที่สุด - มันถูกใช้ในโปรเจ็กต์ที่เกี่ยวข้องกับคอมไพล์แล้ว (git-annex) เพื่อเข้ารหัสเนื้อหาที่เก็บที่จัดเก็บไว้ในบริการคลาวด์ GnuPG (gnu pgp) ให้การเข้ารหัสตามคีย์ที่แข็งแกร่งมาก

  1. คุณเก็บคีย์ไว้ในเครื่องของคุณ
  2. คุณเพิ่ม 'mypassword' ในไฟล์ที่ถูกละเว้น
  3. บนเบ็ดก่อนคอมมิตคุณเข้ารหัสไฟล์ mypassword ลงในไฟล์ mypassword.gpg ที่ติดตามโดย git และเพิ่มลงในคอมมิต
  4. บนเบ็ดหลังการรวมคุณเพียงแค่ถอดรหัส mypassword.gpg เป็น mypassword

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

ในภายหลังคุณสามารถใช้. gitattributes เพื่อทำการถอดรหัสได้ทันทีสำหรับการออกจาก git ที่แตกต่างของรหัสผ่านของคุณ

นอกจากนี้คุณสามารถมีคีย์แยกต่างหากสำหรับรหัสผ่านประเภทต่างๆเป็นต้น


3

โดยปกติฉันแยกรหัสผ่านเป็นไฟล์กำหนดค่า และทำให้พวกเขาห่างไกล

/yourapp
    main.py
    default.cfg.dist

และเมื่อฉันเรียกใช้main.pyให้ใส่รหัสผ่านจริงdefault.cfgที่คัดลอก

ปล. เมื่อคุณทำงานกับคอมไพล์หรือ hg คุณสามารถละเว้น*.cfgไฟล์ที่จะสร้าง.gitignoreหรือ.hgignore


ไฟล์. dist คือสิ่งที่ฉันกำลังพูดถึง: ตัวอย่างไฟล์กำหนดค่าจริง แนวทางปฏิบัติที่ดีคือควรจะสามารถเรียกใช้ซอฟต์แวร์ได้โดยการเปลี่ยนชื่อโดยการลบส่วนขยาย ".dist" ออก (หรือดีกว่า: การคัดลอก) นั่นคือคุณควรจะสามารถลองใช้ซอฟต์แวร์ได้ภายในไม่กี่วินาทีโดยไม่ต้องกำหนดค่าในระหว่าง ตลอดทั้งวัน.
tiktak

3

ระบุวิธีการลบล้างการกำหนดค่า

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

ตัวแปรสภาพแวดล้อม (ตามที่คนอื่น ๆ ได้กล่าวไปแล้ว) เป็นวิธีหนึ่งในการดำเนินการ

วิธีที่ดีที่สุดคือมองหาไฟล์กำหนดค่าภายนอกที่แทนที่ค่ากำหนดค่าเริ่มต้น สิ่งนี้ช่วยให้คุณจัดการการกำหนดค่าภายนอกผ่านระบบการจัดการการกำหนดค่าเช่น Chef, Puppet หรือ Cfengine การจัดการการกำหนดค่าเป็นคำตอบมาตรฐานสำหรับการจัดการคอนฟิกแยกจากโค้ดเบสดังนั้นคุณจึงไม่ต้องทำรีลีสเพื่ออัปเดตการกำหนดค่าบนโฮสต์เดียวหรือกลุ่มโฮสต์

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


2

เข้ารหัสไฟล์รหัสผ่านโดยใช้ตัวอย่างเช่น GPG เพิ่มคีย์บนเครื่องของคุณและบนเซิร์ฟเวอร์ของคุณ ถอดรหัสไฟล์และวางไว้นอกโฟลเดอร์ repo ของคุณ

ฉันใช้ passwords.conf ซึ่งอยู่ในโฟลเดอร์บ้านของฉัน ทุกครั้งที่ปรับใช้ไฟล์นี้จะได้รับการอัปเดต


จากนั้นซอฟต์แวร์จำเป็นต้องถอดรหัสไฟล์รหัสผ่าน
tiktak

เมื่อปรับใช้ไซต์รหัสผ่านจะถูกถอดรหัสและเขียนลงในไฟล์รหัสผ่านข้อความธรรมดาเท่านั้น
Willian

2

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

เริ่มต้นด้วย Django 1.4 ตอนนี้โครงการ Django ของคุณมาพร้อมกับproject.wsgiโมดูลที่กำหนดapplicationวัตถุและเป็นสถานที่ที่สมบูรณ์แบบในการเริ่มบังคับใช้project.localโมดูลการตั้งค่าที่มีการกำหนดค่าเฉพาะไซต์

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

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.local")

# This application object is used by the development server
# as well as any WSGI server configured to use this file.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

ตอนนี้คุณสามารถมีlocal.pyโมดูลที่สามารถกำหนดค่าเจ้าของและกลุ่มเพื่อให้เฉพาะบุคลากรที่ได้รับอนุญาตและกระบวนการ Django เท่านั้นที่สามารถอ่านเนื้อหาของไฟล์ได้


2

หากคุณต้องการ VCS สำหรับความลับของคุณอย่างน้อยคุณควรเก็บไว้ในที่เก็บที่สองโดยแยกออกจากรหัสจริงของคุณ ดังนั้นคุณสามารถให้สมาชิกในทีมของคุณเข้าถึงที่เก็บซอร์สโค้ดและพวกเขาจะไม่เห็นข้อมูลประจำตัวของคุณ นอกจากนี้เจ้าภาพบางแห่งพื้นที่เก็บข้อมูลอื่น ๆ (เช่น. บนเซิร์ฟเวอร์ของคุณเองด้วยระบบไฟล์ที่เข้ารหัสไม่ได้อยู่บน GitHub) และสำหรับการตรวจสอบออกไปยังระบบการผลิตที่คุณสามารถใช้สิ่งที่ต้องการ-git submodule


1

อีกวิธีหนึ่งอาจเป็นการหลีกเลี่ยงการบันทึกความลับในระบบควบคุมเวอร์ชันโดยสิ้นเชิงและใช้เครื่องมือเช่นห้องนิรภัยจาก hashicorpซึ่งเป็นที่เก็บข้อมูลลับที่มีการกลิ้งคีย์และการตรวจสอบด้วย API และการเข้ารหัสแบบฝัง


1

นี่คือสิ่งที่ฉันทำ:

  • เก็บความลับทั้งหมดไว้เป็น env vars ใน $ HOME / .secrets (go-r perms) ที่มา $ HOME / .bashrc (วิธีนี้หากคุณเปิด. bashrc ต่อหน้าใครบางคนพวกเขาจะไม่เห็นความลับ)
  • ไฟล์คอนฟิกูเรชันถูกเก็บไว้ใน VCS เป็นเทมเพลตเช่น config.properties ที่จัดเก็บเป็น config.properties.tmpl
  • ไฟล์เทมเพลตมีตัวยึดสำหรับข้อมูลลับเช่น:

    my.password = ## MY_PASSWORD ##

  • ในการปรับใช้แอปพลิเคชันสคริปต์จะถูกรันที่แปลงไฟล์เทมเพลตเป็นไฟล์เป้าหมายแทนที่ตัวยึดตำแหน่งด้วยค่าของตัวแปรสภาพแวดล้อมเช่นเปลี่ยน ## MY_PASSWORD ## เป็นค่า $ MY_PASSWORD


0

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.