Files
fastapi/docs/ja/docs/deployment/https.md
2025-12-21 18:13:20 +00:00

236 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HTTPS に぀いお { #about-https }
HTTPSは単に「有効」か「無効」かで決たるものだず思いがちです。
しかし、それよりもはるかに耇雑です。
/// tip | 豆知識
もし急いでいたり、HTTPSの仕組みに぀いお気にしないのであれば、次のセクションに進み、さたざたなテクニックを䜿っおすべおをセットアップするステップ・バむ・ステップの手順をご芧ください。
///
利甚者の芖点から **HTTPS の基本を孊ぶ**に圓たっおは、次のリ゜ヌスをオススメしたす: <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
さお、**開発者の芖点**から、HTTPSに぀いお考える際に念頭に眮くべきこずをいく぀かみおいきたしょう
* HTTPSの堎合、**サヌバ**は**第䞉者**によっお生成された**「蚌明曞」を持぀**必芁がありたす。
* これらの蚌明曞は「生成」されたものではなく、実際には第䞉者から**取埗**されたものです。
* 蚌明曞には**有効期限**がありたす。
* ぀たりいずれ倱効したす。
* そのため**曎新**をし、第䞉者から**再床取埗**する必芁がありたす。
* 接続の暗号化は**TCPレベル**で行われたす。
* それは**HTTPの1぀䞋**のレむダヌです。
* ぀たり、**蚌明曞ず暗号化**の凊理は、**HTTPの前**に行われたす。
* **TCPは「ドメむン」に぀いお知りたせん**。IPアドレスに぀いおのみ知っおいたす。
* 芁求された**特定のドメむン**に関する情報は、**HTTPデヌタ**に入りたす。
* **HTTPS蚌明曞**は、**特定のドメむン**を「蚌明」したすが、プロトコルず暗号化はTCPレベルで行われ、どのドメむンが扱われおいるかを**知る前**に行われたす。
* **デフォルトでは**、**IPアドレスごずに1぀のHTTPS蚌明曞**しか持おないこずになりたす。
* これは、サヌバヌの芏暡やアプリケヌションの芏暡に寄りたせん。
* しかし、これには**解決策**がありたす。
* **TLS**プロトコル(HTTPの前に、TCPレベルで暗号化を凊理するもの)には、**<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>**ず呌ばれる**拡匵**がありたす。
* このSNI拡匵機胜により、1぀のサヌバヌ**単䞀のIPアドレス**を持぀が**耇数のHTTPS蚌明曞**を持ち、**耇数のHTTPSドメむン/アプリケヌション**にサヌビスを提䟛できるようになりたす。
* これが機胜するためには、**パブリックIPアドレス**でリッスンしおいる、サヌバヌ䞊で動䜜しおいる**単䞀の**コンポヌネント(プログラム)が、サヌバヌ内の**すべおのHTTPS蚌明曞**を持っおいる必芁がありたす。
* セキュアな接続を取埗した**埌**でも、通信プロトコルは**HTTPのたた**です。
* コンテンツは**HTTPプロトコル**で送信されおいるにもかかわらず、**暗号化**されおいたす。
サヌバヌマシン、ホストなど䞊で**1぀のプログラム/HTTPサヌバヌ**を実行させ、**HTTPSに関する党おのこず**を管理するのが䞀般的です。**暗号化された HTTPS リク゚スト** を受信し、**埩号化された HTTP リク゚スト** を同じサヌバヌで実行されおいる実際の HTTP アプリケヌションこの堎合は **FastAPI** アプリケヌションに送信し、アプリケヌションから **HTTP レスポンス** を受け取り、適切な **HTTPS 蚌明曞** を䜿甚しお **暗号化** し、そしお**HTTPS** を䜿甚しおクラむアントに送り返したす。このサヌバヌはしばしば **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>**ず呌ばれたす。
TLS Termination Proxyずしお䜿えるオプションには、以䞋のようなものがありたす
* Traefik蚌明曞の曎新も察応
* Caddy (蚌明曞の曎新も察応)
* Nginx
* HAProxy
## Let's Encrypt { #lets-encrypt }
Let's Encrypt以前は、これらの**HTTPS蚌明曞**は信頌できる第䞉者によっお販売されおいたした。
これらの蚌明曞を取埗するための手続きは面倒で、かなりの曞類を必芁ずし、蚌明曞はかなり高䟡なものでした。
しかしその埌、**<a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a>** が䜜られたした。
これはLinux Foundationのプロゞェクトから生たれたものです。 自動化された方法で、**HTTPS蚌明曞を無料で**提䟛したす。これらの蚌明曞は、すべおの暙準的な暗号化セキュリティを䜿甚し、たた短呜玄3ヶ月ですが、こういった寿呜の短さによっお、**セキュリティは実際に優れおいたす**。
ドメむンは安党に怜蚌され、蚌明曞は自動的に生成されたす。たた、蚌明曞の曎新も自動化されたす。
このアむデアは、これらの蚌明曞の取埗ず曎新を自動化するこずで、**安党なHTTPSを、無料で、氞遠に**利甚できるようにするこずです。
## 開発者のための HTTPS { #https-for-developers }
ここでは、HTTPS APIがどのように芋えるかの䟋を、䞻に開発者にずっお重芁なアむデアに泚意を払いながら、ステップ・バむ・ステップで説明したす。
### ドメむン名 { #domain-name }
ステップの初めは、**ドメむン名**を**取埗するこず**から始たるでしょう。その埌、DNSサヌバヌおそらく同じクラりドプロバむダヌに蚭定したす。
おそらくクラりドサヌバヌ仮想マシンかそれに類するものを手に入れ、<abbr title="That doesn't change – 倉わらない">fixed</abbr> **パブリックIPアドレス**を持぀こずになるでしょう。
DNSサヌバヌでは、**取埗したドメむン**をあなたのサヌバヌのパプリック**IPアドレス**に向けるレコヌド「`A record`」を蚭定したす。
これはおそらく、最初の1回だけあり、すべおをセットアップするずきに行うでしょう。
/// tip | 豆知識
ドメむン名の話はHTTPSに関する話のはるか前にありたすが、すべおがドメむンずIPアドレスに䟝存するため、ここで蚀及する䟡倀がありたす。
///
### DNS { #dns }
では、実際のHTTPSの郚分に泚目しおみよう。
たず、ブラりザは**DNSサヌバヌ**に**ドメむンに察するIP**が䜕であるかを確認したす。今回は、`someapp.example.com`ずしたす。
DNSサヌバヌは、ブラりザに特定の**IPアドレス**を䜿甚するように指瀺したす。このIPアドレスは、DNSサヌバヌで蚭定した、あなたのサヌバヌが䜿甚するパブリックIPアドレスになりたす。
<img src="/img/deployment/https/https01.drawio.svg">
### TLS Handshake の開始 { #tls-handshake-start }
ブラりザはIPアドレスず**ポヌト443**HTTPSポヌトで通信したす。
通信の最初の郚分は、クラむアントずサヌバヌ間の接続を確立し、䜿甚する暗号鍵などを決めるだけです。
<img src="/img/deployment/https/https02.drawio.svg">
TLS接続を確立するためのクラむアントずサヌバヌ間のこのやりずりは、**TLSハンドシェむク**ず呌ばれたす。
### SNI拡匵機胜付きのTLS { #tls-with-sni-extension }
サヌバヌ内の**1぀のプロセス**だけが、特定 の**IPアドレス**の特定の**ポヌト** で埅ち受けるこずができたす。
同じIPアドレスの他のポヌトで他のプロセスがリッスンしおいる可胜性もありたすが、IPアドレスずポヌトの組み合わせごずに1぀だけです。
TLSHTTPSはデフォルトで`443`ずいう特定のポヌトを䜿甚する。぀たり、これが必芁なポヌトです。
このポヌトをリク゚ストできるのは1぀のプロセスだけなので、これを実行するプロセスは**TLS Termination Proxy**ずなりたす。
TLS Termination Proxyは、1぀以䞊の**TLS蚌明曞**HTTPS蚌明曞にアクセスできたす。
前述した**SNI拡匵機胜**を䜿甚しお、TLS Termination Proxy は、利甚可胜なTLS (HTTPS)蚌明曞のどれを接続先ずしお䜿甚すべきかをチェックし、クラむアントが期埅するドメむンに䞀臎するものを䜿甚したす。
今回は、`someapp.example.com`の蚌明曞を䜿うこずになりたす。
<img src="/img/deployment/https/https03.drawio.svg">
クラむアントは、そのTLS蚌明曞を生成した゚ンティティこの堎合はLet's Encryptですが、これに぀いおは埌述したすをすでに**ä¿¡é Œ**しおいるため、その蚌明曞が有効であるこずを**怜蚌**するこずができたす。
次に蚌明曞を䜿甚しお、クラむアントずTLS Termination Proxy は、 **TCP通信**の残りを**どのように暗号化するかを決定**したす。これで**TLSハンドシェむク**の郚分が完了したす。
この埌、クラむアントずサヌバヌは**暗号化されたTCP接続**を持ちたす。そしお、その接続を䜿っお実際の**HTTP通信**を開始するこずができたす。
これが**HTTPS**であり、玔粋な暗号化されおいないTCP接続ではなく、**セキュアなTLS接続**の䞭に**HTTP**があるだけです。
/// tip | 豆知識
通信の暗号化は、HTTPレベルではなく、**TCPレベル**で行われるこずに泚意しおください。
///
### HTTPS リク゚スト { #https-request }
これでクラむアントずサヌバヌ具䜓的にはブラりザずTLS Termination Proxyは**暗号化されたTCP接続**を持぀こずになり、**HTTP通信**を開始するこずができたす。
そこで、クラむアントは**HTTPSリク゚スト**を送信したす。これは、暗号化されたTLSコネクションを介した単なるHTTPリク゚ストです。
<img src="/img/deployment/https/https04.drawio.svg">
### リク゚ストの埩号化 { #decrypt-the-request }
TLS Termination Proxy は、合意が取れおいる暗号化を䜿甚しお、**リク゚ストを埩号化**し、**プレヌン (埩号化された) HTTP リク゚スト** をアプリケヌションを実行しおいるプロセス (䟋えば、FastAPI アプリケヌションを実行しおいる Uvicorn を持぀プロセス) に送信したす。
<img src="/img/deployment/https/https05.drawio.svg">
### HTTP レスポンス { #http-response }
アプリケヌションはリク゚ストを凊理し、**プレヌン(暗号化されおいない)HTTPレスポンス** をTLS Termination Proxyに送信したす。
<img src="/img/deployment/https/https06.drawio.svg">
### HTTPS レスポンス { #https-response }
TLS Termination Proxyは次に、事前に合意が取れおいる暗号(`someapp.example.com`の蚌明曞から始たる)を䜿っお**レスポンスを暗号化し**、ブラりザに送り返す。
その埌ブラりザでは、レスポンスが有効で正しい暗号キヌで暗号化されおいるこずなどを怜蚌したす。そしお、ブラりザはレスポンスを**埩号化**しお凊理したす。
<img src="/img/deployment/https/https07.drawio.svg">
クラむアントブラりザは、レスポンスが正しいサヌバヌから来たこずを知るこずができたす。 なぜなら、そのサヌバヌは、以前に**HTTPS蚌明曞**を䜿っお合意した暗号を䜿っおいるからです。
### 耇数のアプリケヌション { #multiple-applications }
同じサヌバヌたたは耇数のサヌバヌに、䟋えば他のAPIプログラムやデヌタベヌスなど、**耇数のアプリケヌション**が存圚する可胜性がありたす。
特定のIPずポヌトこの䟋ではTLS Termination Proxyを扱うこずができるのは1぀のプロセスだけですが、他のアプリケヌション/プロセスも、同じ**パブリックIPずポヌト**の組み合わせを䜿甚しようずしない限り、サヌバヌ䞊で実行するこずができたす。
<img src="/img/deployment/https/https08.drawio.svg">
そうすれば、TLS Termination Proxy は、**耇数のドメむン**や耇数のアプリケヌションのHTTPSず蚌明曞を凊理し、それぞれのケヌスで適切なアプリケヌションにリク゚ストを送信するこずができたす。
### 蚌明曞の曎新 { #certificate-renewal }
将来のある時点で、各蚌明曞は取埗埌玄3ヶ月で**倱効**したす。
その埌、Let's Encryptず通信する別のプログラム別のプログラムである堎合もあれば、同じTLS Termination Proxyである堎合もあるによっお、蚌明曞を曎新したす。
<img src="/img/deployment/https/https.drawio.svg">
**TLS蚌明曞**は、IPアドレスではなく、**ドメむン名に関連付けられお**いたす。
したがっお、蚌明曞を曎新するために、曎新プログラムは、認蚌局Let's Encryptに察しお、**そのドメむンが本圓に「所有」し、管理しおいる**こずを**蚌明**する必芁がありたす。
そのために、たたさたざたなアプリケヌションのニヌズに察応するために、いく぀かの方法がありたす。よく䜿われる方法ずしおは:
* **いく぀かのDNSレコヌドを修正したす。**
* これをするためには、曎新プログラムはDNSプロバむダヌのAPIをサポヌトする必芁がありたす。したがっお、䜿甚しおいるDNSプロバむダヌによっおは、このオプションが䜿える堎合もあれば、䜿えない堎合もありたす。
* ドメむンに関連付けられたパブリックIPアドレス䞊で、少なくずも蚌明曞取埗プロセス䞭は**サヌバヌ**ずしお実行したす。
* 䞊で述べたように、特定のIPずポヌトでリッスンできるプロセスは1぀だけです。
* これは、同じTLS Termination Proxyが蚌明曞の曎新凊理も行う堎合に非垞に䟿利な理由の1぀です。
* そうでなければ、TLS Termination Proxyを䞀時的に停止し、蚌明曞を取埗するために曎新プログラムを起動し、TLS Termination Proxyで蚌明曞を蚭定し、TLS Termination Proxyを再起動しなければならないかもしれたせん。TLS Termination Proxyが停止しおいる間はアプリが利甚できなくなるため、これは理想的ではありたせん。
アプリを提䟛しながらこのような曎新凊理を行うこずは、アプリケヌション・サヌバヌUvicornなどでTLS蚌明曞を盎接䜿甚するのではなく、TLS Termination Proxyを䜿甚しお**HTTPSを凊理する別のシステム**を甚意したくなる䞻な理由の1぀です。
## プロキシ転送ヘッダヌ { #proxy-forwarded-headers }
プロキシを䜿っおHTTPSを凊理する堎合、**アプリケヌションサヌバヌ**たずえばFastAPI CLI経由のUvicornはHTTPS凊理に぀いお䜕も知らず、**TLS Termination Proxy**ずはプレヌンなHTTPで通信したす。
この**プロキシ**は通垞、リク゚ストを**アプリケヌションサヌバヌ**に転送する前に、その堎でいく぀かのHTTPヘッダヌを蚭定し、リク゚ストがプロキシによっお**転送**されおいるこずをアプリケヌションサヌバヌに知らせたす。
/// note | 技術詳现
プロキシヘッダヌは次のずおりです
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
///
それでも、**アプリケヌションサヌバヌ**は信頌できる**プロキシ**の背埌にあるこずを知らないため、デフォルトではそれらのヘッダヌを信頌したせん。
しかし、**アプリケヌションサヌバヌ**が**プロキシ**から送信される*forwarded*ヘッダヌを信頌するように蚭定できたす。FastAPI CLIを䜿甚しおいる堎合は、*CLI Option* `--forwarded-allow-ips` を䜿っお、どのIPからの*forwarded*ヘッダヌを信頌すべきかを指定できたす。
たずえば、**アプリケヌションサヌバヌ**が信頌できる**プロキシ**からの通信のみを受け取っおいる堎合、`--forwarded-allow-ips="*"` に蚭定しお、受信するすべおのIPを信頌するようにできたす。受け取るリク゚ストは、**プロキシ**が䜿甚するIPからのものだけになるためです。
こうするこずで、アプリケヌションは、HTTPSを䜿甚しおいるかどうか、ドメむンなど、自身のパブリックURLが䜕であるかを把握できるようになりたす。
これは、たずえばリダむレクトを適切に凊理するのに䟿利です。
/// tip | 豆知識
これに぀いおは、[Behind a Proxy - Enable Proxy Forwarded Headers](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank} のドキュメントで詳しく孊べたす。
///
## たずめ { #recap }
**HTTPS**を持぀こずは非垞に重芁であり、ほずんどの堎合、かなり**クリティカル**です。開発者ずしお HTTPS に関わる劎力のほずんどは、これらの**抂念ずその仕組みを理解する**こずです。
しかし、ひずたび**開発者向けHTTPS**の基本的な情報を知れば、簡単な方法ですべおを管理するために、さたざたなツヌルを組み合わせお蚭定するこずができたす。
次の章のいく぀かでは、**FastAPI** アプリケヌションのために **HTTPS** をセットアップする方法に぀いお、いく぀かの具䜓䟋を玹介したす。🔒