From 34b5e7a2e88d0795a0651c6b9aa1affc5578b165 Mon Sep 17 00:00:00 2001 From: Sander Bruens Date: Fri, 14 Feb 2025 16:51:07 -0500 Subject: [PATCH 01/23] chore: remove lastConnected property and update OpenAPI spec (#1639) * chore: remove `lastConnected` property * Update OpenAPI spec. --- src/shadowbox/server/api.yml | 90 +++++++++++++++----- src/shadowbox/server/manager_metrics.spec.ts | 3 - src/shadowbox/server/manager_metrics.ts | 4 - 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/src/shadowbox/server/api.yml b/src/shadowbox/server/api.yml index 7a7cc025..2532d51c 100644 --- a/src/shadowbox/server/api.yml +++ b/src/shadowbox/server/api.yml @@ -146,46 +146,94 @@ paths: type: object properties: server: - type: array - items: - type: object - properties: - location: - type: string - asn: - type: number - asOrg: - type: string - tunnelTime: + type: object + properties: + tunnelTime: + type: object + properties: + seconds: + type: number + dataTransferred: + type: object + properties: + bytes: + type: number + bandwidth: + type: object + properties: + current: + type: object + properties: + data: + type: object + properties: + bytes: + type: number + timestamp: + type: integer + peak: + type: object + properties: + data: + type: object + properties: + bytes: + type: number + timestamp: + type: integer + locations: + type: array + items: type: object properties: - seconds: - type: number - dataTransferred: - type: object - properties: - bytes: + location: + type: string + asn: type: number + asOrg: + type: string + tunnelTime: + type: object + properties: + seconds: + type: number + dataTransferred: + type: object + properties: + bytes: + type: number accessKeys: type: array items: type: object properties: accessKeyId: - type: string + type: integer tunnelTime: type: object properties: - seconds: + seconds: type: number dataTransferred: type: object properties: - bytes: + bytes: type: number + connection: + type: object + properties: + lastTrafficSeen: + type: number + peakDeviceCount: + type: object + properties: + data: + type: integer + timestamp: + type: integer examples: '0': - value: '{"server":[{"location":"US","asn":null,"asOrg":null,"tunnelTime":{"seconds":100},"dataTransferred":{"bytes":100}}],"accessKeys":[{"accessKeyId":"0","tunnelTime":{"seconds":100},"dataTransferred":{"bytes":100}}]}' + value: '{"server":{"tunnelTime":{"seconds":100},"dataTransferred":{"bytes":100},"bandwidth": {"current": {"data": {"bytes": 10},"timestamp": 1739284734},"peak": {"data": {"bytes": 80},"timestamp": 1738959398}},"locations": [{"location": "US","asn": null,"asOrg": null,"dataTransferred": {"bytes": 100},"tunnelTime": {"seconds": 100}}]},"accessKeys":[{"accessKeyId":0,"tunnelTime":{"seconds":100},"dataTransferred":{"bytes":100},"connection": {"lastTrafficSeen": 1739284734,"peakDeviceCount": {"data": 4,"timestamp": 1738959398}}}]}' /name: put: description: Renames the server diff --git a/src/shadowbox/server/manager_metrics.spec.ts b/src/shadowbox/server/manager_metrics.spec.ts index 4532224f..ed3107ff 100644 --- a/src/shadowbox/server/manager_metrics.spec.ts +++ b/src/shadowbox/server/manager_metrics.spec.ts @@ -202,7 +202,6 @@ describe('PrometheusManagerMetrics', () => { "seconds": 1000 }, "connection": { - "lastConnected": 1738959398, "lastTrafficSeen": 1739284734, "peakDeviceCount": { "data": 4, @@ -389,7 +388,6 @@ describe('PrometheusManagerMetrics', () => { "seconds": 1000 }, "connection": { - "lastConnected": null, "lastTrafficSeen": null, "peakDeviceCount": { "data": 0, @@ -406,7 +404,6 @@ describe('PrometheusManagerMetrics', () => { "seconds": 0 }, "connection": { - "lastConnected": 1738959398, "lastTrafficSeen": 1738959398, "peakDeviceCount": { "data": 4, diff --git a/src/shadowbox/server/manager_metrics.ts b/src/shadowbox/server/manager_metrics.ts index 5c07dbe1..3969ac39 100644 --- a/src/shadowbox/server/manager_metrics.ts +++ b/src/shadowbox/server/manager_metrics.ts @@ -35,7 +35,6 @@ interface TimedData { } interface ConnectionStats { - lastConnected: number | null; lastTrafficSeen: number | null; peakDeviceCount: TimedData; } @@ -211,8 +210,6 @@ export class PrometheusManagerMetrics implements ManagerMetrics { } for (const result of tunnelTimeByAccessKeyRange.result) { const entry = getServerMetricsAccessKeyEntry(accessKeyMap, result.metric); - const lastConnected = findLastNonZero(result.values ?? []); - entry.connection.lastConnected = lastConnected ? Math.min(now, lastConnected[0]) : null; const peakTunnelTimeSec = findPeak(result.values ?? []); if (peakTunnelTimeSec !== null) { const peakValue = parseFloat(peakTunnelTimeSec[1]); @@ -268,7 +265,6 @@ function getServerMetricsAccessKeyEntry( dataTransferred: {bytes: 0}, tunnelTime: {seconds: 0}, connection: { - lastConnected: null, lastTrafficSeen: null, peakDeviceCount: { data: 0, From 47f24520d30646f508841e499e3a658318257286 Mon Sep 17 00:00:00 2001 From: Sander Bruens Date: Wed, 19 Feb 2025 08:54:25 -0500 Subject: [PATCH 02/23] fix(server): set empty IP to bind on all available networks (#1640) * fix(server): set empty IP to bind on all available networks * upgrade `outline-ss-server` --- go.mod | 20 ++++++----- go.sum | 36 +++++++++++-------- .../server/outline_shadowsocks_server.ts | 7 ++-- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index 1228b069..49855d17 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,16 @@ module localhost -go 1.21 +go 1.22 require ( - github.com/Jigsaw-Code/outline-ss-server v1.7.3 + github.com/Jigsaw-Code/outline-ss-server v1.9.2-0.20250218165321-888b9dcbdf1c github.com/go-task/task/v3 v3.36.0 github.com/google/addlicense v1.1.1 ) require ( - github.com/Jigsaw-Code/outline-sdk v0.0.14 // indirect + github.com/Jigsaw-Code/outline-sdk v0.0.18-0.20241106233708-faffebb12629 // indirect + github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20250130222646-80b6430a1fc8 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect @@ -17,7 +18,10 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.16.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/lmittmann/tint v1.0.5 // indirect @@ -37,11 +41,11 @@ require ( github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect mvdan.cc/sh/v3 v3.8.0 // indirect ) diff --git a/go.sum b/go.sum index 84be92e3..a7475566 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,9 @@ -github.com/Jigsaw-Code/outline-sdk v0.0.14 h1:uJLvIne7YJNolbX7KDacd8gLidrUzRuweBO2APmQEmI= -github.com/Jigsaw-Code/outline-sdk v0.0.14/go.mod h1:9cEaF6sWWMzY8orcUI9pV5D0oFp2FZArTSyJiYtMQQs= -github.com/Jigsaw-Code/outline-ss-server v1.7.3 h1:UF8AaOV2agRb6edF0U0CtTcwpyIxm6NVDa5QLkQh28E= -github.com/Jigsaw-Code/outline-ss-server v1.7.3/go.mod h1:cKPicPWlLWZKJfkQ3CBpQm8a3gXrA2+dpQvsECqBVz8= +github.com/Jigsaw-Code/outline-sdk v0.0.18-0.20241106233708-faffebb12629 h1:sHi1X4vwtNNBUDCbxynGXe7cM/inwTbavowHziaxlbk= +github.com/Jigsaw-Code/outline-sdk v0.0.18-0.20241106233708-faffebb12629/go.mod h1:CFDKyGZA4zatKE4vMLe8TyQpZCyINOeRFbMAmYHxodw= +github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20250130222646-80b6430a1fc8 h1:TsWEVm5XU/SalHlZ6VztE9YwHmN0akCgbWFgQ0j7Mys= +github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20250130222646-80b6430a1fc8/go.mod h1:aFUEz6Z/eD0NS3c3fEIX+JO2D9aIrXCmWTb1zJFlItw= +github.com/Jigsaw-Code/outline-ss-server v1.9.2-0.20250218165321-888b9dcbdf1c h1:e8G2DgRGZmhJCgrJw//+IQYkBckmGA4ZeOP4GjkQEDw= +github.com/Jigsaw-Code/outline-ss-server v1.9.2-0.20250218165321-888b9dcbdf1c/go.mod h1:ArtQJ43aUTB5r1gr27E6aMj4nDOZz5vG4WY4NNKJ6ZM= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -22,6 +24,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-task/task/v3 v3.36.0 h1:XVJ5hQ5hdzTAulHpAGzbUMUuYr9MUOEQFOFazI3hUsY= github.com/go-task/task/v3 v3.36.0/go.mod h1:XBCIAzuyG/mgZVHMUm3cCznz4+IpsBQRlW1gw7OA5sA= +github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= +github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -32,6 +36,10 @@ github.com/google/addlicense v1.1.1/go.mod h1:Sm/DHu7Jk+T5miFHHehdIjbi4M5+dJDRS3 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= @@ -91,28 +99,28 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/src/shadowbox/server/outline_shadowsocks_server.ts b/src/shadowbox/server/outline_shadowsocks_server.ts index 1abe1b2c..ab60e451 100644 --- a/src/shadowbox/server/outline_shadowsocks_server.ts +++ b/src/shadowbox/server/outline_shadowsocks_server.ts @@ -113,8 +113,11 @@ export class OutlineShadowsocksServer implements ShadowsocksServer { for (const port in keysByPort) { const service = { listeners: [ - {type: 'tcp', address: `[::]:${port}`}, - {type: 'udp', address: `[::]:${port}`}, + // NOTE: We explicitly specify the address string with only the port + // number. This will result in an address that listens on all + // available network interfaces (both IPv4 and IPv6). + {type: 'tcp', address: `:${port}`}, + {type: 'udp', address: `:${port}`}, ], keys: keysByPort[port].map((key) => ({ id: key.id, From 15a9e54e5e2d36d2001e3ecf375faf43c98baf0a Mon Sep 17 00:00:00 2001 From: Sander Bruens Date: Fri, 21 Feb 2025 16:15:14 -0500 Subject: [PATCH 03/23] refactor(server): use a reusable `http.Agent` (#1644) --- src/shadowbox/infrastructure/prometheus_scraper.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/shadowbox/infrastructure/prometheus_scraper.ts b/src/shadowbox/infrastructure/prometheus_scraper.ts index 5cfe4064..af9ebad5 100644 --- a/src/shadowbox/infrastructure/prometheus_scraper.ts +++ b/src/shadowbox/infrastructure/prometheus_scraper.ts @@ -102,12 +102,17 @@ export interface PrometheusClient { } export class ApiPrometheusClient implements PrometheusClient { - constructor(private address: string) {} + private readonly agent: http.Agent; + + constructor(private address: string) { + this.agent = new http.Agent({ keepAlive: true }); + } private request(url: string): Promise { return new Promise((fulfill, reject) => { + const options = {agent: this.agent}; http - .get(url, (response) => { + .get(url, options, (response) => { if (response.statusCode < 200 || response.statusCode > 299) { reject(new Error(`Got error ${response.statusCode}`)); response.resume(); From d262f5242f5385d41578af9a47de68e31b83d5ad Mon Sep 17 00:00:00 2001 From: Daniel LaCosse <3759828+daniellacosse@users.noreply.github.com> Date: Fri, 21 Feb 2025 17:00:59 -0500 Subject: [PATCH 04/23] feat: cache recent prometheus queries in memory (#1643) * [DO NOT MERGE] prometheus query timer * add cache layer * add query result data * ready for a look * remove logger --- src/shadowbox/server/manager_metrics.ts | 54 +++++++++++++++++++++---- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/src/shadowbox/server/manager_metrics.ts b/src/shadowbox/server/manager_metrics.ts index 3969ac39..7cbc90ff 100644 --- a/src/shadowbox/server/manager_metrics.ts +++ b/src/shadowbox/server/manager_metrics.ts @@ -16,6 +16,7 @@ import { PrometheusClient, PrometheusMetric, PrometheusValue, + QueryResultData, } from '../infrastructure/prometheus_scraper'; import {DataUsageByUser, DataUsageTimeframe} from '../model/metrics'; @@ -111,6 +112,8 @@ export class PrometheusManagerMetrics implements ManagerMetrics { Math.ceil(now / PROMETHEUS_RANGE_QUERY_STEP_SECONDS) * PROMETHEUS_RANGE_QUERY_STEP_SECONDS; const start = end - timeframe.seconds; + this.prunePrometheusCache(); + const [ bandwidth, bandwidthRange, @@ -121,34 +124,34 @@ export class PrometheusManagerMetrics implements ManagerMetrics { dataTransferredByAccessKeyRange, tunnelTimeByAccessKeyRange, ] = await Promise.all([ - this.prometheusClient.query( + this.cachedPrometheusClient.query( `sum(rate(shadowsocks_data_bytes_per_location{dir=~"ct"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s]))` ), - this.prometheusClient.queryRange( + this.cachedPrometheusClient.queryRange( `sum(rate(shadowsocks_data_bytes_per_location{dir=~"ct"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s]))`, start, end, `${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s` ), - this.prometheusClient.query( + this.cachedPrometheusClient.query( `sum(increase(shadowsocks_data_bytes_per_location{dir=~"ct"}[${timeframe.seconds}s])) by (location, asn, asorg)` ), - this.prometheusClient.query( + this.cachedPrometheusClient.query( `sum(increase(shadowsocks_tunnel_time_seconds_per_location[${timeframe.seconds}s])) by (location, asn, asorg)` ), - this.prometheusClient.query( + this.cachedPrometheusClient.query( `sum(increase(shadowsocks_data_bytes{dir=~"ct"}[${timeframe.seconds}s])) by (access_key)` ), - this.prometheusClient.query( + this.cachedPrometheusClient.query( `sum(increase(shadowsocks_tunnel_time_seconds[${timeframe.seconds}s])) by (access_key)` ), - this.prometheusClient.queryRange( + this.cachedPrometheusClient.queryRange( `sum(increase(shadowsocks_data_bytes{dir=~"ct"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s])) by (access_key)`, start, end, `${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s` ), - this.prometheusClient.queryRange( + this.cachedPrometheusClient.queryRange( `sum(increase(shadowsocks_tunnel_time_seconds[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s])) by (access_key)`, start, end, @@ -231,6 +234,41 @@ export class PrometheusManagerMetrics implements ManagerMetrics { accessKeys: Array.from(accessKeyMap.values()), }; } + + private prometheusCache = new Map(); + + private get cachedPrometheusClient() { + return new Proxy(this.prometheusClient, { + get: (target, prop) => { + if (typeof target[prop] !== 'function') { + return target[prop]; + } + + return async (query, ...args) => { + const cacheId = `${String(prop)}: ${query} (args: ${args.join(', ')}))`; + + if (this.prometheusCache.has(cacheId)) { + return this.prometheusCache.get(cacheId).result; + } + + const result = await (target[prop] as Function)(query, ...args); + + this.prometheusCache.set(cacheId, {timestamp: Date.now(), result}); + + return result; + }; + }, + }); + } + + private prunePrometheusCache() { + const now = Date.now(); + for (const [key, value] of this.prometheusCache) { + if (now - value.timestamp > PROMETHEUS_RANGE_QUERY_STEP_SECONDS * 1000) { + this.prometheusCache.delete(key); + } + } + } } function getServerMetricsLocationEntry( From 067d0d47aedac94a3888a127fa6c65f2f53b9987 Mon Sep 17 00:00:00 2001 From: Sander Bruens Date: Mon, 24 Feb 2025 18:07:13 -0500 Subject: [PATCH 05/23] revert(server): revert upgrade of `outline-ss-server` version (#1645) * Revert "fix(server): set empty IP to bind on all available networks (#1640)" This reverts commit 47f24520d30646f508841e499e3a658318257286. * Revert "refactor(server): use the new service config format (#1628)" This reverts commit 13f62390bfda8cd0ac9215aad685ae82f82a1270. --- go.mod | 20 ++++---- go.sum | 36 ++++++-------- .../server/outline_shadowsocks_server.ts | 48 +++---------------- 3 files changed, 29 insertions(+), 75 deletions(-) diff --git a/go.mod b/go.mod index 49855d17..1228b069 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,15 @@ module localhost -go 1.22 +go 1.21 require ( - github.com/Jigsaw-Code/outline-ss-server v1.9.2-0.20250218165321-888b9dcbdf1c + github.com/Jigsaw-Code/outline-ss-server v1.7.3 github.com/go-task/task/v3 v3.36.0 github.com/google/addlicense v1.1.1 ) require ( - github.com/Jigsaw-Code/outline-sdk v0.0.18-0.20241106233708-faffebb12629 // indirect - github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20250130222646-80b6430a1fc8 // indirect + github.com/Jigsaw-Code/outline-sdk v0.0.14 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect @@ -18,10 +17,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.16.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 // indirect - github.com/gorilla/websocket v1.5.3 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/lmittmann/tint v1.0.5 // indirect @@ -41,11 +37,11 @@ require ( github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.23.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect mvdan.cc/sh/v3 v3.8.0 // indirect ) diff --git a/go.sum b/go.sum index a7475566..84be92e3 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ -github.com/Jigsaw-Code/outline-sdk v0.0.18-0.20241106233708-faffebb12629 h1:sHi1X4vwtNNBUDCbxynGXe7cM/inwTbavowHziaxlbk= -github.com/Jigsaw-Code/outline-sdk v0.0.18-0.20241106233708-faffebb12629/go.mod h1:CFDKyGZA4zatKE4vMLe8TyQpZCyINOeRFbMAmYHxodw= -github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20250130222646-80b6430a1fc8 h1:TsWEVm5XU/SalHlZ6VztE9YwHmN0akCgbWFgQ0j7Mys= -github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20250130222646-80b6430a1fc8/go.mod h1:aFUEz6Z/eD0NS3c3fEIX+JO2D9aIrXCmWTb1zJFlItw= -github.com/Jigsaw-Code/outline-ss-server v1.9.2-0.20250218165321-888b9dcbdf1c h1:e8G2DgRGZmhJCgrJw//+IQYkBckmGA4ZeOP4GjkQEDw= -github.com/Jigsaw-Code/outline-ss-server v1.9.2-0.20250218165321-888b9dcbdf1c/go.mod h1:ArtQJ43aUTB5r1gr27E6aMj4nDOZz5vG4WY4NNKJ6ZM= +github.com/Jigsaw-Code/outline-sdk v0.0.14 h1:uJLvIne7YJNolbX7KDacd8gLidrUzRuweBO2APmQEmI= +github.com/Jigsaw-Code/outline-sdk v0.0.14/go.mod h1:9cEaF6sWWMzY8orcUI9pV5D0oFp2FZArTSyJiYtMQQs= +github.com/Jigsaw-Code/outline-ss-server v1.7.3 h1:UF8AaOV2agRb6edF0U0CtTcwpyIxm6NVDa5QLkQh28E= +github.com/Jigsaw-Code/outline-ss-server v1.7.3/go.mod h1:cKPicPWlLWZKJfkQ3CBpQm8a3gXrA2+dpQvsECqBVz8= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -24,8 +22,6 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-task/task/v3 v3.36.0 h1:XVJ5hQ5hdzTAulHpAGzbUMUuYr9MUOEQFOFazI3hUsY= github.com/go-task/task/v3 v3.36.0/go.mod h1:XBCIAzuyG/mgZVHMUm3cCznz4+IpsBQRlW1gw7OA5sA= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -36,10 +32,6 @@ github.com/google/addlicense v1.1.1/go.mod h1:Sm/DHu7Jk+T5miFHHehdIjbi4M5+dJDRS3 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= -github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= @@ -99,28 +91,28 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/src/shadowbox/server/outline_shadowsocks_server.ts b/src/shadowbox/server/outline_shadowsocks_server.ts index ab60e451..e7c40370 100644 --- a/src/shadowbox/server/outline_shadowsocks_server.ts +++ b/src/shadowbox/server/outline_shadowsocks_server.ts @@ -21,26 +21,12 @@ import * as file from '../infrastructure/file'; import * as logging from '../infrastructure/logging'; import {ShadowsocksAccessKey, ShadowsocksServer} from '../model/shadowsocks_server'; -/** Represents an outline-ss-server configuration with multiple services. */ -export interface OutlineSSServerConfig { - services: { - listeners: { - type: string; - address: string; - }[]; - keys: { - id: string; - cipher: string; - secret: string; - }[]; - }[]; -} - // Runs outline-ss-server. export class OutlineShadowsocksServer implements ShadowsocksServer { private ssProcess: child_process.ChildProcess; private ipCountryFilename?: string; private ipAsnFilename?: string; + private isAsnMetricsEnabled = false; private isReplayProtectionEnabled = false; /** @@ -95,42 +81,22 @@ export class OutlineShadowsocksServer implements ShadowsocksServer { private writeConfigFile(keys: ShadowsocksAccessKey[]): Promise { return new Promise((resolve, reject) => { - const validKeys: ShadowsocksAccessKey[] = keys.filter((key) => { + const keysJson = {keys: [] as ShadowsocksAccessKey[]}; + for (const key of keys) { if (!isAeadCipher(key.cipher)) { logging.error( `Cipher ${key.cipher} for access key ${key.id} is not supported: use an AEAD cipher instead.` ); - return false; + continue; } - return true; - }); - const config: OutlineSSServerConfig = {services: []}; - const keysByPort: Record = {}; - for (const key of validKeys) { - (keysByPort[key.port] ??= []).push(key); - } - for (const port in keysByPort) { - const service = { - listeners: [ - // NOTE: We explicitly specify the address string with only the port - // number. This will result in an address that listens on all - // available network interfaces (both IPv4 and IPv6). - {type: 'tcp', address: `:${port}`}, - {type: 'udp', address: `:${port}`}, - ], - keys: keysByPort[port].map((key) => ({ - id: key.id, - cipher: key.cipher, - secret: key.secret, - })), - }; - config.services.push(service); + keysJson.keys.push(key); } mkdirp.sync(path.dirname(this.configFilename)); + try { - file.atomicWriteFileSync(this.configFilename, jsyaml.safeDump(config, {sortKeys: true})); + file.atomicWriteFileSync(this.configFilename, jsyaml.safeDump(keysJson, {sortKeys: true})); resolve(); } catch (error) { reject(error); From d9aa8560ceb8a718fa25eec2d05696c1ac2d0031 Mon Sep 17 00:00:00 2001 From: Sander Bruens Date: Tue, 4 Mar 2025 20:24:13 -0500 Subject: [PATCH 06/23] ci(sentry_webhook): pin Ubuntu due to Chromium bug (via Puppeteer) (#1652) --- .github/workflows/build_and_test_debug.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index 39bd1af0..fff4e8c1 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -119,7 +119,8 @@ jobs: sentry-webhook: name: Sentry Webhook - runs-on: ubuntu-latest + # TODO(puppeteer/puppeteer#12818): Update when chromium bug is resolved. + runs-on: ubuntu-22.04 needs: lint steps: - name: Checkout From 9013feafa7a331b6fe5c3e5c9a8661ff3ec32776 Mon Sep 17 00:00:00 2001 From: Sander Bruens Date: Mon, 10 Mar 2025 14:25:18 -0400 Subject: [PATCH 07/23] chore(server): set `Content-Type` header (#1651) --- src/shadowbox/server/main.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shadowbox/server/main.ts b/src/shadowbox/server/main.ts index 8f52c18d..533f9f43 100644 --- a/src/shadowbox/server/main.ts +++ b/src/shadowbox/server/main.ts @@ -48,6 +48,7 @@ const MMDB_LOCATION_ASN = '/var/lib/libmaxminddb/ip-asn.mmdb'; async function exportPrometheusMetrics(registry: prometheus.Registry, port): Promise { return new Promise((resolve, _) => { const server = http.createServer((_, res) => { + res.setHeader('Content-Type', registry.contentType); res.write(registry.metrics()); res.end(); }); From 9dbfc44a06f656d659ef40112852e20280c262cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 13:23:27 -0400 Subject: [PATCH 08/23] chore: bump golang.org/x/crypto from 0.18.0 to 0.31.0 (#1625) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.18.0 to 0.31.0. - [Commits](https://github.com/golang/crypto/compare/v0.18.0...v0.31.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 1228b069..d519122e 100644 --- a/go.mod +++ b/go.mod @@ -37,10 +37,10 @@ require ( github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - golang.org/x/crypto v0.18.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect mvdan.cc/sh/v3 v3.8.0 // indirect diff --git a/go.sum b/go.sum index 84be92e3..96578b72 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -102,11 +102,11 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= From 0bfa80262c4de942771f2318b8b1732e8836e869 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 14:03:06 -0400 Subject: [PATCH 09/23] chore: bump braces from 3.0.2 to 3.0.3 (#1559) Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 232 +++++++++++++++++----------------------------- 1 file changed, 84 insertions(+), 148 deletions(-) diff --git a/package-lock.json b/package-lock.json index b4d82a70..f38ece7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1891,6 +1891,19 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { "version": "4.22.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", @@ -3819,6 +3832,19 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "1.1.2", "dev": true, @@ -4774,6 +4800,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", @@ -5210,17 +5246,6 @@ "node": ">=8" } }, - "node_modules/karma/node_modules/braces": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/karma/node_modules/chokidar": { "version": "3.5.3", "dev": true, @@ -5247,17 +5272,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/karma/node_modules/fill-range": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/karma/node_modules/fsevents": { "version": "2.3.2", "dev": true, @@ -5292,14 +5306,6 @@ "node": ">=8" } }, - "node_modules/karma/node_modules/is-number": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/karma/node_modules/readdirp": { "version": "3.6.0", "dev": true, @@ -5325,17 +5331,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/karma/node_modules/to-regex-range": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5614,51 +5609,6 @@ "node": ">=8.6" } }, - "node_modules/micromatch/node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/micromatch/node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/micromatch/node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/micromatch/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/mime": { "version": "2.6.0", "dev": true, @@ -8131,6 +8081,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "license": "MIT", @@ -9056,7 +9019,7 @@ "dependencies": { "ip-regex": "^4.1.0", "js-yaml": "^3.12.0", - "outline-shadowsocksconfig": "github:Jigsaw-Code/outline-shadowsocksconfig#v0.2.0", + "outline-shadowsocksconfig": "git+ssh://git@github.com/Jigsaw-Code/outline-shadowsocksconfig.git#add590ed57277653d02dd2031ae301500ae881e1", "prom-client": "^11.1.3", "randomstring": "^1.1.5", "restify": "^11.1.0", @@ -10423,6 +10386,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "requires": { + "fill-range": "^7.1.1" + } + }, "browserslist": { "version": "4.22.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", @@ -11731,6 +11703,15 @@ "flat-cache": "^3.0.4" } }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.1.2", "dev": true, @@ -12352,6 +12333,12 @@ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", @@ -12588,13 +12575,6 @@ "version": "2.2.0", "dev": true }, - "braces": { - "version": "3.0.2", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "chokidar": { "version": "3.5.3", "dev": true, @@ -12609,13 +12589,6 @@ "readdirp": "~3.6.0" } }, - "fill-range": { - "version": "7.0.1", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "fsevents": { "version": "2.3.2", "dev": true, @@ -12635,10 +12608,6 @@ "binary-extensions": "^2.0.0" } }, - "is-number": { - "version": "7.0.0", - "dev": true - }, "readdirp": { "version": "3.6.0", "dev": true, @@ -12652,13 +12621,6 @@ "requires": { "glob": "^7.1.3" } - }, - "to-regex-range": { - "version": "5.0.1", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } } } }, @@ -12926,41 +12888,6 @@ "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } } }, "mime": { @@ -13264,7 +13191,7 @@ "@types/tmp": "^0.2.1", "ip-regex": "^4.1.0", "js-yaml": "^3.12.0", - "outline-shadowsocksconfig": "github:Jigsaw-Code/outline-shadowsocksconfig#v0.2.0", + "outline-shadowsocksconfig": "git+ssh://git@github.com/Jigsaw-Code/outline-shadowsocksconfig.git#add590ed57277653d02dd2031ae301500ae881e1", "prom-client": "^11.1.3", "randomstring": "^1.1.5", "restify": "^11.1.0", @@ -14741,6 +14668,15 @@ } } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.1" }, From 4f59eea8a9a9ce479c59a77d9afea5a89b4e97c5 Mon Sep 17 00:00:00 2001 From: Sander Bruens Date: Fri, 21 Mar 2025 11:58:19 -0400 Subject: [PATCH 10/23] chore(server): update Prometheus to LTS (#1655) * chore(server): update Prometheus to LTS * Add arm64 archives. --- third_party/Taskfile.yml | 12 ++++++------ third_party/prometheus/METADATA | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/third_party/Taskfile.yml b/third_party/Taskfile.yml index a2749545..bdcc6807 100644 --- a/third_party/Taskfile.yml +++ b/third_party/Taskfile.yml @@ -11,17 +11,17 @@ tasks: prometheus:download-*-*: desc: Download and extract prometheus binary vars: - VERSION: '2.37.1' + VERSION: '2.53.4' GOOS: '{{index .MATCH 0}}' GOARCH: '{{index .MATCH 1}}' TEMPFILE: {sh: mktemp} SHA256: '{{printf "%v/%v" .GOOS .GOARCH | get (dict - "linux/amd64" "753f66437597cf52ada98c2f459aa8c03745475c249c9f2b40ac7b3919131ba6" - "linux/arm64" "b59a66fb5c7ec5acf6bf426793528a5789a1478a0dad8c64edc2843caf31b1b8" - "darwin/amd64" "e03a43d98955ac3500f57353ea74b5df829074205f195ea6b3b88f55c4575c79" - "darwin/arm64" "eb8a174c82a0fb6c84e81d9a73214318fb4a605115ad61505d7883d02e5a6f52" - ) + "linux/amd64" "b8b497c4610d1b93208252b60c8f20f6b2e78596ae8df43397a2e805aa53d475" + "linux/arm64" "ec7236ecea7154d0bfe142921708b1ae7b5e921e100e0ee85ab92b7c444357e0" + "darwin/amd64" "10066a1aa21c4ddb8d5e61c31b52e898d8ac42c7e99fd757e2fc4b6c20b8075f" + "darwin/arm64" "cb3e638d8e9b4b27a6aa1f45a4faa3741b548aac67d4649aea7a2fad3c09f0a1" + ) }}' TARGET_DIR: '{{joinPath .OUTPUT_BASE "prometheus" .GOOS .GOARCH}}' TARGET: '{{joinPath .TARGET_DIR "prometheus"}}' diff --git a/third_party/prometheus/METADATA b/third_party/prometheus/METADATA index 6b603f4f..4712de71 100644 --- a/third_party/prometheus/METADATA +++ b/third_party/prometheus/METADATA @@ -10,13 +10,21 @@ third_party { } url { type: ARCHIVE - value: "https://github.com/prometheus/prometheus/releases/download/2.37.1/prometheus-2.37.1.linux-amd64.tar.gz" + value: "https://github.com/prometheus/prometheus/releases/download/v2.53.4/prometheus-2.53.4.linux-amd64.tar.gz" } url { type: ARCHIVE - value: "https://github.com/prometheus/prometheus/releases/download/2.37.1/prometheus-2.37.1.darwin-amd64.tar.gz" + value: "https://github.com/prometheus/prometheus/releases/download/v2.53.4/prometheus-2.53.4.linux-arm64.tar.gz" } - version: "2.37.1" - last_upgrade_date { year: 2022 month: 10 day: 24 } + url { + type: ARCHIVE + value: "https://github.com/prometheus/prometheus/releases/download/v2.53.4/prometheus-2.53.4.darwin-amd64.tar.gz" + } + url { + type: ARCHIVE + value: "https://github.com/prometheus/prometheus/releases/download/v2.53.4/prometheus-2.53.4.darwin-arm64.tar.gz" + } + version: "2.53.4" + last_upgrade_date { year: 2025 month: 3 day: 20 } license_type: PERMISSIVE } From 26803710c9921c91b4cf1435ed15c67cfbf9ca90 Mon Sep 17 00:00:00 2001 From: Daniel LaCosse <3759828+daniellacosse@users.noreply.github.com> Date: Mon, 31 Mar 2025 11:02:33 -0400 Subject: [PATCH 11/23] chore(server): remove bandwidth spot query (#1656) --- src/shadowbox/server/manager_metrics.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/shadowbox/server/manager_metrics.ts b/src/shadowbox/server/manager_metrics.ts index 7cbc90ff..422f1162 100644 --- a/src/shadowbox/server/manager_metrics.ts +++ b/src/shadowbox/server/manager_metrics.ts @@ -115,7 +115,6 @@ export class PrometheusManagerMetrics implements ManagerMetrics { this.prunePrometheusCache(); const [ - bandwidth, bandwidthRange, dataTransferredByLocation, tunnelTimeByLocation, @@ -124,9 +123,6 @@ export class PrometheusManagerMetrics implements ManagerMetrics { dataTransferredByAccessKeyRange, tunnelTimeByAccessKeyRange, ] = await Promise.all([ - this.cachedPrometheusClient.query( - `sum(rate(shadowsocks_data_bytes_per_location{dir=~"ct"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s]))` - ), this.cachedPrometheusClient.queryRange( `sum(rate(shadowsocks_data_bytes_per_location{dir=~"ct"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s]))`, start, @@ -168,13 +164,15 @@ export class PrometheusManagerMetrics implements ManagerMetrics { }, locations: [], }; - for (const result of bandwidth.result) { - if (result.value) { - serverMetrics.bandwidth.current.data.bytes = parseFloat(result.value[1]); - serverMetrics.bandwidth.current.timestamp = result.value[0]; - } - break; // There should only be one result. + + const bandwidthRangeValues = bandwidthRange.result[0].values ?? []; + const currentBandwidth = bandwidthRangeValues[bandwidthRangeValues.length - 1]; + + if (currentBandwidth) { + serverMetrics.bandwidth.current.data.bytes = parseFloat(currentBandwidth[1]); + serverMetrics.bandwidth.current.timestamp = currentBandwidth[0]; } + for (const result of bandwidthRange.result) { const peakDataTransferred = findPeak(result.values ?? []); if (peakDataTransferred !== null) { From 9b44fe58b19d44d1c37dc106e7e0f34e768eed69 Mon Sep 17 00:00:00 2001 From: Sarah Laplante Date: Tue, 6 Jan 2026 13:38:45 +0100 Subject: [PATCH 12/23] update PR name linter --- .github/workflows/pull_request_checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request_checks.yml b/.github/workflows/pull_request_checks.yml index f10203bc..a463c551 100644 --- a/.github/workflows/pull_request_checks.yml +++ b/.github/workflows/pull_request_checks.yml @@ -37,7 +37,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Clone Repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Install Node uses: actions/setup-node@v2.2.0 @@ -49,7 +49,7 @@ jobs: run: npm ci - name: Ensure Commitizen Format - uses: JulienKode/pull-request-name-linter-action@98794a8b815ec05560813c42e55fd8d32d3fd248 + uses: JulienKode/pull-request-name-linter-action@v20.1.0 size_label: name: Change Size Label From 846c0685c34d652b248c5ae22659144e79f48a50 Mon Sep 17 00:00:00 2001 From: Sarah Laplante Date: Tue, 6 Jan 2026 13:43:10 +0100 Subject: [PATCH 13/23] update node version --- .github/workflows/pull_request_checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request_checks.yml b/.github/workflows/pull_request_checks.yml index a463c551..917a34f8 100644 --- a/.github/workflows/pull_request_checks.yml +++ b/.github/workflows/pull_request_checks.yml @@ -40,9 +40,9 @@ jobs: uses: actions/checkout@v4 - name: Install Node - uses: actions/setup-node@v2.2.0 + uses: actions/setup-node@v6.1.0 with: - node-version: 18 + node-version: 24 cache: npm - name: Install NPM Dependencies From 3d2ce1f93e09b704f488e461ed06dd8f772f2f72 Mon Sep 17 00:00:00 2001 From: Sarah Laplante Date: Tue, 6 Jan 2026 14:02:14 +0100 Subject: [PATCH 14/23] revert to node 18 --- .github/workflows/pull_request_checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request_checks.yml b/.github/workflows/pull_request_checks.yml index 917a34f8..3b27ae42 100644 --- a/.github/workflows/pull_request_checks.yml +++ b/.github/workflows/pull_request_checks.yml @@ -42,7 +42,7 @@ jobs: - name: Install Node uses: actions/setup-node@v6.1.0 with: - node-version: 24 + node-version: 18 cache: npm - name: Install NPM Dependencies From 48d336d95baee529fbc41951cf9465b091130367 Mon Sep 17 00:00:00 2001 From: Sarah Laplante Date: Mon, 5 Jan 2026 12:52:11 +0100 Subject: [PATCH 15/23] switch to maintained watchtower fork --- src/server_manager/install_scripts/install_server.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server_manager/install_scripts/install_server.sh b/src/server_manager/install_scripts/install_server.sh index 39ba2b0d..079e6450 100755 --- a/src/server_manager/install_scripts/install_server.sh +++ b/src/server_manager/install_scripts/install_server.sh @@ -376,7 +376,7 @@ function start_watchtower() { -v /var/run/docker.sock:/var/run/docker.sock) # By itself, local messes up the return code. local STDERR_OUTPUT - STDERR_OUTPUT="$(docker run -d "${docker_watchtower_flags[@]}" containrrr/watchtower --cleanup --label-enable --scope=outline --tlsverify --interval "${WATCHTOWER_REFRESH_SECONDS}" 2>&1 >/dev/null)" && return + STDERR_OUTPUT="$(docker run -d "${docker_watchtower_flags[@]}" nicholas-fedor/watchtower --cleanup --label-enable --scope=outline --tlsverify --interval "${WATCHTOWER_REFRESH_SECONDS}" 2>&1 >/dev/null)" && return readonly STDERR_OUTPUT log_error "FAILED" if docker_container_exists watchtower; then From db19f851947498e0a1c819e56ebc0e3e9ddc4da9 Mon Sep 17 00:00:00 2001 From: Sarah Laplante Date: Mon, 5 Jan 2026 13:21:01 +0100 Subject: [PATCH 16/23] switch from github name to container name --- src/server_manager/install_scripts/install_server.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server_manager/install_scripts/install_server.sh b/src/server_manager/install_scripts/install_server.sh index 079e6450..2f7da0eb 100755 --- a/src/server_manager/install_scripts/install_server.sh +++ b/src/server_manager/install_scripts/install_server.sh @@ -376,7 +376,7 @@ function start_watchtower() { -v /var/run/docker.sock:/var/run/docker.sock) # By itself, local messes up the return code. local STDERR_OUTPUT - STDERR_OUTPUT="$(docker run -d "${docker_watchtower_flags[@]}" nicholas-fedor/watchtower --cleanup --label-enable --scope=outline --tlsverify --interval "${WATCHTOWER_REFRESH_SECONDS}" 2>&1 >/dev/null)" && return + STDERR_OUTPUT="$(docker run -d "${docker_watchtower_flags[@]}" nickfedor/watchtower --cleanup --label-enable --scope=outline --tlsverify --interval "${WATCHTOWER_REFRESH_SECONDS}" 2>&1 >/dev/null)" && return readonly STDERR_OUTPUT log_error "FAILED" if docker_container_exists watchtower; then From f9ea8edbb55a64d0324e4a4ef1a3caea752ba2e0 Mon Sep 17 00:00:00 2001 From: "J. Yi" <93548144+jyyi1@users.noreply.github.com> Date: Thu, 8 Jan 2026 13:03:17 -0500 Subject: [PATCH 17/23] chore: update `Jigsaw-Code` references to `OutlineFoundation` (#1693) --- .github/CODEOWNERS | 2 +- README.md | 6 +++--- docs/shadowsocks.md | 2 +- package-lock.json | 11 +++++------ src/metrics_server/connection_metrics.spec.ts | 4 ++-- src/server_manager/README.md | 4 ++-- .../install_scripts/install_server.sh | 4 ++-- src/shadowbox/CHANGELOG.md | 18 ++++++++++-------- src/shadowbox/README.md | 8 ++++---- .../integration_test/client/Dockerfile | 2 +- src/shadowbox/package.json | 2 +- src/shadowbox/server/main.ts | 2 +- 12 files changed, 33 insertions(+), 32 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3b66b7db..34aad372 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ -* @Jigsaw-Code/outline-dev +* @OutlineFoundation/outline-dev /src/server_manager/model/ @fortuna /src/shadowbox/ @fortuna diff --git a/README.md b/README.md index 9ab5ac45..dfb518e4 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # Outline Server -![Build and Test](https://github.com/Jigsaw-Code/outline-server/actions/workflows/build_and_test_debug.yml/badge.svg?branch=master) [![Mattermost](https://badgen.net/badge/Mattermost/Outline%20Community/blue)](https://community.internetfreedomfestival.org/community/channels/outline-community) [![Reddit](https://badgen.net/badge/Reddit/r%2Foutlinevpn/orange)](https://www.reddit.com/r/outlinevpn/) +![Build and Test](https://github.com/OutlineFoundation/outline-server/actions/workflows/build_and_test_debug.yml/badge.svg?branch=master) [![Mattermost](https://badgen.net/badge/Mattermost/Outline%20Community/blue)](https://community.internetfreedomfestival.org/community/channels/outline-community) [![Reddit](https://badgen.net/badge/Reddit/r%2Foutlinevpn/orange)](https://www.reddit.com/r/outlinevpn/) -Outline Server is the component that provides the Shadowsocks service (via [outline-ss-server](https://github.com/Jigsaw-Code/outline-ss-server/)) and a service management API. You can deploy this server directly following simple instructions in this repository, or if you prefer a ready-to-use graphical interface you can use the [Outline Manager](https://github.com/Jigsaw-Code/outline-apps/). +Outline Server is the component that provides the Shadowsocks service (via [outline-ss-server](https://github.com/OutlineFoundation/tunnel-server/)) and a service management API. You can deploy this server directly following simple instructions in this repository, or if you prefer a ready-to-use graphical interface you can use the [Outline Manager](https://github.com/OutlineFoundation/outline-apps/). **Components:** -- **Outline Server** ([`src/shadowbox`](src/shadowbox)): The core proxy server that runs and manages [outline-ss-server](https://github.com/Jigsaw-Code/outline-ss-server/), a Shadowsocks backend. It provides a REST API for access key management. +- **Outline Server** ([`src/shadowbox`](src/shadowbox)): The core proxy server that runs and manages [outline-ss-server](https://github.com/OutlineFoundation/tunnel-server/), a Shadowsocks backend. It provides a REST API for access key management. - **Metrics Server** ([`src/metrics_server`](src/metrics_server)): A REST service for optional, anonymous metrics sharing. diff --git a/docs/shadowsocks.md b/docs/shadowsocks.md index e8f426e9..35b899f4 100644 --- a/docs/shadowsocks.md +++ b/docs/shadowsocks.md @@ -20,6 +20,6 @@ The censors used to block Shadowsocks, but Shadowsocks has evolved, and in 2021, In 2022 China started blocking seemingly random traffic ([report](https://www.opentech.fund/news/exposing-the-great-firewalls-dynamic-blocking-of-fully-encrypted-traffic/)). While there is no evidence they could detect Shadowsocks, the protocol ended up blocked. -As a reponse, we [added a feature to the Outline Client](https://github.com/Jigsaw-Code/outline-apps/pull/1454) that allows service managers to specify a **[connection prefix disguise](https://www.reddit.com/r/outlinevpn/wiki/index/prefixing/)** to be used in the Shadowsocks initialization, which can be used to bypass the blocking in China by making it look like a protocol that is allowed. +As a reponse, we [added a feature to the Outline Client](https://github.com/OutlineFoundation/outline-apps/pull/1454) that allows service managers to specify a **[connection prefix disguise](https://www.reddit.com/r/outlinevpn/wiki/index/prefixing/)** to be used in the Shadowsocks initialization, which can be used to bypass the blocking in China by making it look like a protocol that is allowed. Shadowsocks remains our protocol of choice because it's simple, well understood and very performant. Furthermore, it has an enthusiastic community of very smart people behind it. diff --git a/package-lock.json b/package-lock.json index f38ece7c..30073280 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6044,8 +6044,7 @@ }, "node_modules/outline-shadowsocksconfig": { "version": "0.2.0", - "resolved": "git+ssh://git@github.com/Jigsaw-Code/outline-shadowsocksconfig.git#add590ed57277653d02dd2031ae301500ae881e1", - "license": "Apache-2.0", + "resolved": "git+ssh://git@github.com/OutlineFoundation/shadowsocksconfig.git#add590ed57277653d02dd2031ae301500ae881e1", "dependencies": { "ipaddr.js": "^2.0.0", "js-base64": "^3.5.2", @@ -9019,7 +9018,7 @@ "dependencies": { "ip-regex": "^4.1.0", "js-yaml": "^3.12.0", - "outline-shadowsocksconfig": "git+ssh://git@github.com/Jigsaw-Code/outline-shadowsocksconfig.git#add590ed57277653d02dd2031ae301500ae881e1", + "outline-shadowsocksconfig": "github:OutlineFoundation/shadowsocksconfig#v0.2.0", "prom-client": "^11.1.3", "randomstring": "^1.1.5", "restify": "^11.1.0", @@ -13191,7 +13190,7 @@ "@types/tmp": "^0.2.1", "ip-regex": "^4.1.0", "js-yaml": "^3.12.0", - "outline-shadowsocksconfig": "git+ssh://git@github.com/Jigsaw-Code/outline-shadowsocksconfig.git#add590ed57277653d02dd2031ae301500ae881e1", + "outline-shadowsocksconfig": "github:OutlineFoundation/shadowsocksconfig#v0.2.0", "prom-client": "^11.1.3", "randomstring": "^1.1.5", "restify": "^11.1.0", @@ -13211,8 +13210,8 @@ } }, "outline-shadowsocksconfig": { - "version": "git+ssh://git@github.com/Jigsaw-Code/outline-shadowsocksconfig.git#add590ed57277653d02dd2031ae301500ae881e1", - "from": "outline-shadowsocksconfig@github:Jigsaw-Code/outline-shadowsocksconfig#v0.2.0", + "version": "git+ssh://git@github.com/OutlineFoundation/shadowsocksconfig.git#add590ed57277653d02dd2031ae301500ae881e1", + "from": "outline-shadowsocksconfig@github:OutlineFoundation/shadowsocksconfig#v0.2.0", "requires": { "ipaddr.js": "^2.0.0", "js-base64": "^3.5.2", diff --git a/src/metrics_server/connection_metrics.spec.ts b/src/metrics_server/connection_metrics.spec.ts index 15fb97ca..41aa3af4 100644 --- a/src/metrics_server/connection_metrics.spec.ts +++ b/src/metrics_server/connection_metrics.spec.ts @@ -34,7 +34,7 @@ const VALID_USER_REPORT2: HourlyUserConnectionMetricsReport = { /* * Legacy access key user reports to ensure backwards compatibility with servers not - * synced past https://github.com/Jigsaw-Code/outline-server/pull/1529). + * synced past https://github.com/OutlineFoundation/outline-server/pull/1529). */ const LEGACY_PER_KEY_USER_REPORT: HourlyUserConnectionMetricsReport = { userId: 'foo', @@ -43,7 +43,7 @@ const LEGACY_PER_KEY_USER_REPORT: HourlyUserConnectionMetricsReport = { /* * Legacy multiple countries user reports to ensure backwards compatibility with servers - * not synced past https://github.com/Jigsaw-Code/outline-server/pull/1242. + * not synced past https://github.com/OutlineFoundation/outline-server/pull/1242. */ const LEGACY_PER_LOCATION_USER_REPORT: HourlyUserConnectionMetricsReport = { userId: 'foobar', diff --git a/src/server_manager/README.md b/src/server_manager/README.md index 2672de2d..c0a8a86d 100644 --- a/src/server_manager/README.md +++ b/src/server_manager/README.md @@ -1,5 +1,5 @@ # Outline Manager -> THIS PROJECT HAS MOVED TO A [NEW LOCATION](https://github.com/Jigsaw-Code/outline-apps/tree/master/): Outline Manager is now part of the [Outline Apps repository](https://github.com/Jigsaw-Code/outline-apps). +> THIS PROJECT HAS MOVED TO A [NEW LOCATION](https://github.com/OutlineFoundation/outline-apps/tree/master/server_manager): Outline Manager is now part of the [Outline Apps repository](https://github.com/OutlineFoundation/outline-apps). -We are keeping this folder to support legacy versions of the app that point to the old [server install script](https://github.com/Jigsaw-Code/outline-server/blob/master/src/server_manager/install_scripts/install_server.sh). +We are keeping this folder to support legacy versions of the app that point to the old [server install script](https://github.com/OutlineFoundation/outline-server/blob/master/src/server_manager/install_scripts/install_server.sh). diff --git a/src/server_manager/install_scripts/install_server.sh b/src/server_manager/install_scripts/install_server.sh index 39ba2b0d..21256dcd 100755 --- a/src/server_manager/install_scripts/install_server.sh +++ b/src/server_manager/install_scripts/install_server.sh @@ -160,7 +160,7 @@ function fetch() { function install_docker() { ( # Change umask so that /usr/share/keyrings/docker-archive-keyring.gpg has the right permissions. - # See https://github.com/Jigsaw-Code/outline-server/issues/951. + # See https://github.com/OutlineFoundation/outline-server/issues/951. # We do this in a subprocess so the umask for the calling process is unaffected. umask 0022 fetch https://get.docker.com/ | sh @@ -440,7 +440,7 @@ Make sure to open the following ports on your firewall, router or cloud provider function set_hostname() { # These are URLs that return the client's apparent IP address. # We have more than one to try in case one starts failing - # (e.g. https://github.com/Jigsaw-Code/outline-server/issues/776). + # (e.g. https://github.com/OutlineFoundation/outline-server/issues/776). local -ar urls=( 'https://icanhazip.com/' 'https://ipinfo.io/ip' diff --git a/src/shadowbox/CHANGELOG.md b/src/shadowbox/CHANGELOG.md index af5a38eb..8074d6af 100644 --- a/src/shadowbox/CHANGELOG.md +++ b/src/shadowbox/CHANGELOG.md @@ -1,20 +1,22 @@ # 1.7.2 + - Fixes - - Fix reporting of country metrics and improve logging output (https://github.com/Jigsaw-Code/outline-server/pull/1242) + - Fix reporting of country metrics and improve logging output (https://github.com/OutlineFoundation/outline-server/pull/1242) # 1.7.1 + - Fixes - - Corner case of isPortUsed that could result in infinite restart loop (https://github.com/Jigsaw-Code/outline-server/pull/1238) - - Prevent excessive logging (https://github.com/Jigsaw-Code/outline-server/pull/1232) + - Corner case of isPortUsed that could result in infinite restart loop (https://github.com/OutlineFoundation/outline-server/pull/1238) + - Prevent excessive logging (https://github.com/OutlineFoundation/outline-server/pull/1232) # 1.7.0 - Features - - Add encryption cipher selection to create access key API (https://github.com/Jigsaw-Code/outline-server/pull/1002) - - Make access key secrets longer (https://github.com/Jigsaw-Code/outline-server/pull/1098) + - Add encryption cipher selection to create access key API (https://github.com/OutlineFoundation/outline-server/pull/1002) + - Make access key secrets longer (https://github.com/OutlineFoundation/outline-server/pull/1098) - Fixes - - Race condition on concurrent API calls (https://github.com/Jigsaw-Code/outline-server/pull/995) -- Upgrades (https://github.com/Jigsaw-Code/outline-server/pull/1211) + - Race condition on concurrent API calls (https://github.com/OutlineFoundation/outline-server/pull/995) +- Upgrades (https://github.com/OutlineFoundation/outline-server/pull/1211) - Base image to `node:16.18.0-alpine3.16` - - outline-ss-server from 1.3.5 to [1.4.0](https://github.com/Jigsaw-Code/outline-ss-server/releases/tag/v1.4.0) + - outline-ss-server from 1.3.5 to [1.4.0](https://github.com/OutlineFoundation/outline-ss-server/releases/tag/v1.4.0) - Prometheus from 2.33.5 to [2.37.1](https://github.com/prometheus/prometheus/releases/tag/v2.37.1) diff --git a/src/shadowbox/README.md b/src/shadowbox/README.md index c0519aa2..8462adf7 100644 --- a/src/shadowbox/README.md +++ b/src/shadowbox/README.md @@ -1,6 +1,6 @@ # Outline Server (Shadowbox) -The Outline Server, internal name "Shadowbox," is designed to streamline the setup and sharing of Shadowsocks servers. It includes a user management API and creates Shadowsocks instances when needed. It's managed by the [Outline Manager](https://github.com/Jigsaw-Code/outline-apps/) and used as proxy by the [Outline Client](https://github.com/Jigsaw-Code/outline-apps/) apps. Shadowbox is also compatible with standard Shadowsocks clients. +The Outline Server, internal name "Shadowbox," is designed to streamline the setup and sharing of Shadowsocks servers. It includes a user management API and creates Shadowsocks instances when needed. It's managed by the [Outline Manager](https://github.com/OutlineFoundation/outline-apps/) and used as proxy by the [Outline Client](https://github.com/OutlineFoundation/outline-apps/) apps. Shadowbox is also compatible with standard Shadowsocks clients. ## Installation @@ -9,7 +9,7 @@ The Outline Server, internal name "Shadowbox," is designed to streamline the set 1. **Run the Installation Script** ```sh - sudo bash -c "$(wget -qO- https://raw.githubusercontent.com/Jigsaw-Code/outline-apps/master/server_manager/install_scripts/install_server.sh)" + sudo bash -c "$(wget -qO- https://raw.githubusercontent.com/OutlineFoundation/outline-apps/master/server_manager/install_scripts/install_server.sh)" ``` 1. **Customize (Optional)** @@ -17,7 +17,7 @@ The Outline Server, internal name "Shadowbox," is designed to streamline the set Add flags for hostname, port, etc. Example: ```sh - sudo bash -c "$(wget -qO- https://raw.githubusercontent.com/Jigsaw-Code/outline-apps/master/server_manager/install_scripts/install_server.sh)" install_server.sh \ + sudo bash -c "$(wget -qO- https://raw.githubusercontent.com/OutlineFoundation/outline-apps/master/server_manager/install_scripts/install_server.sh)" install_server.sh \ --hostname=myserver.com \ --keys-port=443 ``` @@ -113,7 +113,7 @@ The Outline Server provides a REST API for access key management. If you know th 1. **Further Options:** - Consult the [OpenAPI spec](./server/api.yml) and [documentation](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/Jigsaw-Code/outline-server/master/src/shadowbox/server/api.yml) for more options. + Consult the [OpenAPI spec](./server/api.yml) and [documentation](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/OutlineFoundation/outline-server/master/src/shadowbox/server/api.yml) for more options. ## Testing diff --git a/src/shadowbox/integration_test/client/Dockerfile b/src/shadowbox/integration_test/client/Dockerfile index 31a51bb6..f2915cdf 100644 --- a/src/shadowbox/integration_test/client/Dockerfile +++ b/src/shadowbox/integration_test/client/Dockerfile @@ -14,7 +14,7 @@ # Alpine 3.19 curl is using the c-ares resolver instead of the system resolver, # which caused DNS issues. Upgrade once the Alpine image includes the fix. See -# https://github.com/Jigsaw-Code/outline-server/pull/1566. +# https://github.com/OutlineFoundation/outline-server/pull/1566. FROM docker.io/golang:1-alpine3.18 # curl for fetching pages using the local proxy diff --git a/src/shadowbox/package.json b/src/shadowbox/package.json index 89a2ef5d..62e4ddd4 100644 --- a/src/shadowbox/package.json +++ b/src/shadowbox/package.json @@ -11,7 +11,7 @@ "dependencies": { "ip-regex": "^4.1.0", "js-yaml": "^3.12.0", - "outline-shadowsocksconfig": "github:Jigsaw-Code/outline-shadowsocksconfig#v0.2.0", + "outline-shadowsocksconfig": "github:OutlineFoundation/shadowsocksconfig#v0.2.0", "prom-client": "^11.1.3", "randomstring": "^1.1.5", "restify": "^11.1.0", diff --git a/src/shadowbox/server/main.ts b/src/shadowbox/server/main.ts index 533f9f43..5d1be776 100644 --- a/src/shadowbox/server/main.ts +++ b/src/shadowbox/server/main.ts @@ -123,7 +123,7 @@ async function main() { const prometheusPort = await portProvider.reserveFirstFreePort(9090); // Use 127.0.0.1 instead of localhost for Prometheus because it's resolving incorrectly for some users. - // See https://github.com/Jigsaw-Code/outline-server/issues/341 + // See https://github.com/OutlineFoundation/outline-server/issues/341 const prometheusLocation = `127.0.0.1:${prometheusPort}`; const nodeMetricsPort = await portProvider.reserveFirstFreePort(prometheusPort + 1); From fa185b0f9002e9c556d995fdaf93adeadcf2af37 Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Wed, 25 Mar 2026 14:49:02 -0600 Subject: [PATCH 18/23] Added support for MacOS and Linux ARM64 --- .github/workflows/build_and_test_debug.yml | 26 +++++++++++++++++++ .../install_scripts/install_server.sh | 4 +-- src/shadowbox/Taskfile.yml | 16 +++++++++--- src/shadowbox/integration_test/test.sh | 8 +++--- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index fff4e8c1..720d90f9 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -81,6 +81,32 @@ jobs: files: | src/shadowbox/server/api.yml + shadowbox-arm64: + name: Shadowbox (arm64) + runs-on: ubuntu-22.04-arm + needs: lint + steps: + - name: Checkout + uses: actions/checkout@v2.3.4 + + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: npm + + - name: Install NPM Dependencies + run: npm ci + + - name: Shadowbox Debug Build (arm64) + run: TARGET_ARCH=aarch64 ./task shadowbox:build + + - name: Shadowbox Unit Test + run: ./task shadowbox:test + + - name: Shadowbox Docker Build (arm64) + run: TARGET_ARCH=aarch64 ./task shadowbox:docker:build + manual-install-script: name: Manual Install Script runs-on: ubuntu-latest diff --git a/src/server_manager/install_scripts/install_server.sh b/src/server_manager/install_scripts/install_server.sh index 04013372..9bf72a09 100755 --- a/src/server_manager/install_scripts/install_server.sh +++ b/src/server_manager/install_scripts/install_server.sh @@ -456,8 +456,8 @@ function set_hostname() { install_shadowbox() { local MACHINE_TYPE MACHINE_TYPE="$(uname -m)" - if [[ "${MACHINE_TYPE}" != "x86_64" ]]; then - log_error "Unsupported machine type: ${MACHINE_TYPE}. Please run this script on a x86_64 machine" + if [[ "${MACHINE_TYPE}" != "x86_64" && "${MACHINE_TYPE}" != "aarch64" && "${MACHINE_TYPE}" != "arm64" ]]; then + log_error "Unsupported machine type: ${MACHINE_TYPE}. Supported architectures: x86_64, aarch64/arm64." exit 1 fi diff --git a/src/shadowbox/Taskfile.yml b/src/shadowbox/Taskfile.yml index fb72a9b8..0dc31414 100644 --- a/src/shadowbox/Taskfile.yml +++ b/src/shadowbox/Taskfile.yml @@ -23,7 +23,7 @@ tasks: vars: TARGET_OS: '{{.TARGET_OS | default "linux"}}' TARGET_ARCH: '{{.TARGET_ARCH | default "x86_64"}}' - GOARCH: '{{get (dict "x86_64" "amd64") .TARGET_ARCH | default .TARGET_ARCH}}' + GOARCH: '{{get (dict "x86_64" "amd64" "aarch64" "arm64") .TARGET_ARCH | default .TARGET_ARCH}}' TARGET_DIR: '{{.TARGET_DIR | default (joinPath .OUTPUT_BASE .TARGET_OS .TARGET_ARCH)}}' NODE_DIR: '{{joinPath .TARGET_DIR "app"}}' BIN_DIR: '{{joinPath .TARGET_DIR "bin"}}' @@ -79,10 +79,19 @@ tasks: # Newer node images have no valid content trust data. # Pin the image node:16.18.0-alpine3.16 by hash. # See image at https://hub.docker.com/_/node/tags?page=1&name=18.18.0-alpine3.18 + # Note: "aarch64" is an alias for "arm64" — Linux ARM64 hosts report "aarch64" via uname -m. NODE_IMAGE: '{{get (dict - "x86_64" "node@sha256:a0b787b0d53feacfa6d606fb555e0dbfebab30573277f1fe25148b05b66fa097" - "arm64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" + "x86_64" "node@sha256:a0b787b0d53feacfa6d606fb555e0dbfebab30573277f1fe25148b05b66fa097" + "arm64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" + "aarch64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" + ) .TARGET_ARCH + }}' + DOCKER_PLATFORM: '{{get + (dict + "x86_64" "linux/amd64" + "arm64" "linux/arm64" + "aarch64" "linux/arm64" ) .TARGET_ARCH }}' env: @@ -103,6 +112,7 @@ tasks: # Build image with given root - | "${DOCKER:-docker}" build --force-rm \ + --platform '{{.DOCKER_PLATFORM}}' \ --build-arg NODE_IMAGE='{{.NODE_IMAGE}}' \ --build-arg VERSION='{{.VERSION}}' \ -f '{{joinPath .TASKFILE_DIR "docker" "Dockerfile"}}' \ diff --git a/src/shadowbox/integration_test/test.sh b/src/shadowbox/integration_test/test.sh index 84b194e6..0f6adc84 100755 --- a/src/shadowbox/integration_test/test.sh +++ b/src/shadowbox/integration_test/test.sh @@ -100,10 +100,13 @@ function setup() { "${DOCKER}" run -d --rm -p "10080:80" --network="${NET_OPEN}" --network-alias="target" --name="${TARGET_CONTAINER}" "${TARGET_IMAGE}" # Shadowsocks service. + # Start on NET_OPEN first so that -p host port binding works on macOS Docker Desktop + # (Docker Desktop does not publish ports when the initial network is --internal). + # Then connect to NET_BLOCKED so the security isolation tests still pass. declare -ar shadowbox_flags=( -d --rm - --network="${NET_BLOCKED}" + --network="${NET_OPEN}" --network-alias="shadowbox" -p "20443:443" -e "SB_API_PORT=443" @@ -118,8 +121,7 @@ function setup() { "${SHADOWBOX_IMAGE}" ) "${DOCKER}" run "${shadowbox_flags[@]}" - # "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" - "${DOCKER}" network connect "${NET_OPEN}" "${SHADOWBOX_CONTAINER}" + "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" # Client service. "${DOCKER}" build --force-rm -t "${CLIENT_IMAGE}" "$(dirname "$0")/client" From 23e468b4340d2f1a59cbdea4494d5131856c6b80 Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Mon, 6 Apr 2026 23:20:18 +0800 Subject: [PATCH 19/23] Skip Chromium install on arm64 Tests passing on ACT --- .github/workflows/build_and_test_debug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index 720d90f9..d68f257b 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -96,7 +96,7 @@ jobs: cache: npm - name: Install NPM Dependencies - run: npm ci + run: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm ci - name: Shadowbox Debug Build (arm64) run: TARGET_ARCH=aarch64 ./task shadowbox:build From 1f1c03cfc43dc77175a434dcb42cf8018e11ff7f Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Tue, 7 Apr 2026 08:33:54 +0800 Subject: [PATCH 20/23] Update build_and_test_debug.yml --- .github/workflows/build_and_test_debug.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index d68f257b..6da6dfbf 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -43,8 +43,16 @@ jobs: node-version: 18 cache: npm + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + cache: false + - name: Install NPM Dependencies run: npm ci + env: + PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true' - name: Lint run: ./task lint @@ -95,8 +103,16 @@ jobs: node-version: 18 cache: npm + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + cache: false + - name: Install NPM Dependencies - run: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm ci + run: npm ci + env: + PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true' - name: Shadowbox Debug Build (arm64) run: TARGET_ARCH=aarch64 ./task shadowbox:build From eb1ae915a8c7d669104a78dff0abd710dbe62d4b Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Tue, 7 Apr 2026 18:44:45 +0800 Subject: [PATCH 21/23] Update build_and_test_debug.yml Use go.mod --- .github/workflows/build_and_test_debug.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index 6da6dfbf..441bc05e 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -46,7 +46,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: go.mod cache: false - name: Install NPM Dependencies @@ -106,7 +106,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: go.mod cache: false - name: Install NPM Dependencies From 847d66f8e449510e27d28869d4347d6df8133045 Mon Sep 17 00:00:00 2001 From: Sean Baker Date: Tue, 7 Apr 2026 19:39:31 +0800 Subject: [PATCH 22/23] Use original test --- src/shadowbox/integration_test/test.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/shadowbox/integration_test/test.sh b/src/shadowbox/integration_test/test.sh index 0f6adc84..84b194e6 100755 --- a/src/shadowbox/integration_test/test.sh +++ b/src/shadowbox/integration_test/test.sh @@ -100,13 +100,10 @@ function setup() { "${DOCKER}" run -d --rm -p "10080:80" --network="${NET_OPEN}" --network-alias="target" --name="${TARGET_CONTAINER}" "${TARGET_IMAGE}" # Shadowsocks service. - # Start on NET_OPEN first so that -p host port binding works on macOS Docker Desktop - # (Docker Desktop does not publish ports when the initial network is --internal). - # Then connect to NET_BLOCKED so the security isolation tests still pass. declare -ar shadowbox_flags=( -d --rm - --network="${NET_OPEN}" + --network="${NET_BLOCKED}" --network-alias="shadowbox" -p "20443:443" -e "SB_API_PORT=443" @@ -121,7 +118,8 @@ function setup() { "${SHADOWBOX_IMAGE}" ) "${DOCKER}" run "${shadowbox_flags[@]}" - "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" + # "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" + "${DOCKER}" network connect "${NET_OPEN}" "${SHADOWBOX_CONTAINER}" # Client service. "${DOCKER}" build --force-rm -t "${CLIENT_IMAGE}" "$(dirname "$0")/client" From de566bfc9ff4429ae839e304b4d7e03b703ce415 Mon Sep 17 00:00:00 2001 From: Sarah Laplante Date: Wed, 13 May 2026 10:50:59 +0200 Subject: [PATCH 23/23] chore: upgrade lib versions for quay security scanner (#1704) * upgrade lib versions for quay security scanner * update image version * upgrade go to latest stable 1.26.3 --- go.mod | 8 ++++---- go.sum | 12 ++++++------ src/shadowbox/Taskfile.yml | 11 +++++------ src/shadowbox/docker/Dockerfile | 5 +++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index d519122e..f5572f2c 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module localhost -go 1.21 +go 1.26.3 require ( github.com/Jigsaw-Code/outline-ss-server v1.7.3 @@ -37,10 +37,10 @@ require ( github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - golang.org/x/crypto v0.31.0 // indirect + golang.org/x/crypto v0.45.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect mvdan.cc/sh/v3 v3.8.0 // indirect diff --git a/go.sum b/go.sum index 96578b72..f86ef755 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -102,11 +102,11 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/src/shadowbox/Taskfile.yml b/src/shadowbox/Taskfile.yml index 0dc31414..adec26d4 100644 --- a/src/shadowbox/Taskfile.yml +++ b/src/shadowbox/Taskfile.yml @@ -76,15 +76,14 @@ tasks: IMAGE_NAME: '{{.IMAGE_NAME | default "localhost/outline/shadowbox"}}' TARGET_ARCH: '{{.TARGET_ARCH | default "x86_64"}}' IMAGE_ROOT: '{{joinPath .OUTPUT_BASE "image_root" .TARGET_ARCH}}' - # Newer node images have no valid content trust data. - # Pin the image node:16.18.0-alpine3.16 by hash. - # See image at https://hub.docker.com/_/node/tags?page=1&name=18.18.0-alpine3.18 + # Pin the image node:18.20.8-alpine3.21 by hash. + # See image at https://hub.docker.com/_/node/tags?page=1&name=18.20.8-alpine3.21 # Note: "aarch64" is an alias for "arm64" — Linux ARM64 hosts report "aarch64" via uname -m. NODE_IMAGE: '{{get (dict - "x86_64" "node@sha256:a0b787b0d53feacfa6d606fb555e0dbfebab30573277f1fe25148b05b66fa097" - "arm64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" - "aarch64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" + "x86_64" "node@sha256:929b04d7c782f04f615cf785488fed452b6569f87c73ff666ad553a7554f0006" + "arm64" "node@sha256:c2281c62c4aadf92ea71a6c05e6c8e640634b6a99dc52a6e54575f9cb298a037" + "aarch64" "node@sha256:c2281c62c4aadf92ea71a6c05e6c8e640634b6a99dc52a6e54575f9cb298a037" ) .TARGET_ARCH }}' DOCKER_PLATFORM: '{{get diff --git a/src/shadowbox/docker/Dockerfile b/src/shadowbox/docker/Dockerfile index c9d27db7..671c421a 100644 --- a/src/shadowbox/docker/Dockerfile +++ b/src/shadowbox/docker/Dockerfile @@ -18,16 +18,17 @@ FROM ${NODE_IMAGE} ARG VERSION # Save metadata on the software versions we are using. -LABEL shadowbox.node_version=16.18.0 +LABEL shadowbox.node_version=18.20.8 LABEL shadowbox.github.release=${VERSION} # The user management service doesn't quit with SIGTERM. STOPSIGNAL SIGKILL +# Upgrade installed Alpine packages to pick up security fixes (musl-utils, busybox, ssl_client, etc.). # We use curl to detect the server's public IP. We need to use the --date option in `date` to # safely grab the ip-to-country database. -RUN apk add --no-cache --upgrade coreutils curl +RUN apk upgrade --no-cache && apk add --no-cache --upgrade coreutils curl COPY . /