การขอใบรับรองดิจิตอล (CA; Certification Authority) เพื่อเข้ารหัส website ให้เป็น HTTPS แสดงเป็นกุญแจเขียวตรง address bar ซึ่งหมายถึงว่า ผู้อ่านเวบไซต์ปลอดภัยจากการโจมตีความเป็นส่วนตัวระดับหนึ่ง ข้อมูลที่รับส่งระหว่างเวบไซต์กับผู้เปิดดูได้รับการเข้ารหัส
การเข้ารหัสเวบมีความสำคัญขึ้นอย่างมากดังจะเห็นได้จากข่าวนี้ New York Times ชวนสำนักข่าวทุกสำนัก เปิด HTTPS ภายในปี 2015; blognone เป็นต้น
Eitan Konigsburg วิศวกรซอฟต์แวร์ของ New York Times ออกมาเขียนบล็อกถึงประเด็นความเป็นส่วนตัวของผู้อ่านว่ามีความสำคัญมากขึ้นเรื่อยๆ จากการโจมตีรูปแบบต่างๆ ตั้งแต่การติดตามผู้ใช้ทำให้เสียความเป็นส่วนตัว ไปจนถึงการเปลี่ยนข้อมูลบนเว็บข่าว
แต่ก่อนจนถึงตอนนี้ถ้าอยากได้ใบรับรองจากตัวแทนจะมีค่าใช้จ่าย เช่นหากจะไปขอใบรับรองจาก VeriSign ขอใบรับรองแบบ domain varification (แบบที่ LE ให้) 1 ปี เราจะต้องจ่าย 39 USD แต่ถ้าใช้ LetsEncrypt เราสามารถขอใบรับรองได้ฟรี
ทำไมฟรี?
Let’s Encrypt ให้บริการฟรีได้ ส่วนหนึ่งเพราะมันทำให้กระบวนการต่างๆ ทำได้ด้วยตัวเองได้โดยผู้ใช้ (มีสคริปต์มาให้รันเองได้ และในอนาคตจะเป็นระบบอัตโนมัติมากขึ้น) ค่าใช้จ่ายก็เลยถูกลง และอีกส่วนหนึ่งเพราะมีองค์กรหลายแห่งสนับสนุนเงินทุน รวมๆ คือคนเหล่านี้อยากเห็นอินเทอร์เน็ตที่มันปลอดภัยขึ้น
จาก bact.cc ครับ
ตอนแรก google หาวิธีทำ เช่น มาเล่น Let’s Encrypt กัน และของชาวต่างๆชาติ ล้วนแต่รันใน server ที่ต้องการ HTTPS แค่ติดตั้ง client รัน script มันจะทำทุกอย่างให้อัตโนมัติ กว่าจะได้วิธีและเนื้อหานี้มาก็มึนไปอาทิตย์กว่า
พูดมากไปหน่อย เข้าขั้นตอนทำกันดีกว่า
วิธีทำ
วิธีที่ผมใช้และนำเสนอใน post นี้ letsencrypt client ไม่ได้ลง/ติดตั้งที่ server ที่จะใช้ HTTPS
ก็คือ จะขอ cert ที่เครื่อง A เอาไปใช้กับ server B
ผมใช้ Ubuntu guest vm (virtualbox) ในการติดตั้ง letsencrypt client
ติดตั้ง letsencrypt client พิมพ์คำสั่งตามนี้
# Clone the repo
git clone https://github.com/letsencrypt/letsencrypt
# Push into the direcotry
pushd letsencrypt
# Run the automated installer (see wait times above)
time ./letsencrypt-auto
ถ้ามีปัญหาลองอ่านเพิ่มเติมจาก Let’s Encrypt on Raspberry Pi (and Ubuntu Linux, etc)
การทำแบบ “ขอ cert ที่เครื่อง A เอาไปใช้กับ server B” นี้ option ที่ใส่เข้าไป คือ
certonly --manual
ที่ Terminal พิมพ์คำสั่ง
sudo ~/.local/share/letsencrypt/bin/letsencrypt certonly --agree-tos --email example@gmail.com --domains redmine.example.com --manual
ข้อสังเกต:
--email example@gmail.com
ตัวนี้ก็ใช้ email ของใครของมันนะ
กด Enter รันคำสั่งแล้ว จะมี window ขึ้นมาถามว่า IP เครื่องที่ใช้จะถูกบันทึกเก็บไว้ (logged) นะ?
ให้ตอบ Yes
แล้วจะมีข้อความตามกล่องข้างล่างนี้ ที่จะแตกต่างกันคือ
- domain name ผมใช้
redmine.example.com
แทนข้อมูลจริง - Hash
dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0
แต่ละครั้งที่ทำมันจะได้ไม่เหมือนกัน
Make sure your web server displays the following content at
http://redmine.example.com/.well-known/acme-challenge/dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0 before continuing:
dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0.S3d81OJkYOCUOuNBhHdd2EfmxWlq6IInmA_B14mjPGc
If you don't have HTTP server configured, you can run the following
command on the target server (as root):
mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0.S3d81OJkYOCUOuNBhHdd2EfmxWlq6IInmA_B14mjPGc > .well-known/acme-challenge/dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"
Press ENTER to continue
ข้อความเป็นแบบนี้
Make sure your web server displays the following content at http://redmine.example.com/.well-known/acme-challenge/dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0
ก่อนจะกด ENTER ให้แน่ใจว่า สามารถแสดงข้อความนี้ ใน browser ได้
dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0.S3d81OJkYOCUOuNBhHdd2EfmxWlq6IInmA_B14mjPGc
โดยใช้ URL ที่ console ให้มา ซึ่งก็คือ URL นี้ http://redmine.example.com/.well-known/acme-challenge/dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0
)
วิธีที่ทำให้มันสามารถแสดงข้อความได้ มี 2 ทาง
วิธีแรก ถ้า server ยังไม่ได้ติดตั้ง apache, nginx, etc. เลย ให้เอาคำสั่งที่แนะนำ มารันเพื่อจำลอง web server ที่ port 80 เพือให้ LestEncrypt สามารถยืนยัน domain ที่เราขอไปได้
สร้างไฟล์
mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0.S3d81OJkYOCUOuNBhHdd2EfmxWlq6IInmA_B14mjPGc > .well-known/acme-challenge/dNaFjetvapR2WmRGeQEDeEb8P54Z8q-aw9izpEafej0
รันคำสั่งเพื่อจำลอง web server
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"
วิธีที่2 ผมมี apache2 อยู่แล้ว จึงเอาไฟล์ q8uaHQM7kzZ9t4fxVJ4BmmrUk-6VwAwEkFDjK0sLl0Q
ไปวางที่ server
ขั้นตอนคร่าวๆ ดังนี้
log in เข้า http server ไปที่ public root folder ซึ่งของผมอยู่ที่ /var/www/html
ต้องเป็น root หรือ account ที่มีสิทธิเขียนไฟล์ลง folder นี้ได้นะครับ
สร้าง folder .well-known/acme-challenge
cd /var/www/html
mkdir .well-known/acme-challenge
สร้างไฟล์ พร้อมเนื้อหา
printf "%s" q8uaHQM7kzZ9t4fxVJ4BmmrUk-6VwAwEkFDjK0sLl0Q.S3d81OJkYOCUOuNBhHdd2EfmxWlq6IInmA_B14mjPGc > .well-known/acme-challenge/q8uaHQM7kzZ9t4fxVJ4BmmrUk-6VwAwEkFDjK0sLl0Q
เมื่อทดสอบเรียก URL http://redmine.example.com/.well-known/acme-challenge/q8uaHQM7kzZ9t4fxVJ4BmmrUk-6VwAwEkFDjK0sLl0Q
ใน browser
จะต้องแสดงเนื้อหาแบบนี้
หลังจากนั้น ไปกด ENTER ที่ terminal รอซักแป๊บ เมื่อทำเสร็จจะได้ข้อความแบบนี้
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/redmine.example.com/fullchain.pem. Your cert will
expire on 2016-03-23. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.
- If like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
เอาล่ะ ตรวจสอบๆ ได้ไฟล์ certificate มาหรือยัง ไฟล์ที่ได้ออกมาจะอยู่ที่ folder /etc/letsencrypt/live/[your domain name]
ls /etc/letsencrypt/live/redmine.example.com/
cert1.pem chain1.pem fullchain1.pem privkey1.pem
หลังจากนั้นเอาไฟล์ไปไว้ที่ apache2 server ใน คู่มือของ letsencrypt ก็มีบอกเอาไว้ ไฟล์ไหนคืออะไร ใช้กับบรรทัดไหน
apache2 แก้ 3 บรรทัดนี้ เราจะใช้แค่ 3 ไฟล์
SSLCertificateFile "/home/apps/drupal-7.12-1/apache2/conf/cms/cert1.pem"
SSLCertificateKeyFile "/home/apps/drupal-7.12-1/apache2/conf/cms/privkey1.pem"
SSLCertificateChainFile "/home/apps/drupal-7.12-1/apache2/conf/cms/chain1.pem"
เมื่อ แก้ไขไฟล์ config ssl เรียบร้อยแล้ว restart apache ครั้งนึงก่อน ถ้าไม่มีข้อความฟ้องปัญหาอะไร
ทดสอบเรียก https ได้เลย
ใช้ได้แล้ว … เย้!
ท้ายสุด หลังจากใช้ได้แล้ว ผมลบ hash file ออกจาก server และเปลี่ยน permission ของ .well-know ให้ไม่สามารถเข้าถึงได้จาก internet
ตอนต่อไป จะเสนอวิธีแก้ไข “Your connection to XXX encrypted using an obsolete cipher suite”