diff --git a/.gitignore b/.gitignore index a4ca8de1..dacf66a1 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ dist .dist installer *.tar +bin diff --git a/Makefile b/Makefile index de182bfe..da0ce742 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -build-all: +build-release: @if [ -z "$(tag)" ]; then \ echo "Error: tag is required. Usage: make build-all tag="; \ exit 1; \ @@ -12,6 +12,9 @@ build-arm: build-x86: docker buildx build --platform linux/amd64 -t fosrl/pangolin:latest . +build-x86-ecr: + docker buildx build --platform linux/amd64 -t 216989133116.dkr.ecr.us-east-1.amazonaws.com/pangolin:latest --push . + build: docker build -t fosrl/pangolin:latest . diff --git a/README.md b/README.md index 759f083b..a1829db4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Pangolin +[![Documentation](https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square)](https://docs.fossorial.io/) +[![Docker](https://img.shields.io/docker/pulls/fosrl/pangolin?style=flat-square)](https://hub.docker.com/r/fosrl/pangolin) +![Stars](https://img.shields.io/github/stars/fosrl/pangolin?style=flat-square) +[![Discord](https://img.shields.io/discord/1325658630518865980?logo=discord&style=flat-square)](https://discord.gg/HCJR8Xhme4) +[![Youtube](https://img.shields.io/badge/YouTube-red?logo=youtube&logoColor=white&style=flat-square)](https://www.youtube.com/@fossorial-app) + Pangolin is a self-hosted tunneled reverse proxy management server with identity and access management, designed to securely expose private resources through use with the Traefik reverse proxy and WireGuard tunnel clients like Newt. With Pangolin, you retain full control over your infrastructure while providing a user-friendly and feature-rich solution for managing proxies, authentication, and access, and simplifying complex network setups, all with a clean and simple UI. ### Installation and Documentation diff --git a/install/Makefile b/install/Makefile index 647bff8b..df531e44 100644 --- a/install/Makefile +++ b/install/Makefile @@ -1,8 +1,12 @@ all: build -build: +build: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o installer +build-release: + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/installer_linux_amd64 + CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o bin/installer_linux_arm64 + clean: - rm installer \ No newline at end of file + rm installer diff --git a/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx index a6d8821b..fdecf9ff 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx @@ -62,6 +62,7 @@ import { SettingsSectionFooter } from "@app/components/Settings"; import { SwitchInput } from "@app/components/SwitchInput"; +import { useSiteContext } from "@app/hooks/useSiteContext"; // Regular expressions for validation const DOMAIN_REGEX = @@ -528,11 +529,23 @@ export default function ReverseProxyTargets(props: { name="ip" render={({ field }) => ( - IP Address + IP / Hostname + {site?.type === "newt" ? ( + + This is the IP or hostname + of the target service on + your network. + + ) : site?.type === "wireguard" ? ( + + This is the IP of the + WireGuard peer. + + ) : null} )} /> @@ -551,6 +564,19 @@ export default function ReverseProxyTargets(props: { /> + {site?.type === "newt" ? ( + + This is the port of the + target service on your + network. + + ) : site?.type === "wireguard" ? ( + + This is the port exposed on + an address on the WireGuard + network. + + ) : null} )} /> diff --git a/src/app/[orgId]/settings/resources/[resourceId]/layout.tsx b/src/app/[orgId]/settings/resources/[resourceId]/layout.tsx index fea9ea78..5f5b90fa 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/layout.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/layout.tsx @@ -2,13 +2,12 @@ import ResourceProvider from "@app/providers/ResourceProvider"; import { internal } from "@app/lib/api"; import { GetResourceAuthInfoResponse, - GetResourceResponse, + GetResourceResponse } from "@server/routers/resource"; import { AxiosResponse } from "axios"; import { redirect } from "next/navigation"; import { authCookieHeader } from "@app/lib/api/cookies"; import { SidebarSettings } from "@app/components/SidebarSettings"; -import { Cloud, Settings, Shield } from "lucide-react"; import SettingsSectionTitle from "@app/components/SettingsSectionTitle"; import { GetOrgResponse } from "@server/routers/org"; import OrgProvider from "@app/providers/OrgProvider"; @@ -20,7 +19,7 @@ import { BreadcrumbLink, BreadcrumbList, BreadcrumbPage, - BreadcrumbSeparator, + BreadcrumbSeparator } from "@app/components/ui/breadcrumb"; import Link from "next/link"; @@ -39,7 +38,7 @@ export default async function ResourceLayout(props: ResourceLayoutProps) { try { const res = await internal.get>( `/resource/${params.resourceId}`, - await authCookieHeader(), + await authCookieHeader() ); resource = res.data.data; } catch { @@ -68,8 +67,8 @@ export default async function ResourceLayout(props: ResourceLayoutProps) { const getOrg = cache(async () => internal.get>( `/org/${params.orgId}`, - await authCookieHeader(), - ), + await authCookieHeader() + ) ); const res = await getOrg(); org = res.data.data; @@ -84,19 +83,19 @@ export default async function ResourceLayout(props: ResourceLayoutProps) { const sidebarNavItems = [ { title: "General", - href: `/{orgId}/settings/resources/{resourceId}/general`, + href: `/{orgId}/settings/resources/{resourceId}/general` // icon: , }, { title: "Connectivity", - href: `/{orgId}/settings/resources/{resourceId}/connectivity`, + href: `/{orgId}/settings/resources/{resourceId}/connectivity` // icon: , }, { title: "Authentication", - href: `/{orgId}/settings/resources/{resourceId}/authentication`, + href: `/{orgId}/settings/resources/{resourceId}/authentication` // icon: , - }, + } ]; return ( diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b4abbad3..02a9daba 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -41,7 +41,7 @@ export default async function RootLayout({ {/* Footer */}