ASSETS ART
บล็อกทั้งหมดAll posts

วิศวกรรมEngineeringอ่าน 7 นาที7 min readมีตัวอย่างให้ลองTry it inside

ชี้โดเมนของคุณมาที่แอป แล้ว HTTPS มาได้ยังไงPointing your own domain at an app, and where the HTTPS comes from

โดย ทีมวิศวกรรม Assets ArtBy Assets Art Engineering

ขนาดตัวอักษรText size

คุณมีโดเมน shop.example.com กับแอปที่ deploy แล้ว อยากให้คนเปิดโดเมนนั้นแล้วเจอแอป พร้อมกุญแจ HTTPS ที่ถูกต้อง บทความนี้ตามไปทีละขั้น ว่าคุณทำอะไร ระบบตรวจอะไร และใบรับรองมาจากไหน แล้วบอกตรง ๆ ว่าตรงไหนที่เราเคยวางแผนไว้แต่ยังไม่ได้สร้างYou have a domain, shop.example.com, and an app that is already deployed. You want anyone who opens that domain to reach the app, with a valid HTTPS lock. This post goes step by step: what you do, what the system checks, and where the certificate comes from. It also says plainly where we planned something and have not built it.

แอปมีที่อยู่ของตัวเองอยู่แล้วThe app already has an address

แอปทุกตัวได้ชื่อ <label>.app.asart.dev ตอนสร้าง label ยาว 3 ถึง 55 ตัวอักษร ใช้ a-z 0-9 และ - ได้ ห้ามขึ้นหรือลงท้ายด้วย - ห้ามมี -- ติดกัน และมีคำสงวนอย่าง www api admin ซ้ำกับแอปที่ยังอยู่ไม่ได้ ชื่อนี้มี HTTPS ให้เลยด้วยใบรับรองกลางของแพลตฟอร์มEvery app gets a name <label>.app.asart.dev when it is created. A label is 3 to 55 characters of a-z 0-9 and -, with no leading or trailing -, no -- in a row, and a list of reserved words such as www api admin. It cannot repeat the label of a live app. This name has HTTPS straight away, from the platform's own certificate.

โดเมนของคุณจึงไม่ต้องรู้ IP ไหนเลย คุณชี้ไปที่ชื่อนี้ ถ้าเราย้ายประตูหน้าไปเครื่องกลุ่มอื่น คำตอบ DNS ของเราเปลี่ยนตาม โดยคุณไม่ต้องแก้อะไรSo your domain never needs to know an IP. You point at this name, and if we move the front door to another group of machines, our DNS answer changes with it and you change nothing.

สองเรคอร์ดที่คุณต้องตั้งThe two records you set

เมื่อคุณเพิ่มโดเมนให้แอป ระบบบันทึกว่าแอปนี้อ้างโดเมนนั้น แล้วให้ค่ามาตั้งที่ผู้ให้บริการ DNS ของคุณ เป็นเรคอร์ด ชื่อ _aa-verify.example.com ที่มีค่าเป็น token ยาว 32 ตัวอักษร และ จาก shop ไปที่ <label>.app.asart.devถ้าเป็นโดเมนหลักเปล่า ๆ (example.com) ให้ใช้ ALIAS, ANAME หรือ CNAME flattening ของผู้ให้บริการคุณ เพราะเราไม่ให้ IP ไปตั้งเป็น A recordWhen you add a domain to an app, the system records that the app claims it, and gives you values to set at your DNS provider: a record named _aa-verify.example.com whose value is a 32-character token, and a from shop to <label>.app.asart.dev. For the bare domain (example.com) use your provider's ALIAS, ANAME or CNAME flattening, because we do not hand out an IP to put in an A record.

TXT หนึ่งตัวพอสำหรับทั้งโดเมน ถ้ามี shop กับ blog ใต้โดเมนเดียวกัน เพราะเราพิสูจน์ความเป็นเจ้าของระดับโดเมน ไม่ใช่ทีละชื่อ ลองดูว่าขาดตัวไหนแล้วเกิดอะไรOne TXT is enough for the whole domain if you have shop and blog under it, because we prove ownership of the domain, not of each name. See what happens when one is missing.

ลองเลยTry itตั้ง DNS แล้วเกิดอะไรขึ้นSet your DNS and see what happens
https://shop.example.com
เบราว์เซอร์ขึ้นข้อความว่าเชื่อมต่ออย่างปลอดภัยไม่ได้The browser says it cannot make a secure connection
เพราะอะไรWhy
owner
ยังไม่เห็น TXT · ไม่ส่ง traffic ของโดเมนนี้มาที่แอปNo TXT yet · none of this domain's traffic is sent to the app
route
ไม่มี CNAME · คนเปิดโดเมนแล้วไม่มาถึงเรา (เราไม่ตรวจเรื่องนี้ให้)No CNAME · visitors do not come to us (we do not check this for you)
cert
ยังไม่ขอ · โดเมนยังไม่ผ่านขั้นแรกNot asked for yet · the domain has not passed the first step
https
เชื่อมต่ออย่างปลอดภัยไม่ได้ · ไม่มีใบรับรองของชื่อนี้No secure connection · there is no certificate for this name
จำลองในเบราว์เซอร์ตามกติกาในบทความ ระบบจริงใช้เวลาตรวจ TXT ตามที่เล่าไว้ ตัวอย่างนี้ตัดเวลาออกA simulation in your browser, following the rules in the post. The real system takes the checking time described there; the demo leaves it out.

ระบบตรวจอะไร และไม่ตรวจอะไรWhat is checked, and what is not

ระบบตรวจ TXT เองทุกประมาณ 30 วินาที ถ้ายังไม่เห็นก็ลองใหม่ที่ 120 วินาที แล้วห่างขึ้นเรื่อย ๆ จนสุดที่หนึ่งชั่วโมง คุณสั่งให้ตรวจเดี๋ยวนั้นแทนการรอรอบได้ เป็นการตรวจแบบเดียวกัน จึงผ่านก็ต่อเมื่อ TXT พร้อมแล้ว เงื่อนไขผ่านคือต้องเห็น TXT ครบจากทุก resolver ที่ตั้งไว้ ค่าเริ่มต้นคือ 1.1.1.1 และ 8.8.8.8 เฉพาะโดเมนที่ผ่านแล้วเท่านั้นที่ระบบส่ง traffic ให้The system checks the TXT by itself about every 30 seconds. If it does not see it yet, it retries at 120 seconds and backs off up to one hour. You can ask for the check to run now instead of waiting for the next round. It is the same check, so it passes only if the TXT is already visible at every configured resolver, 1.1.1.1 and 8.8.8.8 by default. Only domains that have passed get any traffic.

มีสองเรื่องที่คนมักเข้าใจผิด เรื่องแรก เราไม่ตรวจ CNAME ของคุณ ถ้าตั้งผิด ระบบไม่บอก คุณรู้จากหน้าเว็บที่ไม่ขึ้นเท่านั้น เรื่องที่สอง TXT ไม่ใช่ใช้ครั้งเดียวแล้วจบ ระบบดูซ้ำทุกวัน ถ้าหายไปเจ็ดครั้งติดกัน (ราวหนึ่งสัปดาห์) สถานะกลับเป็นรอตรวจ และชื่อใต้โดเมนนั้นหยุดได้ trafficTwo things people tend to get wrong. First, we do not check your CNAME. If it is wrong the system does not say so; you find out because the page does not load. Second, the TXT is not once and done. The system looks again every day, and if it is missing seven times in a row (about a week), the status goes back to pending and the names under that domain stop getting traffic.

ถ้าองค์กรอื่นพิสูจน์โดเมนเดียวกันทีหลัง ผลขึ้นกับว่าเจ้าของเดิมมีชื่อที่ใช้งานอยู่ไหม ถ้าไม่มี คนที่พิสูจน์ล่าสุดได้โดเมนไป ถ้ามี โดเมนเข้าสถานะ "โต้แย้ง" ค้างไว้จนผู้ดูแลระบบ ปล่อยให้If another organization proves the same domain later, the result depends on whether the current holder has a name in live use. If not, the most recent proof takes the domain. If so, the domain goes to a "contested" state and stays there until an operator releases it.

ใบรับรองมาจากไหนWhere the certificate comes from

เมื่อโดเมนผ่าน ระบบส่งเส้นทางของชื่อนั้นไปที่ประตูหน้า ประตูหน้าเห็นชื่อใหม่ที่ยังไม่มีใบรับรอง จึงขอจาก Let's Encrypt ด้วยวิธีที่เรียกว่า HTTP-01 Let's Encrypt เรียกที่อยู่/.well-known/acme-challenge/<token> ผ่านพอร์ต 80 ของชื่อคุณ และประตูหน้าตอบ token กลับ ประตูหน้าตอบ token เฉพาะชื่อที่มันตั้งไว้ให้ ไม่ตอบข้ามชื่อOnce the domain passes, the system sends that name's route to the front door. The front door sees a new name with no certificate and asks Let's Encrypt for one with a method called HTTP-01: Let's Encrypt requests /.well-known/acme-challenge/<token> over port 80 of your name, and the front door answers with the token. It answers a token only for the name it was set for, never across names.

วิธีนี้มีเงื่อนไขสองข้อ ข้อแรก การทดสอบของ Let's Encrypt ต้องมาถึงเรา ซึ่งหมายถึง CNAME ต้องถูก ข้อสอง พอร์ต 80 ต้องเปิด HTTP-01 อย่างเดียวคือสิ่งที่มีวันนี้ ไม่มี DNS-01 สำหรับโดเมนของลูกค้า เรายังไม่มีเทสที่ครอบทั้งสายตั้งแต่ CNAME จนได้ HTTPS ในรอบเดียว มีแต่เทสแยกทีละท่อน1This has two conditions. First, Let's Encrypt's check has to reach us, which means the CNAME must be right. Second, port 80 must be open. HTTP-01 is all there is today; there is no DNS-01 for customer domains. We do not have a test that covers the whole path from CNAME to HTTPS in one run, only tests of the separate pieces.1

ได้ใบแล้ว ประตูหน้าตรวจทุกนาทีว่าใบไหนเหลือไม่เกิน 30 วัน และต่ออายุให้ ถ้าขอไม่สำเร็จ รอ 60 วินาทีแล้วเพิ่มเป็นสองเท่าต่อครั้ง สุดที่หนึ่งชั่วโมง ต่อชื่อ ถ้าคุณลบโดเมนออกจากแอป ใบรับรองและกุญแจของชื่อนั้นถูกลบด้วยOnce issued, the front door checks every minute for certificates with 30 days or less left and renews them. If an order fails, it waits 60 seconds and doubles the wait each time up to one hour, per name. If you remove the domain from the app, that name's certificate and key are deleted too.

ตอนคนเปิดเว็บ ประตูหน้าเลือกใบจากชื่อที่เบราว์เซอร์ส่งมาตอนเริ่มเชื่อมต่อ () ตามลำดับ ใบที่อัปโหลด ใบจาก Let's Encrypt แล้วจึงใบกลางของแพลตฟอร์ม ถ้าไม่มีชื่อมา หรือไม่มีใบสำหรับชื่อนั้น การเชื่อมต่อล้มเหลว เราไม่ตอบด้วยใบของชื่ออื่นแทน ชื่อที่ไม่มีเส้นทางได้ 404 และคำขอ HTTP ธรรมดาของชื่อที่มีเส้นทางถูกเปลี่ยนเป็น HTTPS ด้วย 301When someone opens the site, the front door picks a certificate from the name the browser sends as it starts the connection (), in this order: an uploaded certificate, one from Let's Encrypt, then the platform's own. With no name, or no certificate for that name, the connection fails; we do not answer with another name's certificate instead. A name with no route gets a 404, and a plain HTTP request for a name that has a route is redirected to HTTPS with a 301.

ที่ยังไม่มีWhat does not exist yet

เอกสารแผนของเราพูดถึงหลายอย่างที่ระบบยังไม่ทำ ขอแยกให้ชัดOur planning documents describe several things the system does not do yet. Plainly:

  • อัปโหลดใบรับรองของคุณเอง (รวมถึง Origin CA ของ Cloudflare) ตอนนี้ยังไม่มีทางส่งใบมาถึงจากฝั่งผู้ใช้ ประตูหน้าตรวจใบที่ได้รับได้ถูกต้อง แต่ยังไม่มีทางส่งมาให้Uploading your own certificate (including a Cloudflare Origin CA certificate) has no path from the user's side yet. The front door checks an uploaded certificate correctly, but nothing delivers one.
  • เตือนใบที่อัปโหลดใกล้หมดอายุ ยังไม่ได้ต่อสายExpiry warnings for uploaded certificates are not wired in.
  • ใช้ Cloudflare เป็นตัวกลาง (proxied) พร้อม Authenticated Origin Pulls ประตูหน้าตัดสินใจต่อชื่อได้ แต่ฝั่งที่ออกใบรับรองไคลเอนต์ให้ยังไม่มี เส้นทางที่ใช้ได้จริงวันนี้คือชี้ DNS ตรงมาที่เราแล้วใช้ Let's EncryptPutting Cloudflare in front (proxied) with Authenticated Origin Pulls: the front door can decide per name, but the side that issues the client certificates does not exist yet. The path that works today is pointing DNS straight at us and using Let's Encrypt.
  • ตรวจ CNAME และเตือนเรื่อง proxy วนลูป ยังไม่มีA CNAME check, and a warning about a proxy loop, do not exist.

เชิงอรรถFootnotes

  1. 1ใบรับรองกลางของ *.app.asart.dev ออกด้วยวิธีอื่นที่ใช้ DNS ซึ่งเป็นของแพลตฟอร์มเอง ไม่เกี่ยวกับโดเมนของลูกค้าThe platform's own *.app.asart.dev certificate is issued by another method that uses DNS, which belongs to the platform and has nothing to do with customer domains. กลับไปที่ข้อความBack to the text

เรื่องอื่นในหมวด วิศวกรรมMore in Engineering