diff --git a/cli/go.mod b/cli/go.mod index bdb8839d0..b2d0c83ad 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -20,6 +20,7 @@ require ( github.com/muesli/reflow v0.3.0 github.com/muesli/roff v0.1.0 github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 + github.com/pion/dtls/v3 v3.0.4 github.com/pion/logging v0.2.3 github.com/pion/turn/v4 v4.0.0 github.com/posthog/posthog-go v0.0.0-20221221115252-24dfed35d71a @@ -90,7 +91,6 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/onsi/ginkgo/v2 v2.22.2 // indirect github.com/pelletier/go-toml v1.9.3 // indirect - github.com/pion/dtls/v3 v3.0.4 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/stun/v3 v3.0.0 // indirect github.com/pion/transport/v3 v3.0.7 // indirect diff --git a/cli/go.sum b/cli/go.sum index b72858e9d..5f1f369bb 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -484,8 +484,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -592,8 +590,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -644,13 +640,9 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -662,8 +654,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/cli/packages/cmd/gateway.go b/cli/packages/cmd/gateway.go index d41c2c20e..81baf3910 100644 --- a/cli/packages/cmd/gateway.go +++ b/cli/packages/cmd/gateway.go @@ -4,7 +4,9 @@ import ( "context" "fmt" "os" + "os/exec" "os/signal" + "runtime" "syscall" "time" @@ -16,31 +18,23 @@ import ( ) var gatewayCmd = &cobra.Command{ - Example: `infisical gateway`, - Short: "Used to infisical gateway", Use: "gateway", + Short: "Run the Infisical gateway or manage its systemd service", + Long: "Run the Infisical gateway in the foreground or manage its systemd service installation. Use 'gateway install' to set up the systemd service.", + Example: `infisical gateway --token= + sudo infisical gateway install --token= --domain=`, DisableFlagsInUseLine: true, Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { token, err := util.GetInfisicalToken(cmd) if err != nil { - util.HandleError(err, "Unable to parse flag") + util.HandleError(err, "Unable to parse token flag") } if token == nil { util.HandleError(fmt.Errorf("Token not found")) } - domain, err := cmd.Flags().GetString("domain") - if err != nil { - util.HandleError(err, "Unable to parse domain flag") - } - - // Try to install systemd service if possible - if err := gateway.InstallGatewaySystemdService(token.Token, domain); err != nil { - log.Warn().Msgf("Failed to install systemd service: %v", err) - } - Telemetry.CaptureEvent("cli-command:gateway", posthog.NewProperties().Set("version", util.CLI_VERSION)) sigCh := make(chan os.Signal, 1) @@ -110,6 +104,50 @@ var gatewayCmd = &cobra.Command{ }, } +var gatewayInstallCmd = &cobra.Command{ + Use: "install", + Short: "Install and enable systemd service for the gateway (requires sudo)", + Long: "Install and enable systemd service for the gateway. Must be run with sudo on Linux.", + Example: "sudo infisical gateway install --token= --domain=", + DisableFlagsInUseLine: true, + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + if runtime.GOOS != "linux" { + util.HandleError(fmt.Errorf("systemd service installation is only supported on Linux")) + } + + if os.Geteuid() != 0 { + util.HandleError(fmt.Errorf("systemd service installation requires root/sudo privileges")) + } + + token, err := util.GetInfisicalToken(cmd) + if err != nil { + util.HandleError(err, "Unable to parse flag") + } + + if token == nil { + util.HandleError(fmt.Errorf("Token not found")) + } + + domain, err := cmd.Flags().GetString("domain") + if err != nil { + util.HandleError(err, "Unable to parse domain flag") + } + + if err := gateway.InstallGatewaySystemdService(token.Token, domain); err != nil { + util.HandleError(err, "Failed to install systemd service") + } + + enableCmd := exec.Command("systemctl", "enable", "infisical-gateway") + if err := enableCmd.Run(); err != nil { + util.HandleError(err, "Failed to enable systemd service") + } + + log.Info().Msg("Successfully installed and enabled infisical-gateway service") + log.Info().Msg("To start the service, run: sudo systemctl start infisical-gateway") + }, +} + var gatewayRelayCmd = &cobra.Command{ Example: `infisical gateway relay`, Short: "Used to run infisical gateway relay", @@ -139,9 +177,12 @@ var gatewayRelayCmd = &cobra.Command{ func init() { gatewayCmd.Flags().String("token", "", "Connect with Infisical using machine identity access token") + gatewayInstallCmd.Flags().String("token", "", "Connect with Infisical using machine identity access token") + gatewayInstallCmd.Flags().String("domain", "", "Domain of your self-hosted Infisical instance") gatewayRelayCmd.Flags().String("config", "", "Relay config yaml file path") + gatewayCmd.AddCommand(gatewayInstallCmd) gatewayCmd.AddCommand(gatewayRelayCmd) rootCmd.AddCommand(gatewayCmd) } diff --git a/cli/packages/gateway/systemd.go b/cli/packages/gateway/systemd.go index 8183f3535..601cb9e90 100644 --- a/cli/packages/gateway/systemd.go +++ b/cli/packages/gateway/systemd.go @@ -17,7 +17,7 @@ After=network.target [Service] Type=simple EnvironmentFile=/etc/infisical/gateway.conf -ExecStart=/usr/local/bin/infisical gateway +ExecStart=infisical gateway Restart=on-failure InaccessibleDirectories=/home PrivateTmp=yes diff --git a/docs/cli/commands/gateway.mdx b/docs/cli/commands/gateway.mdx new file mode 100644 index 000000000..fd035f1fd --- /dev/null +++ b/docs/cli/commands/gateway.mdx @@ -0,0 +1,107 @@ +--- +title: "infisical gateway" +description: "Run the Infisical gateway or manage its systemd service" +--- + + + + ```bash + infisical gateway --token= + ``` + + + ```bash + sudo infisical gateway install --token= --domain= + ``` + + + +## Description + +Run the Infisical gateway in the foreground or manage its systemd service installation. The gateway allows secure communication between your self-hosted Infisical instance and client applications. + +## Subcommands & flags + + + Run the Infisical gateway in the foreground. The gateway will connect to the relay service and maintain a persistent connection. + + ```bash + infisical gateway --token= --domain= + ``` + + ### Flags + + + The machine identity access token to authenticate with Infisical. + + ```bash + # Example + infisical gateway --token= + ``` + + You may also expose the token to the CLI by setting the environment variable `INFISICAL_TOKEN` before executing the gateway command. + + + + Domain of your self-hosted Infisical instance. + + ```bash + # Example + sudo infisical gateway install --domain=https://app.your-domain.com + ``` + + + + + Install and enable the gateway as a systemd service. This command must be run with sudo on Linux. + + ```bash + sudo infisical gateway install --token= --domain= + ``` + + ### Requirements + - Must be run on Linux + - Must be run with root/sudo privileges + - Requires systemd + + ### Flags + + + The machine identity access token to authenticate with Infisical. + + ```bash + # Example + sudo infisical gateway install --token= + ``` + + You may also expose the token to the CLI by setting the environment variable `INFISICAL_TOKEN` before executing the install command. + + + + Domain of your self-hosted Infisical instance. + + ```bash + # Example + sudo infisical gateway install --domain=https://app.your-domain.com + ``` + + + ### Service Details + The systemd service is installed with secure defaults: + - Service file: `/etc/systemd/system/infisical-gateway.service` + - Config file: `/etc/infisical/gateway.conf` + - Runs with restricted privileges: + - InaccessibleDirectories=/home + - PrivateTmp=yes + - Resource limits configured for stability + - Automatically restarts on failure + - Enabled to start on boot + + After installation, manage the service with standard systemd commands: + ```bash + sudo systemctl start infisical-gateway # Start the service + sudo systemctl stop infisical-gateway # Stop the service + sudo systemctl status infisical-gateway # Check service status + sudo systemctl disable infisical-gateway # Disable auto-start on boot + ``` + diff --git a/docs/documentation/platform/gateways/overview.mdx b/docs/documentation/platform/gateways/overview.mdx index d263dc278..3f19e6f8d 100644 --- a/docs/documentation/platform/gateways/overview.mdx +++ b/docs/documentation/platform/gateways/overview.mdx @@ -45,19 +45,53 @@ Once authenticated, the Gateway establishes a secure connection with Infisical t - Use the Infisical CLI to deploy the Gateway. You can log in with your machine identity and start the Gateway in one command. The example below demonstrates how to deploy the Gateway using the Universal Auth method: - ```bash - infisical gateway --token $(infisical login --method=universal-auth --client-id=<> --client-secret=<> --plain) - ``` - Alternatively, if you already have the token, use it directly with the `--token` flag: - ```bash - infisical gateway --token - ``` - Or set it as an environment variable: - ```bash - export INFISICAL_TOKEN= - infisical gateway - ``` + Use the Infisical CLI to deploy the Gateway. You can run it directly or install it as a systemd service for production: + + + + For production deployments on Linux, install the Gateway as a systemd service: + ```bash + sudo infisical gateway install --token --domain + sudo systemctl start infisical-gateway + ``` + This will install and start the Gateway as a secure systemd service that: + - Runs with restricted privileges: + - Runs as root user (required for secure token management) + - Restricted access to home directories + - Private temporary directory + - Automatically restarts on failure + - Starts on system boot + - Manages token and domain configuration securely in `/etc/infisical/gateway.conf` + + + The install command requires: + - Linux operating system + - Root/sudo privileges + - Systemd + + + + + For development or testing, you can run the Gateway directly. Log in with your machine identity and start the Gateway in one command: + ```bash + infisical gateway --token $(infisical login --method=universal-auth --client-id=<> --client-secret=<> --plain) + ``` + + Alternatively, if you already have the token, use it directly with the `--token` flag: + ```bash + infisical gateway --token + ``` + + Or set it as an environment variable: + ```bash + export INFISICAL_TOKEN= + infisical gateway + ``` + + + + For detailed information about the gateway command and its options, see the [gateway command documentation](/cli/commands/gateway). + Ensure the deployed Gateway has network access to the private resources you intend to connect with Infisical. @@ -78,4 +112,3 @@ Once authenticated, the Gateway establishes a secure connection with Infisical t Once added to a project, the Gateway becomes available for use by any feature that supports Gateways within that project. - diff --git a/docs/mint.json b/docs/mint.json index bf40a9778..87294a25b 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -339,6 +339,7 @@ "cli/commands/secrets", "cli/commands/dynamic-secrets", "cli/commands/ssh", + "cli/commands/gateway", "cli/commands/export", "cli/commands/token", "cli/commands/service-token",