Skip to content

Commit 1a4d34a

Browse files
Merge pull request #1172 from fosrl/dev
1.8.0
2 parents d95286d + bb15af9 commit 1a4d34a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+3075
-895
lines changed

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ _Pangolin tunnels your services to the internet so you can access anything from
4242
</strong>
4343
</p>
4444

45-
<p align="center">
46-
<a href='https://www.ycombinator.com/launches/O0B-pangolin-open-source-secure-gateway-to-private-networks' target="_blank"><img src='https://www.ycombinator.com/launches/O0B-pangolin-open-source-secure-gateway-to-private-networks/upvote_embed.svg' alt='Launch YC: Pangolin – Open-source secure gateway to private networks'/ ></a>
47-
</p>
48-
4945
Pangolin is a self-hosted tunneled reverse proxy server with identity and access control, designed to securely expose private resources on distributed networks. Acting as a central hub, it connects isolated networks — even those behind restrictive firewalls — through encrypted tunnels, enabling easy access to remote services without opening ports.
5046

5147
<img src="public/screenshots/hero.png" alt="Preview"/>

docker-compose.example.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ services:
3131
- SYS_MODULE
3232
ports:
3333
- 51820:51820/udp
34+
- 21820:21820/udp
3435
- 443:443 # Port for traefik because of the network_mode
3536
- 80:80 # Port for traefik because of the network_mode
3637

install/config/config.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ gerbil:
2222
start_port: 51820
2323
base_endpoint: "{{.DashboardDomain}}"
2424

25-
orgs:
26-
block_size: 24
27-
subnet_group: 100.89.138.0/20
28-
2925
{{if .EnableEmail}}
3026
email:
3127
smtp_host: "{{.EmailSMTPHost}}"

install/config/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ services:
3131
- SYS_MODULE
3232
ports:
3333
- 51820:51820/udp
34+
- 21820:21820/udp
3435
- 443:443 # Port for traefik because of the network_mode
3536
- 80:80 # Port for traefik because of the network_mode
3637
{{end}}

install/main.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,23 @@ const (
6060
)
6161

6262
func main() {
63+
64+
// print a banner about prerequisites - opening port 80, 443, 51820, and 21820 on the VPS and firewall and pointing your domain to the VPS IP with a records. Docs are at http://localhost:3000/Getting%20Started/dns-networking
65+
66+
fmt.Println("Welcome to the Pangolin installer!")
67+
fmt.Println("This installer will help you set up Pangolin on your server.")
68+
fmt.Println("")
69+
fmt.Println("Please make sure you have the following prerequisites:")
70+
fmt.Println("- Open TCP ports 80 and 443 and UDP ports 51820 and 21820 on your VPS and firewall.")
71+
fmt.Println("- Point your domain to the VPS IP with A records.")
72+
fmt.Println("")
73+
fmt.Println("http://docs.fossorial.io/Getting%20Started/dns-networking")
74+
fmt.Println("")
75+
fmt.Println("Lets get started!")
76+
fmt.Println("")
77+
6378
reader := bufio.NewReader(os.Stdin)
64-
inputContainer := readString(reader, "Would you like to run Pangolin as docker or podman container?", "docker")
79+
inputContainer := readString(reader, "Would you like to run Pangolin as Docker or Podman containers?", "docker")
6580

6681
chosenContainer := Docker
6782
if strings.EqualFold(inputContainer, "docker") {

messages/en-US.json

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
"siteErrorCreate": "Error creating site",
6060
"siteErrorCreateKeyPair": "Key pair or site defaults not found",
6161
"siteErrorCreateDefaults": "Site defaults not found",
62-
"siteNameDescription": "This is the display name for the site.",
6362
"method": "Method",
6463
"siteMethodDescription": "This is how you will expose connections.",
6564
"siteLearnNewt": "Learn how to install Newt on your system",
@@ -1094,7 +1093,7 @@
10941093
"sidebarAllUsers": "All Users",
10951094
"sidebarIdentityProviders": "Identity Providers",
10961095
"sidebarLicense": "License",
1097-
"sidebarClients": "Clients",
1096+
"sidebarClients": "Clients (Beta)",
10981097
"sidebarDomains": "Domains",
10991098
"enableDockerSocket": "Enable Docker Socket",
11001099
"enableDockerSocketDescription": "Enable Docker Socket discovery for populating container information. Socket path must be provided to Newt.",
@@ -1196,7 +1195,7 @@
11961195
"sidebarExpand": "Expand",
11971196
"newtUpdateAvailable": "Update Available",
11981197
"newtUpdateAvailableInfo": "A new version of Newt is available. Please update to the latest version for the best experience.",
1199-
"domainPickerEnterDomain": "Enter your domain",
1198+
"domainPickerEnterDomain": "Domain",
12001199
"domainPickerPlaceholder": "myapp.example.com, api.v1.mydomain.com, or just myapp",
12011200
"domainPickerDescription": "Enter the full domain of the resource to see available options.",
12021201
"domainPickerDescriptionSaas": "Enter a full domain, subdomain, or just a name to see available options",
@@ -1206,7 +1205,7 @@
12061205
"domainPickerSortAsc": "A-Z",
12071206
"domainPickerSortDesc": "Z-A",
12081207
"domainPickerCheckingAvailability": "Checking availability...",
1209-
"domainPickerNoMatchingDomains": "No matching domains found for \"{userInput}\". Try a different domain or check your organization's domain settings.",
1208+
"domainPickerNoMatchingDomains": "No matching domains found. Try a different domain or check your organization's domain settings.",
12101209
"domainPickerOrganizationDomains": "Organization Domains",
12111210
"domainPickerProvidedDomains": "Provided Domains",
12121211
"domainPickerSubdomain": "Subdomain: {subdomain}",
@@ -1274,5 +1273,50 @@
12741273
"createDomainDnsPropagation": "DNS Propagation",
12751274
"createDomainDnsPropagationDescription": "DNS changes may take some time to propagate across the internet. This can take anywhere from a few minutes to 48 hours, depending on your DNS provider and TTL settings.",
12761275
"resourcePortRequired": "Port number is required for non-HTTP resources",
1277-
"resourcePortNotAllowed": "Port number should not be set for HTTP resources"
1276+
"resourcePortNotAllowed": "Port number should not be set for HTTP resources",
1277+
"signUpTerms": {
1278+
"IAgreeToThe": "I agree to the",
1279+
"termsOfService": "terms of service",
1280+
"and": "and",
1281+
"privacyPolicy": "privacy policy"
1282+
},
1283+
"siteRequired": "Site is required.",
1284+
"olmTunnel": "Olm Tunnel",
1285+
"olmTunnelDescription": "Use Olm for client connectivity",
1286+
"errorCreatingClient": "Error creating client",
1287+
"clientDefaultsNotFound": "Client defaults not found",
1288+
"createClient": "Create Client",
1289+
"createClientDescription": "Create a new client for connecting to your sites",
1290+
"seeAllClients": "See All Clients",
1291+
"clientInformation": "Client Information",
1292+
"clientNamePlaceholder": "Client name",
1293+
"address": "Address",
1294+
"subnetPlaceholder": "Subnet",
1295+
"addressDescription": "The address that this client will use for connectivity",
1296+
"selectSites": "Select sites",
1297+
"sitesDescription": "The client will have connectivity to the selected sites",
1298+
"clientInstallOlm": "Install Olm",
1299+
"clientInstallOlmDescription": "Get Olm running on your system",
1300+
"clientOlmCredentials": "Olm Credentials",
1301+
"clientOlmCredentialsDescription": "This is how Olm will authenticate with the server",
1302+
"olmEndpoint": "Olm Endpoint",
1303+
"olmId": "Olm ID",
1304+
"olmSecretKey": "Olm Secret Key",
1305+
"clientCredentialsSave": "Save Your Credentials",
1306+
"clientCredentialsSaveDescription": "You will only be able to see this once. Make sure to copy it to a secure place.",
1307+
"generalSettingsDescription": "Configure the general settings for this client",
1308+
"clientUpdated": "Client updated",
1309+
"clientUpdatedDescription": "The client has been updated.",
1310+
"clientUpdateFailed": "Failed to update client",
1311+
"clientUpdateError": "An error occurred while updating the client.",
1312+
"sitesFetchFailed": "Failed to fetch sites",
1313+
"sitesFetchError": "An error occurred while fetching sites.",
1314+
"olmErrorFetchReleases": "An error occurred while fetching Olm releases.",
1315+
"olmErrorFetchLatest": "An error occurred while fetching the latest Olm release.",
1316+
"remoteSubnets": "Remote Subnets",
1317+
"enterCidrRange": "Enter CIDR range",
1318+
"remoteSubnetsDescription": "Add CIDR ranges that can access this site remotely. Use format like 10.0.0.0/24 or 192.168.1.0/24.",
1319+
"resourceEnableProxy": "Enable Public Proxy",
1320+
"resourceEnableProxyDescription": "Enable public proxying to this resource. This allows access to the resource from outside the network through the cloud on an open port. Requires Traefik config.",
1321+
"externalProxyEnabled": "External Proxy Enabled"
12781322
}

server/db/pg/schema.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
boolean,
66
integer,
77
bigint,
8-
real
8+
real,
9+
text
910
} from "drizzle-orm/pg-core";
1011
import { InferSelectModel } from "drizzle-orm";
1112

@@ -58,7 +59,8 @@ export const sites = pgTable("sites", {
5859
publicKey: varchar("publicKey"),
5960
lastHolePunch: bigint("lastHolePunch", { mode: "number" }),
6061
listenPort: integer("listenPort"),
61-
dockerSocketEnabled: boolean("dockerSocketEnabled").notNull().default(true)
62+
dockerSocketEnabled: boolean("dockerSocketEnabled").notNull().default(true),
63+
remoteSubnets: text("remoteSubnets") // comma-separated list of subnets that this site can access
6264
});
6365

6466
export const resources = pgTable("resources", {
@@ -92,7 +94,8 @@ export const resources = pgTable("resources", {
9294
enabled: boolean("enabled").notNull().default(true),
9395
stickySession: boolean("stickySession").notNull().default(false),
9496
tlsServerName: varchar("tlsServerName"),
95-
setHostHeader: varchar("setHostHeader")
97+
setHostHeader: varchar("setHostHeader"),
98+
enableProxy: boolean("enableProxy").default(true),
9699
});
97100

98101
export const targets = pgTable("targets", {
@@ -135,6 +138,8 @@ export const users = pgTable("user", {
135138
twoFactorSecret: varchar("twoFactorSecret"),
136139
emailVerified: boolean("emailVerified").notNull().default(false),
137140
dateCreated: varchar("dateCreated").notNull(),
141+
termsAcceptedTimestamp: varchar("termsAcceptedTimestamp"),
142+
termsVersion: varchar("termsVersion"),
138143
serverAdmin: boolean("serverAdmin").notNull().default(false)
139144
});
140145

@@ -504,8 +509,8 @@ export const clients = pgTable("clients", {
504509
name: varchar("name").notNull(),
505510
pubKey: varchar("pubKey"),
506511
subnet: varchar("subnet").notNull(),
507-
megabytesIn: integer("bytesIn"),
508-
megabytesOut: integer("bytesOut"),
512+
megabytesIn: real("bytesIn"),
513+
megabytesOut: real("bytesOut"),
509514
lastBandwidthUpdate: varchar("lastBandwidthUpdate"),
510515
lastPing: varchar("lastPing"),
511516
type: varchar("type").notNull(), // "olm"
@@ -539,7 +544,7 @@ export const olmSessions = pgTable("clientSession", {
539544
olmId: varchar("olmId")
540545
.notNull()
541546
.references(() => olms.olmId, { onDelete: "cascade" }),
542-
expiresAt: integer("expiresAt").notNull()
547+
expiresAt: bigint("expiresAt", { mode: "number" }).notNull()
543548
});
544549

545550
export const userClients = pgTable("userClients", {
@@ -562,9 +567,11 @@ export const roleClients = pgTable("roleClients", {
562567

563568
export const securityKeys = pgTable("webauthnCredentials", {
564569
credentialId: varchar("credentialId").primaryKey(),
565-
userId: varchar("userId").notNull().references(() => users.userId, {
566-
onDelete: "cascade"
567-
}),
570+
userId: varchar("userId")
571+
.notNull()
572+
.references(() => users.userId, {
573+
onDelete: "cascade"
574+
}),
568575
publicKey: varchar("publicKey").notNull(),
569576
signCount: integer("signCount").notNull(),
570577
transports: varchar("transports"),

server/db/sqlite/schema.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ export const sites = sqliteTable("sites", {
6565
listenPort: integer("listenPort"),
6666
dockerSocketEnabled: integer("dockerSocketEnabled", { mode: "boolean" })
6767
.notNull()
68-
.default(true)
68+
.default(true),
69+
remoteSubnets: text("remoteSubnets"), // comma-separated list of subnets that this site can access
6970
});
7071

7172
export const resources = sqliteTable("resources", {
@@ -105,7 +106,8 @@ export const resources = sqliteTable("resources", {
105106
.notNull()
106107
.default(false),
107108
tlsServerName: text("tlsServerName"),
108-
setHostHeader: text("setHostHeader")
109+
setHostHeader: text("setHostHeader"),
110+
enableProxy: integer("enableProxy", { mode: "boolean" }).default(true),
109111
});
110112

111113
export const targets = sqliteTable("targets", {
@@ -154,6 +156,8 @@ export const users = sqliteTable("user", {
154156
.notNull()
155157
.default(false),
156158
dateCreated: text("dateCreated").notNull(),
159+
termsAcceptedTimestamp: text("termsAcceptedTimestamp"),
160+
termsVersion: text("termsVersion"),
157161
serverAdmin: integer("serverAdmin", { mode: "boolean" })
158162
.notNull()
159163
.default(false)

server/lib/consts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import path from "path";
22
import { fileURLToPath } from "url";
33

44
// This is a placeholder value replaced by the build process
5-
export const APP_VERSION = "1.7.3";
5+
export const APP_VERSION = "1.8.0";
66

77
export const __FILENAME = fileURLToPath(import.meta.url);
88
export const __DIRNAME = path.dirname(__FILENAME);

0 commit comments

Comments
 (0)