feat: changes based on reviews

This commit is contained in:
=
2025-02-26 20:45:40 +05:30
parent 44f74e4d12
commit d84bac5fba
6 changed files with 55 additions and 39 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ export const registerGatewayRouter = async (server: FastifyZodProvider) => {
turnServerPassword: z.string(), turnServerPassword: z.string(),
turnServerRealm: z.string(), turnServerRealm: z.string(),
turnServerAddress: z.string(), turnServerAddress: z.string(),
infisicalStaticIp: z.string() infisicalStaticIp: z.string().optional()
}) })
} }
}, },
@@ -97,12 +97,7 @@ export const gatewayServiceFactory = ({
orgId: actorOrgId orgId: actorOrgId
}); });
if ( if (!envCfg.GATEWAY_RELAY_AUTH_SECRET || !envCfg.GATEWAY_RELAY_ADDRESS || !envCfg.GATEWAY_RELAY_REALM) {
!envCfg.GATEWAY_RELAY_AUTH_SECRET ||
!envCfg.GATEWAY_RELAY_ADDRESS ||
!envCfg.GATEWAY_INFISICAL_STATIC_IP_ADDRESS ||
!envCfg.GATEWAY_RELAY_REALM
) {
throw new BadRequestError({ throw new BadRequestError({
message: "Gateway handshake failed due to missing instance configuration." message: "Gateway handshake failed due to missing instance configuration."
}); });
+7 -1
View File
@@ -105,7 +105,10 @@ export const pingGatewayAndVerify = async ({
} }
} }
throw new Error(`Failed to ping gateway after ${maxRetries} attempts. Last error: ${lastError?.message}`); logger.error(lastError);
throw new BadRequestError({
message: `Failed to ping gateway after ${maxRetries} attempts. Last error: ${lastError?.message}`
});
}; };
interface TProxyServer { interface TProxyServer {
@@ -251,6 +254,9 @@ export const withGatewayProxy = async (
try { try {
// Execute the callback with the allocated port // Execute the callback with the allocated port
await callback(port); await callback(port);
} catch (err) {
logger.error(err, "Failed to proxy");
throw new BadRequestError({ message: (err as Error)?.message });
} finally { } finally {
// Ensure cleanup happens regardless of success or failure // Ensure cleanup happens regardless of success or failure
cleanup(); cleanup();
+29 -15
View File
@@ -49,14 +49,25 @@ func (g *Gateway) ConnectWithRelay() error {
if err != nil { if err != nil {
return err return err
} }
relayAddress, relayPort := strings.Split(relayDetails.TurnServerAddress, ":")[0], strings.Split(relayDetails.TurnServerAddress, ":")[1]
turnServerAddr, err := net.ResolveTCPAddr("tcp", relayDetails.TurnServerAddress) var conn net.Conn
if err != nil {
return fmt.Errorf("Failed to resolve TURN server address: %w", err)
}
// Dial TURN Server // Dial TURN Server
conn, err := net.DialTCP("tcp", nil, turnServerAddr) if relayPort == "5349" {
log.Info().Msgf("Provided relay port %s. Using TLS", relayPort)
conn, err = tls.Dial("tcp", relayDetails.TurnServerAddress, &tls.Config{
InsecureSkipVerify: false,
ServerName: relayAddress,
})
} else {
log.Info().Msgf("Provided relay port %s. Using non TLS connection.", relayPort)
peerAddr, err := net.ResolveTCPAddr("tcp", relayDetails.TurnServerAddress)
if err != nil {
return fmt.Errorf("Failed to parse turn server address: %w", err)
}
conn, err = net.DialTCP("tcp", nil, peerAddr)
}
if err != nil { if err != nil {
return fmt.Errorf("Failed to connect with relay server: %w", err) return fmt.Errorf("Failed to connect with relay server: %w", err)
} }
@@ -85,7 +96,7 @@ func (g *Gateway) ConnectWithRelay() error {
InfisicalStaticIp: relayDetails.InfisicalStaticIp, InfisicalStaticIp: relayDetails.InfisicalStaticIp,
} }
// if port not specific allow all port // if port not specific allow all port
if !strings.Contains(relayDetails.InfisicalStaticIp, ":") { if relayDetails.InfisicalStaticIp != "" && !strings.Contains(relayDetails.InfisicalStaticIp, ":") {
g.config.InfisicalStaticIp = g.config.InfisicalStaticIp + ":0" g.config.InfisicalStaticIp = g.config.InfisicalStaticIp + ":0"
} }
@@ -116,10 +127,6 @@ func (g *Gateway) Listen(ctx context.Context) error {
} }
}() }()
peerAddr, err := net.ResolveTCPAddr("tcp", g.config.InfisicalStaticIp)
if err != nil {
return fmt.Errorf("Failed to parse infisical static ip: %w", err)
}
gatewayCert, err := api.CallExchangeRelayCertV1(g.httpClient, api.ExchangeRelayCertRequestV1{ gatewayCert, err := api.CallExchangeRelayCertV1(g.httpClient, api.ExchangeRelayCertRequestV1{
RelayAddress: relayNonTlsConn.Addr().String(), RelayAddress: relayNonTlsConn.Addr().String(),
}) })
@@ -134,10 +141,17 @@ func (g *Gateway) Listen(ctx context.Context) error {
done := make(chan bool, 1) done := make(chan bool, 1)
g.registerPermissionLifecycle(func() error { if g.config.InfisicalStaticIp != "" {
err := relayNonTlsConn.CreatePermissions(peerAddr) log.Info().Msgf("Found static ip from Infisical: %s. Creating permission IP lifecycle", g.config.InfisicalStaticIp)
return err peerAddr, err := net.ResolveTCPAddr("tcp", g.config.InfisicalStaticIp)
}, done) if err != nil {
return fmt.Errorf("Failed to parse infisical static ip: %w", err)
}
g.registerPermissionLifecycle(func() error {
err := relayNonTlsConn.CreatePermissions(peerAddr)
return err
}, done)
}
cert, err := tls.X509KeyPair([]byte(gatewayCert.Certificate), []byte(gatewayCert.PrivateKey)) cert, err := tls.X509KeyPair([]byte(gatewayCert.Certificate), []byte(gatewayCert.PrivateKey))
if err != nil { if err != nil {
@@ -1,7 +1,7 @@
--- ---
title: "Gateway" title: "Gateway"
sidebarTitle: "Overview" sidebarTitle: "Overview"
description: "How access private network resources from Infisical" description: "How to access private network resources from Infisical"
--- ---
The Infisical Gateway provides secure access to private resources within your network without needing direct inbound connections to your environment. The Infisical Gateway provides secure access to private resources within your network without needing direct inbound connections to your environment.
@@ -9,28 +9,29 @@ This method keeps your resources fully protected from external access while enab
Common use cases include generating dynamic credentials or rotating credentials for private databases. Common use cases include generating dynamic credentials or rotating credentials for private databases.
<Info> <Info>
**Note:** Gateway is a paid feature. **Note:** Gateway is a paid feature. - **Infisical Cloud users:** Gateway is
available under the **Enterprise Tier**. - **Self-Hosted Infisical:** Please
- **Infisical Cloud users:** Gateway is available under the **Enterprise Tier**. contact [[email protected]](mailto:[email protected]) to purchase an
- **Self-Hosted Infisical:** Please contact [[email protected]](mailto:[email protected]) to purchase an enterprise license. enterprise license.
</Info> </Info>
## How It Works ## How It Works
The Gateway serves as a secure intermediary that facilitates direct communication between the Infisical server and your private network. The Gateway serves as a secure intermediary that facilitates direct communication between the Infisical server and your private network.
It’s a lightweight daemon packaged within the Infisical CLI, making it easy to deploy and manage. Once set up, the Gateway establishes a connection with a relay server, ensuring that all communication between Infisical and your Gateway is fully end-to-end encrypted. It’s a lightweight daemon packaged within the Infisical CLI, making it easy to deploy and manage. Once set up, the Gateway establishes a connection with a relay server, ensuring that all communication between Infisical and your Gateway is fully end-to-end encrypted.
This setup guarantees that only the platform and your Gateway can decrypt the transmitted information, keeping communication with your resources secure, private and isolated. This setup guarantees that only the platform and your Gateway can decrypt the transmitted information, keeping communication with your resources secure, private and isolated.
## Deployment ## Deployment
The Infisical Gateway is seamlessly integrated into the Infisical CLI under the `gateway` command, making it simple to deploy and manage.
You can install the Gateway in all the same ways you install the Infisical CLI—whether via npm, Docker, or a binary. The Infisical Gateway is seamlessly integrated into the Infisical CLI under the `gateway` command, making it simple to deploy and manage.
You can install the Gateway in all the same ways you install the Infisical CLI—whether via npm, Docker, or a binary.
For detailed installation instructions, refer to the Infisical [CLI Installation instructions](/cli/overview). For detailed installation instructions, refer to the Infisical [CLI Installation instructions](/cli/overview).
To function, the Gateway must authenticate with Infisical. This requires a machine identity configured with the appropriate permissions to create and manage a Gateway. To function, the Gateway must authenticate with Infisical. This requires a machine identity configured with the appropriate permissions to create and manage a Gateway.
Once authenticated, the Gateway establishes a secure connection with Infisical to allow your private resources to be reachable. Once authenticated, the Gateway establishes a secure connection with Infisical to allow your private resources to be reachable.
### Deployment process ### Deployment process
<Steps> <Steps>
<Step title="Create a Gateway Identity"> <Step title="Create a Gateway Identity">
1. Navigate to **Organization Access Control** in your Infisical dashboard. 1. Navigate to **Organization Access Control** in your Infisical dashboard.
@@ -67,7 +68,6 @@ Once authenticated, the Gateway establishes a secure connection with Infisical t
![Gateway List](../../../images/platform/gateways/gateway-list.png) ![Gateway List](../../../images/platform/gateways/gateway-list.png)
</Step> </Step>
<Step title="Link Gateway to Projects"> <Step title="Link Gateway to Projects">
To enable Infisical features like dynamic secrets or secret rotation to access private resources through the Gateway, you need to link the Gateway to the relevant projects. To enable Infisical features like dynamic secrets or secret rotation to access private resources through the Gateway, you need to link the Gateway to the relevant projects.
@@ -77,4 +77,5 @@ Once authenticated, the Gateway establishes a secure connection with Infisical t
![Project Assignment Modal](../../../images/platform/gateways/assign-project.png) ![Project Assignment Modal](../../../images/platform/gateways/assign-project.png)
Once added to a project, the Gateway becomes available for use by any feature that supports Gateways within that project. Once added to a project, the Gateway becomes available for use by any feature that supports Gateways within that project.
</Step> </Step>
</Steps> </Steps>
@@ -94,7 +94,7 @@ export const GatewayListPage = withPermission(
<span>Gateways</span> <span>Gateways</span>
<a <a
className="-mt-1.5" className="-mt-1.5"
href="https://infisical.com/docs/integrations/gateways/overview" href="https://infisical.com/docs/documentation/platform/gateways/overview"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
@@ -109,7 +109,7 @@ export const GatewayListPage = withPermission(
</a> </a>
</div> </div>
} }
description="Create and configure connections with third-party apps for re-use across Infisical projects" description="Create and configure gateway to access private network resources from Infisical"
/> />
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4"> <div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div> <div>
@@ -118,7 +118,7 @@ export const GatewayListPage = withPermission(
value={search} value={search}
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />} leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
placeholder="Search connections..." placeholder="Search gateway..."
className="flex-1" className="flex-1"
/> />
</div> </div>