ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
ネットワークリレーによるアプリのトラフィック保護
リレーを使用して、VPNのようなオーバーヘッドをかけずに、アプリのネットワークトラフィックをよりプライベートかつセキュアにする方法を学びましょう。リレーサーバーをアプリに統合する方法や、リレーを使用して企業ネットワークで内部リソースに安全にアクセスする方法を紹介します。
関連する章
- 0:00 - Welcome
- 0:56 - Discover relays
- 3:40 - Configure relays in your app
- 7:01 - Access enterprise resources
リソース
関連ビデオ
WWDC23
WWDC21
-
ダウンロード
♪ ♪
こんにちは Internet Technologiesチームの Keith Hollemanです 本日は ネットワークリレーを使って アプリのプライバシーとセキュリティを 強化する方法についてお話します まずはネットワークリレーに使われている テクノロジーについて解説します リレーはAppleのプライバシー機能に 広く使われています このテクノロジーは効果的で 使いやすいのが長所です 皆さんのアプリでも 2つの方法でリレーを使用できます 1つ目は アプリ内でリレーを構成し アプリのネットワークトラフィックを 保護する方法です 2つ目は VPNの代わりとして デバイスに リレーを拡張して 企業内のプライベートな リソースにアクセスする方法です ではさっそく始めましょう リレーは iCloudプライベートリレーや メールのプライバシー保護 Safariでトラッカーに対し IPアドレスを非表示にするなど 優れた機能の基礎となっています 皆さんのアプリで 非公開にすべきユーザーに関する 機密情報を扱う可能性があり その情報をサーバで クライアントIPアドレスと紐づけできないように したい場合があるかも知れません そこで リレーを使用して すべてのユーザーに 強力なプライバシー機能を 提供することができます
リレーは特別なタイプのプロキシで パフォーマンスを最適化し 最新のトランスポートとセキュリティ プロトコルを使用し Appleプラットフォームで利用可能な 最新のネットワークスタックに ネイティブで実装されています これらのリレーはIETFで定義された 2つの標準プロトコル MASQUEと Oblivious HTTPを使用しています MASQUEリレーは アプリのプライバシーを 強化したり プライベートなリソースに アクセスするのに最適な方法です バックエンドサーバを変更することなく あらゆるTCPやUDP接続を リレー経由で送信できます IPアドレスとブラウジングアクティビティを 組み合わせて ユーザーの詳細な プロファイルを作成できないよう リレーサーバをチェーン接続できます これがiCloudプライベートリレーの 基礎となるテクノロジーです リレーは企業のリソースに アクセスするのに最適な方法でもあります リレーはVPNよりも優れたユーザー エクスペリエンスを提供し パフォーマンスも高く 管理も容易です MASQUEリレーは レガシープロキシ プロトコルとは異なり TLS 1.3を使用し プロキシへのトラフィックを セキュアにしています MASQUEは最新のトランスポートプロトコル QUICとHTTP/3を使用して 効率的にプロキシし 単一のトンネル上で 多数のコネクションを多重化します また QUICがネットワークによって ブロックされた場合 HTTP/2にフォールバックできます 皆さんのアプリが 匿名メトリクスレポートや データベースルックアップ DNSクエリなど プライベートで 他のリクエストに リンクされていないことを確認するために HTTPリクエストを送信する場合 Oblivious HTTPを使用できます Oblivious HTTPを使用すると 単一のリレーホップだけで 優れた パフォーマンスとプライバシーを 得ることができます MASQUEリレーとは異なり Oblivious HTTPは 任意のサーバでは動作せず サーバが明示的に サポートしている必要があります Oblivious HTTPについての詳細は “What’s new in Privacy”をご覧ください これら両方のリレータイプを使用して アプリによる接続をプロキシできます これにより アプリの プライバシーを高めるために 選択した 特定のリレーサーバを使用できます 新しいProxyConfiguration クラスを使用すると Networkフレームワーク URLSession WebKitでリレーを定義できます 3つのAPIは すべてこの共通クラスを 同じような方法で使用し アプリ全体または特定の接続だけに リレーを定義することができます ProxyConfigurationオブジェクトの中で 5つの異なるプロトコルに基づく プロキシを定義できます ここでMASQUEとOblivious HTTPの 新しいリレータイプを指定できます 同じオブジェクトを使用して レガシープロキシタイプも構成できます 以前にURLSessionやWebKitで ディクショナリを使用して プロキシを構成していたのであれば この新しいオブジェクトに切り替える 絶好の機会です レガシーなプロキシタイプの場合は SOCKSv5と同様に TLSサポートがプロキシに新しく追加された HTTP CONNECTを構成可能です HTTP/3でMASQUEリレーに接続するために 使用するProxyConfigurationの 定義方法は以下の通りです まず NWEndpointを使用して サーバ名またはURLを指定し それを使用してリレーホップを定義します これらのリレーホップでは HTTP/3 HTTP/2 または両方のサポートを指定できます HTTP/2サーバは QUICプロトコルを使用した HTTP/3へのアクセスが ネットワークによってブロックされた場合の バックアップとして使用されます 次に“relayHops” 配列パラメータにリレーを渡して プロキシ構成を作成します マルチホップの リレー構成を定義する場合は ここで2つのリレーを渡します Networkフレームワークの NWConnectionで ProxyConfigurationを作成するには PrivacyContextを作成するか デフォルトのコンテキストを使用し そのコンテキストに プロキシ構成を追加します NWParametersのコンテキストを設定し 接続の作成と開始時に これらのパラメータを渡します これで この接続はすべてのトラフィックを プロキシ経由で送信するようになります
URLSessionで直接定義したのと 同じプロキシ構成を 使うこともできます その場合は 構成をURLSessionConfigurationの proxyConfigurations配列に追加します そして URLSessionで 通常通りタスクを実行すると そのタスクも プロキシを使うようになります 同じプロキシ構成オブジェクトを使用して WebKitビューでの 接続をプロキシすることもできます まず Webビューの構成を初期化して データストアを追加し プロキシ構成をデータストアに追加します 次に 構成した内容で Webビューを初期化します こうすることで リクエストされたURLを読み込んで 通常と同じように WebKitビューを使用できます これで このWebkitビューはリレー経由で トラフィックを送信するようになります
iOS 17では 自分のアプリに リレーを追加するだけでなく デバイス全体にリレーを 構成することも可能です プライバシー機能を構築できるだけでなく リレーを使用して プライベートな企業ネットワークの リソースへのアクセス方法を提供できます
企業リソースへのアクセスを提供するために VPNを使うこともあるでしょう リレーはVPNの代替となり ユーザーエクスペリエンスに優れ 管理も容易です ネットワークリレーは 複雑なセッションネゴシエーションが不要で 実際のユーザーデータが転送されるまでの やり取りが少なく済む場合が多いです これにより ユーザーが プライベートなリソースを 最初に利用する際の応答性が高まります また リレーはVPNに関連する トンネルや仮想インターフェイス 追加IPアドレスの使用を回避できます 複数のリレーを同時に構成できるので 異なるネットワークの 異なるプライベート ドメインへのアクセスが容易に行えます VPNの代替として リレーサーバを使用したい 企業にとっては 自社のインフラで リレーサーバを用意する 選択肢が生まれます シスコは Cisco Secure Edgeの一環として 企業向けリレーサービスを提供しています ユーザーへ リモートアクセスを提供するために 企業に採用されることを嬉しく思います
MASQUEリレー構成をデバイスに インストールするには2つの方法があります 企業で モバイルデバイス管理(MDM)を介して 構成をプッシュし 新しいリレーペイロードタイプを 使用してリレーを定義することができます これらのペイロードは 管理対象アプリや ドメイン デバイス全体に適用できます NERelayManager APIを使用して リレーを 定義するアプリを作成することもできます これらの構成は 特定のドメインや デバイス全体に適用できます これらのいずれも macOS iOS iPadOS tvOSで利用可能です 今回 tvOSにNetwork Extension サポートが追加され VPNもtvOS 17で新たに追加されました
こちらが構成プロファイルを使って リレーを構成する方法です アプリのProxyConfiguration APIと同様に リレーURLを定義します VPNプロファイルと同様に 同じプロファイル内の 証明書ペイロードを参照することで クライアント証明書を 企業サーバの認証に使用できます ペイロードのMatchDomains部分に ドメインを追加することで 特定のドメインにリレーを適用できます 次に アプリが NERelayManager APIを使用して プログラムでデバイスにリレーを 追加する方法を見ていきます リレーを定義するには NERelayオブジェクトを初期化し リレーのURLを構成します ここでは HTTP/2とHTTP/3の 両方に同じリレーを使っています リレーに追加の HTTPヘッダが必要な場合は NERelayオブジェクトに追加します また 今作成した NERelayオブジェクトを格納するため 共有NERelayManager オブジェクトにもアクセスが必要です リレーをデバイス全体ではなく 特定のドメインのみに 適用したい場合は ドメインを matchDomains配列に追加します 最後に リレーが 有効になっていることを確認し NERelayManagerオブジェクトを システム環境設定にインストールします 実際のリレーを見てみましょう 私はマウンテンバイクが大好きで 自分のバイクショップを開きました 私の店はオンラインショップがあり 社内のWebサイトで すべての注文を追跡できます Webサイトは内部ネットワークにあり 従業員しか利用できません Safariを開いて注文を見ようとしても 内部ネットワークにいないので 見れません リレー構成をインストールすれば どこからでも 内部ネットワークにアクセスできます 先ほど説明したコードで サンプルリレーアプリを開けば 内部ドメインにアクセスして ショップのリレーを使うように デバイス全体を構成できます この構成は設定にも表示され internal.example.comにアクセスする際に リレーを使用することが分かります 再びSafariに戻って 未処理の注文を見ようとすると 注文が表示され 発送が必要な注文の数が分かります シンプルかつ高速で 最初の読み込みから快適です リレーは パフォーマンスを損なうことなく アプリのセキュリティと プライバシーを向上できる 標準ベースの最新のプロキシです MASQUEリレーとOblivious HTTPリレーを アプリに直接適用し ユーザーのプライバシーを強化しましょう 企業では VPNの使用を より管理が簡単でシームレスな ユーザー体験を提供する リレーに置き換えられます ご視聴ありがとうございました 皆さんのリレーの 使用例を見るのが楽しみです!
-
-
4:52 - Configuring a relay
import Network let relayEndpoint = NWEndpoint.url(URL(string: "https://relay.example.com")!) let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint) let relayConfig = ProxyConfiguration(relayHops: [relayServer])
-
5:40 - Configuring a relay in Network framework
import Network let relayEndpoint = NWEndpoint.url(URL(string: "https://relay.example.com")!) let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint) let relayConfig = ProxyConfiguration(relayHops: [relayServer]) var context = NWParameters.PrivacyContext(description: "my relay") context.proxyConfigurations = [relayConfig] let parameters = NWParameters.tls parameters.setPrivacyContext(context) let connection = NWConnection(host: "www.example.com", port: 443, using: parameters) connection.start(queue: .main)
-
6:07 - Configuring a relay in URLSession
import Network let relayEndpoint = NWEndpoint.url(URL(string: "https://relay.example.com")!) let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint) let relayConfig = ProxyConfiguration(relayHops: [relayServer]) let config = URLSessionConfiguration.default config.proxyConfigurations = [relayConfig] let mySession = URLSession(configuration: config) let url = URL(string: "https://www.example.com/api/v1/employees")! let (data, response) = try await mySession.data(from: url)
-
6:30 - Configuring a relay in WebKit
import Network let relayEndpoint = NWEndpoint.url(URL(string: "https://relay.example.com")!) let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint) let relayConfig = ProxyConfiguration(relayHops: [relayServer]) let webkitConfig = WKWebViewConfiguration() webkitConfig.websiteDataStore = WKWebsiteDataStore.nonPersistent() webkitConfig.websiteDataStore.proxyConfigurations = [relayConfig] let webView = WKWebView(frame: .zero, configuration: webkitConfig) let url = URL(string: "https://www.example.com/api/v1/employees")! webView.load(URLRequest(url: url))
-
9:15 - Configuring a relay on the device with a configuration profile
<dict> <key>PayloadType</key> <string>com.apple.relay.managed</string> <key>Relays</key> <array> <dict> <key>HTTP3RelayURL</key> <string>https://relay.example.com</string> <key>PayloadCertificateUUID</key> <string>5AB702EC-32F3-48A9-94FE-8EA1C67ACF46</string> </dict> </array> <key>MatchDomains</key> <array> <string>internal.example.com</string> </array> </dict>
-
9:42 - Configuring a relay on the device with NetworkExtension
import NetworkExtension let newRelay = NERelay() let relayURL = URL(string: "https://relay.example.com:443/") newRelay.http3RelayURL = relayURL newRelay.http2RelayURL = relayURL newRelay.additionalHTTPHeaderFields = ["Authorization" : "PrivateToken=123"] let manager = NERelayManager.shared() manager.relays = [newRelay] manager.matchDomains = ["internal.example.com"] manager.isEnabled = true do { try await manager.saveToPreferences() } catch let saveError { // Handle error }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。