From fee6fbf17b70fda71fe67347ac192f2792254202 Mon Sep 17 00:00:00 2001 From: qrkourier Date: Tue, 5 Mar 2024 12:56:37 +0000 Subject: [PATCH] deploy: 362a0faf5f03733f77a97d441d7e21e6890c5581 --- 404.html | 2 +- assets/js/6e881e32.2eecdb77.js | 1 + assets/js/6e881e32.b57731c8.js | 1 - assets/js/cda0d2e5.40baeef1.js | 1 + assets/js/cda0d2e5.b45c8e1c.js | 1 - ...{runtime~main.c0806695.js => runtime~main.32610af2.js} | 2 +- docs/category/docker-share/index.html | 2 +- docs/category/guides/index.html | 2 +- docs/category/metrics-and-limits/index.html | 2 +- docs/category/oauth/index.html | 2 +- docs/category/self-hosting/index.html | 2 +- docs/concepts/files/index.html | 2 +- docs/concepts/hosting/index.html | 2 +- docs/concepts/http/index.html | 2 +- docs/concepts/index.html | 2 +- docs/concepts/opensource/index.html | 2 +- docs/concepts/sharing-private/index.html | 2 +- docs/concepts/sharing-public/index.html | 2 +- docs/concepts/sharing-reserved/index.html | 2 +- docs/concepts/tunnels/index.html | 2 +- docs/getting-started/index.html | 2 +- .../docker-share/docker_private_share_guide/index.html | 2 +- .../docker-share/docker_public_share_guide/index.html | 2 +- docs/guides/drives/cli/index.html | 2 +- docs/guides/frontdoor/index.html | 8 ++++---- docs/guides/install/index.html | 2 +- docs/guides/install/linux/index.html | 2 +- docs/guides/install/macos/index.html | 2 +- docs/guides/install/windows/index.html | 2 +- .../guides/self-hosting/instance-configuration/index.html | 2 +- .../metrics-and-limits/configuring-limits/index.html | 2 +- .../metrics-and-limits/configuring-metrics/index.html | 2 +- docs/guides/self-hosting/nginx_tls_guide/index.html | 2 +- .../self-hosting/oauth/configuring-oauth/index.html | 8 ++++---- docs/guides/self-hosting/self_hosting_guide/index.html | 2 +- index.html | 2 +- search/index.html | 2 +- zrok-public-reserved/compose.yml | 2 +- zrok-public-share/compose.yml | 2 +- 39 files changed, 43 insertions(+), 43 deletions(-) create mode 100644 assets/js/6e881e32.2eecdb77.js delete mode 100644 assets/js/6e881e32.b57731c8.js create mode 100644 assets/js/cda0d2e5.40baeef1.js delete mode 100644 assets/js/cda0d2e5.b45c8e1c.js rename assets/js/{runtime~main.c0806695.js => runtime~main.32610af2.js} (97%) diff --git a/404.html b/404.html index 73b3a427..816de393 100644 --- a/404.html +++ b/404.html @@ -9,7 +9,7 @@ - + diff --git a/assets/js/6e881e32.2eecdb77.js b/assets/js/6e881e32.2eecdb77.js new file mode 100644 index 00000000..210b7784 --- /dev/null +++ b/assets/js/6e881e32.2eecdb77.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[182],{8214:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>h});var i=n(5893),o=n(1151);const s={},r="OAuth Public Frontend Configuration",a={id:"guides/self-hosting/oauth/configuring-oauth",title:"OAuth Public Frontend Configuration",description:"As of v0.4.7, zrok includes OAuth integration for both Google and GitHub for zrok access public public frontends.",source:"@site/../docs/guides/self-hosting/oauth/configuring-oauth.md",sourceDirName:"guides/self-hosting/oauth",slug:"/guides/self-hosting/oauth/configuring-oauth",permalink:"/docs/guides/self-hosting/oauth/configuring-oauth",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/self-hosting/oauth/configuring-oauth.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"OAuth",permalink:"/docs/category/oauth"},next:{title:"Instance Config",permalink:"/docs/guides/self-hosting/instance-configuration"}},c={},h=[{value:"Planning for the OAuth Frontend",id:"planning-for-the-oauth-frontend",level:2},{value:"Configuring a Google OAuth Client ID",id:"configuring-a-google-oauth-client-id",level:2},{value:"OAuth Content Screen",id:"oauth-content-screen",level:3},{value:"Create the OAuth 2.0 Client ID",id:"create-the-oauth-20-client-id",level:3},{value:"Configuring a GitHub Client ID",id:"configuring-a-github-client-id",level:2},{value:"Configuring your Public Frontend",id:"configuring-your-public-frontend",level:2},{value:"Enabling OAuth on a Public Share",id:"enabling-oauth-on-a-public-share",level:2}];function d(e){const t={code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"oauth-public-frontend-configuration",children:"OAuth Public Frontend Configuration"}),"\n",(0,i.jsxs)(t.p,{children:["As of ",(0,i.jsx)(t.code,{children:"v0.4.7"}),", ",(0,i.jsx)(t.code,{children:"zrok"})," includes OAuth integration for both Google and GitHub for ",(0,i.jsx)(t.code,{children:"zrok access public"})," public frontends."]}),"\n",(0,i.jsx)(t.p,{children:"This integration allows you to create public shares and request that the public frontend authenticate your users against either the Google or GitHub OAuth endpoints (using the user's Google or GitHub accounts). Additionally, you can restrict the email address domain associated with the count to a list of domains that you provide when you create the share."}),"\n",(0,i.jsxs)(t.p,{children:["This is a first step towards a more comprehensive portfolio of user authentication strategies in future ",(0,i.jsx)(t.code,{children:"zrok"})," releases."]}),"\n",(0,i.jsx)(t.h2,{id:"planning-for-the-oauth-frontend",children:"Planning for the OAuth Frontend"}),"\n",(0,i.jsx)(t.p,{children:"The current implementation of the OAuth public frontend uses a HTTP listener to handle redirects from OAuth providers. You'll need to configure a DNS name and a port for this listener that is accessible by your end users. We'll refer to this listener as the \"OAuth frontend\" in this guide."}),"\n",(0,i.jsx)(t.p,{children:'We\'ll use the public DNS address of the OAuth frontend when creating the Google and GitHub OAuth clients below. This address is typically configured into these clients as the "redirect URL" where these clients will send the authenticated users after authentication.'}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"zrok"})," OAuth frontend will capture the successful authentication and forward the user back to their original destination."]}),"\n",(0,i.jsx)(t.h2,{id:"configuring-a-google-oauth-client-id",children:"Configuring a Google OAuth Client ID"}),"\n",(0,i.jsx)(t.h3,{id:"oauth-content-screen",children:"OAuth Content Screen"}),"\n",(0,i.jsx)(t.p,{children:'Before you can configure an OAuth Client ID in Google Cloud, you have to configure the "OAuth content screen".'}),"\n",(0,i.jsxs)(t.p,{children:["In the Google Cloud console, navigate to: ",(0,i.jsx)(t.code,{children:"APIs & Services > Credentials > OAuth content screen"})]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(7199).Z+"",width:"1469",height:"1141"})}),"\n",(0,i.jsxs)(t.p,{children:["Here you can give your ",(0,i.jsx)(t.code,{children:"zrok"})," public frontend an identity and branding to match your deployment."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(2795).Z+"",width:"1469",height:"1141"})}),"\n",(0,i.jsx)(t.p,{children:"Describe what domains are authorized to access your public frontend and establish contact information."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(3923).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(t.p,{children:["Add a non-sensitive scope for ",(0,i.jsx)(t.code,{children:"../auth/userinfo.email"}),". This is important as it allows the ",(0,i.jsx)(t.code,{children:"zrok"})," OAuth frontend to receive the email address of the authenticated user."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(2575).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(72).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsx)(t.p,{children:"Now your OAuth content screen is configured."}),"\n",(0,i.jsx)(t.h3,{id:"create-the-oauth-20-client-id",children:"Create the OAuth 2.0 Client ID"}),"\n",(0,i.jsx)(t.p,{children:"Next we create the OAuth Client ID for your public frontend."}),"\n",(0,i.jsxs)(t.p,{children:["In the Google Cloud Console, navigate to: ",(0,i.jsx)(t.code,{children:"APIs & Services > Credentials > + Create Credentials"})]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(5180).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(t.p,{children:["Select ",(0,i.jsx)(t.code,{children:"OAuth client ID"})," from the ",(0,i.jsx)(t.code,{children:"+ Create Credentials"})," dropdown."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(5871).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(t.p,{children:["Application type is ",(0,i.jsx)(t.code,{children:"Web Application"}),"."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(9572).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(t.p,{children:['The most important bit here is the "Authorized redirect URIs". You\'re going to want to put a URL here that matches the ',(0,i.jsx)(t.code,{children:"zrok"})," OAuth frontend address that you configured at the start of this guide, but at the end of the URL you're going to append ",(0,i.jsx)(t.code,{children:"/google/oauth"})," to the URL."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(1115).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(t.p,{children:["Save the client ID and the client secret. You'll configure these into your ",(0,i.jsx)(t.code,{children:"frontend.yml"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"With this your Google OAuth client should be configured and ready."}),"\n",(0,i.jsx)(t.h2,{id:"configuring-a-github-client-id",children:"Configuring a GitHub Client ID"}),"\n",(0,i.jsx)(t.p,{children:"Register a new OAuth application through the GitHub settings for the account that owns the application."}),"\n",(0,i.jsxs)(t.p,{children:["Navigate to:",(0,i.jsx)(t.code,{children:"Settings > Developer Settings > OAuth Apps > Register a new application"})]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(9980).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(4861).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(t.p,{children:['The "Authorized callback URL" should be configured to match the OAuth frontend address you configured at the start of this guide, with ',(0,i.jsx)(t.code,{children:"/github/oauth"})," appended to the end."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(5758).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsx)(t.p,{children:"Create a new client secret."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(1995).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(t.p,{children:["Save the client ID and the client secret. You'll configure these into your ",(0,i.jsx)(t.code,{children:"frontend.yml"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"configuring-your-public-frontend",children:"Configuring your Public Frontend"}),"\n",(0,i.jsxs)(t.p,{children:["The public frontend configuration includes a new ",(0,i.jsx)(t.code,{children:"oauth"})," section:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-yaml",children:'oauth:\n bind_address: 0.0.0.0:8181\n redirect_url: https://oauth.zrok.io\n cookie_domain: zrok.io\n hash_key: "the quick brown fox jumped over the lazy dog"\n providers:\n - name: google\n client_id: ""\n client_secret: ""\n - name: github\n client_id: ""\n client_secret: ""\n \n'})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"bind_address"})," parameter determines where the OAuth frontend will bind. Should be in ",(0,i.jsx)(t.code,{children:"ip:port"})," format."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"redirect_url"})," parameter determines the base URL where OAuth frontend requests will be redirected."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"cookie_domain"})," is the domain where authentication cookies should be stored."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"hash_key"})," is a unique string for your installation that is used to secure the authentication payloads for your public frontend."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"providers"})," is a list of configured providers for this public frontend. The current implementation supports ",(0,i.jsx)(t.code,{children:"google"})," and ",(0,i.jsx)(t.code,{children:"github"})," as options."]}),"\n",(0,i.jsxs)(t.p,{children:["Both the ",(0,i.jsx)(t.code,{children:"google"})," and ",(0,i.jsx)(t.code,{children:"github"})," providers accept a ",(0,i.jsx)(t.code,{children:"client_id"})," and ",(0,i.jsx)(t.code,{children:"client_secret"})," parameter. These values are provided when you configure the OAuth clients at Google or GitHub."]}),"\n",(0,i.jsx)(t.h2,{id:"enabling-oauth-on-a-public-share",children:"Enabling OAuth on a Public Share"}),"\n",(0,i.jsx)(t.p,{children:"With your public frontend configured to support OAuth, you can test this by creating a public share. There are new command line options to support this:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-text",children:'$ zrok share public --help\nShare a target resource publicly\n\nUsage:\n zrok share public [flags]\n\nFlags:\n -b, --backend-mode string The backend mode {proxy, web, caddy, drive} (default "proxy")\n --basic-auth stringArray Basic authentication users (,...)\n --frontends stringArray Selected frontends to use for the share (default [public])\n --headless Disable TUI and run headless\n -h, --help help for public\n --insecure Enable insecure TLS certificate validation for \n --oauth-check-interval duration Maximum lifetime for OAuth authentication; reauthenticate after expiry (default 3h0m0s)\n --oauth-email-address-patterns stringArray Allow only these email domain globs to authenticate via OAuth\n --oauth-provider string Enable OAuth provider [google, github]\n\nGlobal Flags:\n -p, --panic Panic instead of showing pretty errors\n -v, --verbose Enable verbose logging\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"--oauth-provider"})," flag enables OAuth for the share using the specified provider."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"--oauth-email-address-patterns"})," flag accepts a single glob pattern that matches an authenticated email address that is allowed to access the share. Use this flag multiple times to allow different patterns."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"--oauth-check-interval"})," flag specifies how frequently the authentication must be checked."]}),"\n",(0,i.jsx)(t.p,{children:"An example public share:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-text",children:"zrok share public --backend-mode web --oauth-provider github --oauth-email-address-patterns '*@zrok.io' ~/public\n"})})]})}function l(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},9980:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/github_create_oauth_application_1-dbb289a694d0c99b50cb949654d818f8.png"},4861:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/github_create_oauth_application_2-bc9d4c3f25853d608870eb220d00e5ee.png"},5758:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/github_create_oauth_application_3-7973d63cd117eaba72fbaeb4ff119a39.png"},1995:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/github_create_oauth_application_4-6fed398013c9e6c3a31e5721adac4a4c.png"},5180:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_create_credentials_1-e61ee7e8fa51bdc93feab84235a90673.png"},5871:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_create_credentials_2-60cf4edb52f453d605907c17400e0800.png"},9572:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_create_credentials_3-1b3db3f9057d8626d64c5466dbb05ec7.png"},1115:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_create_credentials_4-f720031df1d09f997a18842745e9ea0d.png"},7199:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_oauth_content_screen_2-b94a6456ce9b13e053b4c07d8f233e84.png"},2795:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_oauth_content_screen_3-edf62ea2b291b58093289d31c2dae58d.png"},3923:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_oauth_content_screen_4-4bc7e07b06c8a9a3c1e8f766f6f1c5a6.png"},2575:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_oauth_content_screen_5-7c375cf49d8e2e392ca12b584462ab59.png"},72:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/google_oauth_content_screen_6-9b0fe216a782ef378313650e99ea52a1.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>a,a:()=>r});var i=n(7294);const o={},s=i.createContext(o);function r(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e881e32.b57731c8.js b/assets/js/6e881e32.b57731c8.js deleted file mode 100644 index c80f8f58..00000000 --- a/assets/js/6e881e32.b57731c8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[182],{8214:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>c,toc:()=>h});var i=t(5893),o=t(1151);const s={},r="OAuth Public Frontend Configuration",c={id:"guides/self-hosting/oauth/configuring-oauth",title:"OAuth Public Frontend Configuration",description:"As of v0.4.7, zrok includes OAuth integration for both Google and GitHub for zrok access public public frontends.",source:"@site/../docs/guides/self-hosting/oauth/configuring-oauth.md",sourceDirName:"guides/self-hosting/oauth",slug:"/guides/self-hosting/oauth/configuring-oauth",permalink:"/docs/guides/self-hosting/oauth/configuring-oauth",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/self-hosting/oauth/configuring-oauth.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"OAuth",permalink:"/docs/category/oauth"},next:{title:"Instance Config",permalink:"/docs/guides/self-hosting/instance-configuration"}},a={},h=[{value:"Planning for the OAuth Frontend",id:"planning-for-the-oauth-frontend",level:2},{value:"Configuring a Google OAuth Client ID",id:"configuring-a-google-oauth-client-id",level:2},{value:"OAuth Content Screen",id:"oauth-content-screen",level:3},{value:"Create the OAuth 2.0 Client ID",id:"create-the-oauth-20-client-id",level:3},{value:"Configuring a GitHub Client ID",id:"configuring-a-github-client-id",level:2},{value:"Configuring your Public Frontend",id:"configuring-your-public-frontend",level:2},{value:"Enabling OAuth on a Public Share",id:"enabling-oauth-on-a-public-share",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"oauth-public-frontend-configuration",children:"OAuth Public Frontend Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["As of ",(0,i.jsx)(n.code,{children:"v0.4.7"}),", ",(0,i.jsx)(n.code,{children:"zrok"})," includes OAuth integration for both Google and GitHub for ",(0,i.jsx)(n.code,{children:"zrok access public"})," public frontends."]}),"\n",(0,i.jsx)(n.p,{children:"This integration allows you to create public shares and request that the public frontend authenticate your users against either the Google or GitHub OAuth endpoints (using the user's Google or GitHub accounts). Additionally, you can restrict the email address domain associated with the count to a list of domains that you provide when you create the share."}),"\n",(0,i.jsxs)(n.p,{children:["This is a first step towards a more comprehensive portfolio of user authentication strategies in future ",(0,i.jsx)(n.code,{children:"zrok"})," releases."]}),"\n",(0,i.jsx)(n.h2,{id:"planning-for-the-oauth-frontend",children:"Planning for the OAuth Frontend"}),"\n",(0,i.jsx)(n.p,{children:"The current implementation of the OAuth public frontend uses a HTTP listener to handle redirects from OAuth providers. You'll need to configure a DNS name and a port for this listener that is accessible by your end users. We'll refer to this listener as the \"OAuth frontend\" in this guide."}),"\n",(0,i.jsx)(n.p,{children:'We\'ll use the public DNS address of the OAuth frontend when creating the Google and GitHub OAuth clients below. This address is typically configured into these clients as the "redirect URL" where these clients will send the authenticated users after authentication.'}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"zrok"})," OAuth frontend will capture the successful authentication and forward the user back to their original destination."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-a-google-oauth-client-id",children:"Configuring a Google OAuth Client ID"}),"\n",(0,i.jsx)(n.h3,{id:"oauth-content-screen",children:"OAuth Content Screen"}),"\n",(0,i.jsx)(n.p,{children:'Before you can configure an OAuth Client ID in Google Cloud, you have to configure the "OAuth content screen".'}),"\n",(0,i.jsxs)(n.p,{children:["In the Google Cloud console, navigate to: ",(0,i.jsx)(n.code,{children:"APIs & Services > Credentials > OAuth content screen"})]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(7199).Z+"",width:"1469",height:"1141"})}),"\n",(0,i.jsxs)(n.p,{children:["Here you can give your ",(0,i.jsx)(n.code,{children:"zrok"})," public frontend an identity and branding to match your deployment."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(2795).Z+"",width:"1469",height:"1141"})}),"\n",(0,i.jsx)(n.p,{children:"Describe what domains are authorized to access your public frontend and establish contact information."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(3923).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(n.p,{children:["Add a non-sensitive scope for ",(0,i.jsx)(n.code,{children:"../auth/userinfo.email"}),". This is important as it allows the ",(0,i.jsx)(n.code,{children:"zrok"})," OAuth frontend to receive the email address of the authenticated user."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(2575).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(72).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsx)(n.p,{children:"Now your OAuth content screen is configured."}),"\n",(0,i.jsx)(n.h3,{id:"create-the-oauth-20-client-id",children:"Create the OAuth 2.0 Client ID"}),"\n",(0,i.jsx)(n.p,{children:"Next we create the OAuth Client ID for your public frontend."}),"\n",(0,i.jsxs)(n.p,{children:["In the Google Cloud Console, navigate to: ",(0,i.jsx)(n.code,{children:"APIs & Services > Credentials > + Create Credentials"})]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(5180).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(n.p,{children:["Select ",(0,i.jsx)(n.code,{children:"OAuth client ID"})," from the ",(0,i.jsx)(n.code,{children:"+ Create Credentials"})," dropdown."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(5871).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(n.p,{children:["Application type is ",(0,i.jsx)(n.code,{children:"Web Application"}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(9572).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(n.p,{children:['The most important bit here is the "Authorized redirect URIs". You\'re going to want to put a URL here that matches the ',(0,i.jsx)(n.code,{children:"zrok"})," OAuth frontend address that you configured at the start of this guide, but at the end of the URL you're going to append ",(0,i.jsx)(n.code,{children:"/google/oauth"})," to the URL."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(1115).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(n.p,{children:["Save the client ID and the client secret. You'll configure these into your ",(0,i.jsx)(n.code,{children:"frontend.yml"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"With this your Google OAuth client should be configured and ready."}),"\n",(0,i.jsx)(n.h2,{id:"configuring-a-github-client-id",children:"Configuring a GitHub Client ID"}),"\n",(0,i.jsx)(n.p,{children:"Register a new OAuth application through the GitHub settings for the account that owns the application."}),"\n",(0,i.jsxs)(n.p,{children:["Navigate to:",(0,i.jsx)(n.code,{children:"Settings > Developer Settings > OAuth Apps > Register a new application"})]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(9980).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(4861).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(n.p,{children:['The "Authorized callback URL" should be configured to match the OAuth frontend address you configured at the start of this guide, with ',(0,i.jsx)(n.code,{children:"/github/oauth"})," appended to the end."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(5758).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsx)(n.p,{children:"Create a new client secret."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(1995).Z+"",width:"1469",height:"1179"})}),"\n",(0,i.jsxs)(n.p,{children:["Save the client ID and the client secret. You'll configure these into your ",(0,i.jsx)(n.code,{children:"frontend.yml"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-your-public-frontend",children:"Configuring your Public Frontend"}),"\n",(0,i.jsxs)(n.p,{children:["The public frontend configuration includes a new ",(0,i.jsx)(n.code,{children:"oauth"})," section:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'oauth:\n bind_address: 0.0.0.0:8181\n redirect_url: https://oauth.zrok.io\n cookie_domain: zrok.io\n hash_key: "the quick brown fox jumped over the lazy dog"\n providers:\n - name: google\n client_id: ""\n client_secret: ""\n - name: github\n client_id: ""\n client_secret: ""\n \n'})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"bind_address"})," parameter determines where the OAuth frontend will bind. Should be in ",(0,i.jsx)(n.code,{children:"ip:port"})," format."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"redirect_url"})," parameter determines the base URL where OAuth frontend requests will be redirected."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"cookie_domain"})," is the domain where authentication cookies should be stored."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"hash_key"})," is a unique string for your installation that is used to secure the authentication payloads for your public frontend."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"providers"})," is a list of configured providers for this public frontend. The current implementation supports ",(0,i.jsx)(n.code,{children:"google"})," and ",(0,i.jsx)(n.code,{children:"github"})," as options."]}),"\n",(0,i.jsxs)(n.p,{children:["Both the ",(0,i.jsx)(n.code,{children:"google"})," and ",(0,i.jsx)(n.code,{children:"github"})," providers accept a ",(0,i.jsx)(n.code,{children:"client_id"})," and ",(0,i.jsx)(n.code,{children:"client_secret"})," parameter. These values are provided when you configure the OAuth clients at Google or GitHub."]}),"\n",(0,i.jsx)(n.h2,{id:"enabling-oauth-on-a-public-share",children:"Enabling OAuth on a Public Share"}),"\n",(0,i.jsx)(n.p,{children:"With your public frontend configured to support OAuth, you can test this by creating a public share. There are new command line options to support this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:'$ zrok share public\nError: accepts 1 arg(s), received 0\nUsage:\n zrok share public [flags]\n\nFlags:\n -b, --backend-mode string The backend mode {proxy, web, caddy, drive} (default "proxy")\n --basic-auth stringArray Basic authentication users (,...)\n --frontends stringArray Selected frontends to use for the share (default [public])\n --headless Disable TUI and run headless\n -h, --help help for public\n --insecure Enable insecure TLS certificate validation for \n --oauth-check-interval duration Maximum lifetime for OAuth authentication; reauthenticate after expiry (default 3h0m0s)\n --oauth-email-domains stringArray Allow only these email domains to authenticate via OAuth\n --oauth-provider string Enable OAuth provider [google, github]\n\nGlobal Flags:\n -p, --panic Panic instead of showing pretty errors\n -v, --verbose Enable verbose logging\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"--oauth-provider"})," flag enables OAuth for the share using the specified provider."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"--oauth-email-domains"})," flag accepts a comma-separated list of authenticated email address domains that are allowed to access the share."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"--oauth-check-interval"})," flag specifies how frequently the authentication must be checked."]}),"\n",(0,i.jsx)(n.p,{children:"An example public share:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:"zrok share public --backend-mode web --oauth-provider github --oauth-email-domains zrok.io ~/public\n"})})]})}function l(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},9980:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/github_create_oauth_application_1-dbb289a694d0c99b50cb949654d818f8.png"},4861:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/github_create_oauth_application_2-bc9d4c3f25853d608870eb220d00e5ee.png"},5758:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/github_create_oauth_application_3-7973d63cd117eaba72fbaeb4ff119a39.png"},1995:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/github_create_oauth_application_4-6fed398013c9e6c3a31e5721adac4a4c.png"},5180:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_create_credentials_1-e61ee7e8fa51bdc93feab84235a90673.png"},5871:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_create_credentials_2-60cf4edb52f453d605907c17400e0800.png"},9572:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_create_credentials_3-1b3db3f9057d8626d64c5466dbb05ec7.png"},1115:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_create_credentials_4-f720031df1d09f997a18842745e9ea0d.png"},7199:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_oauth_content_screen_2-b94a6456ce9b13e053b4c07d8f233e84.png"},2795:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_oauth_content_screen_3-edf62ea2b291b58093289d31c2dae58d.png"},3923:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_oauth_content_screen_4-4bc7e07b06c8a9a3c1e8f766f6f1c5a6.png"},2575:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_oauth_content_screen_5-7c375cf49d8e2e392ca12b584462ab59.png"},72:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/google_oauth_content_screen_6-9b0fe216a782ef378313650e99ea52a1.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>r});var i=t(7294);const o={},s=i.createContext(o);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cda0d2e5.40baeef1.js b/assets/js/cda0d2e5.40baeef1.js new file mode 100644 index 00000000..2a27307d --- /dev/null +++ b/assets/js/cda0d2e5.40baeef1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[846],{9836:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>v,contentTitle:()=>k,default:()=>z,frontMatter:()=>b,metadata:()=>f,toc:()=>y});var s=r(5893),i=r(1151),o=r(7294),t=r(4866),a=r(5518);const c=function(e){const[n,r]=(0,o.useState)(null);return(0,o.useEffect)((()=>{["Mac OS","Windows","Linux"].includes(a.BF)?r(a.BF):r("Linux")}),[]),(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(t.Z,{...e,defaultValue:n,children:e.children})})};var d=r(5162),l=r(1326),h=r(2753);function p(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components},{Details:r}=n;return r||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"goal",children:"Goal"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved public subdomain to a backend target with an always-on Linux system service."}),"\n",(0,s.jsx)(n.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"zrok-share"})," package creates a ",(0,s.jsx)(n.code,{children:"zrok-share.service"})," unit in systemd. The administrator edits the service's configuration file to specify the:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"zrok environment enable token"}),"\n",(0,s.jsxs)(n.li,{children:["target URL or files to be shared and backend mode, e.g. ",(0,s.jsx)(n.code,{children:"proxy"})]}),"\n",(0,s.jsx)(n.li,{children:"authentication options, if wanted"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When the service starts it will:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["enable the zrok environment unless ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/environment.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["reserve a public subdomain for the service unless ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/reserved.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["start sharing the target specified as ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," in the environment file"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Set up ",(0,s.jsx)(n.code,{children:"zrok"}),"'s Linux package repository by following ",(0,s.jsx)(n.a,{href:"/docs/guides/install/linux#install-zrok-from-the-repository",children:"the Linux install guide"}),", or run this one-liner to complete the repo setup and install packages."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sSLf https://get.openziti.io/install.bash \\\n| sudo bash -s zrok-share\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["If you set up the repository by following the guide, then also install the ",(0,s.jsx)(n.code,{children:"zrok-share"})," package. This package provides the systemd service."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Ubuntu, Debian"',children:"sudo apt install zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Fedora, Rocky"',children:"sudo dnf install zrok-share\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(r,{children:[(0,s.jsx)("summary",{children:"Ansible Playbook"}),(0,s.jsxs)(h.Z,{title:"Set up package repository and install zrok-share",children:[l.Z,"\n- name: Install zrok-share package\n gather_facts: false\n hosts: all \n become: true\n tasks:\n - name: Install zrok-share\n ansible.builtin.package:\n name: zrok-share\n state: present\n\n - name: Copy env config from Ansible controller to target\n copy:\n dest: /opt/openziti/etc/zrok/zrok-share.env\n src: /opt/openziti/etc/zrok/zrok-share.env\n\n - name: Enable and restart service\n systemd:\n name: zrok-share\n enabled: yes\n state: restarted\n daemon_reload: yes\n\n - name: Wait for service\n systemd:\n name: zrok-share\n state: started\n register: service_status\n until: service_status.status.ActiveState == 'active'\n retries: 30\n delay: 1\n"]})]}),"\n",(0,s.jsx)(n.h2,{id:"enable",children:"Enable"}),"\n",(0,s.jsx)(n.p,{children:"Save the enable token from the zrok console in the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_ENABLE_TOKEN="14cbfca9772f"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"name-your-share",children:"Name your Share"}),"\n",(0,s.jsxs)(n.p,{children:["This unique name becomes part of the domain name of the share, e.g. ",(0,s.jsx)(n.code,{children:"https://my-prod-app.in.zrok.io"}),". A random name is generated if you don't specify one."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_UNIQUE_NAME="my-prod-app"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,s.jsxs)(n.p,{children:["You may change the target for the current backend mode, e.g. ",(0,s.jsx)(n.code,{children:"proxy"}),", by editing the configuration file and restarting the service. The reserved subdomain will remain the same."]}),"\n",(0,s.jsxs)(n.p,{children:["You may switch between backend modes or change authentication options by deleting ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/reserved.json"})," and restarting the service. A new subdomain will be reserved."]}),"\n",(0,s.jsx)(n.h3,{id:"proxy-a-web-server",children:"Proxy a Web Server"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved subdomain to an existing web server. The web server could be on a private network or on the same host as zrok."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="http://127.0.0.1:3000"\nZROK_BACKEND_MODE="proxy"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If your HTTPS server has an unverifiable TLS server certificate then you must set ",(0,s.jsx)(n.code,{children:"--insecure"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_INSECURE="--insecure"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"serve-static-files",children:"Serve Static Files"}),"\n",(0,s.jsxs)(n.p,{children:["Run zrok's embedded web server to serve the files in a directory. If there's an ",(0,s.jsx)(n.code,{children:"index.html"})," file in the directory then visitors will see that web page in their browser, otherwise they'll see a generated index of the files. The directory must be readable by 'other', e.g. ",(0,s.jsx)(n.code,{children:"chmod -R o+rX /var/www/html"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/var/www/html"\nZROK_BACKEND_MODE="web"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"caddy-server",children:"Caddy Server"}),"\n",(0,s.jsx)(n.p,{children:"Use zrok's built-in Caddy server to serve static files or as a reverse proxy to multiple web servers with various HTTP routes or as a load-balanced set. A sample Caddyfile is available in the path shown."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/opt/openziti/etc/zrok/multiple_upstream.Caddyfile"\nZROK_BACKEND_MODE="caddy"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"network-drive",children:"Network Drive"}),"\n",(0,s.jsxs)(n.p,{children:["This uses zrok's ",(0,s.jsx)(n.code,{children:"drive"})," backend mode to serve a directory of static files as a virtual network drive. The directory must be readable by 'other', e.g. ",(0,s.jsx)(n.code,{children:"chmod -R o+rX /usr/share/doc"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/usr/share/doc"\nZROK_BACKEND_MODE="drive"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://blog.openziti.io/zrok-drives-an-early-preview",children:"Learn more about this feature in this blog post"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"authentication",children:"Authentication"}),"\n",(0,s.jsx)(n.p,{children:"You can limit access to certain email addresses with OAuth or require a password."}),"\n",(0,s.jsx)(n.h3,{id:"oauth",children:"OAuth"}),"\n",(0,s.jsx)(n.p,{children:"You can require that visitors authenticate with an email address that matches at least one of the suffixes you specify. Add the following to the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_OAUTH_PROVIDER="github" # or google\nZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"password",children:"Password"}),"\n",(0,s.jsx)(n.p,{children:"Enable HTTP basic authentication by adding the following to the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_BASIC_AUTH="user:passwd"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"start-the-service",children:"Start the Service"}),"\n",(0,s.jsx)(n.p,{children:"Start the service, and check the zrok console or the service log for the reserved subdomain."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="run now and at startup"',children:"sudo systemctl enable --now zrok-share.service\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="run now"',children:"sudo systemctl restart zrok-share.service\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"journalctl -u zrok-share.service\n"})}),"\n",(0,s.jsx)(n.h2,{id:"compatibility",children:"Compatibility"}),"\n",(0,s.jsxs)(n.p,{children:["The Linux distribution must have a package manager that understands the ",(0,s.jsx)(n.code,{children:".deb"})," or ",(0,s.jsx)(n.code,{children:".rpm"})," format and be running systemd v232 or newer. The service was tested with:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Ubuntu 20.04, 22.04, 23.04"}),"\n",(0,s.jsx)(n.li,{children:"Debian 11 12"}),"\n",(0,s.jsx)(n.li,{children:"Rocky 8, 9"}),"\n",(0,s.jsx)(n.li,{children:"Fedora 37, 38"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"package-contents",children:"Package Contents"}),"\n",(0,s.jsxs)(n.p,{children:["The files included in the ",(0,s.jsx)(n.code,{children:"zrok-share"})," package are sourced ",(0,s.jsx)(n.a,{href:"https://github.com/openziti/zrok/tree/main/nfpm",children:"here in GitHub"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}function m(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"goal",children:"Goal"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved public subdomain to a backend target with an always-on Docker Compose service."}),"\n",(0,s.jsx)(n.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsx)(n.p,{children:"The Docker Compose project uses your zrok account token to reserve a public subdomain and keep sharing the backend\ntarget."}),"\n",(0,s.jsx)(n.p,{children:"When the project runs it will:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["enable a zrok environment unless ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/environment.json"})," exists in the ",(0,s.jsx)(n.code,{children:"zrok_env"})," volume"]}),"\n",(0,s.jsxs)(n.li,{children:["reserve a public subdomain for the service unless ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/reserved.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["start sharing the target specified in the ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," environment variable"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"create-the-docker-project",children:"Create the Docker Project"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok public share with a reserved subdomain and switch to the new directory in your terminal."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Download ",(0,s.jsxs)(n.a,{href:"pathname:///zrok-public-reserved/compose.yml",children:["the reserved public share ",(0,s.jsx)(n.code,{children:"compose.yml"})," project file"]})," into the same directory."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Copy your zrok account's enable token from the zrok web console to your clipboard and paste it in a file named ",(0,s.jsx)(n.code,{children:".env"})," in the same folder like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Name the Share"}),"\n",(0,s.jsxs)(n.p,{children:["This unique name becomes part of the domain name of the share, e.g. ",(0,s.jsx)(n.code,{children:"https://my-prod-app.in.zrok.io"}),". A random name is generated if you don't specify one."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_UNIQUE_NAME="my-prod-app"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run the Compose project to start sharing the built-in demo web server. Be sure to ",(0,s.jsx)(n.code,{children:"--detach"})," so the project runs in the background if you want it to auto-restart when your computer reboots."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Get the public share URL from the output of the ",(0,s.jsx)(n.code,{children:"zrok-share"})," service or by peeking in the zrok console where the share will appear in the graph."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This concludes the minimum steps to begin sharing the demo web server. Read on to learn how to pivot to sharing any website or web service by leveraging additional zrok backend modes."}),"\n",(0,s.jsx)(n.h2,{id:"proxy-any-web-server",children:"Proxy Any Web Server"}),"\n",(0,s.jsxs)(n.p,{children:["The simplest way to share your existing HTTP server is to set ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," (e.g. ",(0,s.jsx)(n.code,{children:"https://example.com"}),") in the environment of the ",(0,s.jsx)(n.code,{children:"docker compose up"})," command. When you restart the share will auto-configure for that URL."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_TARGET="http://example.com:8080"\n'})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose down && docker compose up\n"})}),"\n",(0,s.jsx)(n.h2,{id:"require-authentication",children:"Require Authentication"}),"\n",(0,s.jsx)(n.p,{children:"You can require a password or an OAuth login with certain email addresses."}),"\n",(0,s.jsx)(n.h3,{id:"oauth-email",children:"OAuth Email"}),"\n",(0,s.jsxs)(n.p,{children:["You can allow specific email addresses or an email domain by setting ",(0,s.jsx)(n.code,{children:"ZROK_OAUTH_PROVIDER"})," to ",(0,s.jsx)(n.code,{children:"github"})," or ",(0,s.jsx)(n.code,{children:"google"})," and\n",(0,s.jsx)(n.code,{children:"ZROK_SHARE_OPTS"})," to specify additional command-line options to ",(0,s.jsx)(n.code,{children:"zrok reserve public"}),". Read more about the OAuth\nfeatures in ",(0,s.jsx)(n.a,{href:"https://blog.openziti.io/the-zrok-oauth-public-frontend",children:"this blog post"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_OAUTH_PROVIDER="github"\nZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"caddy-is-powerful",children:"Caddy is Powerful"}),"\n",(0,s.jsxs)(n.p,{children:["The reserved public share project uses zrok's default backend mode, ",(0,s.jsx)(n.code,{children:"proxy"}),". Another backend mode, ",(0,s.jsx)(n.code,{children:"caddy"}),", accepts a path to ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/caddyfile",children:"a Caddyfile"})," as the value of ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," (",(0,s.jsx)(n.a,{href:"https://github.com/openziti/zrok/tree/main/etc/caddy",children:"zrok Caddyfile examples"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["Caddy is the most powerful and flexible backend mode in zrok. You must reserve a new public subdomain whenever you switch the backend mode, so using ",(0,s.jsx)(n.code,{children:"caddy"})," reduces the risk that you'll have to share a new frontend URL with your users."]}),"\n",(0,s.jsx)(n.p,{children:"With Caddy, you can balance the workload for websites or web services or share static sites and files or all of the above at the same time. You can update the Caddyfile and restart the Docker Compose project to start sharing the new configuration with the same reserved public subdomain."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Create a Caddyfile. This example demonstrates proxying two HTTP servers with a weighted round-robin load balancer."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",metastring:'title="Caddyfile"',children:"http:// {\n # zrok requires this bind address template\n bind {{ .ZrokBindAddress }}\n reverse_proxy /* {\n to http://httpbin1:8080 http://httpbin2:8080\n lb_policy weighted_round_robin 3 2\n }\n}\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a file ",(0,s.jsx)(n.code,{children:"compose.override.yml"}),". This example adds two ",(0,s.jsx)(n.code,{children:"httpbin"})," containers for load balancing, and mounts the Caddyfile into the container."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="compose.override.yml"',children:"services:\n httpbin1:\n image: mccutchen/go-httpbin # 8080/tcp\n httpbin2:\n image: mccutchen/go-httpbin # 8080/tcp\n zrok-share:\n volumes:\n - ./Caddyfile:/mnt/.zrok/Caddyfile\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Start a new Docker Compose project or delete the existing state volume."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose down --volumes\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If you prefer to keep using the same zrok environment with the new share then delete ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/reserved.json"})," instead of the entire volume."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Run the project to load the new configuration."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Note the new reserved share URL from the log."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"INFO: zrok public URL: https://88s803f2qvao.in.zrok.io/\n"})}),"\n"]}),"\n"]})]})}function x(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(m,{...e})}):m(e)}var j=r(9965),g=r(4996);const b={title:"zrok frontdoor",sidebar_label:"frontdoor",sidebar_position:20,hide_table_of_contents:!0},k=void 0,f={id:"guides/frontdoor",title:"zrok frontdoor",description:"zrok frontdoor is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends.",source:"@site/../docs/guides/frontdoor.mdx",sourceDirName:"guides",slug:"/guides/frontdoor",permalink:"/docs/guides/frontdoor",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/frontdoor.mdx",tags:[],version:"current",sidebarPosition:20,frontMatter:{title:"zrok frontdoor",sidebar_label:"frontdoor",sidebar_position:20,hide_table_of_contents:!0},sidebar:"tutorialSidebar",previous:{title:"Windows",permalink:"/docs/guides/install/windows"},next:{title:"Docker Share",permalink:"/docs/category/docker-share"}},v={},y=[{value:"Overview",id:"overview",level:2},{value:"Choose your OS",id:"choose-your-os",level:2},{value:"Concepts",id:"concepts",level:2}];function w(e){const n={a:"a",code:"code",h2:"h2",p:"p",strong:"strong",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"zrok frontdoor"})," is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends."]}),"\n",(0,s.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/5Vi8GKuTi_I",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["zrok frontends are the parts of zrok that proxy incoming public web traffic to zrok backend shares via OpenZiti. When you use zrok with a ",(0,s.jsx)(n.code,{children:"zrok.io"})," frontend, you're using ",(0,s.jsx)(n.strong,{children:"zrok frontdoor"}),". ",(0,s.jsx)(n.code,{children:"zrok.io"})," is zrok-as-a-service by NetFoundry, the team behind OpenZiti. You need a free account to use ",(0,s.jsx)(n.strong,{children:"zrok frontdoor"}),"."]}),"\n",(0,s.jsx)(j.Z,{alt:"frontdoor diagram",sources:{light:(0,g.Z)("/img/zrok-frontdoor-light-mode.svg"),dark:(0,g.Z)("/img/zrok-frontdoor-dark-mode.svg")}}),"\n",(0,s.jsx)(n.h2,{id:"choose-your-os",children:"Choose your OS"}),"\n",(0,s.jsx)(n.p,{children:"Choose between installing the Linux package or running zrok with Docker (Linux, macOS, or Windows)."}),"\n",(0,s.jsxs)(c,{queryString:"os",values:[{label:"Linux",value:"Linux"},{label:"macOS",value:"Mac OS"},{label:"Windows",value:"Windows"}],children:[(0,s.jsxs)(d.Z,{value:"Linux",children:[(0,s.jsxs)(n.p,{children:["On Linux, zrok frontdoor is implemented natively as a system service provided by the ",(0,s.jsx)(n.code,{children:"zrok-share"})," DEB or RPM package."]}),(0,s.jsxs)(n.p,{children:["If you'd prefer to run zrok in Docker instead of installing the package then you can follow the Docker instructions. With Docker, the steps are the same for Linux, ",(0,s.jsx)(n.a,{href:"./?os=Mac+OS",children:"macOS"}),", and ",(0,s.jsx)(n.a,{href:"./?os=Windows",children:"Windows"}),"."]}),(0,s.jsx)(u,{})]}),(0,s.jsxs)(d.Z,{value:"Mac OS",children:[(0,s.jsx)(n.p,{children:"On macOS, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service."}),(0,s.jsx)(x,{})]}),(0,s.jsxs)(d.Z,{value:"Windows",children:[(0,s.jsx)(n.p,{children:"On Windows, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service."}),(0,s.jsx)(x,{})]})]}),"\n",(0,s.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,s.jsxs)(n.p,{children:["Overview of ",(0,s.jsx)(n.a,{href:"/docs/concepts/sharing-reserved",children:"zrok reserved shares"})]})]})}function z(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(w,{...e})}):w(e)}},2753:(e,n,r)=>{r.d(n,{Z:()=>t});r(7294);var s=r(1272),i=r(9286),o=r(5893);const t=e=>{let{title:n,children:r}=e;const t=r.map((e=>"string"==typeof e?e.trim():s.ZP.dump(e).trim())).join("\n\n");return(0,o.jsx)("div",{children:(0,o.jsx)(i.Z,{language:"yaml",title:n,children:t})})}},1326:(e,n,r)=>{r.d(n,{Z:()=>s});const s=[{name:"Set up zrok Package Repo",gather_facts:!0,hosts:"all",become:!0,tasks:[{name:"Set up apt repo",when:'ansible_os_family == "Debian"',block:[{name:"Install playbook dependencies","ansible.builtin.package":{name:["gnupg"],state:"present"}},{name:"Fetch armored pubkey","ansible.builtin.uri":{url:"https://get.openziti.io/tun/package-repos.gpg",return_content:"yes"},register:"armored_pubkey"},{name:"Dearmor pubkey","ansible.builtin.shell":'gpg --dearmor --output /usr/share/keyrings/openziti.gpg <<< "{{ armored_pubkey.content }}"\n',args:{creates:"/usr/share/keyrings/openziti.gpg",executable:"/bin/bash"}},{name:"Set pubkey filemode","ansible.builtin.file":{path:"/usr/share/keyrings/openziti.gpg",mode:"a+rX"}},{name:"Install OpenZiti repo deb source","ansible.builtin.copy":{dest:"/etc/apt/sources.list.d/openziti-release.list",content:"deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable debian main\n"}},{name:"Refresh Repo Sources","ansible.builtin.apt":{update_cache:"yes",cache_valid_time:3600}}]},{name:"Set up yum repo",when:'ansible_os_family == "RedHat"',block:[{name:"Install OpenZiti repo rpm source","ansible.builtin.yum_repository":{name:"OpenZitiRelease",description:"OpenZiti Release",baseurl:"https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch",enabled:"yes",gpgkey:"https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch/repodata/repomd.xml.key",repo_gpgcheck:"yes",gpgcheck:"no"}}]}]}]}}]); \ No newline at end of file diff --git a/assets/js/cda0d2e5.b45c8e1c.js b/assets/js/cda0d2e5.b45c8e1c.js deleted file mode 100644 index 49e238bc..00000000 --- a/assets/js/cda0d2e5.b45c8e1c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[846],{9836:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>v,contentTitle:()=>k,default:()=>z,frontMatter:()=>b,metadata:()=>f,toc:()=>y});var s=r(5893),i=r(1151),o=r(7294),t=r(4866),a=r(5518);const d=function(e){const[n,r]=(0,o.useState)(null);return(0,o.useEffect)((()=>{["Mac OS","Windows","Linux"].includes(a.BF)?r(a.BF):r("Linux")}),[]),(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(t.Z,{...e,defaultValue:n,children:e.children})})};var c=r(5162),l=r(1326),h=r(2753);function p(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components},{Details:r}=n;return r||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"goal",children:"Goal"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved public subdomain to a backend target with an always-on Linux system service."}),"\n",(0,s.jsx)(n.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"zrok-share"})," package creates a ",(0,s.jsx)(n.code,{children:"zrok-share.service"})," unit in systemd. The administrator edits the service's configuration file to specify the:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"zrok environment enable token"}),"\n",(0,s.jsxs)(n.li,{children:["target URL or files to be shared and backend mode, e.g. ",(0,s.jsx)(n.code,{children:"proxy"})]}),"\n",(0,s.jsx)(n.li,{children:"authentication options, if wanted"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When the service starts it will:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["enable the zrok environment unless ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/environment.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["reserve a public subdomain for the service unless ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/reserved.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["start sharing the target specified as ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," in the environment file"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Set up ",(0,s.jsx)(n.code,{children:"zrok"}),"'s Linux package repository by following ",(0,s.jsx)(n.a,{href:"/docs/guides/install/linux#install-zrok-from-the-repository",children:"the Linux install guide"}),", or run this one-liner to complete the repo setup and install packages."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sSLf https://get.openziti.io/install.bash \\\n| sudo bash -s zrok-share\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["If you set up the repository by following the guide, then also install the ",(0,s.jsx)(n.code,{children:"zrok-share"})," package. This package provides the systemd service."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Ubuntu, Debian"',children:"sudo apt install zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Fedora, Rocky"',children:"sudo dnf install zrok-share\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(r,{children:[(0,s.jsx)("summary",{children:"Ansible Playbook"}),(0,s.jsxs)(h.Z,{title:"Set up package repository and install zrok-share",children:[l.Z,"\n- name: Install zrok-share package\n gather_facts: false\n hosts: all \n become: true\n tasks:\n - name: Install zrok-share\n ansible.builtin.package:\n name: zrok-share\n state: present\n\n - name: Copy env config from Ansible controller to target\n copy:\n dest: /opt/openziti/etc/zrok/zrok-share.env\n src: /opt/openziti/etc/zrok/zrok-share.env\n\n - name: Enable and restart service\n systemd:\n name: zrok-share\n enabled: yes\n state: restarted\n daemon_reload: yes\n\n - name: Wait for service\n systemd:\n name: zrok-share\n state: started\n register: service_status\n until: service_status.status.ActiveState == 'active'\n retries: 30\n delay: 1\n"]})]}),"\n",(0,s.jsx)(n.h2,{id:"enable",children:"Enable"}),"\n",(0,s.jsx)(n.p,{children:"Save the enable token from the zrok console in the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_ENABLE_TOKEN="14cbfca9772f"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"name-your-share",children:"Name your Share"}),"\n",(0,s.jsxs)(n.p,{children:["This unique name becomes part of the domain name of the share, e.g. ",(0,s.jsx)(n.code,{children:"https://my-prod-app.in.zrok.io"}),". A random name is generated if you don't specify one."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_UNIQUE_NAME="my-prod-app"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,s.jsxs)(n.p,{children:["You may change the target for the current backend mode, e.g. ",(0,s.jsx)(n.code,{children:"proxy"}),", by editing the configuration file and restarting the service. The reserved subdomain will remain the same."]}),"\n",(0,s.jsxs)(n.p,{children:["You may switch between backend modes or change authentication options by deleting ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/reserved.json"})," and restarting the service. A new subdomain will be reserved."]}),"\n",(0,s.jsx)(n.h3,{id:"proxy-a-web-server",children:"Proxy a Web Server"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved subdomain to an existing web server. The web server could be on a private network or on the same host as zrok."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="http://127.0.0.1:3000"\nZROK_BACKEND_MODE="proxy"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If your HTTPS server has an unverifiable TLS server certificate then you must set ",(0,s.jsx)(n.code,{children:"--insecure"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_INSECURE="--insecure"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"serve-static-files",children:"Serve Static Files"}),"\n",(0,s.jsxs)(n.p,{children:["Run zrok's embedded web server to serve the files in a directory. If there's an ",(0,s.jsx)(n.code,{children:"index.html"})," file in the directory then visitors will see that web page in their browser, otherwise they'll see a generated index of the files. The directory must be readable by 'other', e.g. ",(0,s.jsx)(n.code,{children:"chmod -R o+rX /var/www/html"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/var/www/html"\nZROK_BACKEND_MODE="web"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"caddy-server",children:"Caddy Server"}),"\n",(0,s.jsx)(n.p,{children:"Use zrok's built-in Caddy server to serve static files or as a reverse proxy to multiple web servers with various HTTP routes or as a load-balanced set. A sample Caddyfile is available in the path shown."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/opt/openziti/etc/zrok/multiple_upstream.Caddyfile"\nZROK_BACKEND_MODE="caddy"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"network-drive",children:"Network Drive"}),"\n",(0,s.jsxs)(n.p,{children:["This uses zrok's ",(0,s.jsx)(n.code,{children:"drive"})," backend mode to serve a directory of static files as a virtual network drive. The directory must be readable by 'other', e.g. ",(0,s.jsx)(n.code,{children:"chmod -R o+rX /usr/share/doc"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/usr/share/doc"\nZROK_BACKEND_MODE="drive"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://blog.openziti.io/zrok-drives-an-early-preview",children:"Learn more about this feature in this blog post"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"authentication",children:"Authentication"}),"\n",(0,s.jsx)(n.p,{children:"You can limit access to certain email addresses with OAuth or require a password."}),"\n",(0,s.jsx)(n.h3,{id:"oauth",children:"OAuth"}),"\n",(0,s.jsx)(n.p,{children:"You can require that visitors authenticate with an email address that matches at least one of the suffixes you specify. Add the following to the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_OAUTH_PROVIDER="github" # or google\nZROK_OAUTH_EMAILS="bob@example.com @acme.example.com"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"password",children:"Password"}),"\n",(0,s.jsx)(n.p,{children:"Enable HTTP basic authentication by adding the following to the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_BASIC_AUTH="user:passwd"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"start-the-service",children:"Start the Service"}),"\n",(0,s.jsx)(n.p,{children:"Start the service, and check the zrok console or the service log for the reserved subdomain."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="run now and at startup"',children:"sudo systemctl enable --now zrok-share.service\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="run now"',children:"sudo systemctl restart zrok-share.service\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"journalctl -u zrok-share.service\n"})}),"\n",(0,s.jsx)(n.h2,{id:"compatibility",children:"Compatibility"}),"\n",(0,s.jsxs)(n.p,{children:["The Linux distribution must have a package manager that understands the ",(0,s.jsx)(n.code,{children:".deb"})," or ",(0,s.jsx)(n.code,{children:".rpm"})," format and be running systemd v232 or newer. The service was tested with:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Ubuntu 20.04, 22.04, 23.04"}),"\n",(0,s.jsx)(n.li,{children:"Debian 11 12"}),"\n",(0,s.jsx)(n.li,{children:"Rocky 8, 9"}),"\n",(0,s.jsx)(n.li,{children:"Fedora 37, 38"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"package-contents",children:"Package Contents"}),"\n",(0,s.jsxs)(n.p,{children:["The files included in the ",(0,s.jsx)(n.code,{children:"zrok-share"})," package are sourced ",(0,s.jsx)(n.a,{href:"https://github.com/openziti/zrok/tree/main/nfpm",children:"here in GitHub"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}function m(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"goal",children:"Goal"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved public subdomain to a backend target with an always-on Docker Compose service."}),"\n",(0,s.jsx)(n.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsx)(n.p,{children:"The Docker Compose project uses your zrok account token to reserve a public subdomain and keep sharing the backend\ntarget."}),"\n",(0,s.jsx)(n.p,{children:"When the project runs it will:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["enable a zrok environment unless ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/environment.json"})," exists in the ",(0,s.jsx)(n.code,{children:"zrok_env"})," volume"]}),"\n",(0,s.jsxs)(n.li,{children:["reserve a public subdomain for the service unless ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/reserved.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["start sharing the target specified in the ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," environment variable"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"create-the-docker-project",children:"Create the Docker Project"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok public share with a reserved subdomain and switch to the new directory in your terminal."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Download ",(0,s.jsxs)(n.a,{href:"pathname:///zrok-public-reserved/compose.yml",children:["the reserved public share ",(0,s.jsx)(n.code,{children:"compose.yml"})," project file"]})," into the same directory."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Copy your zrok account's enable token from the zrok web console to your clipboard and paste it in a file named ",(0,s.jsx)(n.code,{children:".env"})," in the same folder like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Name the Share"}),"\n",(0,s.jsxs)(n.p,{children:["This unique name becomes part of the domain name of the share, e.g. ",(0,s.jsx)(n.code,{children:"https://my-prod-app.in.zrok.io"}),". A random name is generated if you don't specify one."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_UNIQUE_NAME="my-prod-app"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run the Compose project to start sharing the built-in demo web server. Be sure to ",(0,s.jsx)(n.code,{children:"--detach"})," so the project runs in the background if you want it to auto-restart when your computer reboots."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Get the public share URL from the output of the ",(0,s.jsx)(n.code,{children:"zrok-share"})," service or by peeking in the zrok console where the share will appear in the graph."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This concludes the minimum steps to begin sharing the demo web server. Read on to learn how to pivot to sharing any website or web service by leveraging additional zrok backend modes."}),"\n",(0,s.jsx)(n.h2,{id:"proxy-any-web-server",children:"Proxy Any Web Server"}),"\n",(0,s.jsxs)(n.p,{children:["The simplest way to share your existing HTTP server is to set ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," (e.g. ",(0,s.jsx)(n.code,{children:"https://example.com"}),") in the environment of the ",(0,s.jsx)(n.code,{children:"docker compose up"})," command. When you restart the share will auto-configure for that URL."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_TARGET="http://example.com:8080"\n'})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose down && docker compose up\n"})}),"\n",(0,s.jsx)(n.h2,{id:"require-authentication",children:"Require Authentication"}),"\n",(0,s.jsx)(n.p,{children:"You can require a password or an OAuth login with certain email addresses."}),"\n",(0,s.jsx)(n.h3,{id:"oauth-email",children:"OAuth Email"}),"\n",(0,s.jsxs)(n.p,{children:["You can allow specific email addresses or an email domain by setting ",(0,s.jsx)(n.code,{children:"ZROK_OAUTH_PROVIDER"})," to ",(0,s.jsx)(n.code,{children:"github"})," or ",(0,s.jsx)(n.code,{children:"google"})," and\n",(0,s.jsx)(n.code,{children:"ZROK_SHARE_OPTS"})," to specify additional command-line options to ",(0,s.jsx)(n.code,{children:"zrok reserve public"}),". Read more about the OAuth\nfeatures in ",(0,s.jsx)(n.a,{href:"https://blog.openziti.io/the-zrok-oauth-public-frontend",children:"this blog post"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_OAUTH_PROVIDER="github"\nZROK_SHARE_OPTS="--oauth-email-domains @example.com"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"caddy-is-powerful",children:"Caddy is Powerful"}),"\n",(0,s.jsxs)(n.p,{children:["The reserved public share project uses zrok's default backend mode, ",(0,s.jsx)(n.code,{children:"proxy"}),". Another backend mode, ",(0,s.jsx)(n.code,{children:"caddy"}),", accepts a path to ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/caddyfile",children:"a Caddyfile"})," as the value of ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," (",(0,s.jsx)(n.a,{href:"https://github.com/openziti/zrok/tree/main/etc/caddy",children:"zrok Caddyfile examples"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["Caddy is the most powerful and flexible backend mode in zrok. You must reserve a new public subdomain whenever you switch the backend mode, so using ",(0,s.jsx)(n.code,{children:"caddy"})," reduces the risk that you'll have to share a new frontend URL with your users."]}),"\n",(0,s.jsx)(n.p,{children:"With Caddy, you can balance the workload for websites or web services or share static sites and files or all of the above at the same time. You can update the Caddyfile and restart the Docker Compose project to start sharing the new configuration with the same reserved public subdomain."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Create a Caddyfile. This example demonstrates proxying two HTTP servers with a weighted round-robin load balancer."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",metastring:'title="Caddyfile"',children:"http:// {\n # zrok requires this bind address template\n bind {{ .ZrokBindAddress }}\n reverse_proxy /* {\n to http://httpbin1:8080 http://httpbin2:8080\n lb_policy weighted_round_robin 3 2\n }\n}\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a file ",(0,s.jsx)(n.code,{children:"compose.override.yml"}),". This example adds two ",(0,s.jsx)(n.code,{children:"httpbin"})," containers for load balancing, and mounts the Caddyfile into the container."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="compose.override.yml"',children:"services:\n httpbin1:\n image: mccutchen/go-httpbin # 8080/tcp\n httpbin2:\n image: mccutchen/go-httpbin # 8080/tcp\n zrok-share:\n volumes:\n - ./Caddyfile:/mnt/.zrok/Caddyfile\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Start a new Docker Compose project or delete the existing state volume."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose down --volumes\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If you prefer to keep using the same zrok environment with the new share then delete ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/reserved.json"})," instead of the entire volume."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Run the project to load the new configuration."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Note the new reserved share URL from the log."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"INFO: zrok public URL: https://88s803f2qvao.in.zrok.io/\n"})}),"\n"]}),"\n"]})]})}function x(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(m,{...e})}):m(e)}var j=r(9965),g=r(4996);const b={title:"zrok frontdoor",sidebar_label:"frontdoor",sidebar_position:20,hide_table_of_contents:!0},k=void 0,f={id:"guides/frontdoor",title:"zrok frontdoor",description:"zrok frontdoor is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends.",source:"@site/../docs/guides/frontdoor.mdx",sourceDirName:"guides",slug:"/guides/frontdoor",permalink:"/docs/guides/frontdoor",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/frontdoor.mdx",tags:[],version:"current",sidebarPosition:20,frontMatter:{title:"zrok frontdoor",sidebar_label:"frontdoor",sidebar_position:20,hide_table_of_contents:!0},sidebar:"tutorialSidebar",previous:{title:"Windows",permalink:"/docs/guides/install/windows"},next:{title:"Docker Share",permalink:"/docs/category/docker-share"}},v={},y=[{value:"Overview",id:"overview",level:2},{value:"Choose your OS",id:"choose-your-os",level:2},{value:"Concepts",id:"concepts",level:2}];function w(e){const n={a:"a",code:"code",h2:"h2",p:"p",strong:"strong",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"zrok frontdoor"})," is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends."]}),"\n",(0,s.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/5Vi8GKuTi_I",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["zrok frontends are the parts of zrok that proxy incoming public web traffic to zrok backend shares via OpenZiti. When you use zrok with a ",(0,s.jsx)(n.code,{children:"zrok.io"})," frontend, you're using ",(0,s.jsx)(n.strong,{children:"zrok frontdoor"}),". ",(0,s.jsx)(n.code,{children:"zrok.io"})," is zrok-as-a-service by NetFoundry, the team behind OpenZiti. You need a free account to use ",(0,s.jsx)(n.strong,{children:"zrok frontdoor"}),"."]}),"\n",(0,s.jsx)(j.Z,{alt:"frontdoor diagram",sources:{light:(0,g.Z)("/img/zrok-frontdoor-light-mode.svg"),dark:(0,g.Z)("/img/zrok-frontdoor-dark-mode.svg")}}),"\n",(0,s.jsx)(n.h2,{id:"choose-your-os",children:"Choose your OS"}),"\n",(0,s.jsx)(n.p,{children:"Choose between installing the Linux package or running zrok with Docker (Linux, macOS, or Windows)."}),"\n",(0,s.jsxs)(d,{queryString:"os",values:[{label:"Linux",value:"Linux"},{label:"macOS",value:"Mac OS"},{label:"Windows",value:"Windows"}],children:[(0,s.jsxs)(c.Z,{value:"Linux",children:[(0,s.jsxs)(n.p,{children:["On Linux, zrok frontdoor is implemented natively as a system service provided by the ",(0,s.jsx)(n.code,{children:"zrok-share"})," DEB or RPM package."]}),(0,s.jsxs)(n.p,{children:["If you'd prefer to run zrok in Docker instead of installing the package then you can follow the Docker instructions. With Docker, the steps are the same for Linux, ",(0,s.jsx)(n.a,{href:"./?os=Mac+OS",children:"macOS"}),", and ",(0,s.jsx)(n.a,{href:"./?os=Windows",children:"Windows"}),"."]}),(0,s.jsx)(u,{})]}),(0,s.jsxs)(c.Z,{value:"Mac OS",children:[(0,s.jsx)(n.p,{children:"On macOS, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service."}),(0,s.jsx)(x,{})]}),(0,s.jsxs)(c.Z,{value:"Windows",children:[(0,s.jsx)(n.p,{children:"On Windows, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service."}),(0,s.jsx)(x,{})]})]}),"\n",(0,s.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,s.jsxs)(n.p,{children:["Overview of ",(0,s.jsx)(n.a,{href:"/docs/concepts/sharing-reserved",children:"zrok reserved shares"})]})]})}function z(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(w,{...e})}):w(e)}},2753:(e,n,r)=>{r.d(n,{Z:()=>t});r(7294);var s=r(1272),i=r(9286),o=r(5893);const t=e=>{let{title:n,children:r}=e;const t=r.map((e=>"string"==typeof e?e.trim():s.ZP.dump(e).trim())).join("\n\n");return(0,o.jsx)("div",{children:(0,o.jsx)(i.Z,{language:"yaml",title:n,children:t})})}},1326:(e,n,r)=>{r.d(n,{Z:()=>s});const s=[{name:"Set up zrok Package Repo",gather_facts:!0,hosts:"all",become:!0,tasks:[{name:"Set up apt repo",when:'ansible_os_family == "Debian"',block:[{name:"Install playbook dependencies","ansible.builtin.package":{name:["gnupg"],state:"present"}},{name:"Fetch armored pubkey","ansible.builtin.uri":{url:"https://get.openziti.io/tun/package-repos.gpg",return_content:"yes"},register:"armored_pubkey"},{name:"Dearmor pubkey","ansible.builtin.shell":'gpg --dearmor --output /usr/share/keyrings/openziti.gpg <<< "{{ armored_pubkey.content }}"\n',args:{creates:"/usr/share/keyrings/openziti.gpg",executable:"/bin/bash"}},{name:"Set pubkey filemode","ansible.builtin.file":{path:"/usr/share/keyrings/openziti.gpg",mode:"a+rX"}},{name:"Install OpenZiti repo deb source","ansible.builtin.copy":{dest:"/etc/apt/sources.list.d/openziti-release.list",content:"deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable debian main\n"}},{name:"Refresh Repo Sources","ansible.builtin.apt":{update_cache:"yes",cache_valid_time:3600}}]},{name:"Set up yum repo",when:'ansible_os_family == "RedHat"',block:[{name:"Install OpenZiti repo rpm source","ansible.builtin.yum_repository":{name:"OpenZitiRelease",description:"OpenZiti Release",baseurl:"https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch",enabled:"yes",gpgkey:"https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch/repodata/repomd.xml.key",repo_gpgcheck:"yes",gpgcheck:"no"}}]}]}]}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.c0806695.js b/assets/js/runtime~main.32610af2.js similarity index 97% rename from assets/js/runtime~main.c0806695.js rename to assets/js/runtime~main.32610af2.js index f279a6b5..9782ce1b 100644 --- a/assets/js/runtime~main.c0806695.js +++ b/assets/js/runtime~main.32610af2.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,t,r,b,f={},d={};function c(e){var a=d[e];if(void 0!==a)return a.exports;var t=d[e]={id:e,loaded:!1,exports:{}};return f[e].call(t.exports,t,t.exports,c),t.loaded=!0,t.exports}c.m=f,c.c=d,c.amdO={},e=[],c.O=(a,t,r,b)=>{if(!t){var f=1/0;for(i=0;i=b)&&Object.keys(c.O).every((e=>c.O[e](t[o])))?t.splice(o--,1):(d=!1,b0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[t,r,b]},c.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return c.d(a,{a:a}),a},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var b=Object.create(null);c.r(b);var f={};a=a||[null,t({}),t([]),t(t)];for(var d=2&r&&e;"object"==typeof d&&!~a.indexOf(d);d=t(d))Object.getOwnPropertyNames(d).forEach((a=>f[a]=()=>e[a]));return f.default=()=>e,c.d(b,f),b},c.d=(e,a)=>{for(var t in a)c.o(a,t)&&!c.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:a[t]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((a,t)=>(c.f[t](e,a),a)),[])),c.u=e=>"assets/js/"+({22:"0654c903",53:"935f2afb",55:"613b9d03",76:"2e812224",108:"288b1075",142:"1ba5bc99",176:"6272ba0e",182:"6e881e32",195:"c4f5d8e4",196:"bbbe662c",198:"50ef9c44",209:"881eafa3",212:"8ae7f3b1",318:"8ef4b25e",327:"c304be44",360:"34e1d3b9",364:"60d45520",368:"a94703ab",387:"4555b262",402:"5b30ef33",518:"a7bd4aaa",661:"5e95c892",711:"9a9d4214",732:"c015c796",817:"14eb3368",826:"47881d5c",828:"48230885",838:"75b20590",846:"cda0d2e5",848:"e6ffb4b4",889:"339d500a",900:"600b2345",905:"07d0b302",913:"b6569025",918:"17896441",920:"1a4e3797",938:"f888b719",945:"bc747cac",992:"f2348458",993:"5cd0a723"}[e]||e)+"."+{22:"7aaae210",53:"bb561c88",55:"70520b78",76:"cf9aefef",108:"eff043f2",142:"b4a62798",174:"7183a347",176:"ec9db412",182:"b57731c8",195:"de5bd68b",196:"04415d84",198:"6d266622",209:"b2106c29",212:"e3f6a489",272:"4ca67fd7",312:"b4df1bd8",318:"6f594527",327:"af997900",360:"790fb2cb",364:"b80527ca",368:"61d15177",387:"6f007c31",402:"60970f99",426:"b59e2f12",518:"f24b7b2f",661:"b51f25a8",711:"1eaae2f3",732:"d34463ac",772:"4f8739fc",817:"8950462c",826:"ae1dcb33",828:"4fdb4d08",838:"85da3a5a",846:"b45c8e1c",848:"45c4cedd",889:"5d4c822f",894:"e787cecf",900:"d3eef0d4",905:"2ee3176b",913:"a6bd5acc",918:"fb6affb9",920:"1600a42d",938:"f45e9c0f",945:"7c08391c",969:"ba5129f7",992:"46b5aa6d",993:"e074238f"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r={},b="website:",c.l=(e,a,t,f)=>{if(r[e])r[e].push(a);else{var d,o;if(void 0!==t)for(var n=document.getElementsByTagName("script"),i=0;i{d.onerror=d.onload=null,clearTimeout(s);var b=r[e];if(delete r[e],d.parentNode&&d.parentNode.removeChild(d),b&&b.forEach((e=>e(t))),a)return a(t)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=l.bind(null,d.onerror),d.onload=l.bind(null,d.onload),o&&document.head.appendChild(d)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.p="/",c.gca=function(e){return e={17896441:"918",48230885:"828","0654c903":"22","935f2afb":"53","613b9d03":"55","2e812224":"76","288b1075":"108","1ba5bc99":"142","6272ba0e":"176","6e881e32":"182",c4f5d8e4:"195",bbbe662c:"196","50ef9c44":"198","881eafa3":"209","8ae7f3b1":"212","8ef4b25e":"318",c304be44:"327","34e1d3b9":"360","60d45520":"364",a94703ab:"368","4555b262":"387","5b30ef33":"402",a7bd4aaa:"518","5e95c892":"661","9a9d4214":"711",c015c796:"732","14eb3368":"817","47881d5c":"826","75b20590":"838",cda0d2e5:"846",e6ffb4b4:"848","339d500a":"889","600b2345":"900","07d0b302":"905",b6569025:"913","1a4e3797":"920",f888b719:"938",bc747cac:"945",f2348458:"992","5cd0a723":"993"}[e]||e,c.p+c.u(e)},(()=>{var e={303:0,532:0};c.f.j=(a,t)=>{var r=c.o(e,a)?e[a]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(303|532)$/.test(a))e[a]=0;else{var b=new Promise(((t,b)=>r=e[a]=[t,b]));t.push(r[2]=b);var f=c.p+c.u(a),d=new Error;c.l(f,(t=>{if(c.o(e,a)&&(0!==(r=e[a])&&(e[a]=void 0),r)){var b=t&&("load"===t.type?"missing":t.type),f=t&&t.target&&t.target.src;d.message="Loading chunk "+a+" failed.\n("+b+": "+f+")",d.name="ChunkLoadError",d.type=b,d.request=f,r[1](d)}}),"chunk-"+a,a)}},c.O.j=a=>0===e[a];var a=(a,t)=>{var r,b,f=t[0],d=t[1],o=t[2],n=0;if(f.some((a=>0!==e[a]))){for(r in d)c.o(d,r)&&(c.m[r]=d[r]);if(o)var i=o(c)}for(a&&a(t);n{"use strict";var e,a,t,r,b,f={},d={};function c(e){var a=d[e];if(void 0!==a)return a.exports;var t=d[e]={id:e,loaded:!1,exports:{}};return f[e].call(t.exports,t,t.exports,c),t.loaded=!0,t.exports}c.m=f,c.c=d,c.amdO={},e=[],c.O=(a,t,r,b)=>{if(!t){var f=1/0;for(i=0;i=b)&&Object.keys(c.O).every((e=>c.O[e](t[o])))?t.splice(o--,1):(d=!1,b0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[t,r,b]},c.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return c.d(a,{a:a}),a},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var b=Object.create(null);c.r(b);var f={};a=a||[null,t({}),t([]),t(t)];for(var d=2&r&&e;"object"==typeof d&&!~a.indexOf(d);d=t(d))Object.getOwnPropertyNames(d).forEach((a=>f[a]=()=>e[a]));return f.default=()=>e,c.d(b,f),b},c.d=(e,a)=>{for(var t in a)c.o(a,t)&&!c.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:a[t]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((a,t)=>(c.f[t](e,a),a)),[])),c.u=e=>"assets/js/"+({22:"0654c903",53:"935f2afb",55:"613b9d03",76:"2e812224",108:"288b1075",142:"1ba5bc99",176:"6272ba0e",182:"6e881e32",195:"c4f5d8e4",196:"bbbe662c",198:"50ef9c44",209:"881eafa3",212:"8ae7f3b1",318:"8ef4b25e",327:"c304be44",360:"34e1d3b9",364:"60d45520",368:"a94703ab",387:"4555b262",402:"5b30ef33",518:"a7bd4aaa",661:"5e95c892",711:"9a9d4214",732:"c015c796",817:"14eb3368",826:"47881d5c",828:"48230885",838:"75b20590",846:"cda0d2e5",848:"e6ffb4b4",889:"339d500a",900:"600b2345",905:"07d0b302",913:"b6569025",918:"17896441",920:"1a4e3797",938:"f888b719",945:"bc747cac",992:"f2348458",993:"5cd0a723"}[e]||e)+"."+{22:"7aaae210",53:"bb561c88",55:"70520b78",76:"cf9aefef",108:"eff043f2",142:"b4a62798",174:"7183a347",176:"ec9db412",182:"2eecdb77",195:"de5bd68b",196:"04415d84",198:"6d266622",209:"b2106c29",212:"e3f6a489",272:"4ca67fd7",312:"b4df1bd8",318:"6f594527",327:"af997900",360:"790fb2cb",364:"b80527ca",368:"61d15177",387:"6f007c31",402:"60970f99",426:"b59e2f12",518:"f24b7b2f",661:"b51f25a8",711:"1eaae2f3",732:"d34463ac",772:"4f8739fc",817:"8950462c",826:"ae1dcb33",828:"4fdb4d08",838:"85da3a5a",846:"40baeef1",848:"45c4cedd",889:"5d4c822f",894:"e787cecf",900:"d3eef0d4",905:"2ee3176b",913:"a6bd5acc",918:"fb6affb9",920:"1600a42d",938:"f45e9c0f",945:"7c08391c",969:"ba5129f7",992:"46b5aa6d",993:"e074238f"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r={},b="website:",c.l=(e,a,t,f)=>{if(r[e])r[e].push(a);else{var d,o;if(void 0!==t)for(var n=document.getElementsByTagName("script"),i=0;i{d.onerror=d.onload=null,clearTimeout(s);var b=r[e];if(delete r[e],d.parentNode&&d.parentNode.removeChild(d),b&&b.forEach((e=>e(t))),a)return a(t)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=l.bind(null,d.onerror),d.onload=l.bind(null,d.onload),o&&document.head.appendChild(d)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.p="/",c.gca=function(e){return e={17896441:"918",48230885:"828","0654c903":"22","935f2afb":"53","613b9d03":"55","2e812224":"76","288b1075":"108","1ba5bc99":"142","6272ba0e":"176","6e881e32":"182",c4f5d8e4:"195",bbbe662c:"196","50ef9c44":"198","881eafa3":"209","8ae7f3b1":"212","8ef4b25e":"318",c304be44:"327","34e1d3b9":"360","60d45520":"364",a94703ab:"368","4555b262":"387","5b30ef33":"402",a7bd4aaa:"518","5e95c892":"661","9a9d4214":"711",c015c796:"732","14eb3368":"817","47881d5c":"826","75b20590":"838",cda0d2e5:"846",e6ffb4b4:"848","339d500a":"889","600b2345":"900","07d0b302":"905",b6569025:"913","1a4e3797":"920",f888b719:"938",bc747cac:"945",f2348458:"992","5cd0a723":"993"}[e]||e,c.p+c.u(e)},(()=>{var e={303:0,532:0};c.f.j=(a,t)=>{var r=c.o(e,a)?e[a]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(303|532)$/.test(a))e[a]=0;else{var b=new Promise(((t,b)=>r=e[a]=[t,b]));t.push(r[2]=b);var f=c.p+c.u(a),d=new Error;c.l(f,(t=>{if(c.o(e,a)&&(0!==(r=e[a])&&(e[a]=void 0),r)){var b=t&&("load"===t.type?"missing":t.type),f=t&&t.target&&t.target.src;d.message="Loading chunk "+a+" failed.\n("+b+": "+f+")",d.name="ChunkLoadError",d.type=b,d.request=f,r[1](d)}}),"chunk-"+a,a)}},c.O.j=a=>0===e[a];var a=(a,t)=>{var r,b,f=t[0],d=t[1],o=t[2],n=0;if(f.some((a=>0!==e[a]))){for(r in d)c.o(d,r)&&(c.m[r]=d[r]);if(o)var i=o(c)}for(a&&a(t);n