diff --git a/backend/src/ee/routes/v1/gateway-router.ts b/backend/src/ee/routes/v1/gateway-router.ts
index ea3e1f6d6..c916e229e 100644
--- a/backend/src/ee/routes/v1/gateway-router.ts
+++ b/backend/src/ee/routes/v1/gateway-router.ts
@@ -37,7 +37,7 @@ export const registerGatewayRouter = async (server: FastifyZodProvider) => {
turnServerPassword: z.string(),
turnServerRealm: z.string(),
turnServerAddress: z.string(),
- infisicalStaticIp: z.string()
+ infisicalStaticIp: z.string().optional()
})
}
},
diff --git a/backend/src/ee/services/gateway/gateway-service.ts b/backend/src/ee/services/gateway/gateway-service.ts
index 10314335b..fdfaa8ab1 100644
--- a/backend/src/ee/services/gateway/gateway-service.ts
+++ b/backend/src/ee/services/gateway/gateway-service.ts
@@ -97,12 +97,7 @@ export const gatewayServiceFactory = ({
orgId: actorOrgId
});
- if (
- !envCfg.GATEWAY_RELAY_AUTH_SECRET ||
- !envCfg.GATEWAY_RELAY_ADDRESS ||
- !envCfg.GATEWAY_INFISICAL_STATIC_IP_ADDRESS ||
- !envCfg.GATEWAY_RELAY_REALM
- ) {
+ if (!envCfg.GATEWAY_RELAY_AUTH_SECRET || !envCfg.GATEWAY_RELAY_ADDRESS || !envCfg.GATEWAY_RELAY_REALM) {
throw new BadRequestError({
message: "Gateway handshake failed due to missing instance configuration."
});
diff --git a/backend/src/lib/gateway/index.ts b/backend/src/lib/gateway/index.ts
index 4cb3e87b8..eaebd896d 100644
--- a/backend/src/lib/gateway/index.ts
+++ b/backend/src/lib/gateway/index.ts
@@ -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 {
@@ -251,6 +254,9 @@ export const withGatewayProxy = async (
try {
// Execute the callback with the allocated port
await callback(port);
+ } catch (err) {
+ logger.error(err, "Failed to proxy");
+ throw new BadRequestError({ message: (err as Error)?.message });
} finally {
// Ensure cleanup happens regardless of success or failure
cleanup();
diff --git a/cli/packages/gateway/gateway.go b/cli/packages/gateway/gateway.go
index 658d1fef8..e5ec03293 100644
--- a/cli/packages/gateway/gateway.go
+++ b/cli/packages/gateway/gateway.go
@@ -49,14 +49,25 @@ func (g *Gateway) ConnectWithRelay() error {
if err != nil {
return err
}
-
- turnServerAddr, err := net.ResolveTCPAddr("tcp", relayDetails.TurnServerAddress)
- if err != nil {
- return fmt.Errorf("Failed to resolve TURN server address: %w", err)
- }
+ relayAddress, relayPort := strings.Split(relayDetails.TurnServerAddress, ":")[0], strings.Split(relayDetails.TurnServerAddress, ":")[1]
+ var conn net.Conn
// 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 {
return fmt.Errorf("Failed to connect with relay server: %w", err)
}
@@ -85,7 +96,7 @@ func (g *Gateway) ConnectWithRelay() error {
InfisicalStaticIp: relayDetails.InfisicalStaticIp,
}
// 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"
}
@@ -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{
RelayAddress: relayNonTlsConn.Addr().String(),
})
@@ -134,10 +141,17 @@ func (g *Gateway) Listen(ctx context.Context) error {
done := make(chan bool, 1)
- g.registerPermissionLifecycle(func() error {
- err := relayNonTlsConn.CreatePermissions(peerAddr)
- return err
- }, done)
+ if g.config.InfisicalStaticIp != "" {
+ log.Info().Msgf("Found static ip from Infisical: %s. Creating permission IP lifecycle", g.config.InfisicalStaticIp)
+ peerAddr, err := net.ResolveTCPAddr("tcp", g.config.InfisicalStaticIp)
+ 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))
if err != nil {
diff --git a/docs/documentation/platform/gateways/overview.mdx b/docs/documentation/platform/gateways/overview.mdx
index 1dfde2784..d263dc278 100644
--- a/docs/documentation/platform/gateways/overview.mdx
+++ b/docs/documentation/platform/gateways/overview.mdx
@@ -1,7 +1,7 @@
---
title: "Gateway"
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.
@@ -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.