浏览代码

Local sites working

Owen Schwartz 6 月之前
父节点
当前提交
161e87dbda
共有 4 个文件被更改,包括 111 次插入85 次删除
  1. 9 0
      install/fs/docker-compose.yml
  2. 3 8
      install/main.go
  3. 89 77
      server/routers/target/createTarget.ts
  4. 10 0
      server/routers/traefik/getTraefikConfig.ts

+ 9 - 0
install/fs/docker-compose.yml

@@ -11,6 +11,7 @@ services:
       timeout: "3s"
       retries: 5
 
+{{if .InstallGerbil}}
   gerbil:
     image: fosrl/gerbil:{{.GerbilVersion}}
     container_name: gerbil
@@ -32,12 +33,20 @@ services:
       - 51820:51820/udp
       - 443:443 # Port for traefik because of the network_mode
       - 80:80 # Port for traefik because of the network_mode
+{{end}}
 
   traefik:
     image: traefik:v3.1
     container_name: traefik
     restart: unless-stopped
+{{if .InstallGerbil}}
     network_mode: service:gerbil # Ports appear on the gerbil service
+{{end}}
+{{if not .InstallGerbil}}
+    ports:
+      - 443:443
+      - 80:80
+{{end}}
     depends_on:
       pangolin:
         condition: service_healthy

+ 3 - 8
install/main.go

@@ -41,6 +41,7 @@ type Config struct {
 	EmailSMTPUser              string
 	EmailSMTPPass              string
 	EmailNoReply               string
+	InstallGerbil              bool
 }
 
 func main() {
@@ -64,7 +65,7 @@ func main() {
 		}
 
 		if !isDockerInstalled() && runtime.GOOS == "linux" {
-			if shouldInstallDocker() {
+			if readBool(reader, "Docker is not installed. Would you like to install it?", true) {
 				installDocker()
 			}
 		}
@@ -140,6 +141,7 @@ func collectUserInput(reader *bufio.Reader) Config {
 	config.BaseDomain = readString(reader, "Enter your base domain (no subdomain e.g. example.com)", "")
 	config.DashboardDomain = readString(reader, "Enter the domain for the Pangolin dashboard", "pangolin."+config.BaseDomain)
 	config.LetsEncryptEmail = readString(reader, "Enter email for Let's Encrypt certificates", "")
+	config.InstallGerbil = readBool(reader, "Do you want to use Gerbil to allow tunned connections", true)
 
 	// Admin user configuration
 	fmt.Println("\n=== Admin User Configuration ===")
@@ -340,13 +342,6 @@ func createConfigFiles(config Config) error {
 	return nil
 }
 
-func shouldInstallDocker() bool {
-	reader := bufio.NewReader(os.Stdin)
-	fmt.Print("Would you like to install Docker? (yes/no): ")
-	response, _ := reader.ReadString('\n')
-	return strings.ToLower(strings.TrimSpace(response)) == "yes"
-}
-
 func installDocker() error {
 	// Detect Linux distribution
 	cmd := exec.Command("cat", "/etc/os-release")

+ 89 - 77
server/routers/target/createTarget.ts

@@ -123,88 +123,100 @@ export async function createTarget(
             );
         }
 
-        // make sure the target is within the site subnet
-        if (
-            site.type == "wireguard" &&
-            !isIpInCidr(targetData.ip, site.subnet!)
-        ) {
-            return next(
-                createHttpError(
-                    HttpCode.BAD_REQUEST,
-                    `Target IP is not within the site subnet`
-                )
-            );
-        }
-
-        // Fetch resources for this site
-        const resourcesRes = await db.query.resources.findMany({
-            where: eq(resources.siteId, site.siteId)
-        });
+        let newTarget: Target[] = [];
+        if (site.type == "local") {
+            newTarget = await db
+                .insert(targets)
+                .values({
+                    resourceId,
+                    protocol: "tcp", // hard code for now
+                    ...targetData
+                })
+                .returning();
+        } else {
+            // make sure the target is within the site subnet
+            if (
+                site.type == "wireguard" &&
+                !isIpInCidr(targetData.ip, site.subnet!)
+            ) {
+                return next(
+                    createHttpError(
+                        HttpCode.BAD_REQUEST,
+                        `Target IP is not within the site subnet`
+                    )
+                );
+            }
 
-        // TODO: is this all inefficient?
-        // Fetch targets for all resources of this site
-        let targetIps: string[] = [];
-        let targetInternalPorts: number[] = [];
-        await Promise.all(
-            resourcesRes.map(async (resource) => {
-                const targetsRes = await db.query.targets.findMany({
-                    where: eq(targets.resourceId, resource.resourceId)
-                });
-                targetsRes.forEach((target) => {
-                    targetIps.push(`${target.ip}/32`);
-                    if (target.internalPort) {
-                        targetInternalPorts.push(target.internalPort);
-                    }
-                });
-            })
-        );
+            // Fetch resources for this site
+            const resourcesRes = await db.query.resources.findMany({
+                where: eq(resources.siteId, site.siteId)
+            });
+
+            // TODO: is this all inefficient?
+            // Fetch targets for all resources of this site
+            let targetIps: string[] = [];
+            let targetInternalPorts: number[] = [];
+            await Promise.all(
+                resourcesRes.map(async (resource) => {
+                    const targetsRes = await db.query.targets.findMany({
+                        where: eq(targets.resourceId, resource.resourceId)
+                    });
+                    targetsRes.forEach((target) => {
+                        targetIps.push(`${target.ip}/32`);
+                        if (target.internalPort) {
+                            targetInternalPorts.push(target.internalPort);
+                        }
+                    });
+                })
+            );
 
-        let internalPort!: number;
-        // pick a port
-        for (let i = 40000; i < 65535; i++) {
-            if (!targetInternalPorts.includes(i)) {
-                internalPort = i;
-                break;
+            let internalPort!: number;
+            // pick a port
+            for (let i = 40000; i < 65535; i++) {
+                if (!targetInternalPorts.includes(i)) {
+                    internalPort = i;
+                    break;
+                }
             }
-        }
 
-        if (!internalPort) {
-            return next(
-                createHttpError(
-                    HttpCode.BAD_REQUEST,
-                    `No available internal port`
-                )
-            );
-        }
+            if (!internalPort) {
+                return next(
+                    createHttpError(
+                        HttpCode.BAD_REQUEST,
+                        `No available internal port`
+                    )
+                );
+            }
 
-        const newTarget = await db
-            .insert(targets)
-            .values({
-                resourceId,
-                protocol: "tcp", // hard code for now
-                internalPort,
-                ...targetData
-            })
-            .returning();
-
-        // add the new target to the targetIps array
-        targetIps.push(`${targetData.ip}/32`);
-
-        if (site.pubKey) {
-            if (site.type == "wireguard") {
-                await addPeer(site.exitNodeId!, {
-                    publicKey: site.pubKey,
-                    allowedIps: targetIps.flat()
-                });
-            } else if (site.type == "newt") {
-                // get the newt on the site by querying the newt table for siteId
-                const [newt] = await db
-                    .select()
-                    .from(newts)
-                    .where(eq(newts.siteId, site.siteId))
-                    .limit(1);
-
-                addTargets(newt.newtId, newTarget);
+            newTarget = await db
+                .insert(targets)
+                .values({
+                    resourceId,
+                    protocol: "tcp", // hard code for now
+                    internalPort,
+                    ...targetData
+                })
+                .returning();
+
+            // add the new target to the targetIps array
+            targetIps.push(`${targetData.ip}/32`);
+
+            if (site.pubKey) {
+                if (site.type == "wireguard") {
+                    await addPeer(site.exitNodeId!, {
+                        publicKey: site.pubKey,
+                        allowedIps: targetIps.flat()
+                    });
+                } else if (site.type == "newt") {
+                    // get the newt on the site by querying the newt table for siteId
+                    const [newt] = await db
+                        .select()
+                        .from(newts)
+                        .where(eq(newts.siteId, site.siteId))
+                        .limit(1);
+
+                    addTargets(newt.newtId, newTarget);
+                }
             }
         }
 

+ 10 - 0
server/routers/traefik/getTraefikConfig.ts

@@ -151,6 +151,16 @@ export async function traefikConfigProvider(
                         ],
                     },
                 };
+            } else if (site.type === "local") {
+                http.services![serviceName] = {
+                    loadBalancer: {
+                        servers: [
+                            {
+                                url: `${target.method}://${target.ip}:${target.port}`,
+                            },
+                        ],
+                    },
+                };
             }
         }