feat: changes based on reviews

This commit is contained in:
=
2025-02-26 20:43:59 +05:30
parent 44f74e4d12
commit d84bac5fba
6 changed files with 55 additions and 39 deletions

View File

@@ -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()
})
}
},

View File

@@ -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."
});

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 {
@@ -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();

View File

@@ -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 {

View File

@@ -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.
<Info>
**Note:** Gateway is a paid feature.
- **Infisical Cloud users:** Gateway is available under the **Enterprise Tier**.
- **Self-Hosted Infisical:** Please contact [sales@infisical.com](mailto:sales@infisical.com) to purchase an enterprise license.
**Note:** Gateway is a paid feature. - **Infisical Cloud users:** Gateway is
available under the **Enterprise Tier**. - **Self-Hosted Infisical:** Please
contact [sales@infisical.com](mailto:sales@infisical.com) to purchase an
enterprise license.
</Info>
## 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.
Its 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.
## 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).
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.
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.
### Deployment process
<Steps>
<Step title="Create a Gateway Identity">
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)
</Step>
<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.
@@ -77,4 +77,5 @@ Once authenticated, the Gateway establishes a secure connection with Infisical t
![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.
</Step>
</Steps>
</Steps>

View File

@@ -94,7 +94,7 @@ export const GatewayListPage = withPermission(
<span>Gateways</span>
<a
className="-mt-1.5"
href="https://infisical.com/docs/integrations/gateways/overview"
href="https://infisical.com/docs/documentation/platform/gateways/overview"
target="_blank"
rel="noopener noreferrer"
>
@@ -109,7 +109,7 @@ export const GatewayListPage = withPermission(
</a>
</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>
@@ -118,7 +118,7 @@ export const GatewayListPage = withPermission(
value={search}
onChange={(e) => setSearch(e.target.value)}
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
placeholder="Search connections..."
placeholder="Search gateway..."
className="flex-1"
/>
</div>