mirror of
https://github.com/openziti/zrok.git
synced 2025-01-03 12:39:07 +01:00
Merge remote-tracking branch 'origin/main' into node-sdk
This commit is contained in:
commit
9f071f5ec6
1
BUILD.md
1
BUILD.md
@ -10,6 +10,7 @@ To build, follow these steps:
|
||||
* run `npm install`
|
||||
* run `npm run build` (this process takes a while the first time and only needs to be run if the ui changes)
|
||||
* change back to the checkout root
|
||||
* make sure the dist directory exists: `mkdir -p dist`
|
||||
* build the go project normally: `go build -o dist ./...`
|
||||
|
||||
## Documentation/Website
|
||||
|
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,8 +1,20 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.4.28
|
||||
|
||||
FEATURE: A Docker Compose project for self-hosting a zrok instance and [accompanying Docker guide](https://docs.zrok.io/docs/guides/self-hosting/docker) for more information.
|
||||
|
||||
CHANGE: the container images run as "ziggy" (UID 2171) instead of the generic restricted user "nobody" (UID 65534). This reduces the risk of unexpected file permissions when binding the Docker host's filesystem to a zrok container.
|
||||
|
||||
CHANGE: the Docker sharing guides were simplified and expanded
|
||||
|
||||
## v0.4.27
|
||||
|
||||
CHANGE: Update to OpenZiti SDK (`github.com/openziti/sdk-golang`) at `v0.23.10`.
|
||||
FEATURE: New `vpn` backend mode. Use `sudo zrok share private --backend-mode vpn` on the _VPN server_ host, then `sudo zrok access private <token>` on _VPN client_ machine. Works with reserved shares using `zrok reserve private --backend-mode vpn`. Use `<target>` parameter to override default VPN network settings `zrok share private -b vpn 192.168.255.42/24` -- server IP is `192.168.255.42` and VPN netmask will be `192.168.255.0/24`. Client IPs are assigned automatically from netmask range.
|
||||
|
||||
CHANGE: Update to OpenZiti SDK (`github.com/openziti/sdk-golang`) at `v0.23.22`.
|
||||
|
||||
CHANGE: Added indexes to `environments`, `shares`, and `frontends` tables to improve overall query performance on both PostgreSQL and Sqlite.
|
||||
|
||||
FIX: Also update the Python SDK to include the permission mode and access grants fields on the `ShareRequest` (https://github.com/openziti/zrok/issues/432)
|
||||
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/openziti/zrok/endpoints/proxy"
|
||||
"github.com/openziti/zrok/endpoints/tcpTunnel"
|
||||
"github.com/openziti/zrok/endpoints/udpTunnel"
|
||||
"github.com/openziti/zrok/endpoints/vpn"
|
||||
"github.com/openziti/zrok/environment"
|
||||
"github.com/openziti/zrok/rest_client_zrok"
|
||||
"github.com/openziti/zrok/rest_client_zrok/share"
|
||||
@ -165,6 +166,30 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
}
|
||||
}()
|
||||
|
||||
case "vpn":
|
||||
endpointUrl = &url.URL{
|
||||
Scheme: "VPN",
|
||||
}
|
||||
fe, err := vpn.NewFrontend(&vpn.FrontendConfig{
|
||||
IdentityName: env.EnvironmentIdentityName(),
|
||||
ShrToken: args[0],
|
||||
RequestsChan: requests,
|
||||
})
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to create private access", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
if err := fe.Run(); err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("error starting access", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
default:
|
||||
cfg := proxy.DefaultFrontendConfig(env.EnvironmentIdentityName())
|
||||
cfg.ShrToken = shrToken
|
||||
|
@ -3,12 +3,14 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/openziti/zrok/endpoints/vpn"
|
||||
"github.com/openziti/zrok/environment"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"github.com/openziti/zrok/tui"
|
||||
"github.com/openziti/zrok/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"net"
|
||||
"slices"
|
||||
"time"
|
||||
)
|
||||
@ -40,7 +42,7 @@ func newReserveCommand() *reserveCommand {
|
||||
command := &reserveCommand{cmd: cmd}
|
||||
cmd.Flags().StringVarP(&command.uniqueName, "unique-name", "n", "", "A unique name for the reserved share (defaults to generated identifier)")
|
||||
cmd.Flags().StringArrayVar(&command.frontendSelection, "frontends", []string{"public"}, "Selected frontends to use for the share")
|
||||
cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode (public|private: proxy, web, caddy, drive) (private: tcpTunnel, udpTunnel, socks)")
|
||||
cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode (public|private: proxy, web, caddy, drive) (private: tcpTunnel, udpTunnel, socks, vpn)")
|
||||
cmd.Flags().BoolVarP(&command.jsonOutput, "json-output", "j", false, "Emit JSON describing the created reserved share")
|
||||
cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (<username:password>,...)")
|
||||
cmd.Flags().StringVar(&command.oauthProvider, "oauth-provider", "", "Enable OAuth provider [google, github]")
|
||||
@ -56,7 +58,7 @@ func newReserveCommand() *reserveCommand {
|
||||
|
||||
func (cmd *reserveCommand) run(_ *cobra.Command, args []string) {
|
||||
shareMode := sdk.ShareMode(args[0])
|
||||
privateOnlyModes := []string{"tcpTunnel", "udpTunnel", "socks"}
|
||||
privateOnlyModes := []string{"tcpTunnel", "udpTunnel", "socks", "vpn"}
|
||||
if shareMode != sdk.PublicShareMode && shareMode != sdk.PrivateShareMode {
|
||||
tui.Error("invalid sharing mode; expecting 'public' or 'private'", nil)
|
||||
} else if shareMode == sdk.PublicShareMode && slices.Contains(privateOnlyModes, cmd.backendMode) {
|
||||
@ -114,8 +116,20 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) {
|
||||
tui.Error("the 'socks' backend mode does not expect <target>", nil)
|
||||
}
|
||||
|
||||
case "vpn":
|
||||
if len(args) == 2 {
|
||||
_, _, err := net.ParseCIDR(args[1])
|
||||
if err != nil {
|
||||
tui.Error("the 'vpn' backend expect valid CIDR <target>", err)
|
||||
}
|
||||
target = args[1]
|
||||
} else {
|
||||
target = vpn.DefaultTarget()
|
||||
}
|
||||
|
||||
default:
|
||||
tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel, udpTunnel, caddy, drive, socks}", cmd.backendMode), nil)
|
||||
tui.Error(fmt.Sprintf("invalid backend mode '%v'; "+
|
||||
"expected {proxy, web, tcpTunnel, udpTunnel, caddy, drive, socks, vpn}", cmd.backendMode), nil)
|
||||
}
|
||||
|
||||
env, err := environment.LoadRoot()
|
||||
|
@ -9,12 +9,14 @@ import (
|
||||
"github.com/openziti/zrok/endpoints/socks"
|
||||
"github.com/openziti/zrok/endpoints/tcpTunnel"
|
||||
"github.com/openziti/zrok/endpoints/udpTunnel"
|
||||
"github.com/openziti/zrok/endpoints/vpn"
|
||||
"github.com/openziti/zrok/environment"
|
||||
"github.com/openziti/zrok/environment/env_core"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"github.com/openziti/zrok/tui"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
@ -42,7 +44,7 @@ func newSharePrivateCommand() *sharePrivateCommand {
|
||||
}
|
||||
command := &sharePrivateCommand{cmd: cmd}
|
||||
cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (<username:password>,...")
|
||||
cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode {proxy, web, tcpTunnel, udpTunnel, caddy, drive, socks}")
|
||||
cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode {proxy, web, tcpTunnel, udpTunnel, caddy, drive, socks, vpn}")
|
||||
cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless")
|
||||
cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for <target>")
|
||||
cmd.Flags().BoolVar(&command.closed, "closed", false, "Enable closed permission mode (see --access-grant)")
|
||||
@ -105,6 +107,17 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
}
|
||||
target = "socks"
|
||||
|
||||
case "vpn":
|
||||
if len(args) == 1 {
|
||||
_, _, err := net.ParseCIDR(args[0])
|
||||
if err != nil {
|
||||
tui.Error("the 'vpn' backend expect valid CIDR <target>", err)
|
||||
}
|
||||
target = args[0]
|
||||
} else {
|
||||
target = vpn.DefaultTarget()
|
||||
}
|
||||
|
||||
default:
|
||||
tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel, udpTunnel, caddy, drive}", cmd.backendMode), nil)
|
||||
}
|
||||
@ -318,6 +331,28 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
}
|
||||
}()
|
||||
|
||||
case "vpn":
|
||||
cfg := &vpn.BackendConfig{
|
||||
IdentityPath: zif,
|
||||
EndpointAddress: target,
|
||||
ShrToken: shr.Token,
|
||||
RequestsChan: requests,
|
||||
}
|
||||
|
||||
be, err := vpn.NewBackend(cfg)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("error creating VPN backend", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := be.Run(); err != nil {
|
||||
logrus.Errorf("error running VPN backend: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
default:
|
||||
tui.Error("invalid backend mode", nil)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/openziti/zrok/endpoints/socks"
|
||||
"github.com/openziti/zrok/endpoints/tcpTunnel"
|
||||
"github.com/openziti/zrok/endpoints/udpTunnel"
|
||||
"github.com/openziti/zrok/endpoints/vpn"
|
||||
"github.com/openziti/zrok/environment"
|
||||
"github.com/openziti/zrok/rest_client_zrok/metadata"
|
||||
"github.com/openziti/zrok/rest_client_zrok/share"
|
||||
@ -282,6 +283,28 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) {
|
||||
}
|
||||
}()
|
||||
|
||||
case "vpn":
|
||||
cfg := &vpn.BackendConfig{
|
||||
IdentityPath: zif,
|
||||
EndpointAddress: target,
|
||||
ShrToken: shrToken,
|
||||
RequestsChan: requests,
|
||||
}
|
||||
|
||||
be, err := vpn.NewBackend(cfg)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("error creating VPN backend", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := be.Run(); err != nil {
|
||||
logrus.Errorf("error running VPN backend: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
default:
|
||||
tui.Error("invalid backend mode", nil)
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
-- +migrate Up
|
||||
|
||||
create index environments_account_id_idx on environments (account_id);
|
||||
create index shares_token_perf_idx on shares (token);
|
||||
create index shares_environment_id_idx on shares (environment_id);
|
||||
create index frontends_environment_id_idx on frontends (environment_id);
|
@ -0,0 +1,3 @@
|
||||
-- +migrate Up
|
||||
|
||||
alter type backend_mode add value 'vpn';
|
@ -0,0 +1,6 @@
|
||||
-- +migrate Up
|
||||
|
||||
create index environments_account_id_idx on environments (account_id);
|
||||
create index shares_token_perf_idx on shares (token);
|
||||
create index shares_environment_id_idx on shares (environment_id);
|
||||
create index frontends_environment_id_idx on frontends (environment_id);
|
@ -0,0 +1,76 @@
|
||||
-- +migrate Up
|
||||
|
||||
alter table shares rename to shares_old;
|
||||
create table shares (
|
||||
id integer primary key,
|
||||
environment_id integer constraint fk_environments_shares references environments on delete cascade,
|
||||
z_id string not null unique,
|
||||
token string not null,
|
||||
share_mode string not null,
|
||||
backend_mode string not null,
|
||||
frontend_selection string,
|
||||
frontend_endpoint string,
|
||||
backend_proxy_endpoint string,
|
||||
reserved boolean not null default(false),
|
||||
created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
deleted boolean not null default(false),
|
||||
permission_mode string not null default('open'),
|
||||
|
||||
constraint chk_z_id check (z_id <> ''),
|
||||
constraint chk_token check (token <> ''),
|
||||
constraint chk_share_mode check (share_mode == 'public' or share_mode == 'private'),
|
||||
constraint chk_backend_mode check (backend_mode == 'proxy' or backend_mode == 'web' or backend_mode == 'tcpTunnel' or backend_mode == 'udpTunnel' or backend_mode == 'caddy' or backend_mode == 'drive' or backend_mode == 'socks' or backend_mode == 'vpn')
|
||||
);
|
||||
insert into shares select * from shares_old;
|
||||
drop index shares_token_idx;
|
||||
create unique index shares_token_idx ON shares(token) WHERE deleted is false;
|
||||
drop index shares_token_perf_idx;
|
||||
create index shares_token_perf_idx on shares (token);
|
||||
drop index shares_environment_id_idx;
|
||||
create index shares_environment_id_idx on shares (environment_id);
|
||||
|
||||
alter table frontends rename to frontends_old;
|
||||
create table frontends (
|
||||
id integer primary key,
|
||||
environment_id integer references environments(id),
|
||||
token varchar(32) not null unique,
|
||||
z_id varchar(32) not null,
|
||||
public_name varchar(64) unique,
|
||||
url_template varchar(1024),
|
||||
reserved boolean not null default(false),
|
||||
created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
deleted boolean not null default(false),
|
||||
private_share_id integer references shares(id)
|
||||
);
|
||||
insert into frontends select * from frontends_old;
|
||||
drop table frontends_old;
|
||||
create index frontends_environment_id_idx on frontends (environment_id);
|
||||
|
||||
alter table share_limit_journal rename to share_limit_journal_old;
|
||||
create table share_limit_journal (
|
||||
id integer primary key,
|
||||
share_id integer references shares(id),
|
||||
rx_bytes bigint not null,
|
||||
tx_bytes bigint not null,
|
||||
action limit_action_type not null,
|
||||
created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now'))
|
||||
);
|
||||
insert into share_limit_journal select * from share_limit_journal_old;
|
||||
drop table share_limit_journal_old;
|
||||
|
||||
alter table access_grants rename to access_grants_old;
|
||||
create table access_grants (
|
||||
id integer primary key,
|
||||
share_id integer references shares(id),
|
||||
account_id integer references accounts(id),
|
||||
created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
deleted boolean not null default(false)
|
||||
);
|
||||
insert into access_grants select * from access_grants_old;
|
||||
drop table access_grants_old;
|
||||
|
||||
drop table shares_old;
|
2
docker/compose/zrok-instance/.gitignore
vendored
Normal file
2
docker/compose/zrok-instance/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/.env
|
||||
/compose.yml
|
31
docker/compose/zrok-instance/Caddyfile
Normal file
31
docker/compose/zrok-instance/Caddyfile
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
email {$CADDY_ACME_EMAIL}
|
||||
acme_ca {$CADDY_ACME_API}
|
||||
admin 0.0.0.0:2019
|
||||
}
|
||||
|
||||
http:// {
|
||||
redir https://{host}{uri} permanent
|
||||
}
|
||||
|
||||
*.{$ZROK_DNS_ZONE} {
|
||||
tls {
|
||||
dns {$CADDY_DNS_PLUGIN} {$CADDY_DNS_PLUGIN_TOKEN}
|
||||
}
|
||||
|
||||
log {
|
||||
output stdout
|
||||
format console
|
||||
level DEBUG
|
||||
}
|
||||
|
||||
@oauth host oauth.{$ZROK_DNS_ZONE}
|
||||
reverse_proxy @oauth zrok-frontend:{$ZROK_OAUTH_PORT}
|
||||
|
||||
@ctrl host zrok.{$ZROK_DNS_ZONE}
|
||||
reverse_proxy @ctrl zrok-controller:{$ZROK_CTRL_PORT}
|
||||
|
||||
reverse_proxy zrok-frontend:{$ZROK_FRONTEND_PORT} {
|
||||
header_up Host {http.request.host}
|
||||
}
|
||||
}
|
231
docker/compose/zrok-instance/README.md
Normal file
231
docker/compose/zrok-instance/README.md
Normal file
@ -0,0 +1,231 @@
|
||||
|
||||
## Docker Quickstart
|
||||
|
||||
### DNS Configuration
|
||||
|
||||
The quickstart makes these assumptions about your global DNS configuration.
|
||||
|
||||
1. A Caddy DNS plugin is available for your DNS provider (see [github.com/caddy-dns](https://github.com/orgs/caddy-dns/repositories?type=all&q=sort%3Aname-asc))
|
||||
1. You have designated A DNS zone for zrok, e.g. `example.com` or `share.example.com` and created (and delegated, if necessary) the zone on your DNS provider's platform.
|
||||
1. A wildcard record exists for the IP address where the zrok instance will run, e.g. if your DNS zone is `share.example.com`, then your wildcard record is `*.share.example.com`.
|
||||
1. You have created an API token in your DNS provider's platform and the token has permission to create DNS records in the DNS zone.
|
||||
|
||||
### Create the Docker Compose Project
|
||||
|
||||
Create a working directory on your Docker host and save these Docker Compose project files. A OpenZiti network is provided by the "quickstart" container and is managed exclusively by zrok.
|
||||
|
||||
#### Shortcut option
|
||||
|
||||
1. Run this script to download the files.
|
||||
|
||||
```bash
|
||||
curl https://get.openziti.io/zrok-docker/fetch.bash | bash
|
||||
```
|
||||
|
||||
Optionally, customize the install path instead of using the current directory.
|
||||
|
||||
```bash
|
||||
curl https://get.openziti.io/zrok-docker/fetch.bash | bash -s /path/to/install
|
||||
```
|
||||
|
||||
#### Do it Yourself
|
||||
|
||||
1. Fetch the ziti quickstart Compose file.
|
||||
|
||||
```bash
|
||||
wget https://get.openziti.io/dock/all-in-one/compose.yml
|
||||
```
|
||||
|
||||
1. Get the zrok repo ZIP file.
|
||||
|
||||
```bash
|
||||
wget https://github.com/openziti/zrok/archive/refs/heads/main.zip
|
||||
```
|
||||
|
||||
1. Unzip the zrok-instance files into the project directory.
|
||||
|
||||
```bash
|
||||
unzip -j -d . main.zip '*/docker/compose/zrok-instance/*'
|
||||
```
|
||||
|
||||
### Configure the Docker Compose Project Environment
|
||||
|
||||
Create an `.env` file in the working directory.
|
||||
|
||||
```bash title=".env required"
|
||||
ZROK_DNS_ZONE=share.example.com
|
||||
|
||||
CADDY_DNS_PLUGIN=cloudflare
|
||||
CADDY_DNS_PLUGIN_TOKEN=abcd1234
|
||||
CADDY_ACME_EMAIL=me@example.com
|
||||
|
||||
# this must == ziti.${ZROK_DNS_ZONE}
|
||||
ZITI_CTRL_ADVERTISED_ADDRESS=ziti.share.example.com
|
||||
ZITI_PWD=zitiadminpw
|
||||
|
||||
ZROK_ADMIN_TOKEN=zroktoken
|
||||
ZROK_USER_PWD=zrokuserpw
|
||||
```
|
||||
|
||||
```bash title=".env options"
|
||||
ZITI_CTRL_ADVERTISED_PORT=1280
|
||||
ZITI_ROUTER_PORT=3022
|
||||
|
||||
# configure oauth for public shares
|
||||
ZROK_OAUTH_HASH_KEY=oauthhashkeysecret
|
||||
ZROK_OAUTH_GITHUB_CLIENT_ID=abcd1234
|
||||
ZROK_OAUTH_GITHUB_CLIENT_SECRET=abcd1234
|
||||
ZROK_OAUTH_GOOGLE_CLIENT_ID=abcd1234
|
||||
ZROK_OAUTH_GOOGLE_CLIENT_SECRET=abcd1234
|
||||
|
||||
# use the staging API until you're sure everything is working to avoid hitting the main CA's rate limit
|
||||
CADDY_ACME_API=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
```
|
||||
|
||||
### Start the Docker Compose Project
|
||||
|
||||
1. Start the ziti network. This runs `ziti edge quickstart` ([link to readme](https://github.com/openziti/ziti/tree/main/quickstart/docker/all-in-one#readme)).
|
||||
|
||||
```bash
|
||||
docker compose --profile ziti up --detach
|
||||
```
|
||||
|
||||
1. Start the zrok instance.
|
||||
|
||||
The container images for zrok (including caddy) are built in this step. This provides a simple configuration to get started. You can modify the templates named like `*.envsubst` or mount a customized configuration file to mask the one that was built in.
|
||||
|
||||
```bash
|
||||
docker compose --profile zrok up --build --detach
|
||||
```
|
||||
|
||||
### Set up a User Account
|
||||
|
||||
This step creates a user account. You will log in to the zrok web console with the account password created in this step. The CADDY_ACME_EMAIL and ZROK_USER_PWD variables are set in the `.env` file. You can create more user accounts the same way by substituting a different email and password.
|
||||
|
||||
```bash
|
||||
docker compose exec zrok-controller bash -xc 'zrok admin create account /etc/zrok-controller/config.yml ${CADDY_ACME_EMAIL} ${ZROK_USER_PWD}'
|
||||
```
|
||||
|
||||
```buttonless title="Example output"
|
||||
+ zrok admin create account /etc/zrok-controller/config.yml me@example.com zrokuserpw
|
||||
[ 0.000] INFO zrok/controller/store.Open: database connected
|
||||
[ 0.002] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations
|
||||
heMqncCyxZcx
|
||||
```
|
||||
|
||||
### Enable the User Environment
|
||||
|
||||
You must enable each device environment with the account token obtained when the account was created. This is separate from the account password that's used to log in to the web console.
|
||||
|
||||
Follow [the getting started guide](/docs/getting-started#installing-the-zrok-command) to install the zrok CLI on some device and enable a zrok environment.
|
||||
|
||||
1. Configure the environment with the zrok API. Substitute the API endpoint with the one you're using, e.g. `https://zrok.${ZROK_DNS_ZONE}`.
|
||||
|
||||
```bash
|
||||
zrok config set apiEndpoint https://zrok.share.example.com
|
||||
```
|
||||
|
||||
1. Enable an environment on this device with the account token from the previous step.
|
||||
|
||||
```bash
|
||||
zrok enable heMqncCyxZcx
|
||||
```
|
||||
|
||||
### Firewall Configuration
|
||||
|
||||
The `quickstart` and `caddy` containers publish ports to all devices that use zrok shares. The `zrok-controller` and `zrok-frontend` containers expose ports only to the `caddy` container and the Docker host's loopback interface.
|
||||
|
||||
#### Required
|
||||
|
||||
1. `443/tcp` - reverse proxy handles HTTPS requests for zrok API, OAuth, and public shares (published by container `caddy`)
|
||||
1. `1280/tcp` - ziti ctrl plane (published by container `quickstart`)
|
||||
1. `3022/tcp` - ziti data plane (published by container `quickstart`)
|
||||
|
||||
#### Optional
|
||||
|
||||
1. `80/tcp` - reverse proxy redirects non-HTTPS requests to `443/tcp` (published by container `caddy`)
|
||||
<!-- 1. 443/udp used by Caddy for HTTP/3 QUIC protocol (published by container `caddy`) -->
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
1. Check the ziti and zrok logs.
|
||||
|
||||
You can substitute the service container name of each to check their logs individually: `quickstart` (ziti container), `zrok-controller`, `zrok-frontend`.
|
||||
|
||||
```bash
|
||||
docker compose logs zrok-controller
|
||||
```
|
||||
|
||||
1. Check the caddy logs.
|
||||
|
||||
It can take a few minutes for Caddy to obtain the wildcard certificate. You can check the logs to see if there were any errors completing the DNS challenge which involves using the Caddy DNS plugin to create a TXT record in your DNS zone. This leverages the API token you provided in the `.env` file, which must have permission to create DNS records in the zrok DNS zone.
|
||||
|
||||
```bash
|
||||
docker compose logs caddy
|
||||
```
|
||||
|
||||
1. `zrok enable` fails certificate verification: ensure you are not using the staging API for Let's Encrypt.
|
||||
|
||||
If you are using the staging API, you will see an error about the API certificate when you use the zrok CLI. You can switch to the production API by removing the overriding assignment of the `CADDY_ACME_API` variable.
|
||||
|
||||
```buttonless title="Example output"
|
||||
there was a problem enabling your environment!
|
||||
you are trying to use the zrok service at: https://zrok.share.example.com
|
||||
you can change your zrok service endpoint using this command:
|
||||
|
||||
$ zrok config set apiEndpoint <newEndpoint>
|
||||
|
||||
(where newEndpoint is something like: https://some.zrok.io)
|
||||
[ERROR]: error creating service client (error getting version from api endpoint 'https://zrok.share.example.com': Get "https://zrok.share.example.com/api/v1/version": tls: failed to verify certificate: x509: certificate signed by unknown authority: Get "https://zrok.share.example.com/api/v1/version": tls: failed to verify certificate: x509: certificate signed by unknown authority)
|
||||
```
|
||||
|
||||
1. Validate the Caddyfile.
|
||||
|
||||
```bash
|
||||
docker compose exec caddy caddy validate --config /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
1. Verify the correct DNS provider module was built-in to Caddy.
|
||||
|
||||
```bash
|
||||
docker compose exec caddy caddy list-modules | grep dns.providers
|
||||
```
|
||||
|
||||
```buttonless title="Example output"
|
||||
dns.providers.cloudflare
|
||||
```
|
||||
|
||||
1. Verify certificates.
|
||||
|
||||
You can check the certificates that Caddy has obtained.
|
||||
|
||||
```bash
|
||||
docker compose exec caddy caddy list-certificates
|
||||
```
|
||||
|
||||
1. Use the Caddy admin API.
|
||||
|
||||
You can use the Caddy admin API to check the status of the Caddy instance. The admin API is available on port `2019/tcp` inside the Docker Compose project. You can modify `compose.override.yml` to publish the port if you want to access the admin API from the Docker host or elsewhere.
|
||||
|
||||
```bash
|
||||
docker compose exec caddy curl http://localhost:2019/config/ | jq
|
||||
```
|
||||
|
||||
1. My provider, e.g., Route53 doesn't give me a single API token.
|
||||
|
||||
As long as your DNS provider is supported by Caddy then it will work. You can modify the Caddyfile to use a different set of properties than the example. Here's how the `tls` section should look for Route53.
|
||||
|
||||
```json
|
||||
tls {
|
||||
dns {$CADDY_DNS_PLUGIN} {
|
||||
access_key_id {$AWS_ACCESS_KEY_ID}
|
||||
secret_access_key {$AWS_SECRET_ACCESS_KEY}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash title=".env"
|
||||
CADDY_DNS_PLUGIN=route53
|
||||
AWS_ACCESS_KEY_ID=abcd1234
|
||||
AWS_SECRET_ACCESS_KEY=abcd1234
|
||||
```
|
23
docker/compose/zrok-instance/bootstrap-controller.bash
Executable file
23
docker/compose/zrok-instance/bootstrap-controller.bash
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
set -o xtrace
|
||||
|
||||
for arg in "${@}"; do
|
||||
if [[ ! "${arg}" =~ ^- && -s "${arg}" ]]; then
|
||||
CONFIG="${arg}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -z "${CONFIG}" ]]; then
|
||||
echo "ERROR: args '${*}' do not contain a non-empty config file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# config.yml is first param
|
||||
zrok admin bootstrap --skip-frontend "${CONFIG}"
|
||||
|
||||
exec "$@"
|
116
docker/compose/zrok-instance/bootstrap-frontend.bash
Executable file
116
docker/compose/zrok-instance/bootstrap-frontend.bash
Executable file
@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
# set -o xtrace
|
||||
|
||||
getZitiPublicFrontend(){
|
||||
local RETURNED
|
||||
local -A FIELDS
|
||||
FIELDS[all]=0
|
||||
FIELDS[zid]=1
|
||||
FIELDS[name]=2
|
||||
FIELDS[type]=3
|
||||
FIELDS[attributes]=4
|
||||
FIELDS[policy]=5
|
||||
|
||||
if (( $# )); then
|
||||
RETURNED="$1"
|
||||
shift
|
||||
else
|
||||
RETURNED="all"
|
||||
fi
|
||||
|
||||
if (( $# )); then
|
||||
echo "WARN: ignoring unexpected parameters: $*" >&2
|
||||
fi
|
||||
|
||||
if [[ -z "${FIELDS[$RETURNED]}" ]]; then
|
||||
echo "ERROR: invalid return field $RETURNED" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
ziti edge list identities 'name="public"' --csv \
|
||||
| awk -F, '$'${FIELDS[name]}'=="public" {print $'${FIELDS[$RETURNED]}';}'
|
||||
}
|
||||
|
||||
getZrokPublicFrontend(){
|
||||
local RETURNED
|
||||
local -A FIELDS
|
||||
FIELDS[all]=0
|
||||
FIELDS[token]=1
|
||||
FIELDS[zid]=2
|
||||
FIELDS[name]=3
|
||||
FIELDS[template]=4
|
||||
FIELDS[created]=5
|
||||
FIELDS[updated]=6
|
||||
|
||||
if (( $# )); then
|
||||
RETURNED="$1"
|
||||
shift
|
||||
else
|
||||
RETURNED="all"
|
||||
fi
|
||||
|
||||
if (( $# )); then
|
||||
echo "WARN: ignoring unexpected parameters: $*" >&2
|
||||
fi
|
||||
|
||||
if [[ -z "${FIELDS[$RETURNED]}" ]]; then
|
||||
echo "ERROR: invalid return field $RETURNED" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# strip ANSI sequences and return the first position from the line with a name exactly matching "public"
|
||||
zrok admin list frontends | sed 's/\x1b\[[0-9;]*m//g' \
|
||||
| awk '$'${FIELDS[name]}'=="public" {print $'${FIELDS[$RETURNED]}'}'
|
||||
}
|
||||
|
||||
ziti edge login "https://ziti.${ZROK_DNS_ZONE}:${ZITI_CTRL_ADVERTISED_PORT}" \
|
||||
--username admin \
|
||||
--password "${ZITI_PWD}" \
|
||||
--yes
|
||||
|
||||
if ! [[ -s ~/.zrok/identities/public.json ]]; then
|
||||
mkdir -p ~/.zrok/identities
|
||||
ziti edge create identity "public" --jwt-output-file /tmp/public.jwt
|
||||
ziti edge enroll --jwt /tmp/public.jwt --out ~/.zrok/identities/public.json
|
||||
fi
|
||||
|
||||
# find Ziti ID of default "public" frontend
|
||||
ZITI_PUBLIC_ID="$(getZitiPublicFrontend zid)"
|
||||
until [[ -n "${ZITI_PUBLIC_ID}" ]]; do
|
||||
echo "DEBUG: waiting for default frontend "public" Ziti identity to be created"
|
||||
sleep 3
|
||||
ZITI_PUBLIC_ID="$(getZitiPublicFrontend zid)"
|
||||
done
|
||||
echo "DEBUG: 'public' ZITI_PUBLIC_ID=$ZITI_PUBLIC_ID"
|
||||
|
||||
until curl -sSf "${ZROK_API_ENDPOINT}/api/v1/version"; do
|
||||
echo "DEBUG: waiting for zrok controller API version endpoint to respond"
|
||||
sleep 3
|
||||
done
|
||||
|
||||
# if default "public" frontend already exists
|
||||
ZROK_PUBLIC_TOKEN=$(getZrokPublicFrontend token)
|
||||
if [[ -n "${ZROK_PUBLIC_TOKEN}" ]]; then
|
||||
|
||||
# ensure the Ziti ID of the public frontend's identity is the same in Ziti and zrok
|
||||
ZROK_PUBLIC_ZID=$(getZrokPublicFrontend zid)
|
||||
if [[ "${ZITI_PUBLIC_ID}" != "${ZROK_PUBLIC_ZID}" ]]; then
|
||||
echo "ERROR: existing Ziti Identity named 'public' with id '$ZITI_PUBLIC_ID' is from a previous zrok"\
|
||||
"instance life cycle. Delete it then re-run zrok." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "INFO: updating frontend"
|
||||
zrok admin update frontend "${ZROK_PUBLIC_TOKEN}" \
|
||||
--url-template "https://{token}.${ZROK_DNS_ZONE}"
|
||||
else
|
||||
echo "INFO: creating frontend"
|
||||
zrok admin create frontend "${ZITI_PUBLIC_ID}" public \
|
||||
"https://{token}.${ZROK_DNS_ZONE}"
|
||||
fi
|
||||
|
||||
exec "${@}"
|
19
docker/compose/zrok-instance/caddy.Dockerfile
Normal file
19
docker/compose/zrok-instance/caddy.Dockerfile
Normal file
@ -0,0 +1,19 @@
|
||||
# Use the official Caddy image as a parent image
|
||||
FROM caddy:2-builder AS builder
|
||||
|
||||
# e.g., "github.com/caddy-dns/digitalocean"
|
||||
ARG CADDY_DNS_PLUGIN
|
||||
|
||||
# Build Caddy with the specified DNS provider plugin
|
||||
RUN xcaddy build \
|
||||
--with github.com/caddy-dns/${CADDY_DNS_PLUGIN}
|
||||
|
||||
# Use the official Caddy image to create the final image
|
||||
FROM caddy:2
|
||||
|
||||
# install curl to support using the Caddy API
|
||||
RUN apk add --no-cache curl
|
||||
|
||||
# Copy the custom Caddy build into the final image
|
||||
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
||||
COPY ./Caddyfile /etc/caddy/Caddyfile
|
137
docker/compose/zrok-instance/compose.override.yml
Normal file
137
docker/compose/zrok-instance/compose.override.yml
Normal file
@ -0,0 +1,137 @@
|
||||
# this compose file is designed to merge with the ziti all-in-one quickstart compose file by renaming
|
||||
# https://get.openziti.io/dock/all-in-one/compose.yml to compose.override.yml
|
||||
|
||||
services:
|
||||
zrok-permissions:
|
||||
image: busybox
|
||||
command:
|
||||
- /bin/sh
|
||||
- -euxc
|
||||
- |
|
||||
chown -Rc ${ZIGGY_UID:-2171} /var/lib/zrok-*;
|
||||
chmod -Rc ug=rwX,o-rwx /var/lib/zrok-*;
|
||||
volumes:
|
||||
- zrok_ctrl:/var/lib/zrok-controller
|
||||
- zrok_frontend:/var/lib/zrok-frontend
|
||||
|
||||
zrok-controller:
|
||||
profiles:
|
||||
- zrok
|
||||
depends_on:
|
||||
zrok-permissions:
|
||||
condition: service_completed_successfully
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./zrok-controller.Dockerfile
|
||||
args:
|
||||
ZROK_CLI_IMAGE: ${ZROK_CLI_IMAGE:-openziti/zrok}
|
||||
ZROK_CLI_TAG: ${ZROK_CLI_TAG:-latest}
|
||||
ZROK_DNS_ZONE: ${ZROK_DNS_ZONE} # e.g., "example.com" or "127.0.0.1.sslip.io"
|
||||
ZITI_CTRL_ADVERTISED_PORT: ${ZITI_CTRL_ADVERTISED_PORT:-1280}
|
||||
ZROK_ADMIN_TOKEN: ${ZROK_ADMIN_TOKEN} # zrok controller admin password
|
||||
ZROK_CTRL_PORT: ${ZROK_CTRL_PORT:-18080}
|
||||
ZITI_PWD: ${ZITI_PWD} # ziti controller admin password
|
||||
user: ${ZIGGY_UID:-2171}
|
||||
command: zrok controller /etc/zrok-controller/config.yml --verbose
|
||||
volumes:
|
||||
- zrok_ctrl:/var/lib/zrok-controller
|
||||
networks:
|
||||
quickstart:
|
||||
aliases:
|
||||
- zrok.${ZROK_DNS_ZONE}
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- ${ZROK_CTRL_PORT:-18080} # (not published)
|
||||
# Caddy's published ports provide a TLS reverse proxy for the zrok controller
|
||||
# ports:
|
||||
# - 127.0.0.1:${ZROK_CTRL_PORT:-18080}:${ZROK_CTRL_PORT:-18080}
|
||||
environment:
|
||||
ZROK_USER_PWD: ${ZROK_USER_PWD} # admin account password (initial user account)
|
||||
CADDY_ACME_EMAIL: ${CADDY_ACME_EMAIL} # login email address (initial user account)
|
||||
|
||||
zrok-frontend:
|
||||
profiles:
|
||||
- zrok
|
||||
depends_on:
|
||||
zrok-permissions:
|
||||
condition: service_completed_successfully
|
||||
build:
|
||||
context: .
|
||||
dockerfile: zrok-frontend.Dockerfile
|
||||
args:
|
||||
ZROK_CLI_IMAGE: ${ZROK_CLI_IMAGE:-openziti/zrok}
|
||||
ZROK_CLI_TAG: ${ZROK_CLI_TAG:-latest}
|
||||
ZROK_DNS_ZONE: ${ZROK_DNS_ZONE} # e.g., "example.com" or "127.0.0.1.sslip.io"
|
||||
ZROK_FRONTEND_PORT: ${ZROK_FRONTEND_PORT:-8080}
|
||||
ZROK_OAUTH_PORT: ${ZROK_OAUTH_PORT:-8081}
|
||||
ZROK_OAUTH_HASH_KEY: ${ZROK_OAUTH_HASH_KEY-noop}
|
||||
ZROK_OAUTH_GOOGLE_CLIENT_ID: ${ZROK_OAUTH_GOOGLE_CLIENT_ID:-noop}
|
||||
ZROK_OAUTH_GOOGLE_CLIENT_SECRET: ${ZROK_OAUTH_GOOGLE_CLIENT_SECRET:-noop}
|
||||
ZROK_OAUTH_GITHUB_CLIENT_ID: ${ZROK_OAUTH_GITHUB_CLIENT_ID:-noop}
|
||||
ZROK_OAUTH_GITHUB_CLIENT_SECRET: ${ZROK_OAUTH_GITHUB_CLIENT_SECRET:-noop}
|
||||
user: ${ZIGGY_UID:-2171}
|
||||
command: zrok access public /etc/zrok-frontend/config.yml --verbose
|
||||
volumes:
|
||||
- zrok_frontend:/var/lib/zrok-frontend
|
||||
networks:
|
||||
quickstart:
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- ${ZROK_FRONTEND_PORT:-8080} # (not published)
|
||||
- ${ZROK_OAUTH_PORT:-8081} # (not published)
|
||||
# ports:
|
||||
# - 127.0.0.1:${ZROK_FRONTEND_PORT:-8080}:${ZROK_FRONTEND_PORT:-8080}
|
||||
# - 127.0.0.1:${ZROK_OAUTH_PORT:-8081}:${ZROK_OAUTH_PORT:-8081}
|
||||
environment:
|
||||
HOME: /var/lib/zrok-frontend
|
||||
ZROK_DNS_ZONE: ${ZROK_DNS_ZONE} # e.g., "example.com" or "127.0.0.1.sslip.io"
|
||||
ZROK_ADMIN_TOKEN: ${ZROK_ADMIN_TOKEN} # zrok controller admin password
|
||||
ZROK_API_ENDPOINT: http://zrok-controller:${ZROK_CTRL_PORT:-18080} # bridge address of the zrok controller
|
||||
ZITI_CTRL_ADVERTISED_PORT: ${ZITI_CTRL_ADVERTISED_PORT:-1280}
|
||||
ZITI_PWD: ${ZITI_PWD} # ziti controller admin password
|
||||
|
||||
caddy:
|
||||
profiles:
|
||||
- zrok
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./caddy.Dockerfile
|
||||
args:
|
||||
CADDY_DNS_PLUGIN: ${CADDY_DNS_PLUGIN} # e.g., "digitalocean" (see github.com/caddy-dns)
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
CADDY_DNS_PLUGIN: ${CADDY_DNS_PLUGIN} # e.g., "digitalocean" (see github.com/caddy-dns)
|
||||
CADDY_DNS_PLUGIN_TOKEN: ${CADDY_DNS_PLUGIN_TOKEN} # API token from DNS provider used by plugin to solve the ACME challenge
|
||||
CADDY_ACME_EMAIL: ${CADDY_ACME_EMAIL} # email address sent to CA for ACME account and renewal notifications
|
||||
CADDY_ACME_API: ${CADDY_ACME_API:-https://acme-v02.api.letsencrypt.org/directory} # ACME API endpoint
|
||||
ZROK_DNS_ZONE: ${ZROK_DNS_ZONE} # e.g., "example.com" or "127.0.0.1.sslip.io"
|
||||
ZROK_CTRL_PORT: ${ZROK_CTRL_PORT:-18080}
|
||||
ZROK_FRONTEND_PORT: ${ZROK_FRONTEND_PORT:-8080}
|
||||
ZROK_OAUTH_PORT: ${ZROK_OAUTH_PORT:-8081}
|
||||
expose:
|
||||
- 80/tcp
|
||||
- 443/tcp
|
||||
- 443/udp # Caddy's HTTP/3 (QUIC) (not published)
|
||||
- 2019/tcp # Caddy's admin API (not published)
|
||||
ports:
|
||||
- ${CADDY_INTERFACE:-0.0.0.0}:80:80
|
||||
- ${CADDY_INTERFACE:-0.0.0.0}:443:443
|
||||
# - ${CADDY_INTERFACE:-0.0.0.0}:443:443/udp" # future: HTTP/3 (QUIC)
|
||||
volumes:
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
networks:
|
||||
quickstart:
|
||||
|
||||
quickstart:
|
||||
profiles:
|
||||
- ziti
|
||||
quickstart-check:
|
||||
profiles:
|
||||
- ziti
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
zrok_ctrl:
|
||||
zrok_frontend:
|
42
docker/compose/zrok-instance/envsubst.bash
Executable file
42
docker/compose/zrok-instance/envsubst.bash
Executable file
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# Read the shell-format template from stdin
|
||||
TEMPLATE=$(cat)
|
||||
|
||||
# consume args as default values from a file or a list of shell commands
|
||||
while (( $# )); do
|
||||
if [ -s "$1" ]; then
|
||||
# Read the default values from the file
|
||||
# shellcheck disable=SC1090
|
||||
source "$1"
|
||||
else
|
||||
# Use the argument as a shell command
|
||||
eval "$1"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -z "$TEMPLATE" ]; then
|
||||
echo "Error: no template provided on stdin" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# obtain the list of required variables
|
||||
read -ra VARIABLES <<< "$(envsubst "$TEMPLATE" --variables)"
|
||||
|
||||
# Check that all required variables are set
|
||||
for var in "${VARIABLES[@]}"; do
|
||||
if [ -z "${!var:-}" ]; then
|
||||
echo "Error: $var is null" >&2
|
||||
exit 1
|
||||
else
|
||||
export "${var?}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Render the template to stdout
|
||||
envsubst <<< "$TEMPLATE"
|
86
docker/compose/zrok-instance/fetch.bash
Executable file
86
docker/compose/zrok-instance/fetch.bash
Executable file
@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
set -o xtrace
|
||||
|
||||
requireBashVersion() {
|
||||
if (( "${BASH_VERSION%%.*}" < 4 )); then
|
||||
echo "This script requires Bash major version 4 or greater."
|
||||
echo "Detected version: $BASH_VERSION"
|
||||
exit 1;
|
||||
fi
|
||||
}
|
||||
|
||||
fetchFile() {
|
||||
|
||||
local url="${1}"
|
||||
local path="${2}"
|
||||
|
||||
if [[ -s "$path" ]]; then
|
||||
echo "ERROR: file already exists: $path" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if { command -v curl > /dev/null; } 2>&1; then
|
||||
curl -fLsS --output "${path}" "${url}"
|
||||
elif { command -v wget > /dev/null; } 2>&1; then
|
||||
wget --output-document "${path}" "${url}"
|
||||
else
|
||||
echo "ERROR: need one of curl or wget to fetch the artifact." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
requireCommand() {
|
||||
if ! command -v "$1" &>/dev/null; then
|
||||
logError "this script requires command '$1'. Please install on the search PATH and try again."
|
||||
$1
|
||||
fi
|
||||
}
|
||||
|
||||
setWorkingDir() {
|
||||
workdir="${1}"
|
||||
|
||||
cd "${workdir}"
|
||||
|
||||
# Count non-hidden files
|
||||
non_hidden_files=$(find . -maxdepth 1 -not -name '.*' | wc -l)
|
||||
# Count hidden files
|
||||
if ls -ld .[^.]* 2> /dev/null; then
|
||||
hidden_files=0
|
||||
for file in .[^.]*; do
|
||||
if [[ -f "$file" ]]; then
|
||||
hidden_files=$((hidden_files + 1))
|
||||
fi
|
||||
done
|
||||
else
|
||||
hidden_files=0
|
||||
fi
|
||||
# Calculate total number of files
|
||||
total_files=$((non_hidden_files + hidden_files))
|
||||
if (( total_files > 0 )); then
|
||||
echo "WARN: working directory is not empty: ${workdir}" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
requireBashVersion
|
||||
declare -a BINS=(unzip find)
|
||||
for BIN in "${BINS[@]}"; do
|
||||
requireCommand "$BIN"
|
||||
done
|
||||
setWorkingDir "${1:-$PWD}" || {
|
||||
echo "WARN: installing anyway in a few seconds...press Ctrl-C to abort" >&2
|
||||
sleep 9
|
||||
}
|
||||
fetchFile "${ZITI_QUICK_COMPOSE:-"https://get.openziti.io/dock/all-in-one/compose.yml"}" "compose.yml"
|
||||
fetchFile "${ZROK_REPO_ZIP:-"https://github.com/openziti/zrok/archive/refs/heads/main.zip"}" "zrok.zip"
|
||||
unzip -j -d . zrok.zip '*/docker/compose/zrok-instance/*'
|
||||
rm zrok.zip .gitignore fetch.bash
|
||||
}
|
||||
|
||||
main "${@}"
|
@ -0,0 +1,25 @@
|
||||
# _____ __ ___ | | __
|
||||
# |_ / '__/ _ \| |/ /
|
||||
# / /| | | (_) | <
|
||||
# /___|_| \___/|_|\_\
|
||||
# controller configuration
|
||||
|
||||
v: 3
|
||||
admin:
|
||||
# generate these admin tokens from a source of randomness, e.g.
|
||||
# LC_ALL=C tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c32
|
||||
secrets:
|
||||
- ${ZROK_ADMIN_TOKEN}
|
||||
endpoint:
|
||||
host: 0.0.0.0
|
||||
port: ${ZROK_CTRL_PORT}
|
||||
invites:
|
||||
invites_open: true
|
||||
token_strategy: store
|
||||
store:
|
||||
path: /var/lib/zrok-controller/sqlite3.db
|
||||
type: sqlite3
|
||||
ziti:
|
||||
api_endpoint: https://ziti.${ZROK_DNS_ZONE}:${ZITI_CTRL_ADVERTISED_PORT}/edge/management/v1
|
||||
username: admin
|
||||
password: ${ZITI_PWD}
|
37
docker/compose/zrok-instance/zrok-controller.Dockerfile
Normal file
37
docker/compose/zrok-instance/zrok-controller.Dockerfile
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
ARG ZROK_CLI_TAG=latest
|
||||
ARG ZROK_CLI_IMAGE=openziti/zrok
|
||||
FROM ${ZROK_CLI_IMAGE}:${ZROK_CLI_TAG}
|
||||
|
||||
# set up image as root
|
||||
USER root
|
||||
|
||||
# install envsubst
|
||||
RUN INSTALL_PKGS="gettext" && \
|
||||
microdnf -y update --setopt=install_weak_deps=0 --setopt=tsflags=nodocs && \
|
||||
microdnf -y install --setopt=install_weak_deps=0 --setopt=tsflags=nodocs ${INSTALL_PKGS}
|
||||
|
||||
ARG ZROK_DNS_ZONE
|
||||
ARG ZROK_ADMIN_TOKEN
|
||||
ARG ZROK_CTRL_PORT
|
||||
ARG ZITI_CTRL_ADVERTISED_PORT
|
||||
ARG ZITI_PWD
|
||||
|
||||
# render zrok controller config.yml
|
||||
COPY ./envsubst.bash ./bootstrap-controller.bash /usr/local/bin/
|
||||
RUN chmod 0755 /usr/local/bin/envsubst.bash /usr/local/bin/bootstrap-controller.bash
|
||||
COPY ./zrok-controller-config.yml.envsubst /tmp/
|
||||
RUN mkdir -p /etc/zrok-controller/
|
||||
RUN envsubst.bash \
|
||||
ZROK_DNS_ZONE=${ZROK_DNS_ZONE} \
|
||||
ZROK_ADMIN_TOKEN=${ZROK_ADMIN_TOKEN} \
|
||||
ZROK_CTRL_PORT=${ZROK_CTRL_PORT} \
|
||||
ZITI_CTRL_ADVERTISED_PORT=${ZITI_CTRL_ADVERTISED_PORT} \
|
||||
ZITI_PWD=${ZITI_PWD} \
|
||||
< /tmp/zrok-controller-config.yml.envsubst > /etc/zrok-controller/config.yml
|
||||
|
||||
# run as ziggy (or ZIGGY_UID if set in compose project)
|
||||
USER ziggy
|
||||
ENV HOME=/var/lib/zrok-controller
|
||||
WORKDIR /var/lib/zrok-controller
|
||||
ENTRYPOINT ["bootstrap-controller.bash"]
|
@ -0,0 +1,18 @@
|
||||
v: 3
|
||||
|
||||
host_match: ${ZROK_DNS_ZONE}
|
||||
address: 0.0.0.0:${ZROK_FRONTEND_PORT}
|
||||
|
||||
# delete if not using oauth for public shares
|
||||
oauth:
|
||||
bind_address: 0.0.0.0:${ZROK_OAUTH_PORT}
|
||||
redirect_url: https://oauth.${ZROK_DNS_ZONE}
|
||||
cookie_domain: ${ZROK_DNS_ZONE}
|
||||
hash_key: ${ZROK_OAUTH_HASH_KEY}
|
||||
providers:
|
||||
- name: github
|
||||
client_id: ${ZROK_OAUTH_GITHUB_CLIENT_ID}
|
||||
client_secret: ${ZROK_OAUTH_GITHUB_CLIENT_SECRET}
|
||||
- name: google
|
||||
client_id: ${ZROK_OAUTH_GOOGLE_CLIENT_ID}
|
||||
client_secret: ${ZROK_OAUTH_GOOGLE_CLIENT_SECRET}
|
43
docker/compose/zrok-instance/zrok-frontend.Dockerfile
Normal file
43
docker/compose/zrok-instance/zrok-frontend.Dockerfile
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
ARG ZROK_CLI_TAG=latest
|
||||
ARG ZROK_CLI_IMAGE=openziti/zrok
|
||||
FROM ${ZROK_CLI_IMAGE}:${ZROK_CLI_TAG}
|
||||
|
||||
# set up image as root
|
||||
USER root
|
||||
|
||||
# install envsubst
|
||||
RUN INSTALL_PKGS="gettext" && \
|
||||
microdnf -y update --setopt=install_weak_deps=0 --setopt=tsflags=nodocs && \
|
||||
microdnf -y install --setopt=install_weak_deps=0 --setopt=tsflags=nodocs ${INSTALL_PKGS}
|
||||
|
||||
ARG ZROK_DNS_ZONE
|
||||
ARG ZROK_FRONTEND_PORT
|
||||
ARG ZROK_OAUTH_PORT
|
||||
ARG ZROK_OAUTH_HASH_KEY
|
||||
ARG ZROK_OAUTH_GOOGLE_CLIENT_ID
|
||||
ARG ZROK_OAUTH_GOOGLE_CLIENT_SECRET
|
||||
ARG ZROK_OAUTH_GITHUB_CLIENT_ID
|
||||
ARG ZROK_OAUTH_GITHUB_CLIENT_SECRET
|
||||
|
||||
# render zrok frontend config.yml
|
||||
COPY ./envsubst.bash ./bootstrap-frontend.bash /usr/local/bin/
|
||||
RUN chmod 0755 /usr/local/bin/envsubst.bash /usr/local/bin/bootstrap-frontend.bash
|
||||
COPY ./zrok-frontend-config.yml.envsubst /tmp/
|
||||
RUN mkdir -p /etc/zrok-frontend/
|
||||
RUN envsubst.bash \
|
||||
ZROK_DNS_ZONE=${ZROK_DNS_ZONE} \
|
||||
ZROK_FRONTEND_PORT=${ZROK_FRONTEND_PORT} \
|
||||
ZROK_OAUTH_PORT=${ZROK_OAUTH_PORT} \
|
||||
ZROK_OAUTH_HASH_KEY=${ZROK_OAUTH_HASH_KEY} \
|
||||
ZROK_OAUTH_GOOGLE_CLIENT_ID=${ZROK_OAUTH_GOOGLE_CLIENT_ID} \
|
||||
ZROK_OAUTH_GOOGLE_CLIENT_SECRET=${ZROK_OAUTH_GOOGLE_CLIENT_SECRET} \
|
||||
ZROK_OAUTH_GITHUB_CLIENT_ID=${ZROK_OAUTH_GITHUB_CLIENT_ID} \
|
||||
ZROK_OAUTH_GITHUB_CLIENT_SECRET=${ZROK_OAUTH_GITHUB_CLIENT_SECRET} \
|
||||
< /tmp/zrok-frontend-config.yml.envsubst > /etc/zrok-frontend/config.yml
|
||||
|
||||
# run as ziggy (or ZIGGY_UID if set in compose project)
|
||||
USER ziggy
|
||||
ENV HOME=/var/lib/zrok-frontend
|
||||
WORKDIR /var/lib/zrok-frontend
|
||||
ENTRYPOINT ["bootstrap-frontend.bash"]
|
@ -1,7 +1,7 @@
|
||||
# this builds docker.io/openziti/zrok
|
||||
ARG ZITI_CLI_TAG="0.32.1"
|
||||
ARG ZITI_CLI_TAG="1.0.0"
|
||||
ARG ZITI_CLI_IMAGE="docker.io/openziti/ziti-cli"
|
||||
# this builds docker.io/openziti/ziti-controller
|
||||
|
||||
FROM ${ZITI_CLI_IMAGE}:${ZITI_CLI_TAG}
|
||||
|
||||
ARG ARTIFACTS_DIR=./dist
|
||||
@ -20,16 +20,12 @@ LABEL name="openziti/zrok" \
|
||||
|
||||
USER root
|
||||
|
||||
### install packages: findutils provides xargs which is used by the zrok Helm chart's controller bootstrapping script to
|
||||
#create the default account enable token
|
||||
RUN INSTALL_PKGS="findutils" && \
|
||||
microdnf -y update --setopt=install_weak_deps=0 --setopt=tsflags=nodocs && \
|
||||
microdnf -y install --setopt=install_weak_deps=0 --setopt=tsflags=nodocs ${INSTALL_PKGS}
|
||||
|
||||
### add licenses to this directory
|
||||
RUN mkdir -p -m0755 /licenses
|
||||
COPY ./LICENSE /licenses/apache.txt
|
||||
|
||||
ENV PFXLOG_NO_JSON=true
|
||||
|
||||
RUN mkdir -p /usr/local/bin
|
||||
COPY ${ARTIFACTS_DIR}/${TARGETARCH}/${TARGETOS}/zrok \
|
||||
./nfpm/zrok-enable.bash \
|
||||
@ -40,5 +36,5 @@ RUN chmod 0755 \
|
||||
/usr/local/bin/zrok-enable.bash \
|
||||
/usr/local/bin/zrok-share.bash
|
||||
|
||||
USER nobody
|
||||
USER ziggy
|
||||
ENTRYPOINT [ "zrok" ]
|
||||
|
@ -6,7 +6,7 @@ sidebar_position: 200
|
||||
|
||||
## Self-Hosted
|
||||
|
||||
`zrok` is not limited to a managed offering. You can [host your own](../guides/self-hosting/self_hosting_guide.md) instance of `zrok` as well. `zrok` is
|
||||
`zrok` is not limited to a managed offering. You can [host your own](/guides/self-hosting/linux.mdx) instance of `zrok` as well. `zrok` is
|
||||
also freely available as open source software hosted by GitHub under a very permissive Apache v2 license.
|
||||
|
||||
## Managed Service
|
||||
|
@ -10,4 +10,4 @@ sidebar_position: 25
|
||||
Sharing with `zrok` can be either [`public`](./sharing-public.md) or [`private`](./sharing-private.md).
|
||||
Naturally, regular web-based resources can be shared but `zrok` also includes support for sharing raw [TCP](./tunnels.md) and [UDP](./tunnels.md) network connections, and also includes a [website and file sharing](./files.md) feature.
|
||||
|
||||
Learn about `zrok` [hosting here](./hosting.md), including instructions on how to [install your own `zrok` instance](../guides/self-hosting/self_hosting_guide.md).
|
||||
Learn about `zrok` [hosting here](./hosting.md), including instructions on how to [install your own `zrok` instance](/guides/self-hosting/linux.mdx).
|
||||
|
@ -4,7 +4,7 @@ sidebar_position: 0
|
||||
# Private Shares
|
||||
|
||||
`zrok` was built to share and access digital resources. A `private` share allows a resource to be
|
||||
accessed on another user's system as if it were local to them. Privately shared resources can only be accessed by another `zrok` user who has the details of your unique share. You are in control of who can access your `private` shares by sharing the the share token.
|
||||
accessed on another user's system as if it were local to them. Privately shared resources can only be accessed by another `zrok` user who has the details of your unique share. You are in control of who can access your `private` shares by sharing the share token.
|
||||
|
||||
Peer-to-peer private resource sharing is one of the things that makes `zrok` unique.
|
||||
|
||||
@ -26,4 +26,4 @@ The shared resource can be a development web server to share with friends and co
|
||||
|
||||
The peer-to-peer capabilities of `zrok` are an important property of the underlying [OpenZiti](https://docs.openziti.io/docs/learn/introduction/) network that `zrok` uses to provide connectivity between users and resources.
|
||||
|
||||
Creating `private` shares is easy and is accomplished using the `zrok share private` command. Run `zrok share private` to see the usage output and to further learn how to use the command.
|
||||
Creating `private` shares is easy and is accomplished using the `zrok share private` command. Run `zrok share private` to see the usage output and to further learn how to use the command.
|
||||
|
@ -356,7 +356,7 @@ You use the `zrok reserve` command to create _reserved shares_. Reserved shares
|
||||
|
||||
## Self-Hosting an Instance
|
||||
|
||||
Interested in self-hosting your own `zrok` instance? See the [self-hosting guide](./guides/self-hosting/self_hosting_guide.md) for details.
|
||||
Interested in self-hosting your own `zrok` instance? See the [self-hosting guide](./guides/self-hosting/linux.mdx) for details.
|
||||
|
||||
[openziti]: https://docs.openziti.io/docs/learn/introduction/ "OpenZiti"
|
||||
[ zrok-download]: https://zrok.io "zrok Download"
|
||||
|
@ -1,134 +0,0 @@
|
||||
## Goal
|
||||
|
||||
Proxy a reserved public subdomain to a backend target with an always-on Docker Compose service.
|
||||
|
||||
## How it Works
|
||||
|
||||
The Docker Compose project uses your zrok account token to reserve a public subdomain and keep sharing the backend
|
||||
target.
|
||||
|
||||
When the project runs it will:
|
||||
|
||||
1. enable a zrok environment unless `/mnt/.zrok/environment.json` exists in the `zrok_env` volume
|
||||
1. reserve a public subdomain for the service unless `/mnt/.zrok/reserved.json` exists
|
||||
1. start sharing the target specified in the `ZROK_TARGET` environment variable
|
||||
|
||||
## Create the Docker Project
|
||||
|
||||
1. 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.
|
||||
1. Download [the reserved public share `compose.yml` project file](pathname:///zrok-public-reserved/compose.yml) into the same directory.
|
||||
1. Copy your zrok account's enable token from the zrok web console to your clipboard and paste it in a file named `.env` in the same folder like this:
|
||||
|
||||
```bash title=".env"
|
||||
ZROK_ENABLE_TOKEN="8UL9-48rN0ua"
|
||||
```
|
||||
1. Name the Share
|
||||
|
||||
This unique name becomes part of the domain name of the share, e.g. `https://my-prod-app.in.zrok.io`. A random name is generated if you don't specify one.
|
||||
|
||||
```bash title=".env"
|
||||
ZROK_UNIQUE_NAME="my-prod-app"
|
||||
```
|
||||
|
||||
1. Run the Compose project to start sharing the built-in demo web server. Be sure to `--detach` so the project runs in the background if you want it to auto-restart when your computer reboots.
|
||||
|
||||
```bash
|
||||
docker compose up --detach
|
||||
```
|
||||
|
||||
1. Get the public share URL from the output of the `zrok-share` service or by peeking in the zrok console where the share will appear in the graph.
|
||||
|
||||
```bash
|
||||
docker compose logs zrok-share
|
||||
```
|
||||
|
||||
```buttonless title="Output"
|
||||
zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Proxy Any Web Server
|
||||
|
||||
The simplest way to share your existing HTTP server is to set `ZROK_TARGET` (e.g. `https://example.com`) in the environment of the `docker compose up` command. When you restart the share will auto-configure for that URL.
|
||||
|
||||
```bash title=".env"
|
||||
ZROK_TARGET="http://example.com:8080"
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose down && docker compose up
|
||||
```
|
||||
|
||||
## Require Authentication
|
||||
|
||||
You can require a password or an OAuth login with certain email addresses.
|
||||
|
||||
### OAuth Email
|
||||
|
||||
You can allow specific email addresses or an email domain by setting `ZROK_OAUTH_PROVIDER` to `github` or `google` and
|
||||
`ZROK_SHARE_OPTS` to specify additional command-line options to `zrok reserve public`. Read more about the OAuth
|
||||
features in [this blog post](https://blog.openziti.io/the-zrok-oauth-public-frontend).
|
||||
|
||||
```bash title=".env"
|
||||
ZROK_OAUTH_PROVIDER="github"
|
||||
ZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"
|
||||
```
|
||||
|
||||
## Caddy is Powerful
|
||||
|
||||
The reserved public share project uses zrok's default backend mode, `proxy`. Another backend mode, `caddy`, accepts a path to [a Caddyfile](https://caddyserver.com/docs/caddyfile) as the value of `ZROK_TARGET` ([zrok Caddyfile examples](https://github.com/openziti/zrok/tree/main/etc/caddy)).
|
||||
|
||||
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 `caddy` reduces the risk that you'll have to share a new frontend URL with your users.
|
||||
|
||||
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.
|
||||
|
||||
1. Create a Caddyfile. This example demonstrates proxying two HTTP servers with a weighted round-robin load balancer.
|
||||
|
||||
```console title="Caddyfile"
|
||||
http:// {
|
||||
# zrok requires this bind address template
|
||||
bind {{ .ZrokBindAddress }}
|
||||
reverse_proxy /* {
|
||||
to http://httpbin1:8080 http://httpbin2:8080
|
||||
lb_policy weighted_round_robin 3 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Create a file `compose.override.yml`. This example adds two `httpbin` containers for load balancing, and mounts the Caddyfile into the container.
|
||||
|
||||
```yaml title="compose.override.yml"
|
||||
services:
|
||||
httpbin1:
|
||||
image: mccutchen/go-httpbin # 8080/tcp
|
||||
httpbin2:
|
||||
image: mccutchen/go-httpbin # 8080/tcp
|
||||
zrok-share:
|
||||
volumes:
|
||||
- ./Caddyfile:/mnt/.zrok/Caddyfile
|
||||
```
|
||||
|
||||
1. Start a new Docker Compose project or delete the existing state volume.
|
||||
|
||||
```bash
|
||||
docker compose down --volumes
|
||||
```
|
||||
|
||||
If you prefer to keep using the same zrok environment with the new share then delete `/mnt/.zrok/reserved.json` instead of the entire volume.
|
||||
|
||||
1. Run the project to load the new configuration.
|
||||
|
||||
```bash
|
||||
docker compose up --detach
|
||||
```
|
||||
|
||||
1. Note the new reserved share URL from the log.
|
||||
|
||||
```bash
|
||||
docker compose logs zrok-share
|
||||
```
|
||||
|
||||
```buttonless title="Output"
|
||||
INFO: zrok public URL: https://88s803f2qvao.in.zrok.io/
|
||||
```
|
@ -2,6 +2,7 @@
|
||||
"label": "Docker Share",
|
||||
"position": 40,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
"type": "doc",
|
||||
"id": "guides/docker-share/index"
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
---
|
||||
title: Docker Private Share
|
||||
sidebar_position: 20
|
||||
sidebar_label: Private Share
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
# Docker Private Share
|
||||
Privately share a Docker Compose service with a separate zrok environment and a permanent zrok share token.
|
||||
|
||||
With zrok, you can privately share a server app that's running in Docker, or any server that's reachable by the zrok container. Then, a zrok private access running somewhere else can use the private share. In this guide we'll cover both sides: the private share and the private access.
|
||||
## Overview
|
||||
|
||||
With zrok, you can privately share a service that's running in Docker. You need a zrok private share running somewhere that it can reach the service you're sharing, and a zrok private access running somewhere else where you want to use the private share. Together, the private share and private access form a private point-to-point tunnel.
|
||||
|
||||
Here's a short article with an overview of [private sharing with zrok](/concepts/sharing-private.md).
|
||||
|
||||
@ -14,6 +18,16 @@ Here's a short article with an overview of [private sharing with zrok](/concepts
|
||||
|
||||
<iframe width="100%" height="315" src="https://www.youtube.com/embed/HxyvtFAvwUE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
||||
## How it Works
|
||||
|
||||
The Docker Compose project uses your zrok account token to reserve a private share token and keep sharing the backend target.
|
||||
|
||||
When the project runs it will:
|
||||
|
||||
1. enable a zrok environment unless `/mnt/.zrok/environment.json` exists in the `zrok_env` volume
|
||||
1. reserve a private share token for the service unless `/mnt/.zrok/reserved.json` exists
|
||||
1. start sharing the target specified in the `ZROK_TARGET` environment variable
|
||||
|
||||
## Before You Begin
|
||||
|
||||
To follow this guide you will need [Docker](https://docs.docker.com/get-docker/) and [the Docker Compose plugin](https://docs.docker.com/compose/install/) for running `docker compose` commands in your terminal.
|
||||
|
@ -1,10 +1,16 @@
|
||||
---
|
||||
title: Docker Public Share
|
||||
title: Docker Compose Public Share
|
||||
sidebar_position: 10
|
||||
sidebar_label: Public Share
|
||||
---
|
||||
|
||||
With zrok and Docker, you can publicly share a web server that's running in a local container or anywhere that's reachable by the zrok container. The share can be reached through a temporary public URL that expires when the container is stopped. If you're looking for a reserved subdomain for the share, check out [zrok frontdoor](/guides/frontdoor.mdx).
|
||||
## Goal
|
||||
|
||||
Publicly share a Docker Compose service with a separate zrok environment and a permanent zrok share URL.
|
||||
|
||||
## Overview
|
||||
|
||||
With zrok, you can publicly share a service that's running in Docker. You need a zrok public share running somewhere that it can reach the service you're sharing. As long as that public share is running and your service is available, anyone with the address can use your service.
|
||||
|
||||
Here's a short article with an overview of [public sharing with zrok](/concepts/sharing-public.md).
|
||||
|
||||
@ -12,101 +18,134 @@ Here's a short article with an overview of [public sharing with zrok](/concepts/
|
||||
|
||||
<iframe width="100%" height="315" src="https://www.youtube.com/embed/ycov--9ZtB4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
||||
## Before You Begin
|
||||
## How it Works
|
||||
|
||||
To follow this guide you will need [Docker](https://docs.docker.com/get-docker/) and [the Docker Compose plugin](https://docs.docker.com/compose/install/) for running `docker compose` commands in your terminal.
|
||||
The Docker Compose project uses your zrok account token to reserve a public subdomain and keep sharing the backend
|
||||
target.
|
||||
|
||||
## Begin Sharing with Docker Compose
|
||||
When the project runs it will:
|
||||
|
||||
A temporary public share is a great way to share a web server running in a container with someone else for a short time.
|
||||
1. enable a zrok environment unless `/mnt/.zrok/environment.json` exists in the `zrok_env` volume
|
||||
1. reserve a public subdomain for the service unless `/mnt/.zrok/reserved.json` exists
|
||||
1. start sharing the target specified in the `ZROK_TARGET` environment variable
|
||||
|
||||
1. Make a folder on your computer to use as a Docker Compose project for your zrok public share.
|
||||
1. In your terminal, change directory to the newly-created project folder.
|
||||
1. Download [the temporary public share project file](pathname:///zrok-public-share/compose.yml).
|
||||
1. Copy your zrok environment token from the zrok web console to your clipboard and paste it in a file named `.env` in the same folder like this:
|
||||
## Create the Docker Project
|
||||
|
||||
```bash title=".env"
|
||||
ZROK_ENABLE_TOKEN="8UL9-48rN0ua"
|
||||
```
|
||||
1. 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.
|
||||
1. Download [the reserved public share `compose.yml` project file](pathname:///zrok-public-reserved/compose.yml) into the same directory.
|
||||
1. Copy your zrok account's enable token from the zrok web console to your clipboard and paste it in a file named `.env` in the same folder like this:
|
||||
|
||||
1. Set the zrok API endpoint if self-hosting zrok. Skip this if using zrok.io.
|
||||
```bash title=".env"
|
||||
ZROK_ENABLE_TOKEN="8UL9-48rN0ua"
|
||||
```
|
||||
|
||||
```bash title=".env"
|
||||
ZROK_API_ENDPOINT="https://zrok.example.com"
|
||||
```
|
||||
1. Name the Share
|
||||
|
||||
1. Run the Compose project to start sharing the built-in demo web server.
|
||||
This unique name becomes part of the domain name of the share, e.g. `https://my-prod-app.in.zrok.io`. A random name is generated if you don't specify one.
|
||||
|
||||
```bash
|
||||
docker compose up --detach
|
||||
```
|
||||
```bash title=".env"
|
||||
ZROK_UNIQUE_NAME="my-prod-app"
|
||||
```
|
||||
|
||||
1. Get the public share URL from the output of the `zrok-share` service or by peeking in the zrok console where the share will be graphed.
|
||||
1. Run the Compose project to start sharing the built-in demo web server. Be sure to `--detach` so the project runs in the background if you want it to auto-restart when your computer reboots.
|
||||
|
||||
```bash
|
||||
docker compose logs zrok-share
|
||||
```
|
||||
```bash
|
||||
docker compose up --detach
|
||||
```
|
||||
|
||||
```buttonless title="Output"
|
||||
zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/
|
||||
```
|
||||
1. Get the public share URL from the output of the `zrok-share` service or by peeking in the zrok console where the share will appear in the graph.
|
||||
|
||||
This concludes sharing the demo web server. Read on to learn how to pivot to sharing any web server leveraging additional zrok backend modes.
|
||||
```bash
|
||||
docker compose logs zrok-share
|
||||
```
|
||||
|
||||
```buttonless title="Output"
|
||||
zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Proxy Any Web Server
|
||||
|
||||
The simplest way to share your web server is to set `ZROK_TARGET` (e.g. `https://example.com`) in the environment file.
|
||||
The simplest way to share your existing HTTP server is to set `ZROK_TARGET` (e.g. `https://example.com`) in the environment of the `docker compose up` command. When you restart the share will auto-configure for that URL.
|
||||
|
||||
```bash title=".env"
|
||||
ZROK_TARGET="http://example.com:8080"
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose down && docker compose up
|
||||
```
|
||||
|
||||
## Require Authentication
|
||||
|
||||
You can require authentication for your public share by setting `ZROK_OAUTH_PROVIDER` to `github` or `google` with zrok.io. You could parse the authenticated email address from the request cookie if you're building a custom server app. Read more about the OAuth features in [this blog post](https://blog.openziti.io/the-zrok-oauth-public-frontend).
|
||||
You can require a password or an OAuth login with certain email addresses.
|
||||
|
||||
### OAuth Email
|
||||
|
||||
You can allow specific email addresse patterns by setting `ZROK_OAUTH_PROVIDER` to `github` or `google` and
|
||||
`ZROK_OAUTH_EMAILS`. Read more about the OAuth features in [this blog
|
||||
post](https://blog.openziti.io/the-zrok-oauth-public-frontend).
|
||||
|
||||
```bash title=".env"
|
||||
ZROK_OAUTH_PROVIDER="github"
|
||||
ZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"
|
||||
```
|
||||
|
||||
## Customize Temporary Public Share
|
||||
## Caddy is Powerful
|
||||
|
||||
This technique is useful for adding a containerized service to the project, or mounting a filesystem directory into the container to share as a static website or file server.
|
||||
The reserved public share project uses zrok's default backend mode, `proxy`. Another backend mode, `caddy`, accepts a path to [a Caddyfile](https://caddyserver.com/docs/caddyfile) as the value of `ZROK_TARGET` ([zrok Caddyfile examples](https://github.com/openziti/zrok/tree/main/etc/caddy)).
|
||||
|
||||
Any additional services specified in the override file will be merged with `compose.yml` when you `up` the project.
|
||||
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 `caddy` reduces the risk that you'll have to share a new frontend URL with your users.
|
||||
|
||||
You may override individual values from in `compose.yml` by specifying them in the override file.
|
||||
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.
|
||||
|
||||
1. Create a file `compose.override.yml`. This example demonstrates sharing a static HTML directory `/tmp/html` from the Docker host's filesystem.
|
||||
1. Create a Caddyfile. This example demonstrates proxying two HTTP servers with a weighted round-robin load balancer.
|
||||
|
||||
```yaml title="compose.override.yml"
|
||||
services:
|
||||
zrok-share:
|
||||
command: share public --headless --backend-mode web /tmp/html
|
||||
volumes:
|
||||
- /tmp/html:/tmp/html
|
||||
```
|
||||
|
||||
1. Re-run the project to load the new configuration.
|
||||
|
||||
```bash
|
||||
docker compose up --force-recreate --detach
|
||||
```
|
||||
|
||||
1. Get the new tempoary public share URL for the `zrok-share` container.
|
||||
|
||||
```bash
|
||||
docker compose logs zrok-share
|
||||
```
|
||||
|
||||
```buttonless title="Output"
|
||||
zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/
|
||||
```console title="Caddyfile"
|
||||
http:// {
|
||||
# zrok requires this bind address template
|
||||
bind {{ .ZrokBindAddress }}
|
||||
reverse_proxy /* {
|
||||
to http://httpbin1:8080 http://httpbin2:8080
|
||||
lb_policy weighted_round_robin 3 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Destroy the zrok Environment
|
||||
1. Create a file `compose.override.yml`. This example adds two `httpbin` containers for load balancing, and mounts the Caddyfile into the container.
|
||||
|
||||
This destroys the Docker volumes containing the zrok environment secrets. The zrok environment can also be destroyed in the web console.
|
||||
```yaml title="compose.override.yml"
|
||||
services:
|
||||
httpbin1:
|
||||
image: mccutchen/go-httpbin # 8080/tcp
|
||||
httpbin2:
|
||||
image: mccutchen/go-httpbin # 8080/tcp
|
||||
zrok-share:
|
||||
volumes:
|
||||
- ./Caddyfile:/mnt/.zrok/Caddyfile
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose down --volumes
|
||||
```
|
||||
1. Start a new Docker Compose project or delete the existing state volume.
|
||||
|
||||
```bash
|
||||
docker compose down --volumes
|
||||
```
|
||||
|
||||
If you prefer to keep using the same zrok environment with the new share then delete `/mnt/.zrok/reserved.json` instead of the entire volume.
|
||||
|
||||
1. Run the project to load the new configuration.
|
||||
|
||||
```bash
|
||||
docker compose up --detach
|
||||
```
|
||||
|
||||
1. Note the new reserved share URL from the log.
|
||||
|
||||
```bash
|
||||
docker compose logs zrok-share
|
||||
```
|
||||
|
||||
```buttonless title="Output"
|
||||
INFO: zrok public URL: https://88s803f2qvao.in.zrok.io/
|
||||
```
|
||||
|
112
docs/guides/docker-share/index.mdx
Normal file
112
docs/guides/docker-share/index.mdx
Normal file
@ -0,0 +1,112 @@
|
||||
---
|
||||
title: Getting Started with Docker
|
||||
---
|
||||
|
||||
import Details from '@theme/MDXComponents/Details';
|
||||
|
||||
## Overview
|
||||
|
||||
To follow the guides in this section you will need [Docker](https://docs.docker.com/get-docker/).
|
||||
|
||||
You have the option to enable a `zrok` account on the Docker host and mount it on the container or you can use the provided Docker Compose project files (`compose.yml`) to enable a separate `zrok` environment for each project.
|
||||
|
||||
This page provides `docker` and `docker compose` examples of mounting the host's `zrok` environment on the container. You'll need to first [enable zrok on the Docker host](/docs/getting-started/#installing-the-zrok-command) to use this approach.
|
||||
|
||||
## Permanent Public Share
|
||||
|
||||
Let's say you have a `compose.yml` file that defines a web app known within the project's bridge network as `https://myapp:8080` and you want to publish it as a reliable, public site.
|
||||
|
||||
1. Reserve a subdomain by running `zrok reserve public --unique-name "myapp" https://myapp:8080` on the Docker host.
|
||||
1. Merge this YAML with `compose.yml` or save it in the same directory as `compose.override.yml` to let `docker compose up` merge it for you.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
zrok:
|
||||
image: openziti/zrok
|
||||
restart: unless-stopped
|
||||
user: "${UID}"
|
||||
volumes:
|
||||
- ${HOME}/.zrok:/.zrok
|
||||
environment:
|
||||
PFXLOG_NO_JSON: "true"
|
||||
command: share reserved "myapp" --headless
|
||||
```
|
||||
|
||||
The reserved share will be available at `https://myapp.share.zrok.io` each time the `zrok` container starts up.
|
||||
|
||||
## Temporary Public Share
|
||||
|
||||
Let's say you have a web server running on the host's private network at `https://10.11.12.13:8080`. With one additional `docker` command, you can share the web server publicly as long as the `zrok` container stays running.
|
||||
|
||||
```bash title="BASH"
|
||||
docker run \
|
||||
--rm \
|
||||
--network=host \
|
||||
--volume ~/.zrok:/.zrok \
|
||||
--user "${UID}" \
|
||||
openziti/zrok share public \
|
||||
--headless \
|
||||
https://10.11.12.13:8080
|
||||
```
|
||||
|
||||
<Details>
|
||||
<summary>PowerShell</summary>
|
||||
|
||||
```powershell
|
||||
docker.exe run `
|
||||
--rm `
|
||||
--network "host" `
|
||||
--volume "${env:USERPROFILE}\.zrok:/.zrok" `
|
||||
--user "1000" `
|
||||
openziti/zrok share public `
|
||||
--headless `
|
||||
https://10.11.12.13:8080
|
||||
```
|
||||
|
||||
</Details>
|
||||
|
||||
|
||||
<Details>
|
||||
<summary>Command Prompt (batch)</summary>
|
||||
|
||||
```cmd
|
||||
docker.exe run ^
|
||||
--rm ^
|
||||
--network "host" ^
|
||||
--volume "%USERPROFILE%\.zrok:/.zrok" ^
|
||||
--user "1000" ^
|
||||
openziti/zrok share public ^
|
||||
--headless ^
|
||||
https://10.11.12.13:8080
|
||||
```
|
||||
|
||||
</Details>
|
||||
|
||||
<Details>
|
||||
<summary>Windows Subsystem for Linux (WSL)</summary>
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
--rm \
|
||||
--network "host" \
|
||||
--volume "/mnt/c/Users/$(powershell.exe -Command 'Write-Output $env:USERNAME' | tr -d '\r')/.zrok:/.zrok" \
|
||||
--user "$UID" \
|
||||
openziti/zrok share public \
|
||||
--headless \
|
||||
https://10.11.12.13:8080
|
||||
```
|
||||
|
||||
</Details>
|
||||
|
||||
The public share URL appears near the beginning of the container's log.
|
||||
|
||||
Let's break down those options and arguments.
|
||||
|
||||
1. `--rm` don't save this container because it's providing a temporary public share that's destroyed when the container stops
|
||||
1. `--network=host` shares the host's network with the container so that the container can reach the web server directly. This is always necessary when the web server is listening only on the host's loopback interface, e.g., `https://::1:8080`, and may not be strictly necessary if the target is routeable from the default Docker bridge.
|
||||
1. `--volume ~/.zrok:/.zrok` mounts the `zrok` configuration from the Docker host into the container.
|
||||
1. `--user "${UID}:${GID}"` sets the container's user to the current user on the Docker host to avoid permission issues with reading the mounted `zrok` configuration.
|
||||
1. `openziti/zrok` is the `zrok` Docker image.
|
||||
1. `share public` is the `zrok` command to share the target publicly until zrok exits.
|
||||
1. `--headless` runs the `zrok` command without the interactive terminal UI.
|
||||
1. `https://10.11.12.13:8080` is the target web server to share.
|
@ -8,7 +8,6 @@ hide_table_of_contents: true
|
||||
import OsTabs from '@theme/OsTabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import LinuxService from './_frontdoor-linux.mdx';
|
||||
import ReservedDocker from './_frontdoor-docker.mdx';
|
||||
import ThemedImage from '@theme/ThemedImage';
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
|
||||
@ -37,8 +36,7 @@ Choose between installing the Linux package or running zrok with Docker (Linux,
|
||||
queryString="os"
|
||||
values={[
|
||||
{ label: 'Linux', value: 'Linux', },
|
||||
{ label: 'macOS', value: 'Mac OS', },
|
||||
{ label: 'Windows', value: 'Windows', },
|
||||
{ label: 'Docker', value: 'Docker', },
|
||||
]}
|
||||
>
|
||||
|
||||
@ -46,25 +44,13 @@ Choose between installing the Linux package or running zrok with Docker (Linux,
|
||||
|
||||
On Linux, zrok frontdoor is implemented natively as a system service provided by the `zrok-share` DEB or RPM package.
|
||||
|
||||
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, [macOS](./?os=Mac+OS), and [Windows](./?os=Windows).
|
||||
|
||||
<LinuxService/>
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="Mac OS">
|
||||
<TabItem value="Docker">
|
||||
|
||||
On macOS, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service.
|
||||
|
||||
<ReservedDocker/>
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="Windows">
|
||||
|
||||
On Windows, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service.
|
||||
|
||||
<ReservedDocker/>
|
||||
On macOS and Windows, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service and manages a zrok environment that's separate from the Docker host. [Link to the Docker Public Share Guide](/guides/docker-share/docker_public_share_guide.md)
|
||||
|
||||
</TabItem>
|
||||
|
||||
|
9
docs/guides/self-hosting/docker.mdx
Normal file
9
docs/guides/self-hosting/docker.mdx
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Self-hosting guide for Docker
|
||||
sidebar_label: Docker
|
||||
sidebar_position: 45
|
||||
---
|
||||
|
||||
import DockerInstance from '/../docker/compose/zrok-instance/README.md'
|
||||
|
||||
<DockerInstance />
|
@ -1,10 +1,9 @@
|
||||
---
|
||||
sidebar_position: 40
|
||||
sidebar_label: Linux VPS
|
||||
title: Self-Hosting Guide for Linux
|
||||
sidebar_label: Linux
|
||||
---
|
||||
|
||||
# Self-Hosting Guide for Linux
|
||||
|
||||
## Walkthrough Video
|
||||
|
||||
<iframe width="100%" height="315" src="https://www.youtube.com/embed/870A5dke_u4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
@ -110,7 +109,7 @@ With your OpenZiti network running and your configuration saved to a local file
|
||||
Use the `zrok admin bootstrap` command to bootstrap like this:
|
||||
|
||||
```bash
|
||||
$ zrok admin bootstrap etc/ctrl.yml
|
||||
$ zrok admin bootstrap etc/ctrl.yml
|
||||
[ 0.002] INFO main.(*adminBootstrap).run: {
|
||||
...
|
||||
}
|
||||
@ -146,6 +145,8 @@ Notice this warning:
|
||||
[ 0.120] WARNING zrok/controller.Bootstrap: missing public frontend for ziti id 'sqJRAINSiB'; please use 'zrok admin create frontend sqJRAINSiB public https://{token}.your.dns.name' to create a frontend instance
|
||||
```
|
||||
|
||||
If you find it necessary to re-run the `zrok admin bootstrap` command, you may need to add the `--skip-frontend` flag to avoid re-creating the default `public` frontend's Ziti identity and router policy.
|
||||
|
||||
## Run zrok Controller
|
||||
|
||||
The `zrok` bootstrap process wants us to create a "public frontend" for our service. `zrok` uses public frontends to allow users to specify where they would like public traffic to ingress from.
|
||||
@ -180,15 +181,14 @@ $ zrok admin create frontend sqJRAINSiB public http://{token}.zrok.quigley.com:8
|
||||
The id of the frontend was emitted earlier in by the zrok controller when we ran the bootstrap command. If you don't have that log message the you can find the id again with the `ziti` CLI like this:
|
||||
|
||||
```bash
|
||||
# initialize the Ziti quickstart env
|
||||
source ~/.ziti/quickstart/$(hostname -s)/$(hostname -s).env
|
||||
# login as admin
|
||||
zitiLogin
|
||||
# log in as admin (example)
|
||||
ziti edge login localhost:1280 -u admin -p XO0xHp75uuyeireO2xmmVlK91T7B9fpD
|
||||
|
||||
# list Ziti identities created by the quickstart and bootstrap
|
||||
ziti edge list identities
|
||||
```
|
||||
|
||||
The id is shown for the "frontend" identity.
|
||||
The id is shown for the frontend identity named "public."
|
||||
|
||||
Nice work! The `zrok` controller is fully configured now that you have created the zrok frontend.
|
||||
|
||||
@ -217,10 +217,10 @@ $ zrok access public etc/http-frontend.yml
|
||||
[ 0.002] INFO main.(*accessPublicCommand).run: {
|
||||
...
|
||||
}
|
||||
[ 0.002] INFO zrok/endpoints/public_frontend.newMetricsAgent: loaded 'frontend' identity
|
||||
[ 0.002] INFO zrok/endpoints/public_frontend.newMetricsAgent: loaded 'public' identity
|
||||
```
|
||||
|
||||
This process uses the `frontend` identity created during the bootstrap process to provide public access for the `zrok` deployment. It is expected that the configured listener for this `frontend` corresponds to the DNS template specified when creating the public frontend record above.
|
||||
The zrok frontend uses the `public` identity created during the bootstrap process to securely access zrok backends. to provide public access for the `zrok` deployment. It is expected that the configured listener for this frontend corresponds to the DNS template specified when creating the public frontend record above.
|
||||
|
||||
## Invite Yourself
|
||||
|
@ -1,9 +1,9 @@
|
||||
---
|
||||
sidebar_position: 50
|
||||
sidebar_label: Nginx TLS
|
||||
sidebar_label: NGINX TLS
|
||||
---
|
||||
|
||||
# Nginx Reverse Proxy for zrok
|
||||
# NGINX Reverse Proxy for zrok
|
||||
|
||||
## Walkthrough Video
|
||||
|
||||
@ -11,7 +11,7 @@ sidebar_label: Nginx TLS
|
||||
|
||||
## Before You Begin
|
||||
|
||||
I'll assume you have a running zrok controller and public frontend and wish to front both with Nginx providing server TLS. Go back to [Self-Hosting Guide](./self_hosting_guide.md) if you still need to spin those up.
|
||||
I'll assume you have a running zrok controller and frontend and wish to front both with NGINX providing server TLS. Go back to [Self-Hosting Guide](./linux.mdx) if you still need to spin those up.
|
||||
|
||||
## Choose a Reverse Proxy Address
|
||||
|
||||
@ -29,9 +29,9 @@ You must complete a DNS challenge to obtain a wildcard certificate from Let's En
|
||||
sudo certbot certonly --manual
|
||||
````
|
||||
|
||||
## [Install Nginx](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/)
|
||||
## [Install NGINX](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/)
|
||||
|
||||
## Configure Nginx
|
||||
## Configure NGINX
|
||||
|
||||
```
|
||||
server {
|
||||
@ -78,15 +78,15 @@ server {
|
||||
}
|
||||
```
|
||||
|
||||
## Restart Nginx
|
||||
## Restart NGINX
|
||||
|
||||
Load the new configuration by restarting Nginx. Check the logs to make sure it's happy.
|
||||
Load the new configuration by restarting NGINX. Check the logs to make sure it's happy.
|
||||
|
||||
> Started A high performance web server and a reverse proxy server.
|
||||
|
||||
## Check the Firewall
|
||||
|
||||
If you followed the non-TLS quickstart then you may have opened 8080,108080/tcp in your firewall. You can go ahead and replace those exceptions with 443/tcp because only Nginx needs to be reachable for zrok to function.
|
||||
If you followed the non-TLS quickstart then you may have opened 8080,108080/tcp in your firewall. You can go ahead and replace those exceptions with 443/tcp because only NGINX needs to be reachable for zrok to function.
|
||||
|
||||
## Update the zrok Frontend
|
||||
|
||||
@ -99,7 +99,7 @@ $ zrok admin list frontends
|
||||
2NiDTRYUww18 7DsLh9DXG public http://{token}.zrok.quigley.com:8080 2023-01-19 05:29:20.793 +0000 UTC 2023-01-19 06:17:25 +0000 UTC
|
||||
```
|
||||
|
||||
Update the URL template to use Nginx.
|
||||
Update the URL template to use NGINX.
|
||||
|
||||
```bash
|
||||
$ zrok admin update frontend 2NiDTRYUww18 --url-template https://{token}.zrok.quigley.com:443
|
||||
|
BIN
docs/guides/vpn/vpn-share.png
Normal file
BIN
docs/guides/vpn/vpn-share.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 170 KiB |
120
docs/guides/vpn/vpn.md
Normal file
120
docs/guides/vpn/vpn.md
Normal file
@ -0,0 +1,120 @@
|
||||
---
|
||||
sidebar_label: VPN
|
||||
---
|
||||
|
||||
# zrok VPN Guide
|
||||
|
||||
zrok VPN backend allows for simple host-to-host VPN setup.
|
||||
|
||||
## Starting VPN server
|
||||
|
||||
VPN is shared through the `vpn` backend of `zrok` command.
|
||||
|
||||
```
|
||||
eugene@hermes $ sudo -E zrok share private --headless --backend-mode vpn
|
||||
[ 0.542] INFO sdk-golang/ziti.(*listenerManager).createSessionWithBackoff: {session token=[589d443c-f59d-4fc8-8c48-76609b7fb402]} new service session
|
||||
[ 0.705] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:
|
||||
zrok access private 3rq7torslq3n
|
||||
[ 0.705] INFO zrok/endpoints/vpn.(*Backend).Run: started
|
||||
```
|
||||
|
||||
![VPN share](./vpn-share.png)
|
||||
|
||||
`sudo` or equivalent invocation is required because VPN mode needs to create a virtual network device (`tun`)
|
||||
`-E` option allows `zrok` to find your zrok configuration files (in your `$HOME/.zrok`)
|
||||
|
||||
By default `vpn` backend uses subnet `10.122.0.0/16` and assigns `10.122.0.1` to the host that stared VPN share.
|
||||
|
||||
```
|
||||
$ ifconfig
|
||||
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 16384
|
||||
inet 10.122.0.1 netmask 255.255.0.0 destination 10.122.0.1
|
||||
inet6 fe80::705f:24e4:dcfc:a6b2 prefixlen 64 scopeid 0x20<link>
|
||||
inet6 fd00:7a72:6f6b::1 prefixlen 64 scopeid 0x0<global>
|
||||
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
|
||||
RX packets 0 bytes 0 (0.0 B)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 27 bytes 3236 (3.2 KB)
|
||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||
```
|
||||
|
||||
Default IP/subnet setting can be overridden by adding `<target>` parameter:
|
||||
```
|
||||
$ sudo -E zrok share private --headless --backend-mode vpn 192.168.42.12/24
|
||||
```
|
||||
|
||||
## VPN share reservation
|
||||
|
||||
Share reservation works the same as with other backend types:
|
||||
|
||||
```
|
||||
eugene@hermes $ zrok reserve private -b vpn
|
||||
[ 0.297] INFO main.(*reserveCommand).run: your reserved share token is 'k77y2cl7jmjl'
|
||||
|
||||
eugene@hermes $ sudo -E zrok share reserved k77y2cl7jmjl --headless
|
||||
[ 0.211] INFO main.(*shareReservedCommand).run: sharing target: '10.122.0.1/16'
|
||||
[ 0.211] INFO main.(*shareReservedCommand).run: using existing backend proxy endpoint: 10.122.0.1/16
|
||||
[ 0.463] INFO sdk-golang/ziti.(*listenerManager).createSessionWithBackoff: {session token=[22c5708d-e2f2-41aa-a507-454055f8bfcc]} new service session
|
||||
[ 0.641] INFO main.(*shareReservedCommand).run: use this command to access your zrok share: 'zrok access private k77y2cl7jmjl'
|
||||
[
|
||||
|
||||
```
|
||||
|
||||
## Accessing VPN share
|
||||
|
||||
Accessing a VPN share works similar to other backends.
|
||||
|
||||
```
|
||||
eugene@calculon % sudo -E zrok access private --headless k77y2cl7jmjl
|
||||
[ 0.201] INFO main.(*accessPrivateCommand).run: allocated frontend '50B5hloP1s1X'
|
||||
[ 0.662] INFO main.(*accessPrivateCommand).run: access the zrok share at the following endpoint: VPN:
|
||||
[ 0.662] INFO main.(*accessPrivateCommand).run: 10.122.0.1 -> CONNECTED Welcome to zrok VPN
|
||||
[ 0.662] INFO zrok/endpoints/vpn.(*Frontend).Run: connected:Welcome to zrok VPN
|
||||
```
|
||||
|
||||
Starting `zrok access` to a VPN share creates virtual network device/interface:
|
||||
|
||||
```
|
||||
eugene@calculon ~ % ifconfig
|
||||
...
|
||||
utun5: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
|
||||
inet 10.122.0.3 --> 10.122.0.1 netmask 0xff000000
|
||||
inet6 fe80::ce08:faff:fe8a:7b25%utun5 prefixlen 64 scopeid 0x14
|
||||
nd6 options=201<PERFORMNUD,DAD>
|
||||
...
|
||||
```
|
||||
|
||||
At this point a VPN tunnel is active between your server and client.
|
||||
In the example above server is `hermes(10.122.0.1)` and client is `calculon(10.122.0.3)`.
|
||||
You can access server from client by using assigned IP address.
|
||||
|
||||
```
|
||||
eugene@calculon ~ % ssh eugene@10.122.0.1
|
||||
Welcome to Ubuntu 23.10 (GNU/Linux 6.5.0-27-generic x86_64)
|
||||
|
||||
* Documentation: https://help.ubuntu.com
|
||||
* Management: https://landscape.canonical.com
|
||||
* Support: https://ubuntu.com/pro
|
||||
|
||||
0 updates can be applied immediately.
|
||||
|
||||
Last login: Tue Apr 16 09:27:13 2024 from 127.0.0.1
|
||||
|
||||
eugene@hermes:~$ who am i
|
||||
eugene pts/8 2024-04-16 10:04 (10.122.0.3)
|
||||
|
||||
eugene@hermes:~$
|
||||
```
|
||||
|
||||
You can also make a reverse(server-to-client) connection:
|
||||
```
|
||||
eugene@hermes:~$ ssh 10.122.0.3
|
||||
The authenticity of host '10.122.0.3 (10.122.0.3)' can't be established.
|
||||
<..snip..>
|
||||
Warning: Permanently added '10.122.0.3' (ED25519) to the list of known hosts.
|
||||
(eugene@10.122.0.3) Password:
|
||||
Last login: Tue Apr 16 09:57:28 2024
|
||||
eugene@calculon ~ % who am i
|
||||
eugene ttys008 Apr 16 10:06 (10.122.0.1)
|
||||
eugene@calculon ~ %
|
||||
```
|
267
endpoints/vpn/backend.go
Normal file
267
endpoints/vpn/backend.go
Normal file
@ -0,0 +1,267 @@
|
||||
package vpn
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/net-byte/vtun/common/config"
|
||||
"github.com/net-byte/vtun/tun"
|
||||
_ "github.com/net-byte/vtun/tun"
|
||||
"github.com/net-byte/water"
|
||||
"github.com/openziti/sdk-golang/ziti"
|
||||
"github.com/openziti/sdk-golang/ziti/edge"
|
||||
"github.com/openziti/zrok/endpoints"
|
||||
cmap "github.com/orcaman/concurrent-map/v2"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/songgao/water/waterutil"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BackendConfig struct {
|
||||
IdentityPath string
|
||||
EndpointAddress string
|
||||
ShrToken string
|
||||
RequestsChan chan *endpoints.Request
|
||||
}
|
||||
|
||||
type client struct {
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
type Backend struct {
|
||||
cfg *BackendConfig
|
||||
listener edge.Listener
|
||||
|
||||
addr net.IP
|
||||
addr6 net.IP
|
||||
subnet *net.IPNet
|
||||
subnet6 *net.IPNet
|
||||
tun *water.Interface
|
||||
mtu int
|
||||
|
||||
counter atomic.Uint32
|
||||
clients cmap.ConcurrentMap[dest, *client]
|
||||
}
|
||||
|
||||
func NewBackend(cfg *BackendConfig) (*Backend, error) {
|
||||
|
||||
options := ziti.ListenOptions{
|
||||
ConnectTimeout: 5 * time.Minute,
|
||||
WaitForNEstablishedListeners: 1,
|
||||
}
|
||||
zcfg, err := ziti.NewConfigFromFile(cfg.IdentityPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error loading config")
|
||||
}
|
||||
zctx, err := ziti.NewContext(zcfg)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error loading ziti context")
|
||||
}
|
||||
listener, err := zctx.ListenWithOptions(cfg.ShrToken, &options)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error listening")
|
||||
}
|
||||
|
||||
addr6 := zrokIPv6Addr
|
||||
addr4 := zrokIPv4Addr
|
||||
sub4 := zrokIPv4
|
||||
sub6 := zrokIPv6
|
||||
|
||||
if cfg.EndpointAddress != "" {
|
||||
addr4, sub4, err = net.ParseCIDR(cfg.EndpointAddress)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse VPN subnet config")
|
||||
}
|
||||
}
|
||||
|
||||
b := &Backend{
|
||||
cfg: cfg,
|
||||
listener: listener,
|
||||
mtu: ZROK_VPN_MTU,
|
||||
clients: cmap.NewWithCustomShardingFunction[dest, *client](func(key dest) uint32 {
|
||||
return key.toInt32()
|
||||
}),
|
||||
addr: addr4,
|
||||
addr6: addr6,
|
||||
subnet: sub4,
|
||||
subnet6: sub6,
|
||||
}
|
||||
b.counter.Store(1)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *Backend) readTun() {
|
||||
buf := make([]byte, ZROK_VPN_MTU)
|
||||
for {
|
||||
n, err := b.tun.Read(buf)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("failed to read tun device")
|
||||
// handle? error
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
pkt := packet(buf[:n])
|
||||
if !waterutil.IsIPv4(pkt) {
|
||||
continue
|
||||
}
|
||||
|
||||
logrus.WithField("packet", pkt).Trace("read from tun device")
|
||||
dest := pkt.destination()
|
||||
if clt, ok := b.clients.Get(dest); ok {
|
||||
_, err := clt.conn.Write(pkt)
|
||||
if err != nil {
|
||||
b.cfg.RequestsChan <- &endpoints.Request{
|
||||
Stamp: time.Now(),
|
||||
RemoteAddr: dest.String(),
|
||||
Method: "DISCONNECTED",
|
||||
}
|
||||
|
||||
logrus.WithError(err).Errorf("failed to write packet to clt[%v]", dest)
|
||||
_ = clt.conn.Close()
|
||||
b.clients.Remove(dest)
|
||||
}
|
||||
} else {
|
||||
if b.subnet.Contains(net.IP(dest.addr[:])) {
|
||||
logrus.Errorf("no client with address[%v]", dest)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Backend) Run() error {
|
||||
logrus.Info("started")
|
||||
defer logrus.Info("exited")
|
||||
|
||||
bits, _ := b.subnet.Mask.Size()
|
||||
bits6, _ := b.subnet6.Mask.Size()
|
||||
|
||||
tunCfg := config.Config{
|
||||
ServerIP: b.addr.String(),
|
||||
ServerIPv6: b.addr6.String(),
|
||||
CIDR: b.addr.String() + "/" + strconv.Itoa(bits),
|
||||
CIDRv6: b.addr6.String() + "/" + strconv.Itoa(bits6),
|
||||
MTU: ZROK_VPN_MTU,
|
||||
Verbose: true,
|
||||
}
|
||||
logrus.Infof("%+v", tunCfg)
|
||||
b.tun = tun.CreateTun(tunCfg)
|
||||
defer func() {
|
||||
_ = b.tun.Close()
|
||||
}()
|
||||
|
||||
go b.readTun()
|
||||
|
||||
for {
|
||||
if conn, err := b.listener.Accept(); err == nil {
|
||||
go b.handle(conn)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Backend) handle(conn net.Conn) {
|
||||
defer func(conn net.Conn) {
|
||||
_ = conn.Close()
|
||||
}(conn)
|
||||
|
||||
ipv4, ipv6 := b.nextIP()
|
||||
ip := ipToDest(ipv4)
|
||||
|
||||
bits, _ := b.subnet.Mask.Size()
|
||||
bits6, _ := b.subnet6.Mask.Size()
|
||||
|
||||
cfg := &ClientConfig{
|
||||
Greeting: "Welcome to zrok VPN",
|
||||
ServerIP: b.addr.String(),
|
||||
ServerIPv6: b.addr6.String(),
|
||||
CIDR: ipv4.String() + "/" + strconv.Itoa(bits),
|
||||
CIDR6: ipv6.String() + "/" + strconv.Itoa(bits6),
|
||||
MTU: b.mtu,
|
||||
}
|
||||
|
||||
b.cfg.RequestsChan <- &endpoints.Request{
|
||||
Stamp: time.Now(),
|
||||
RemoteAddr: ipv4.String(),
|
||||
Method: "CONNECTED",
|
||||
Path: cfg.ServerIP,
|
||||
}
|
||||
|
||||
j, err := json.Marshal(&cfg)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("failed to write client VPN config")
|
||||
return
|
||||
}
|
||||
_, err = conn.Write(j)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("failed to write client VPN config")
|
||||
return
|
||||
}
|
||||
|
||||
clt := &client{conn: conn}
|
||||
b.clients.Set(ip, clt)
|
||||
|
||||
buf := make([]byte, b.mtu)
|
||||
for {
|
||||
read, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
logrus.WithError(err).Error("read error")
|
||||
}
|
||||
b.cfg.RequestsChan <- &endpoints.Request{
|
||||
Stamp: time.Now(),
|
||||
RemoteAddr: ipv4.String(),
|
||||
Method: "DISCONNECTED",
|
||||
}
|
||||
return
|
||||
}
|
||||
pkt := packet(buf[:read])
|
||||
logrus.WithField("packet", pkt).Trace("read from ziti")
|
||||
_, err = b.tun.Write(pkt)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("failed to write packet to tun")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Backend) nextIP() (net.IP, net.IP) {
|
||||
ip4 := make([]byte, len(b.subnet.IP))
|
||||
for {
|
||||
copy(ip4, b.subnet.IP)
|
||||
n := b.counter.Add(1)
|
||||
if n == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for i := 0; i < len(ip4); i++ {
|
||||
b := (n >> (i * 8)) % 0xff
|
||||
ip4[len(ip4)-1-i] ^= byte(b)
|
||||
}
|
||||
|
||||
// subnet overflow
|
||||
if !b.subnet.Contains(ip4) {
|
||||
b.counter.Store(1)
|
||||
continue
|
||||
}
|
||||
|
||||
if cmp.Equal(b.addr, ip4) {
|
||||
continue
|
||||
}
|
||||
|
||||
if b.clients.Has(ipToDest(ip4)) {
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
ip6 := append([]byte{}, b.subnet6.IP...)
|
||||
copy(ip6[net.IPv6len-net.IPv4len:], ip4)
|
||||
|
||||
return ip4, ip6
|
||||
}
|
131
endpoints/vpn/frontend.go
Normal file
131
endpoints/vpn/frontend.go
Normal file
@ -0,0 +1,131 @@
|
||||
package vpn
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/net-byte/vtun/common/config"
|
||||
"github.com/net-byte/vtun/tun"
|
||||
"github.com/openziti/sdk-golang/ziti"
|
||||
"github.com/openziti/zrok/endpoints"
|
||||
"github.com/openziti/zrok/environment"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FrontendConfig struct {
|
||||
IdentityName string
|
||||
ShrToken string
|
||||
RequestsChan chan *endpoints.Request
|
||||
}
|
||||
|
||||
type Frontend struct {
|
||||
cfg *FrontendConfig
|
||||
ztx ziti.Context
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
func NewFrontend(cfg *FrontendConfig) (*Frontend, error) {
|
||||
env, err := environment.LoadRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error loading environment root")
|
||||
}
|
||||
zCfgPath, err := env.ZitiIdentityNamed(cfg.IdentityName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error getting ziti identity '%v' from environment", cfg.IdentityName)
|
||||
}
|
||||
zCfg, err := ziti.NewConfigFromFile(zCfgPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error loading config")
|
||||
}
|
||||
zCfg.ConfigTypes = []string{sdk.ZrokProxyConfig}
|
||||
zCtx, err := ziti.NewContext(zCfg)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error loading ziti context")
|
||||
}
|
||||
|
||||
zConn, err := zCtx.Dial(cfg.ShrToken)
|
||||
if err != nil {
|
||||
zCtx.Close()
|
||||
return nil, errors.Wrap(err, "error connecting to ziti")
|
||||
}
|
||||
return &Frontend{
|
||||
cfg: cfg,
|
||||
ztx: zCtx,
|
||||
conn: zConn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *Frontend) Run() error {
|
||||
var cltCfg ClientConfig
|
||||
d := json.NewDecoder(f.conn)
|
||||
if err := d.Decode(&cltCfg); err != nil {
|
||||
return errors.Wrap(err, "error decoding vpn config")
|
||||
}
|
||||
f.cfg.RequestsChan <- &endpoints.Request{
|
||||
Stamp: time.Now(),
|
||||
RemoteAddr: cltCfg.ServerIP,
|
||||
Method: "CONNECTED",
|
||||
Path: cltCfg.Greeting,
|
||||
}
|
||||
logrus.Info("connected:", cltCfg.Greeting)
|
||||
|
||||
defer func() {
|
||||
f.cfg.RequestsChan <- &endpoints.Request{
|
||||
Stamp: time.Now(),
|
||||
RemoteAddr: cltCfg.ServerIP,
|
||||
Method: "Disconnected",
|
||||
}
|
||||
}()
|
||||
|
||||
cfg := config.Config{
|
||||
ServerIP: cltCfg.ServerIP,
|
||||
CIDR: cltCfg.CIDR,
|
||||
ServerIPv6: cltCfg.ServerIPv6,
|
||||
CIDRv6: cltCfg.CIDR6,
|
||||
MTU: cltCfg.MTU,
|
||||
Verbose: false,
|
||||
}
|
||||
iface := tun.CreateTun(cfg)
|
||||
|
||||
logrus.Infof("created tun device: %s", iface.Name())
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
_ = f.conn.Close()
|
||||
_ = iface.Close()
|
||||
}()
|
||||
|
||||
b := make([]byte, cltCfg.MTU)
|
||||
for {
|
||||
n, err := f.conn.Read(b)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("error reading from ziti")
|
||||
return
|
||||
}
|
||||
p := packet(b[:n])
|
||||
logrus.WithField("packet", p).Trace("received packet from peer")
|
||||
_, err = iface.Write(p)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("error writing to device")
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
buf := make([]byte, cltCfg.MTU)
|
||||
for {
|
||||
n, err := iface.Read(buf)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error reading packet")
|
||||
}
|
||||
pkt := packet(buf[:n])
|
||||
logrus.WithField("packet", pkt).Trace("read packet from tun device")
|
||||
_, err = f.conn.Write(pkt)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error sending packet to ziti")
|
||||
}
|
||||
}
|
||||
}
|
94
endpoints/vpn/vpn.go
Normal file
94
endpoints/vpn/vpn.go
Normal file
@ -0,0 +1,94 @@
|
||||
package vpn
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/songgao/water/waterutil"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const ZROK_VPN_MTU = 16 * 1024
|
||||
|
||||
var (
|
||||
zrokIPv4Addr = net.IPv4(10, 'z', 0, 0)
|
||||
zrokIPv4 = &net.IPNet{
|
||||
IP: net.IPv4(10, 'z', 0, 0),
|
||||
Mask: net.CIDRMask(16, 8*net.IPv4len),
|
||||
}
|
||||
|
||||
zrokIPv6Addr = net.IP{0xfd, 0, 'z', 'r', 'o', 'k', 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
|
||||
zrokIPv6 = &net.IPNet{
|
||||
IP: net.IP{0xfd, 0, 'z', 'r', 'o', 'k', // prefix + global ID
|
||||
0, 0, // subnet id
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
},
|
||||
Mask: net.CIDRMask(64, 8*net.IPv6len),
|
||||
}
|
||||
)
|
||||
|
||||
func DefaultTarget() string {
|
||||
l := len(zrokIPv4Addr)
|
||||
subnet := net.IPNet{
|
||||
IP: make([]byte, l),
|
||||
Mask: zrokIPv4.Mask,
|
||||
}
|
||||
|
||||
copy(subnet.IP, zrokIPv4Addr)
|
||||
subnet.IP[l-1] = 1
|
||||
return subnet.String()
|
||||
}
|
||||
|
||||
type ClientConfig struct {
|
||||
Greeting string
|
||||
CIDR string
|
||||
CIDR6 string
|
||||
ServerIP string
|
||||
ServerIPv6 string
|
||||
Routes []string
|
||||
MTU int
|
||||
}
|
||||
|
||||
type dest struct {
|
||||
addr [4]byte
|
||||
}
|
||||
|
||||
func (d dest) String() string {
|
||||
return net.IP(d.addr[:]).String()
|
||||
}
|
||||
|
||||
func (d dest) toInt32() uint32 {
|
||||
return uint32(d.addr[0])<<24 + uint32(d.addr[1])<<16 + uint32(d.addr[2])<<8 + uint32(d.addr[3])
|
||||
}
|
||||
|
||||
func ipToDest(addr net.IP) dest {
|
||||
d := dest{}
|
||||
copy(d.addr[:], addr.To4())
|
||||
return d
|
||||
}
|
||||
|
||||
type packet []byte
|
||||
|
||||
func (p packet) destination() dest {
|
||||
return ipToDest(waterutil.IPv4Destination(p))
|
||||
}
|
||||
|
||||
func (p packet) String() string {
|
||||
return fmt.Sprintf("%s %s:%d -> %s:%d %d bytes", p.proto(),
|
||||
waterutil.IPv4Source(p), waterutil.IPv4SourcePort(p),
|
||||
waterutil.IPv4Destination(p), waterutil.IPv4DestinationPort(p), len(waterutil.IPv4Payload(p)))
|
||||
}
|
||||
|
||||
func (p packet) proto() string {
|
||||
proto := waterutil.IPv4Protocol(p)
|
||||
switch proto {
|
||||
case waterutil.TCP:
|
||||
return "tcp"
|
||||
case waterutil.UDP:
|
||||
return "udp"
|
||||
case waterutil.ICMP:
|
||||
return "icmp"
|
||||
default:
|
||||
return strconv.Itoa(int(proto))
|
||||
}
|
||||
}
|
81
go.mod
81
go.mod
@ -8,15 +8,16 @@ require (
|
||||
github.com/charmbracelet/bubbles v0.14.0
|
||||
github.com/charmbracelet/bubbletea v0.23.1
|
||||
github.com/charmbracelet/lipgloss v0.6.0
|
||||
github.com/go-openapi/errors v0.21.0
|
||||
github.com/go-openapi/loads v0.21.5
|
||||
github.com/go-openapi/runtime v0.27.1
|
||||
github.com/go-openapi/spec v0.20.14
|
||||
github.com/go-openapi/strfmt v0.22.1
|
||||
github.com/go-openapi/swag v0.22.9
|
||||
github.com/go-openapi/validate v0.23.0
|
||||
github.com/go-openapi/errors v0.22.0
|
||||
github.com/go-openapi/loads v0.22.0
|
||||
github.com/go-openapi/runtime v0.28.0
|
||||
github.com/go-openapi/spec v0.21.0
|
||||
github.com/go-openapi/strfmt v0.23.0
|
||||
github.com/go-openapi/swag v0.23.0
|
||||
github.com/go-openapi/validate v0.24.0
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/iancoleman/strcase v0.2.0
|
||||
@ -30,28 +31,32 @@ require (
|
||||
github.com/michaelquigley/cf v0.0.13
|
||||
github.com/michaelquigley/pfxlog v0.6.10
|
||||
github.com/muesli/reflow v0.3.0
|
||||
github.com/net-byte/vtun v1.7.0
|
||||
github.com/net-byte/water v0.0.7
|
||||
github.com/nxadm/tail v1.4.8
|
||||
github.com/openziti/channel/v2 v2.0.121
|
||||
github.com/openziti/edge-api v0.26.12
|
||||
github.com/openziti/channel/v2 v2.0.128
|
||||
github.com/openziti/edge-api v0.26.16
|
||||
github.com/openziti/fabric v0.23.26
|
||||
github.com/openziti/identity v1.0.72
|
||||
github.com/openziti/sdk-golang v0.23.10
|
||||
github.com/openziti/transport/v2 v2.0.124
|
||||
github.com/openziti/identity v1.0.75
|
||||
github.com/openziti/sdk-golang v0.23.22
|
||||
github.com/openziti/transport/v2 v2.0.131
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rabbitmq/amqp091-go v1.8.1
|
||||
github.com/rubenv/sql-migrate v1.6.0
|
||||
github.com/shirou/gopsutil/v3 v3.24.1
|
||||
github.com/shirou/gopsutil/v3 v3.24.3
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/wneessen/go-mail v0.2.7
|
||||
github.com/zitadel/oidc/v2 v2.12.0
|
||||
go.uber.org/zap v1.25.0
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/net v0.21.0
|
||||
golang.org/x/oauth2 v0.16.0
|
||||
golang.org/x/time v0.3.0
|
||||
nhooyr.io/websocket v1.8.10
|
||||
golang.org/x/crypto v0.22.0
|
||||
golang.org/x/net v0.24.0
|
||||
golang.org/x/oauth2 v0.19.0
|
||||
golang.org/x/time v0.5.0
|
||||
nhooyr.io/websocket v1.8.11
|
||||
)
|
||||
|
||||
require (
|
||||
@ -75,7 +80,7 @@ require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/biogo/store v0.0.0-20200525035639-8c94ae1e7c9c // indirect
|
||||
github.com/caddyserver/certmagic v0.20.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chzyer/readline v1.5.1 // indirect
|
||||
@ -101,14 +106,17 @@ require (
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/analysis v0.22.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.2 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.4 // indirect
|
||||
github.com/go-resty/resty/v2 v2.11.0 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.12.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.1.0 // indirect
|
||||
github.com/golang/glog v1.1.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/cel-go v0.15.1 // indirect
|
||||
github.com/google/certificate-transparency-go v1.1.6 // indirect
|
||||
@ -123,6 +131,7 @@ require (
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
|
||||
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.14.0 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
@ -159,14 +168,14 @@ require (
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/termenv v0.13.0 // indirect
|
||||
github.com/muhlemmer/gu v0.3.1 // indirect
|
||||
github.com/net-byte/go-gateway v0.0.2 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/openziti/foundation/v2 v2.0.39 // indirect
|
||||
github.com/openziti/metrics v1.2.47 // indirect
|
||||
github.com/openziti/secretstream v0.1.17 // indirect
|
||||
github.com/openziti/foundation/v2 v2.0.42 // indirect
|
||||
github.com/openziti/metrics v1.2.51 // indirect
|
||||
github.com/openziti/secretstream v0.1.19 // indirect
|
||||
github.com/openziti/storage v0.2.6 // indirect
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1 // indirect
|
||||
github.com/parallaxsecond/parsec-client-go v0.0.0-20221025095442-f0a77d263cf9 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
@ -200,7 +209,7 @@ require (
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/yuin/goldmark v1.5.6 // indirect
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.etcd.io/bbolt v1.3.7 // indirect
|
||||
go.mongodb.org/mongo-driver v1.14.0 // indirect
|
||||
@ -215,7 +224,7 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
go.step.sm/cli-utils v0.8.0 // indirect
|
||||
@ -226,15 +235,17 @@ require (
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/term v0.18.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/term v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.13.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 // indirect
|
||||
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
|
163
go.sum
163
go.sum
@ -128,8 +128,8 @@ github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4
|
||||
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
@ -266,30 +266,30 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0=
|
||||
github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo=
|
||||
github.com/go-openapi/errors v0.21.0 h1:FhChC/duCnfoLj1gZ0BgaBmzhJC2SL/sJr8a2vAobSY=
|
||||
github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho=
|
||||
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
|
||||
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
|
||||
github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
|
||||
github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
|
||||
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
|
||||
github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU=
|
||||
github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4=
|
||||
github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRzT0=
|
||||
github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8=
|
||||
github.com/go-openapi/runtime v0.27.1 h1:ae53yaOoh+fx/X5Eaq8cRmavHgDma65XPZuvBqvJYto=
|
||||
github.com/go-openapi/runtime v0.27.1/go.mod h1:fijeJEiEclyS8BRurYE1DE5TLb9/KZl6eAdbzjsrlLU=
|
||||
github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do=
|
||||
github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw=
|
||||
github.com/go-openapi/strfmt v0.22.1 h1:5Ky8cybT4576C6Ffc+8gYji/wRXCo6Ozm8RaWjPI6jc=
|
||||
github.com/go-openapi/strfmt v0.22.1/go.mod h1:OfVoytIXJasDkkGvkb1Cceb3BPyMOwk1FgmyyEw7NYg=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||
github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=
|
||||
github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=
|
||||
github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ=
|
||||
github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc=
|
||||
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
|
||||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||
github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
|
||||
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE=
|
||||
github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE=
|
||||
github.com/go-openapi/validate v0.23.0 h1:2l7PJLzCis4YUGEoW6eoQw3WhyM65WSIcjX6SQnlfDw=
|
||||
github.com/go-openapi/validate v0.23.0/go.mod h1:EeiAZ5bmpSIOJV1WLfyYF9qp/B1ZgSaEpHTJHtN5cbE=
|
||||
github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
|
||||
github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
|
||||
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
|
||||
github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA=
|
||||
github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
@ -301,6 +301,12 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
@ -309,8 +315,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
|
||||
github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
|
||||
@ -345,8 +351,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
@ -481,6 +487,8 @@ github.com/influxdata/influxdb-client-go/v2 v2.11.0/go.mod h1:YteV91FiQxRdccyJ2c
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU=
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
|
||||
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743 h1:X3Xxno5Ji8idrNiUoFc7QyXpqhSYlDRYQmc7mlpMBzU=
|
||||
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743/go.mod h1:KrtyD5PFj++GKkFS/7/RRrfnRhAMGQwy75GLCHWrCNs=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
@ -704,6 +712,12 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/net-byte/go-gateway v0.0.2 h1:xNB7CqWh7js6PB/xOochjyJlDHl6sZthhPSoJdxwoLY=
|
||||
github.com/net-byte/go-gateway v0.0.2/go.mod h1:+NvPbRjN64RUYvm6xtRBUswoAXKAe44Y/PfWtWMgwwY=
|
||||
github.com/net-byte/vtun v1.7.0 h1:mt8sUKbFPbl5pc0EXeRFl5zCKXr3QCaSYZp7raGd5y0=
|
||||
github.com/net-byte/vtun v1.7.0/go.mod h1:SVFWdwuyvV7BRyeyiaay7HfWor6se5894IkNsNTTo54=
|
||||
github.com/net-byte/water v0.0.7 h1:wJUVq8x1AdfzZ5G8Qv61YRX+d22wx0ZgWNG0ihLqglo=
|
||||
github.com/net-byte/water v0.0.7/go.mod h1:tRTm034ul8JBKkYFGN/WrnUM4cctr9laq5IpwvaVqUE=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
@ -738,26 +752,26 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openziti/channel/v2 v2.0.121 h1:dCPNbn0VbGIOrzXHcnjp5p0XzZCbpHKRmMhi9LRex0E=
|
||||
github.com/openziti/channel/v2 v2.0.121/go.mod h1:f/DLqWVAFF5pDIpse8BRm4ZwhpAFjx0gUGjPEqlPSZE=
|
||||
github.com/openziti/edge-api v0.26.12 h1:5VRz0cWtfQq2rhSA7Ne6amM7YNI6pQGRfNgbKt0g6kQ=
|
||||
github.com/openziti/edge-api v0.26.12/go.mod h1:tKZRUFDB9zM5J1zBS0ok2r40OhJqWykZaU9HSBQgr8w=
|
||||
github.com/openziti/channel/v2 v2.0.128 h1:kRigyUmrN1q56ydRmBWzruV0DvVntYx/f2DT2P0qSh4=
|
||||
github.com/openziti/channel/v2 v2.0.128/go.mod h1:ugebO2eO2CdaVQE45o20iE4R9DK0VRoJsGBZt0x3eLc=
|
||||
github.com/openziti/edge-api v0.26.16 h1:oU4t2Q4f0+K/ypwdQIecgA836PJkCnDMe1glc56ovaA=
|
||||
github.com/openziti/edge-api v0.26.16/go.mod h1:HTp6bC3cBKAoIwyA06aKKrrBwxFtJALfpEinmvCRgBc=
|
||||
github.com/openziti/fabric v0.23.26 h1:wEPNh8m3qcq9sw1Zmg5YgFZw1FovsKGu53rRf8qzI7A=
|
||||
github.com/openziti/fabric v0.23.26/go.mod h1:0MtkZqIHs3cJPP4DB88xsWUemDm77nN/GvWBBfq7peo=
|
||||
github.com/openziti/foundation/v2 v2.0.39 h1:psv1cTgBErOME4K5TmxolUzz8VabJVhGygsAz6uXAQM=
|
||||
github.com/openziti/foundation/v2 v2.0.39/go.mod h1:38RikdtjvzDUALm3jT3PSOrU0bHCleRty6bHGdfFyUI=
|
||||
github.com/openziti/identity v1.0.72 h1:Y14nUtgDiUBWZ6WBo6S1rw5qb57QNnZGhsFnMPqfJB8=
|
||||
github.com/openziti/identity v1.0.72/go.mod h1:sh1STe6K3EM3K0atBVDLq5jpUxAAFCAQZmIkD0MYIKY=
|
||||
github.com/openziti/metrics v1.2.47 h1:hIp1xnqLxNc7O0yTHIp65REhYBXj7QWeOiayGDzjRrw=
|
||||
github.com/openziti/metrics v1.2.47/go.mod h1:pHj/z3HCls4/+dLoQKTURNTnHmwUbjZFZOGzj2X6HeI=
|
||||
github.com/openziti/sdk-golang v0.23.10 h1:ygpOt99Rd5ESoH1ExYqBHhZp47s5/DYxyfgTO6uYr7Q=
|
||||
github.com/openziti/sdk-golang v0.23.10/go.mod h1:07G4gYyZzRt9fb3uxEhwdsgJwDrqEkjuvVnnRlsrfEc=
|
||||
github.com/openziti/secretstream v0.1.17 h1:bcaPGGpUl0+3GzfQkshKh5slUE7QDXxFq3vyDQgHkCA=
|
||||
github.com/openziti/secretstream v0.1.17/go.mod h1:gosi8ohW+dAHhz1h/MjZEcEVWO0jisWqWjEjmx7oAEs=
|
||||
github.com/openziti/foundation/v2 v2.0.42 h1:cXZFql3xY92AHPCk/wqIoSUX9EHgegwPrs5bhFE2jNg=
|
||||
github.com/openziti/foundation/v2 v2.0.42/go.mod h1:a+REYnK9bZ2cvmOiuBLp57MjQqn3U5cHhJcDMLMO8rE=
|
||||
github.com/openziti/identity v1.0.75 h1:FDm3ZojmmGP9eoOxMvmF52RS6JzToTTeWB0pthIA+ks=
|
||||
github.com/openziti/identity v1.0.75/go.mod h1:ouF+CYh5ywvvMr0Uy1+tbkILIPTdob5WZEnm3v0bPMQ=
|
||||
github.com/openziti/metrics v1.2.51 h1:+RfVdEGMOmhXBcC/gFIqXeNVnpWt9+cfrbCacFV/e3w=
|
||||
github.com/openziti/metrics v1.2.51/go.mod h1:qvX8EKF8I42tA4KlNFX+RBx+ywNiVRvJTS4QofDU8KU=
|
||||
github.com/openziti/sdk-golang v0.23.22 h1:gGyH0tTjEZiJCbUuL4/L3NsTbajB/Aeg3rYHNSjr6d4=
|
||||
github.com/openziti/sdk-golang v0.23.22/go.mod h1:+B9KFCQw9pUxleSs5L9LQCf0zq06a+j9UpFk6CmITqw=
|
||||
github.com/openziti/secretstream v0.1.19 h1:qSX23lyOI5ROvYPTjy7Lo6eFsq9qBBPzaG5hvgLlw48=
|
||||
github.com/openziti/secretstream v0.1.19/go.mod h1:1n/Uk8PQEREwB7iQXhUzNqt+8jYEpUZOJDGcetMI08o=
|
||||
github.com/openziti/storage v0.2.6 h1:/pbIRzDwrczMWRVkN75PfwAXFbArplIqhpRsUrsUOBc=
|
||||
github.com/openziti/storage v0.2.6/go.mod h1:JnjCofrnPcajwn6VIB2CgI7pVVUFBL7evbezIsQ4AgA=
|
||||
github.com/openziti/transport/v2 v2.0.124 h1:84bq7vyqzGJXPek9qyc/7mtVEhp6KTQMK2msq3hwGkY=
|
||||
github.com/openziti/transport/v2 v2.0.124/go.mod h1:eQ3011tfSlmBI3cIkcJOf9YP/afj+Jd2EQM6MCHoJCQ=
|
||||
github.com/openziti/transport/v2 v2.0.131 h1:K1h3sl04QWQdYGSPSI1aZLufrL44Azw4WmdprzkIMxo=
|
||||
github.com/openziti/transport/v2 v2.0.131/go.mod h1:N+OPeoqIuZwS72q0XnM4DLHVdKZ3ZOR37rqjOjWA0b8=
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1 h1:jOJ5Pg2w1oeB6PeDurIYf6k9PQ+aTITr/6lP/L/zp6c=
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1/go.mod h1:9Eq3TG2oBe5FirmYWQfYO5iH1q0Jv47PLaNK++uCdOM=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
@ -851,8 +865,8 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
|
||||
github.com/schollz/jsonstore v1.1.0 h1:WZBDjgezFS34CHI+myb4s8GGpir3UMpy7vWoCeO0n6E=
|
||||
github.com/schollz/jsonstore v1.1.0/go.mod h1:15c6+9guw8vDRyozGjN3FoILt0wpruJk9Pi66vjaZfg=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shirou/gopsutil/v3 v3.24.1 h1:R3t6ondCEvmARp3wxODhXMTLC/klMa87h2PHUw5m7QI=
|
||||
github.com/shirou/gopsutil/v3 v3.24.1/go.mod h1:UU7a2MSBQa+kW1uuDq8DeEBS8kmrnQwsv2b5O513rwU=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
@ -885,6 +899,8 @@ github.com/smallstep/truststore v0.12.1/go.mod h1:M4mebeNy28KusGX3lJxpLARIktLcyq
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
|
||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
@ -920,6 +936,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@ -966,8 +983,8 @@ github.com/yuin/goldmark v1.5.6 h1:COmQAWTCcGetChm3Ig7G/t8AFAN00t+o8Mt4cf7JpwA=
|
||||
github.com/yuin/goldmark v1.5.6/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
|
||||
@ -1020,8 +1037,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqhe
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||
@ -1075,9 +1092,10 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -1169,9 +1187,10 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -1184,8 +1203,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
|
||||
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
|
||||
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
||||
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -1254,6 +1273,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -1280,10 +1300,10 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@ -1291,9 +1311,10 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1306,7 +1327,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -1315,8 +1335,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -1386,6 +1406,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 h1:vDy//hdR+GnROE3OdYbQKt9rdtNdHkDtONvpRwmls/0=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U=
|
||||
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
|
||||
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
@ -1418,7 +1444,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@ -1507,8 +1532,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@ -1554,8 +1579,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
|
||||
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||
nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q=
|
||||
nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
||||
nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0=
|
||||
nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
@ -31,7 +31,7 @@ type ShareRequest struct {
|
||||
AuthUsers []*AuthUser `json:"authUsers"`
|
||||
|
||||
// backend mode
|
||||
// Enum: [proxy web tcpTunnel udpTunnel caddy drive socks]
|
||||
// Enum: [proxy web tcpTunnel udpTunnel caddy drive socks vpn]
|
||||
BackendMode string `json:"backendMode,omitempty"`
|
||||
|
||||
// backend proxy endpoint
|
||||
@ -128,7 +128,7 @@ var shareRequestTypeBackendModePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["proxy","web","tcpTunnel","udpTunnel","caddy","drive","socks"]`), &res); err != nil {
|
||||
if err := json.Unmarshal([]byte(`["proxy","web","tcpTunnel","udpTunnel","caddy","drive","socks","vpn"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
@ -158,6 +158,9 @@ const (
|
||||
|
||||
// ShareRequestBackendModeSocks captures enum value "socks"
|
||||
ShareRequestBackendModeSocks string = "socks"
|
||||
|
||||
// ShareRequestBackendModeVpn captures enum value "vpn"
|
||||
ShareRequestBackendModeVpn string = "vpn"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
|
@ -1589,7 +1589,8 @@ func init() {
|
||||
"udpTunnel",
|
||||
"caddy",
|
||||
"drive",
|
||||
"socks"
|
||||
"socks",
|
||||
"vpn"
|
||||
]
|
||||
},
|
||||
"backendProxyEndpoint": {
|
||||
@ -3344,7 +3345,8 @@ func init() {
|
||||
"udpTunnel",
|
||||
"caddy",
|
||||
"drive",
|
||||
"socks"
|
||||
"socks",
|
||||
"vpn"
|
||||
]
|
||||
},
|
||||
"backendProxyEndpoint": {
|
||||
|
@ -11,6 +11,8 @@ const (
|
||||
UdpTunnelBackendMode BackendMode = "udpTunnel"
|
||||
CaddyBackendMode BackendMode = "caddy"
|
||||
DriveBackendMode BackendMode = "drive"
|
||||
SocksBackendMode BackendMode = "socks"
|
||||
VpnBackendMode BackendMode = "vpn"
|
||||
)
|
||||
|
||||
type ShareMode string
|
||||
|
@ -7,6 +7,9 @@ WEB_BACKEND_MODE: BackendMode = "web"
|
||||
TCP_TUNNEL_BACKEND_MODE: BackendMode = "tcpTunnel"
|
||||
UDP_TUNNEL_BACKEND_MODE: BackendMode = "udpTunnel"
|
||||
CADDY_BACKEND_MODE: BackendMode = "caddy"
|
||||
DRIVE_BACKEND_MODE: BackendMode = "drive"
|
||||
SOCKS_BACKEND_MODE: BackendMode = "socks"
|
||||
VPN_BACKEND_MODE: BackendMode = "vpn"
|
||||
|
||||
ShareMode = str
|
||||
|
||||
|
@ -194,7 +194,7 @@ class ShareRequest(object):
|
||||
:param backend_mode: The backend_mode of this ShareRequest. # noqa: E501
|
||||
:type: str
|
||||
"""
|
||||
allowed_values = ["proxy", "web", "tcpTunnel", "udpTunnel", "caddy", "drive", "socks"] # noqa: E501
|
||||
allowed_values = ["proxy", "web", "tcpTunnel", "udpTunnel", "caddy", "drive", "socks", "vpn"] # noqa: E501
|
||||
if backend_mode not in allowed_values:
|
||||
raise ValueError(
|
||||
"Invalid value for `backend_mode` ({0}), must be one of {1}" # noqa: E501
|
||||
|
@ -1039,7 +1039,7 @@ definitions:
|
||||
type: string
|
||||
backendMode:
|
||||
type: string
|
||||
enum: ["proxy", "web", "tcpTunnel", "udpTunnel", "caddy", "drive", "socks"]
|
||||
enum: ["proxy", "web", "tcpTunnel", "udpTunnel", "caddy", "drive", "socks", "vpn"]
|
||||
backendProxyEndpoint:
|
||||
type: string
|
||||
authScheme:
|
||||
|
@ -34,6 +34,10 @@ const config = {
|
||||
'@docusaurus/plugin-client-redirects',
|
||||
{
|
||||
redirects: [
|
||||
{
|
||||
to: '/docs/guides/self-hosting/linux',
|
||||
from: ['/docs/guides/self-hosting/self_hosting_guide'],
|
||||
},
|
||||
{
|
||||
to: '/docs/guides/self-hosting/metrics-and-limits/configuring-limits',
|
||||
from: ['/docs/guides/metrics-and-limits/configuring-limits'],
|
||||
|
@ -6,5 +6,5 @@
|
||||
},
|
||||
"cleanUrls": false,
|
||||
"public": true,
|
||||
"ignoreCommand": "grep -qE '^(gh-pages)$' <<< ${VERCEL_GIT_COMMIT_REF} || git diff --quiet HEAD^ HEAD -- ../website/ ../docs/"
|
||||
"ignoreCommand": "grep -qE '^(gh-pages)$' <<< ${VERCEL_GIT_COMMIT_REF} || git diff --quiet HEAD^ HEAD -- ../website/ ../docs/ ../**/*.md"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user