Skip to content

Commit f5c7943

Browse files
authored
Merge pull request #3226 from Infisical/support-systemd
Add proper support for systemd
2 parents 5f0dd31 + 3c59f7f commit f5c7943

File tree

7 files changed

+211
-39
lines changed

7 files changed

+211
-39
lines changed

cli/go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ require (
2020
github.com/muesli/reflow v0.3.0
2121
github.com/muesli/roff v0.1.0
2222
github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9
23+
github.com/pion/dtls/v3 v3.0.4
2324
github.com/pion/logging v0.2.3
2425
github.com/pion/turn/v4 v4.0.0
2526
github.com/posthog/posthog-go v0.0.0-20221221115252-24dfed35d71a
@@ -90,7 +91,6 @@ require (
9091
github.com/oklog/ulid v1.3.1 // indirect
9192
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
9293
github.com/pelletier/go-toml v1.9.3 // indirect
93-
github.com/pion/dtls/v3 v3.0.4 // indirect
9494
github.com/pion/randutil v0.1.0 // indirect
9595
github.com/pion/stun/v3 v3.0.0 // indirect
9696
github.com/pion/transport/v3 v3.0.7 // indirect

cli/go.sum

-10
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
484484
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
485485
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
486486
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
487-
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
488-
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
489487
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
490488
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
491489
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
592590
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
593591
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
594592
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
595-
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
596-
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
597593
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
598594
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
599595
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
644640
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
645641
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
646642
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
647-
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
648-
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
649643
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
650644
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
651645
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
652-
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
653-
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
654646
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
655647
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
656648
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=
662654
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
663655
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
664656
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
665-
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
666-
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
667657
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
668658
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
669659
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

cli/packages/cmd/gateway.go

+54-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"os/exec"
78
"os/signal"
9+
"runtime"
810
"syscall"
911
"time"
1012

@@ -16,31 +18,23 @@ import (
1618
)
1719

1820
var gatewayCmd = &cobra.Command{
19-
Example: `infisical gateway`,
20-
Short: "Used to infisical gateway",
2121
Use: "gateway",
22+
Short: "Run the Infisical gateway or manage its systemd service",
23+
Long: "Run the Infisical gateway in the foreground or manage its systemd service installation. Use 'gateway install' to set up the systemd service.",
24+
Example: `infisical gateway --token=<token>
25+
sudo infisical gateway install --token=<token> --domain=<domain>`,
2226
DisableFlagsInUseLine: true,
2327
Args: cobra.NoArgs,
2428
Run: func(cmd *cobra.Command, args []string) {
2529
token, err := util.GetInfisicalToken(cmd)
2630
if err != nil {
27-
util.HandleError(err, "Unable to parse flag")
31+
util.HandleError(err, "Unable to parse token flag")
2832
}
2933

3034
if token == nil {
3135
util.HandleError(fmt.Errorf("Token not found"))
3236
}
3337

34-
domain, err := cmd.Flags().GetString("domain")
35-
if err != nil {
36-
util.HandleError(err, "Unable to parse domain flag")
37-
}
38-
39-
// Try to install systemd service if possible
40-
if err := gateway.InstallGatewaySystemdService(token.Token, domain); err != nil {
41-
log.Warn().Msgf("Failed to install systemd service: %v", err)
42-
}
43-
4438
Telemetry.CaptureEvent("cli-command:gateway", posthog.NewProperties().Set("version", util.CLI_VERSION))
4539

4640
sigCh := make(chan os.Signal, 1)
@@ -110,6 +104,50 @@ var gatewayCmd = &cobra.Command{
110104
},
111105
}
112106

107+
var gatewayInstallCmd = &cobra.Command{
108+
Use: "install",
109+
Short: "Install and enable systemd service for the gateway (requires sudo)",
110+
Long: "Install and enable systemd service for the gateway. Must be run with sudo on Linux.",
111+
Example: "sudo infisical gateway install --token=<token> --domain=<domain>",
112+
DisableFlagsInUseLine: true,
113+
Args: cobra.NoArgs,
114+
Run: func(cmd *cobra.Command, args []string) {
115+
if runtime.GOOS != "linux" {
116+
util.HandleError(fmt.Errorf("systemd service installation is only supported on Linux"))
117+
}
118+
119+
if os.Geteuid() != 0 {
120+
util.HandleError(fmt.Errorf("systemd service installation requires root/sudo privileges"))
121+
}
122+
123+
token, err := util.GetInfisicalToken(cmd)
124+
if err != nil {
125+
util.HandleError(err, "Unable to parse flag")
126+
}
127+
128+
if token == nil {
129+
util.HandleError(fmt.Errorf("Token not found"))
130+
}
131+
132+
domain, err := cmd.Flags().GetString("domain")
133+
if err != nil {
134+
util.HandleError(err, "Unable to parse domain flag")
135+
}
136+
137+
if err := gateway.InstallGatewaySystemdService(token.Token, domain); err != nil {
138+
util.HandleError(err, "Failed to install systemd service")
139+
}
140+
141+
enableCmd := exec.Command("systemctl", "enable", "infisical-gateway")
142+
if err := enableCmd.Run(); err != nil {
143+
util.HandleError(err, "Failed to enable systemd service")
144+
}
145+
146+
log.Info().Msg("Successfully installed and enabled infisical-gateway service")
147+
log.Info().Msg("To start the service, run: sudo systemctl start infisical-gateway")
148+
},
149+
}
150+
113151
var gatewayRelayCmd = &cobra.Command{
114152
Example: `infisical gateway relay`,
115153
Short: "Used to run infisical gateway relay",
@@ -139,9 +177,12 @@ var gatewayRelayCmd = &cobra.Command{
139177

140178
func init() {
141179
gatewayCmd.Flags().String("token", "", "Connect with Infisical using machine identity access token")
180+
gatewayInstallCmd.Flags().String("token", "", "Connect with Infisical using machine identity access token")
181+
gatewayInstallCmd.Flags().String("domain", "", "Domain of your self-hosted Infisical instance")
142182

143183
gatewayRelayCmd.Flags().String("config", "", "Relay config yaml file path")
144184

185+
gatewayCmd.AddCommand(gatewayInstallCmd)
145186
gatewayCmd.AddCommand(gatewayRelayCmd)
146187
rootCmd.AddCommand(gatewayCmd)
147188
}

cli/packages/gateway/systemd.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ After=network.target
1717
[Service]
1818
Type=simple
1919
EnvironmentFile=/etc/infisical/gateway.conf
20-
ExecStart=/usr/local/bin/infisical gateway
20+
ExecStart=infisical gateway
2121
Restart=on-failure
2222
InaccessibleDirectories=/home
2323
PrivateTmp=yes

docs/cli/commands/gateway.mdx

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
title: "infisical gateway"
3+
description: "Run the Infisical gateway or manage its systemd service"
4+
---
5+
6+
<Tabs>
7+
<Tab title="Run gateway">
8+
```bash
9+
infisical gateway --token=<token>
10+
```
11+
</Tab>
12+
<Tab title="Install service">
13+
```bash
14+
sudo infisical gateway install --token=<token> --domain=<domain>
15+
```
16+
</Tab>
17+
</Tabs>
18+
19+
## Description
20+
21+
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.
22+
23+
## Subcommands & flags
24+
25+
<Accordion title="infisical gateway" defaultOpen="true">
26+
Run the Infisical gateway in the foreground. The gateway will connect to the relay service and maintain a persistent connection.
27+
28+
```bash
29+
infisical gateway --token=<token> --domain=<domain>
30+
```
31+
32+
### Flags
33+
34+
<Accordion title="--token">
35+
The machine identity access token to authenticate with Infisical.
36+
37+
```bash
38+
# Example
39+
infisical gateway --token=<token>
40+
```
41+
42+
You may also expose the token to the CLI by setting the environment variable `INFISICAL_TOKEN` before executing the gateway command.
43+
</Accordion>
44+
45+
<Accordion title="--domain">
46+
Domain of your self-hosted Infisical instance.
47+
48+
```bash
49+
# Example
50+
sudo infisical gateway install --domain=https://app.your-domain.com
51+
```
52+
</Accordion>
53+
</Accordion>
54+
55+
<Accordion title="infisical gateway install">
56+
Install and enable the gateway as a systemd service. This command must be run with sudo on Linux.
57+
58+
```bash
59+
sudo infisical gateway install --token=<token> --domain=<domain>
60+
```
61+
62+
### Requirements
63+
- Must be run on Linux
64+
- Must be run with root/sudo privileges
65+
- Requires systemd
66+
67+
### Flags
68+
69+
<Accordion title="--token">
70+
The machine identity access token to authenticate with Infisical.
71+
72+
```bash
73+
# Example
74+
sudo infisical gateway install --token=<token>
75+
```
76+
77+
You may also expose the token to the CLI by setting the environment variable `INFISICAL_TOKEN` before executing the install command.
78+
</Accordion>
79+
80+
<Accordion title="--domain">
81+
Domain of your self-hosted Infisical instance.
82+
83+
```bash
84+
# Example
85+
sudo infisical gateway install --domain=https://app.your-domain.com
86+
```
87+
</Accordion>
88+
89+
### Service Details
90+
The systemd service is installed with secure defaults:
91+
- Service file: `/etc/systemd/system/infisical-gateway.service`
92+
- Config file: `/etc/infisical/gateway.conf`
93+
- Runs with restricted privileges:
94+
- InaccessibleDirectories=/home
95+
- PrivateTmp=yes
96+
- Resource limits configured for stability
97+
- Automatically restarts on failure
98+
- Enabled to start on boot
99+
100+
After installation, manage the service with standard systemd commands:
101+
```bash
102+
sudo systemctl start infisical-gateway # Start the service
103+
sudo systemctl stop infisical-gateway # Stop the service
104+
sudo systemctl status infisical-gateway # Check service status
105+
sudo systemctl disable infisical-gateway # Disable auto-start on boot
106+
```
107+
</Accordion>

docs/documentation/platform/gateways/overview.mdx

+47-14
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,53 @@ Once authenticated, the Gateway establishes a secure connection with Infisical t
4545
</Step>
4646

4747
<Step title="Deploy the Gateway">
48-
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:
49-
```bash
50-
infisical gateway --token $(infisical login --method=universal-auth --client-id=<> --client-secret=<> --plain)
51-
```
52-
Alternatively, if you already have the token, use it directly with the `--token` flag:
53-
```bash
54-
infisical gateway --token <your-machine-identity-token>
55-
```
56-
Or set it as an environment variable:
57-
```bash
58-
export INFISICAL_TOKEN=<your-machine-identity-token>
59-
infisical gateway
60-
```
48+
Use the Infisical CLI to deploy the Gateway. You can run it directly or install it as a systemd service for production:
49+
50+
<Tabs>
51+
<Tab title="Production (systemd)">
52+
For production deployments on Linux, install the Gateway as a systemd service:
53+
```bash
54+
sudo infisical gateway install --token <your-machine-identity-token> --domain <your-infisical-domain>
55+
sudo systemctl start infisical-gateway
56+
```
57+
This will install and start the Gateway as a secure systemd service that:
58+
- Runs with restricted privileges:
59+
- Runs as root user (required for secure token management)
60+
- Restricted access to home directories
61+
- Private temporary directory
62+
- Automatically restarts on failure
63+
- Starts on system boot
64+
- Manages token and domain configuration securely in `/etc/infisical/gateway.conf`
65+
66+
<Warning>
67+
The install command requires:
68+
- Linux operating system
69+
- Root/sudo privileges
70+
- Systemd
71+
</Warning>
72+
</Tab>
73+
74+
<Tab title="Development (direct)">
75+
For development or testing, you can run the Gateway directly. Log in with your machine identity and start the Gateway in one command:
76+
```bash
77+
infisical gateway --token $(infisical login --method=universal-auth --client-id=<> --client-secret=<> --plain)
78+
```
79+
80+
Alternatively, if you already have the token, use it directly with the `--token` flag:
81+
```bash
82+
infisical gateway --token <your-machine-identity-token>
83+
```
84+
85+
Or set it as an environment variable:
86+
```bash
87+
export INFISICAL_TOKEN=<your-machine-identity-token>
88+
infisical gateway
89+
```
90+
</Tab>
91+
</Tabs>
92+
93+
For detailed information about the gateway command and its options, see the [gateway command documentation](/cli/commands/gateway).
94+
6195
<Note>
6296
Ensure the deployed Gateway has network access to the private resources you intend to connect with Infisical.
6397
</Note>
@@ -78,4 +112,3 @@ Once authenticated, the Gateway establishes a secure connection with Infisical t
78112
Once added to a project, the Gateway becomes available for use by any feature that supports Gateways within that project.
79113
</Step>
80114
</Steps>
81-

docs/mint.json

+1
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@
339339
"cli/commands/secrets",
340340
"cli/commands/dynamic-secrets",
341341
"cli/commands/ssh",
342+
"cli/commands/gateway",
342343
"cli/commands/export",
343344
"cli/commands/token",
344345
"cli/commands/service-token",

0 commit comments

Comments
 (0)