1
mirror of https://github.com/xddxdd/bird-lg-go synced 2025-10-17 22:42:12 +02:00

118 Commits

Author SHA1 Message Date
Lan Tian
ae6460d2d3 release: v1.3.12 2025-10-04 13:41:36 -07:00
Ljcbaby
d312f7de1b fix: " cuase unexpected TEXT but ' not 2025-10-04 13:40:45 -07:00
Ljcbaby
1097e69070 fix: " cuase unexpected TEXT but ' not 2025-10-04 13:40:45 -07:00
Lan Tian
4a8c752157 release: v1.3.11 2025-09-27 01:54:01 -07:00
Lan Tian
5ad6a4d35c frontend: fix race condition when setting up web server 2025-09-27 01:50:53 -07:00
Ljcbaby
5422c8fd8c refactor: deplcate Handle register 2025-09-27 01:50:53 -07:00
Ljcbaby
5042980d79 frontend multi listen 2025-09-27 01:50:53 -07:00
Ljcbaby
7884531a24 proxy multi listen 2025-09-27 01:50:53 -07:00
dependabot[bot]
cc804e81b6 Merge pull request #129 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/viper-1.21.0 2025-09-09 00:07:01 +00:00
dependabot[bot]
c9bab2ae2b Merge pull request #130 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/viper-1.21.0 2025-09-09 00:05:57 +00:00
dependabot[bot]
b9a4f95978 build(deps): bump github.com/spf13/viper from 1.19.0 to 1.21.0 in /proxy
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.19.0 to 1.21.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.19.0...v1.21.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-version: 1.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-09 00:04:35 +00:00
dependabot[bot]
7cd69746df build(deps): bump github.com/spf13/viper in /frontend
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.19.0 to 1.21.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.19.0...v1.21.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-version: 1.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-09 00:04:30 +00:00
dependabot[bot]
e719859d68 Merge pull request #128 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/pflag-1.0.10 2025-09-03 22:06:35 +00:00
dependabot[bot]
5d06affefc build(deps): bump github.com/spf13/pflag from 1.0.8 to 1.0.10 in /proxy
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.8 to 1.0.10.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.8...v1.0.10)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-03 22:05:01 +00:00
dependabot[bot]
060fe9bf8e Merge pull request #127 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/pflag-1.0.10 2025-09-03 19:13:13 +00:00
dependabot[bot]
f23d36f357 build(deps): bump github.com/spf13/pflag in /frontend
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.8 to 1.0.10.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.8...v1.0.10)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-03 19:11:24 +00:00
dependabot[bot]
1dbc0fccd2 Merge pull request #126 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/pflag-1.0.8 2025-09-01 00:08:36 +00:00
dependabot[bot]
b2d64d19e3 build(deps): bump github.com/spf13/pflag in /frontend
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.7 to 1.0.8.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.7...v1.0.8)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 00:06:28 +00:00
dependabot[bot]
4dee4b0806 Merge pull request #125 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/pflag-1.0.8 2025-09-01 00:06:18 +00:00
dependabot[bot]
cb279e0459 build(deps): bump github.com/spf13/pflag from 1.0.7 to 1.0.8 in /proxy
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.7 to 1.0.8.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.7...v1.0.8)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 00:04:16 +00:00
dependabot[bot]
31ba36beaf Merge pull request #123 from xddxdd/dependabot/go_modules/frontend/github.com/jarcoal/httpmock-1.4.1 2025-08-20 05:14:21 +00:00
dependabot[bot]
5ab3b95d64 build(deps): bump github.com/jarcoal/httpmock in /frontend
Bumps [github.com/jarcoal/httpmock](https://github.com/jarcoal/httpmock) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/jarcoal/httpmock/releases)
- [Commits](https://github.com/jarcoal/httpmock/compare/v1.4.0...v1.4.1)

---
updated-dependencies:
- dependency-name: github.com/jarcoal/httpmock
  dependency-version: 1.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-20 05:12:43 +00:00
dependabot[bot]
7bf654f35f Merge pull request #122 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/pflag-1.0.7 2025-07-17 00:25:25 +00:00
dependabot[bot]
5b33629a9d build(deps): bump github.com/spf13/pflag from 1.0.6 to 1.0.7 in /proxy
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.6...v1.0.7)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-17 00:23:21 +00:00
dependabot[bot]
0868c5d42c Merge pull request #121 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/pflag-1.0.7 2025-07-17 00:09:29 +00:00
dependabot[bot]
bc61579e6a build(deps): bump github.com/spf13/pflag in /frontend
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.6...v1.0.7)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-17 00:07:25 +00:00
Lan Tian
e9750a8278 release: v1.3.10 2025-07-02 19:58:51 -07:00
Lan Tian
d40dd3a4d3 frontend: handle protocol names with dash 2025-07-01 17:45:12 -07:00
Lan Tian
ffdeeac06e frontend: refactor summary table parsing 2025-07-01 00:55:15 -07:00
Lan Tian
7eb4d75bbf frontend: handle protocol names starting with number 2025-07-01 00:04:03 -07:00
Lan Tian
6e5e190d32 frontend: try fix TestWhoisConnectionError on darwin 2025-06-08 22:01:39 -07:00
Lan Tian
1b2573d87c release: v1.3.9 2025-04-23 21:13:36 -07:00
Lan Tian
0d5337508b frontend: update API test to adapt to changes in #118 2025-04-23 21:12:40 -07:00
Mxmilu666
b9094d3d6c fix(template): typo 2025-04-23 21:08:40 -07:00
Mxmilu666
ec7f348418 feat(api): return data from available services even if one backend fails 2025-04-23 21:08:40 -07:00
dependabot[bot]
a632739443 Merge pull request #117 from xddxdd/dependabot/go_modules/proxy/github.com/magiconair/properties-1.8.10 2025-04-10 00:55:19 +00:00
dependabot[bot]
a9e278357a build(deps): bump github.com/magiconair/properties in /proxy
Bumps [github.com/magiconair/properties](https://github.com/magiconair/properties) from 1.8.9 to 1.8.10.
- [Release notes](https://github.com/magiconair/properties/releases)
- [Commits](https://github.com/magiconair/properties/compare/v1.8.9...v1.8.10)

---
updated-dependencies:
- dependency-name: github.com/magiconair/properties
  dependency-version: 1.8.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-10 00:53:10 +00:00
dependabot[bot]
e4c00c897f Merge pull request #116 from xddxdd/dependabot/go_modules/frontend/github.com/magiconair/properties-1.8.10 2025-04-10 00:22:47 +00:00
dependabot[bot]
4df3918b35 build(deps): bump github.com/magiconair/properties in /frontend
Bumps [github.com/magiconair/properties](https://github.com/magiconair/properties) from 1.8.9 to 1.8.10.
- [Release notes](https://github.com/magiconair/properties/releases)
- [Commits](https://github.com/magiconair/properties/compare/v1.8.9...v1.8.10)

---
updated-dependencies:
- dependency-name: github.com/magiconair/properties
  dependency-version: 1.8.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-10 00:20:55 +00:00
dependabot[bot]
45dc24470d Merge pull request #115 from xddxdd/dependabot/go_modules/frontend/github.com/jarcoal/httpmock-1.4.0 2025-04-07 00:54:10 +00:00
dependabot[bot]
55ea5c3b28 build(deps): bump github.com/jarcoal/httpmock in /frontend
Bumps [github.com/jarcoal/httpmock](https://github.com/jarcoal/httpmock) from 1.3.1 to 1.4.0.
- [Release notes](https://github.com/jarcoal/httpmock/releases)
- [Commits](https://github.com/jarcoal/httpmock/compare/v1.3.1...v1.4.0)

---
updated-dependencies:
- dependency-name: github.com/jarcoal/httpmock
  dependency-version: 1.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 00:52:24 +00:00
dependabot[bot]
7eb44c3828 Merge pull request #110 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/pflag-1.0.6 2025-01-30 00:16:58 +00:00
dependabot[bot]
124fdedbda build(deps): bump github.com/spf13/pflag from 1.0.5 to 1.0.6 in /proxy
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.5...v1.0.6)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-30 00:14:41 +00:00
dependabot[bot]
e6a98358b5 Merge pull request #109 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/pflag-1.0.6 2025-01-30 00:04:45 +00:00
dependabot[bot]
761eb2160a build(deps): bump github.com/spf13/pflag in /frontend
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.5...v1.0.6)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-30 00:02:32 +00:00
dependabot[bot]
cc2a146a88 Merge pull request #108 from xddxdd/dependabot/go_modules/frontend/github.com/magiconair/properties-1.8.9 2024-12-09 00:51:25 +00:00
dependabot[bot]
3db9454350 build(deps): bump github.com/magiconair/properties in /frontend
Bumps [github.com/magiconair/properties](https://github.com/magiconair/properties) from 1.8.7 to 1.8.9.
- [Release notes](https://github.com/magiconair/properties/releases)
- [Commits](https://github.com/magiconair/properties/compare/v1.8.7...v1.8.9)

---
updated-dependencies:
- dependency-name: github.com/magiconair/properties
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 00:50:06 +00:00
dependabot[bot]
c30bed112c Merge pull request #107 from xddxdd/dependabot/go_modules/proxy/github.com/magiconair/properties-1.8.9 2024-12-09 00:18:14 +00:00
dependabot[bot]
af5ab3c78f build(deps): bump github.com/magiconair/properties in /proxy
Bumps [github.com/magiconair/properties](https://github.com/magiconair/properties) from 1.8.7 to 1.8.9.
- [Release notes](https://github.com/magiconair/properties/releases)
- [Commits](https://github.com/magiconair/properties/compare/v1.8.7...v1.8.9)

---
updated-dependencies:
- dependency-name: github.com/magiconair/properties
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 00:16:23 +00:00
Marc 'risson' Schmitt
0fdde8afc7 frontend: allow webserver to trust proxy headers (#106)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2024-07-14 15:50:18 -07:00
Lan Tian
39a129db9d release: v1.3.8 2024-07-01 21:31:55 -07:00
Lan Tian
0dd1c07b66 frontend: disable escaping of special HTML chars for BGPMap graph 2024-07-01 21:17:43 -07:00
Lan Tian
f0f072c4a6 frontend: handle UTF-8 characters in GraphViz graphs 2024-06-30 13:04:15 -07:00
dependabot[bot]
657565857b Merge pull request #104 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/viper-1.19.0 2024-06-03 00:40:25 +00:00
dependabot[bot]
7ac2158e70 build(deps): bump github.com/spf13/viper from 1.18.2 to 1.19.0 in /proxy
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.2 to 1.19.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.18.2...v1.19.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-03 00:38:37 +00:00
dependabot[bot]
5c433bc27a Merge pull request #103 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/viper-1.19.0 2024-06-03 00:35:26 +00:00
dependabot[bot]
1b0b923da9 build(deps): bump github.com/spf13/viper in /frontend
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.2 to 1.19.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.18.2...v1.19.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-03 00:32:44 +00:00
Lan Tian
01438edaef release: v1.3.7.1 2024-03-12 18:05:50 -07:00
Lan Tian
90f36610dc ci: fix failing whois test 2024-03-12 18:03:23 -07:00
Lan Tian
6174208d07 ci: fix typo in release workflow 2024-03-12 17:56:52 -07:00
Lan Tian
76174cdc08 release: v1.3.7 2024-03-12 17:47:29 -07:00
Lan Tian
088bb6fe5a readme: add mention of MTR based lgproxy docker image 2024-03-12 17:46:56 -07:00
Lan Tian
3951eed011 ci: fix dockerfile path for proxy image with mtr 2024-03-09 12:21:00 -08:00
Lan Tian
91c0a8962b ci: also test mtr binary in proxy image 2024-03-09 12:09:19 -08:00
Lan Tian
5f7850a903 ci: also build docker image with mtr on regular commits 2024-03-09 12:05:20 -08:00
Lan Tian
6a78cf2e80 proxy: add docker image with mtr 2024-03-09 12:04:05 -08:00
Lan Tian
5b5a44bcb6 release: v1.3.6 2024-02-25 19:47:39 -08:00
Marc 'risson' Schmitt
ac31862237 frontend: show dynamic BGP sessions without any color (#98)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2024-02-18 22:11:20 -08:00
Lan Tian
86129190ab release: v1.3.5 2024-01-01 14:43:25 -08:00
Lan Tian
ff55064a20 frontend: adjust navbar display of many servers 2023-12-31 16:31:56 -08:00
dependabot[bot]
dbb02c04ed Merge pull request #95 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/viper-1.18.2 2023-12-19 00:50:09 +00:00
dependabot[bot]
c2b7de2e17 build(deps): bump github.com/spf13/viper from 1.18.1 to 1.18.2 in /proxy
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.1 to 1.18.2.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.18.1...v1.18.2)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 00:48:47 +00:00
dependabot[bot]
c1b578e8db Merge pull request #94 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/viper-1.18.2 2023-12-19 00:28:10 +00:00
dependabot[bot]
7b0e5689d4 build(deps): bump github.com/spf13/viper in /frontend
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.1 to 1.18.2.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.18.1...v1.18.2)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 00:26:13 +00:00
dependabot[bot]
3c46bda49d Merge pull request #93 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/viper-1.18.1 2023-12-11 00:45:58 +00:00
dependabot[bot]
32e00d2ce3 build(deps): bump github.com/spf13/viper in /frontend
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.0 to 1.18.1.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.18.0...v1.18.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 00:44:41 +00:00
dependabot[bot]
a19750cdef Merge pull request #92 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/viper-1.18.1 2023-12-11 00:04:27 +00:00
dependabot[bot]
7f1cdaa4ee build(deps): bump github.com/spf13/viper from 1.18.0 to 1.18.1 in /proxy
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.0 to 1.18.1.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.18.0...v1.18.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 00:03:09 +00:00
Lan Tian
2d2193041e release: v1.3.4 2023-12-06 23:54:47 -08:00
dependabot[bot]
aad8ee98d7 Merge pull request #91 from xddxdd/dependabot/go_modules/frontend/github.com/spf13/viper-1.18.0 2023-12-07 00:58:49 +00:00
dependabot[bot]
00b5c12787 build(deps): bump github.com/spf13/viper in /frontend
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.17.0...v1.18.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 00:57:01 +00:00
dependabot[bot]
55a1eb54fd Merge pull request #90 from xddxdd/dependabot/go_modules/proxy/github.com/spf13/viper-1.18.0 2023-12-07 00:33:12 +00:00
dependabot[bot]
0594edc69d build(deps): bump github.com/spf13/viper from 1.17.0 to 1.18.0 in /proxy
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.17.0...v1.18.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 00:31:37 +00:00
Lan Tian
38bf6aba09 frontend: fix unit tests 2023-11-25 10:47:37 -08:00
Lan Tian
d261c22235 frontend: add connection timeout 2023-11-25 10:30:13 -08:00
dependabot[bot]
19aa8c77c5 Merge pull request #88 from xddxdd/dependabot/go_modules/frontend/github.com/gorilla/handlers-1.5.2 2023-11-06 01:01:43 +00:00
dependabot[bot]
fe07ebb5a5 build(deps): bump github.com/gorilla/handlers in /frontend
Bumps [github.com/gorilla/handlers](https://github.com/gorilla/handlers) from 1.5.1 to 1.5.2.
- [Release notes](https://github.com/gorilla/handlers/releases)
- [Commits](https://github.com/gorilla/handlers/compare/v1.5.1...v1.5.2)

---
updated-dependencies:
- dependency-name: github.com/gorilla/handlers
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 01:00:08 +00:00
dependabot[bot]
66547ebfa9 Merge pull request #87 from xddxdd/dependabot/go_modules/proxy/github.com/gorilla/handlers-1.5.2 2023-11-06 00:24:24 +00:00
dependabot[bot]
d253e4311b build(deps): bump github.com/gorilla/handlers in /proxy
Bumps [github.com/gorilla/handlers](https://github.com/gorilla/handlers) from 1.5.1 to 1.5.2.
- [Release notes](https://github.com/gorilla/handlers/releases)
- [Commits](https://github.com/gorilla/handlers/compare/v1.5.1...v1.5.2)

---
updated-dependencies:
- dependency-name: github.com/gorilla/handlers
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 00:22:00 +00:00
Lan Tian
026498ba2f general: auto merge updates from dependabot 2023-10-24 23:32:55 -07:00
Lan Tian
27c348a864 release: v1.3.3 2023-10-21 00:03:02 -07:00
Lan Tian
43b4ad93dd general: only build docker develop images on master branch push 2023-10-08 21:08:07 -07:00
dependabot[bot]
6176c45006 build(deps): bump github.com/spf13/viper from 1.16.0 to 1.17.0 in /proxy (#86)
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-08 21:04:12 -07:00
dependabot[bot]
47113184f4 build(deps): bump github.com/spf13/viper in /frontend (#85)
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-08 21:04:04 -07:00
Simon Marsh
3c9a3e4339 Enable proxy to allow access by CIDR network as well as IP (#84) 2023-10-04 21:33:37 -07:00
Lan Tian
8457b18d46 release: v1.3.2.2 2023-09-09 01:44:16 -07:00
Lan Tian
f8f64b03a6 general: add tag for release Docker images 2023-09-09 01:42:38 -07:00
Lan Tian
cc818c1cc0 release: v1.3.2.1 2023-09-09 01:33:24 -07:00
Lan Tian
6224b43808 general: update GitHub actions 2023-09-09 01:32:56 -07:00
Lan Tian
17e0b14243 general: update GitHub actions 2023-09-09 01:29:49 -07:00
Lan Tian
b4c1bed9ba release: v1.3.2 2023-09-09 01:23:14 -07:00
Lan Tian
abb32abff3 general: add unit test for docker images 2023-09-08 18:45:58 -07:00
Lan Tian
b368c75aa3 frontend: fix whois client cannot get default whois port 2023-09-08 18:38:23 -07:00
Lan Tian
09405cdb38 frontend: also print whois client output on error 2023-09-08 18:22:31 -07:00
Lan Tian
f999d47d9f frontend: force enable whois client regex parser on alpine/musl 2023-09-07 19:14:04 -07:00
Lan Tian
005dfb1435 frontend: make docker image whois client try to use config file 2023-09-07 00:51:56 -07:00
Lan Tian
4bd7a6bb95 general: also release docker image to GitHub container registry 2023-09-06 21:06:10 -07:00
Lan Tian
462d76a2d0 general: reenable docker multiarch build 2023-09-06 21:02:32 -07:00
Lan Tian
58f217578c readme: add note about development version of docker image 2023-09-06 20:59:27 -07:00
Lan Tian
0e95727de1 general: reorganize GitHub Actions workflows and readd unit test 2023-09-06 20:55:45 -07:00
Lan Tian
a48f1c8040 general: move Docker image build to GitHub Actions 2023-09-06 20:48:14 -07:00
Lan Tian
81acde3a37 frontend: add whois client for more complex whois lookup 2023-09-06 20:35:30 -07:00
Lan Tian
7c0fe0d512 proxy: update traceroute version in Docker image 2023-09-06 20:33:40 -07:00
dependabot[bot]
a5f4452d02 build(deps): bump github.com/jarcoal/httpmock in /frontend (#82)
Bumps [github.com/jarcoal/httpmock](https://github.com/jarcoal/httpmock) from 1.3.0 to 1.3.1.
- [Release notes](https://github.com/jarcoal/httpmock/releases)
- [Commits](https://github.com/jarcoal/httpmock/compare/v1.3.0...v1.3.1)

---
updated-dependencies:
- dependency-name: github.com/jarcoal/httpmock
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-25 00:44:30 -07:00
Lan Tian
b237185ef7 release: v1.3.1 2023-06-18 20:14:41 -07:00
towalink
e949646790 Properly escape URL path (#81) 2023-06-10 15:14:10 -07:00
dependabot[bot]
bb479d22ae build(deps): bump github.com/spf13/viper from 1.15.0 to 1.16.0 in /proxy (#79)
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.15.0...v1.16.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-02 00:58:12 -07:00
dependabot[bot]
d40f41b4d5 build(deps): bump github.com/spf13/viper in /frontend (#80)
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.15.0...v1.16.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-02 00:58:06 -07:00
33 changed files with 825 additions and 2997 deletions

View File

@@ -1,127 +0,0 @@
version: 2.1
workflows:
docker:
jobs:
- build
- docker-frontend-deploy:
context:
- docker
requires:
- build
filters:
branches:
only: master
- docker-proxy-deploy:
context:
- docker
requires:
- build
filters:
branches:
only: master
jobs:
build:
docker:
- image: cimg/go:1.17
working_directory: /home/circleci/go/src/github.com/xddxdd/bird-lg-go
steps:
- checkout
- run:
name: Test frontend
command: |
export GO111MODULE=on
cd frontend
go get -v -t -d ./...
go test -v ./...
- run:
name: Test proxy
command: |
export GO111MODULE=on
cd proxy
go get -v -t -d ./...
go test -v ./...
docker-frontend-deploy:
machine:
image: ubuntu-2004:202111-02
environment:
BUILDX_PLATFORMS: linux/amd64,linux/arm64,linux/386,linux/arm/v7
steps:
- checkout
- run:
name: Install buildx
command: |
BUILDX_BINARY_URL="https://github.com/docker/buildx/releases/download/v0.7.1/buildx-v0.7.1.linux-amd64"
curl --output docker-buildx \
--silent --show-error --location --fail --retry 3 \
"$BUILDX_BINARY_URL"
mkdir -p ~/.docker/cli-plugins
mv docker-buildx ~/.docker/cli-plugins/
chmod a+x ~/.docker/cli-plugins/docker-buildx
docker buildx install
# Run binfmt
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- run:
name: Build Docker image
environment:
BUILD_ID: << pipeline.number >>
command: |
echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
docker buildx create --name mybuilder --use
docker buildx build \
--platform $BUILDX_PLATFORMS \
-t $DOCKER_USERNAME/bird-lg-go:circleci-build$BUILD_ID \
--progress plain \
--push frontend
docker buildx build \
--platform $BUILDX_PLATFORMS \
-t $DOCKER_USERNAME/bird-lg-go:latest \
--progress plain \
--push frontend
docker-proxy-deploy:
machine:
image: ubuntu-2004:202111-02
environment:
BUILDX_PLATFORMS: linux/amd64,linux/arm64,linux/386,linux/arm/v7
steps:
- checkout
- run:
name: Install buildx
command: |
BUILDX_BINARY_URL="https://github.com/docker/buildx/releases/download/v0.7.1/buildx-v0.7.1.linux-amd64"
curl --output docker-buildx \
--silent --show-error --location --fail --retry 3 \
"$BUILDX_BINARY_URL"
mkdir -p ~/.docker/cli-plugins
mv docker-buildx ~/.docker/cli-plugins/
chmod a+x ~/.docker/cli-plugins/docker-buildx
docker buildx install
# Run binfmt
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- run:
name: Build Docker image
environment:
BUILD_ID: << pipeline.number >>
command: |
echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
docker buildx create --name mybuilder --use
docker buildx build \
--platform $BUILDX_PLATFORMS \
-t $DOCKER_USERNAME/bird-lgproxy-go:circleci-build$BUILD_ID \
--push proxy
docker buildx build \
--platform $BUILDX_PLATFORMS \
-t $DOCKER_USERNAME/bird-lgproxy-go:latest \
--progress plain \
--push proxy

16
.github/workflows/auto-merge.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: auto-merge
on:
pull_request_target:
jobs:
auto-merge:
name: Dependabot Auto Merge
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]'
steps:
- uses: actions/checkout@v2
- uses: ahmadnassri/action-dependabot-auto-merge@v2
with:
target: minor
github-token: ${{ secrets.AUTOMERGE_TOKEN }}

127
.github/workflows/develop.yaml vendored Normal file
View File

@@ -0,0 +1,127 @@
on:
push:
branches:
- 'master'
pull_request:
branches:
- 'master'
jobs:
go-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Golang
uses: actions/setup-go@v4
- name: Run frontend unit test
run: |
export GO111MODULE=on
cd frontend
go get -v -t -d ./...
go test -v ./...
cd ..
- name: Run proxy unit test
run: |
export GO111MODULE=on
cd proxy
go get -v -t -d ./...
go test -v ./...
cd ..
docker-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Test whois binary in frontend image
run: |
docker build -t local/frontend frontend/
docker run --rm --net host --entrypoint whois local/frontend -I github.com || exit 1
docker run --rm --net host --entrypoint whois local/frontend -h whois.ripe.net github.com || exit 1
docker run --rm --net host --entrypoint whois local/frontend -h whois.ripe.net:43 github.com || exit 1
- name: Test traceroute binary in proxy image
run: |
docker build -t local/proxy proxy/
docker run --rm --net host --entrypoint traceroute local/proxy 127.0.0.1 || exit 1
docker run --rm --net host --entrypoint traceroute local/proxy ::1 || exit 1
- name: Test mtr binary in proxy image
run: |
docker build -t local/proxy:mtr -f proxy/Dockerfile.mtr proxy/
docker run --rm --net host --entrypoint mtr local/proxy:mtr -w -c1 -Z1 -G1 -b 127.0.0.1 || exit 1
docker run --rm --net host --entrypoint mtr local/proxy:mtr -w -c1 -Z1 -G1 -b ::1 || exit 1
docker-develop:
runs-on: ubuntu-latest
needs:
- go-test
- docker-test
if: github.event_name != 'pull_request'
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build frontend docker image
uses: docker/build-push-action@v4
with:
context: '{{defaultContext}}:frontend'
platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7
push: true
tags: |
xddxdd/bird-lg-go:develop
xddxdd/bird-lg-go:develop-${{ github.sha }}
ghcr.io/xddxdd/bird-lg-go:frontend-develop
ghcr.io/xddxdd/bird-lg-go:frontend-develop-${{ github.sha }}
- name: Build proxy docker image
uses: docker/build-push-action@v4
with:
context: '{{defaultContext}}:proxy'
platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7
push: true
tags: |
xddxdd/bird-lgproxy-go:develop
xddxdd/bird-lgproxy-go:develop-${{ github.sha }}
ghcr.io/xddxdd/bird-lg-go:proxy-develop
ghcr.io/xddxdd/bird-lg-go:proxy-develop-${{ github.sha }}
- name: Build proxy docker image
uses: docker/build-push-action@v4
with:
context: '{{defaultContext}}:proxy'
file: 'Dockerfile.mtr'
platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7
push: true
tags: |
xddxdd/bird-lgproxy-go:develop-mtr
xddxdd/bird-lgproxy-go:develop-${{ github.sha }}-mtr
ghcr.io/xddxdd/bird-lg-go:proxy-develop-mtr
ghcr.io/xddxdd/bird-lg-go:proxy-develop-${{ github.sha }}-mtr

View File

@@ -3,10 +3,11 @@ on:
types: [created]
jobs:
releases-matrix:
go-release:
name: Release Go Binary
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
goos: [linux, windows, darwin]
goarch: ["386", amd64, "arm", arm64]
@@ -18,18 +19,82 @@ jobs:
- goarch: "arm"
goos: windows
steps:
- uses: actions/checkout@v3
- uses: wangyoucao577/go-release-action@v1.34
- name: Checkout
uses: actions/checkout@v3
- name: Release frontend
uses: wangyoucao577/go-release-action@v1.40
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
project_path: "./frontend"
binary_name: "bird-lg-go"
- uses: wangyoucao577/go-release-action@v1.34
- name: Release proxy
uses: wangyoucao577/go-release-action@v1.40
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
project_path: "./proxy"
binary_name: "bird-lgproxy-go"
docker-release:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build frontend docker image
uses: docker/build-push-action@v4
with:
context: '{{defaultContext}}:frontend'
platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7
push: true
tags: |
xddxdd/bird-lg-go:latest
xddxdd/bird-lg-go:${{ github.event.release.tag_name }}
ghcr.io/xddxdd/bird-lg-go:frontend
ghcr.io/xddxdd/bird-lg-go:frontend-${{ github.event.release.tag_name }}
- name: Build proxy docker image
uses: docker/build-push-action@v4
with:
context: '{{defaultContext}}:proxy'
platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7
push: true
tags: |
xddxdd/bird-lgproxy-go:latest
xddxdd/bird-lgproxy-go:${{ github.event.release.tag_name }}
ghcr.io/xddxdd/bird-lg-go:proxy
ghcr.io/xddxdd/bird-lg-go:proxy-${{ github.event.release.tag_name }}
- name: Build proxy docker image
uses: docker/build-push-action@v4
with:
context: '{{defaultContext}}:proxy'
file: 'Dockerfile.mtr'
platforms: linux/amd64,linux/arm64,linux/386,linux/arm/v7
push: true
tags: |
xddxdd/bird-lgproxy-go:latest-mtr
xddxdd/bird-lgproxy-go:${{ github.event.release.tag_name }}-mtr
ghcr.io/xddxdd/bird-lg-go:proxy-mtr
ghcr.io/xddxdd/bird-lg-go:proxy-${{ github.event.release.tag_name }}-mtr

4
.gitignore vendored
View File

@@ -20,7 +20,3 @@ proxy/proxy
# don't include generated bindata file
frontend/bindata.go
# don't include generated Dockerfiles
frontend/Dockerfile.*
proxy/Dockerfile.*

View File

@@ -90,7 +90,8 @@ Example: the following docker-compose.yml entry does the same as above, but by s
```yaml
services:
bird-lg:
image: xddxdd/bird-lg-go
# Use xddxdd/bird-lg-go:develop for the latest build from master branch
image: xddxdd/bird-lg-go:latest
container_name: bird-lg
restart: always
environment:
@@ -124,7 +125,7 @@ Configuration is handled by [viper](https://github.com/spf13/viper), any config
| Config Key | Parameter | Environment Variable | Description |
| ---------- | --------- | -------------------- | ----------- |
| allowed_ips | --allowed | ALLOWED_IPS | IPs allowed to access this proxy, separated by commas. Don't set to allow all IPs. (default "") |
| allowed_ips | --allowed | ALLOWED_IPS | IPs or networks allowed to access this proxy, separated by commas. Don't set to allow all IPs. (default "") |
| bird_socket | --bird | BIRD_SOCKET | socket file for bird, set either in parameter or environment variable BIRD_SOCKET (default "/var/run/bird/bird.ctl") |
| listen | --listen | BIRDLG_PROXY_PORT | listen address, set either in parameter or environment variable BIRDLG_PROXY_PORT(default "8000") |
| traceroute_bin | --traceroute_bin | BIRDLG_TRACEROUTE_BIN | traceroute binary file, set either in parameter or environment variable BIRDLG_TRACEROUTE_BIN |
@@ -165,7 +166,9 @@ Example: the following docker-compose.yml entry does the same as above, but by s
```yaml
services:
bird-lgproxy:
image: xddxdd/bird-lgproxy-go
# Use xddxdd/bird-lgproxy-go:develop for the latest build from master branch
# Use xddxdd/bird-lgproxy-go:latest-mtr to use MTR instead of Traceroute
image: xddxdd/bird-lgproxy-go:latest
container_name: bird-lgproxy
restart: always
volumes:

View File

@@ -1 +1 @@
v1.3.0
v1.3.12

View File

@@ -1,4 +1,4 @@
FROM golang:buster AS step_0
FROM golang AS step_0
ENV CGO_ENABLED=0 GO111MODULE=on
WORKDIR /root
COPY . .
@@ -6,6 +6,28 @@ RUN go build -ldflags "-w -s" -o /frontend
################################################################################
FROM scratch AS step_1
FROM alpine:edge AS step_1
WORKDIR /root
RUN apk add --no-cache build-base pkgconf perl gettext \
libidn2-dev libidn2-static libunistring-dev libunistring-static gnu-libiconv-dev
RUN wget https://github.com/rfc1036/whois/archive/refs/tags/v5.5.18.tar.gz \
-O whois-5.5.18.tar.gz
RUN tar xvf whois-5.5.18.tar.gz \
&& cd whois-5.5.18 \
&& sed -i "s/#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L/#if 1/g" config.h \
&& make whois -j4 \
LDFLAGS="-static" CONFIG_FILE="/etc/whois.conf" PKG_CONFIG="pkg-config --static" HAVE_ICONV=1 \
&& strip /root/whois-5.5.18/whois
################################################################################
FROM scratch AS step_2
ENV PATH=/
ENV BIRDLG_WHOIS=/whois
COPY --from=step_0 /frontend /
COPY --from=step_1 /root/whois-5.5.18/whois /
COPY --from=step_1 /etc/services /etc/services
ENTRYPOINT ["/frontend"]

View File

@@ -20,6 +20,7 @@ type apiGenericResultPair struct {
type apiSummaryResultPair struct {
Server string `json:"server"`
Data []SummaryRowData `json:"data"`
Error string `json:"error,omitempty"`
}
type apiResponse struct {
@@ -70,9 +71,12 @@ func apiSummaryHandler(request apiRequest) apiResponse {
for i, result := range results {
parsedSummary, err := summaryParse(result, request.Servers[i])
if err != nil {
return apiResponse{
Error: err.Error(),
}
response.Result = append(response.Result, &apiSummaryResultPair{
Server: request.Servers[i],
Data: []SummaryRowData{},
Error: err.Error(),
})
continue
}
response.Result = append(response.Result, &apiSummaryResultPair{

View File

@@ -73,13 +73,14 @@ func TestApiSummaryHandler(t *testing.T) {
summary := response.Result[0].(*apiSummaryResultPair)
assert.Equal(t, summary.Server, "alpha")
assert.Equal(t, len(summary.Data), 7)
// Protocol list will be sorted
assert.Equal(t, summary.Data[1].Name, "device1")
assert.Equal(t, summary.Data[1].Proto, "Device")
assert.Equal(t, summary.Data[1].Table, "---")
assert.Equal(t, summary.Data[1].State, "up")
assert.Equal(t, summary.Data[1].Since, "2021-08-27")
assert.Equal(t, summary.Data[1].Info, "")
assert.Equal(t, summary.Data[0].Name, "device1")
assert.Equal(t, summary.Data[0].Proto, "Device")
assert.Equal(t, summary.Data[0].Table, "---")
assert.Equal(t, summary.Data[0].State, "up")
assert.Equal(t, summary.Data[0].Since, "2021-08-27")
assert.Equal(t, summary.Data[0].Info, "")
}
func TestApiSummaryHandlerError(t *testing.T) {
@@ -100,7 +101,10 @@ func TestApiSummaryHandlerError(t *testing.T) {
}
response := apiSummaryHandler(request)
assert.Equal(t, response.Error, "Mock backend error")
assert.Equal(t, response.Error, "")
summary := response.Result[0].(*apiSummaryResultPair)
assert.Equal(t, summary.Error, "Mock backend error")
}
func TestApiWhoisHandler(t *testing.T) {

View File

@@ -5,8 +5,19 @@
<script src="/static/jsdelivr/npm/viz.js@2.1.2/viz.min.js" crossorigin="anonymous"></script>
<script src="/static/jsdelivr/npm/viz.js@2.1.2/lite.render.js" crossorigin="anonymous"></script>
<script>
function decodeBase64(base64) {
const text = atob(base64);
const length = text.length;
const bytes = new Uint8Array(length);
for (let i = 0; i < length; i++) {
bytes[i] = text.charCodeAt(i);
}
const decoder = new TextDecoder();
return decoder.decode(bytes);
}
var viz = new Viz();
viz.renderSVGElement(atob({{ .Result }}))
viz.renderSVGElement(decodeBase64({{ .Result }}))
.then(element => {
document.getElementById("bgpmap").appendChild(element);
})

View File

@@ -7,7 +7,20 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="renderer" content="webkit">
<title>{{ html .Title }}</title>
<link rel="stylesheet" href="/static/jsdelivr/npm/bootstrap@4.5.1/dist/css/bootstrap.min.css" integrity="sha256-VoFZSlmyTXsegReQCNmbXrS4hBBUl/cexZvPmPWoJsY=" crossorigin="anonymous">
<link rel="stylesheet" href="/static/jsdelivr/npm/bootstrap@4.5.1/dist/css/bootstrap.min.css" crossorigin="anonymous">
<style>
.navbar-nav {
flex-wrap: wrap;
}
@media (min-width: 768px) {
.navbar form {
min-width: 400px;
}
.nav-link {
padding: 0.2rem 0.5rem !important;
}
}
</style>
<meta name="robots" content="noindex, nofollow">
</head>
<body>
@@ -60,7 +73,7 @@
<option value="{{ html $k }}"{{ if eq $k $.URLOption }} selected{{end}}>{{ html $v }}</option>
{{ end }}
</select>
<input name="server" class="d-none" value="{{ html $server }}">
<input name="server" class="d-none" value="{{ html ($server | pathescape) }}">
<input name="target" class="form-control" placeholder="Target" aria-label="Target" value="{{ html $target }}">
<div class="input-group-append">
<button class="btn btn-outline-success" type="submit">&raquo;</button>
@@ -74,8 +87,8 @@
{{ .Content }}
</div>
<script src="/static/jsdelivr/npm/jquery@3.5.1/dist/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="/static/jsdelivr/npm/bootstrap@4.5.1/dist/js/bootstrap.min.js" integrity="sha256-0IiaoZCI++9oAAvmCb5Y0r93XkuhvJpRalZLffQXLok=" crossorigin="anonymous"></script>
<script src="/static/jsdelivr/npm/jquery@3.5.1/dist/jquery.min.js" crossorigin="anonymous"></script>
<script src="/static/jsdelivr/npm/bootstrap@4.5.1/dist/js/bootstrap.min.js" crossorigin="anonymous"></script>
<script src="/static/sortTable.js"></script>
<script>

View File

@@ -1,6 +1,7 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"strings"
@@ -69,11 +70,15 @@ func (graph *RouteGraph) attrsToString(attrs RouteAttrs) string {
}
func (graph *RouteGraph) escape(s string) string {
result, err := json.Marshal(s)
buffer := &bytes.Buffer{}
encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
err := encoder.Encode(s)
if err != nil {
return err.Error()
} else {
return string(result)
return string(buffer.Bytes())
}
}

View File

@@ -33,7 +33,7 @@ func TestBirdRouteToGraphvizXSS(t *testing.T) {
fakeResult,
}, fakeResult)
if strings.Contains(result, "<script>") {
if strings.Contains(result, fakeResult) {
t.Errorf("XSS injection succeeded: %s", result)
}
}

View File

@@ -1,29 +1,27 @@
module github.com/xddxdd/bird-lg-go/frontend
go 1.17
go 1.23.0
require (
github.com/gorilla/handlers v1.5.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.15.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/gorilla/handlers v1.5.2
github.com/jarcoal/httpmock v1.4.1
github.com/magiconair/properties v1.8.10
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.21.0
)
require (
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jarcoal/httpmock v1.3.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.28.0 // indirect
)

File diff suppressed because it is too large Load Diff

View File

@@ -2,11 +2,14 @@ package main
import (
"io"
"net"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/jarcoal/httpmock"
)
type channelData struct {
@@ -14,6 +17,29 @@ type channelData struct {
data string
}
func createConnectionTimeoutRoundTripper(timeout int) http.RoundTripper {
context := net.Dialer{
Timeout: time.Duration(timeout) * time.Second,
}
// Prefer httpmock's transport if activated, so unit tests can work
if http.DefaultTransport == httpmock.DefaultTransport {
return httpmock.DefaultTransport
}
return &http.Transport{
DialContext: context.DialContext,
// Default options from transport.go
Proxy: http.ProxyFromEnvironment,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
}
// Send commands to lgproxy instances in parallel, and retrieve their responses
func batchRequest(servers []string, endpoint string, command string) []string {
// Channel and array for storing responses
@@ -47,7 +73,10 @@ func batchRequest(servers []string, endpoint string, command string) []string {
}
url := "http://" + hostname + ":" + strconv.Itoa(setting.proxyPort) + "/" + url.PathEscape(endpoint) + "?q=" + url.QueryEscape(command)
go func(url string, i int) {
client := http.Client{Timeout: time.Duration(setting.timeOut) * time.Second}
client := http.Client{
Transport: createConnectionTimeoutRoundTripper(setting.connectionTimeOut),
Timeout: time.Duration(setting.timeOut) * time.Second,
}
response, err := client.Get(url)
if err != nil {
ch <- channelData{i, "request failed: " + err.Error() + "\n"}

View File

@@ -7,24 +7,26 @@ import (
)
type settingType struct {
servers []string
serversDisplay []string
domain string
proxyPort int
whoisServer string
listen string
dnsInterface string
netSpecificMode string
titleBrand string
navBarBrand string
navBarBrandURL string
navBarAllServer string
navBarAllURL string
bgpmapInfo string
telegramBotName string
protocolFilter []string
nameFilter string
timeOut int
servers []string
serversDisplay []string
domain string
proxyPort int
whoisServer string
listen []string
dnsInterface string
netSpecificMode string
titleBrand string
navBarBrand string
navBarBrandURL string
navBarAllServer string
navBarAllURL string
bgpmapInfo string
telegramBotName string
protocolFilter []string
nameFilter string
timeOut int
connectionTimeOut int
trustProxyHeaders bool
}
var setting settingType
@@ -33,24 +35,29 @@ func main() {
parseSettings()
ImportTemplates()
var l net.Listener
var err error
for _, listenAddr := range setting.listen {
go func(listenAddr string) {
var l net.Listener
var err error
if strings.HasPrefix(setting.listen, "/") {
// Delete existing socket file, ignore errors (will fail later anyway)
os.Remove(setting.listen)
l, err = net.Listen("unix", setting.listen)
} else {
listenAddr := setting.listen
if !strings.Contains(listenAddr, ":") {
listenAddr = ":" + listenAddr
}
l, err = net.Listen("tcp", listenAddr)
if strings.HasPrefix(listenAddr, "/") {
// Delete existing socket file, ignore errors (will fail later anyway)
os.Remove(listenAddr)
l, err = net.Listen("unix", listenAddr)
} else {
if !strings.Contains(listenAddr, ":") {
listenAddr = ":" + listenAddr
}
l, err = net.Listen("tcp", listenAddr)
}
if err != nil {
panic(err)
}
webServerStart(l)
}(listenAddr)
}
if err != nil {
panic(err)
}
webServerStart(l)
select {}
}

View File

@@ -35,15 +35,6 @@ var optionsMap = map[string]string{
"traceroute": "traceroute ...",
}
// pre-compiled regexp and constant statemap for summary rendering
var splitSummaryLine = regexp.MustCompile(`(\w+)(\s+)(\w+)(\s+)([\w-]+)(\s+)(\w+)(\s+)([0-9\-\. :]+)(.*)`)
var summaryStateMap = map[string]string{
"up": "success",
"down": "secondary",
"start": "danger",
"passive": "info",
}
// render the page template
func renderPageTemplate(w http.ResponseWriter, r *http.Request, title string, content template.HTML) {
path := r.URL.Path[1:]
@@ -143,58 +134,23 @@ func summaryParse(data string, serverName string) (TemplateSummary, error) {
// parse each line
for _, line := range rows {
// Ignore empty lines
line = strings.TrimSpace(line)
if len(line) == 0 {
row := SummaryRowDataFromLine(line)
if row == nil {
continue
}
// Parse a total of 6 columns from bird summary
lineSplitted := splitSummaryLine.FindStringSubmatch(line)
if lineSplitted == nil {
// Filter row name
if setting.nameFilter != "" && nameFilterRegexp.MatchString(row.Name) {
continue
}
var row SummaryRowData
if len(lineSplitted) >= 2 {
row.Name = strings.TrimSpace(lineSplitted[1])
if setting.nameFilter != "" && nameFilterRegexp.MatchString(row.Name) {
continue
}
}
if len(lineSplitted) >= 4 {
row.Proto = strings.TrimSpace(lineSplitted[3])
// Filter away unwanted protocol types, if setting.protocolFilter is non-empty
found := false
for _, protocol := range setting.protocolFilter {
if strings.EqualFold(row.Proto, protocol) {
found = true
break
}
}
if len(setting.protocolFilter) > 0 && !found {
continue
}
}
if len(lineSplitted) >= 6 {
row.Table = strings.TrimSpace(lineSplitted[5])
}
if len(lineSplitted) >= 8 {
row.State = strings.TrimSpace(lineSplitted[7])
row.MappedState = summaryStateMap[row.State]
}
if len(lineSplitted) >= 10 {
row.Since = strings.TrimSpace(lineSplitted[9])
}
if len(lineSplitted) >= 11 {
row.Info = strings.TrimSpace(lineSplitted[10])
// Filter away unwanted protocol types, if setting.protocolFilter is non-empty
if len(setting.protocolFilter) > 0 && !row.ProtocolMatches(setting.protocolFilter) {
continue
}
// add to the result
args.Rows = append(args.Rows, row)
args.Rows = append(args.Rows, *row)
}
return args, nil

View File

@@ -8,8 +8,7 @@ import (
"testing"
)
const BirdSummaryData = `BIRD 2.0.8 ready.
Name Proto Table State Since Info
const BirdSummaryData = `Name Proto Table State Since Info
static1 Static master4 up 2021-08-27
static2 Static master6 up 2021-08-27
device1 Device --- up 2021-08-27

View File

@@ -9,23 +9,25 @@ import (
)
type viperSettingType struct {
Servers string `mapstructure:"servers"`
Domain string `mapstructure:"domain"`
ProxyPort int `mapstructure:"proxy_port"`
WhoisServer string `mapstructure:"whois"`
Listen string `mapstructure:"listen"`
DNSInterface string `mapstructure:"dns_interface"`
NetSpecificMode string `mapstructure:"net_specific_mode"`
TitleBrand string `mapstructure:"title_brand"`
NavBarBrand string `mapstructure:"navbar_brand"`
NavBarBrandURL string `mapstructure:"navbar_brand_url"`
NavBarAllServer string `mapstructure:"navbar_all_servers"`
NavBarAllURL string `mapstructure:"navbar_all_url"`
BgpmapInfo string `mapstructure:"bgpmap_info"`
TelegramBotName string `mapstructure:"telegram_bot_name"`
ProtocolFilter string `mapstructure:"protocol_filter"`
NameFilter string `mapstructure:"name_filter"`
TimeOut int `mapstructure:"timeout"`
Servers string `mapstructure:"servers"`
Domain string `mapstructure:"domain"`
ProxyPort int `mapstructure:"proxy_port"`
WhoisServer string `mapstructure:"whois"`
Listen []string `mapstructure:"listen"`
DNSInterface string `mapstructure:"dns_interface"`
NetSpecificMode string `mapstructure:"net_specific_mode"`
TitleBrand string `mapstructure:"title_brand"`
NavBarBrand string `mapstructure:"navbar_brand"`
NavBarBrandURL string `mapstructure:"navbar_brand_url"`
NavBarAllServer string `mapstructure:"navbar_all_servers"`
NavBarAllURL string `mapstructure:"navbar_all_url"`
BgpmapInfo string `mapstructure:"bgpmap_info"`
TelegramBotName string `mapstructure:"telegram_bot_name"`
ProtocolFilter string `mapstructure:"protocol_filter"`
NameFilter string `mapstructure:"name_filter"`
TimeOut int `mapstructure:"timeout"`
ConnectionTimeOut int `mapstructure:"connection_timeout"`
TrustProxyHeaders bool `mapstructure:"trust_proxy_headers"`
}
// Parse settings with viper, and convert to legacy setting format
@@ -50,7 +52,7 @@ func parseSettings() {
pflag.String("whois", "whois.verisign-grs.com", "whois server for queries")
viper.BindPFlag("whois", pflag.Lookup("whois"))
pflag.String("listen", "5000", "address or unix socket bird-lg is listening on")
pflag.StringSlice("listen", []string{"5000"}, "address or unix socket bird-lg is listening on")
viper.BindPFlag("listen", pflag.Lookup("listen"))
pflag.String("dns-interface", "asn.cymru.com", "dns zone to query ASN information")
@@ -87,9 +89,15 @@ func parseSettings() {
pflag.String("name-filter", "", "protocol name regex to hide in summary tables (RE2 syntax); defaults to none if not set")
viper.BindPFlag("name_filter", pflag.Lookup("name-filter"))
pflag.Int("time-out", 120, "time before request timed out, in seconds; defaults to 120 if not set")
pflag.Int("time-out", 120, "time before backend HTTP request times out, in seconds; defaults to 120 if not set")
viper.BindPFlag("timeout", pflag.Lookup("time-out"))
pflag.Int("connection-time-out", 5, "time before backend TCP connection times out, in seconds; defaults to 5 if not set")
viper.BindPFlag("connection_timeout", pflag.Lookup("connection-time-out"))
pflag.Bool("trust-proxy-headers", false, "Trust X-Forwared-For, X-Real-IP, X-Forwarded-Proto, X-Forwarded-Scheme and X-Forwarded-Host sent by the client")
viper.BindPFlag("trust_proxy_headers", pflag.Lookup("trust-proxy-headers"))
pflag.Parse()
if err := viper.ReadInConfig(); err != nil {
@@ -139,6 +147,8 @@ func parseSettings() {
setting.nameFilter = viperSettings.NameFilter
setting.timeOut = viperSettings.TimeOut
setting.connectionTimeOut = viperSettings.ConnectionTimeOut
setting.trustProxyHeaders = viperSettings.TrustProxyHeaders
fmt.Printf("%#v\n", setting)
}

View File

@@ -3,10 +3,13 @@ package main
import (
"embed"
"html/template"
"net/url"
"regexp"
"strings"
)
// import templates and other assets
//
//go:embed assets
var assets embed.FS
@@ -63,6 +66,47 @@ func (r SummaryRowData) NameContains(prefix string) bool {
return strings.Contains(r.Name, prefix)
}
func (r SummaryRowData) ProtocolMatches(protocols []string) bool {
for _, protocol := range protocols {
if strings.EqualFold(r.Proto, protocol) {
return true
}
}
return false
}
// pre-compiled regexp and constant statemap for summary rendering
var splitSummaryLine = regexp.MustCompile(`^([\w-]+)\s+(\w+)\s+([\w-]+)\s+(\w+)\s+([0-9\-\. :]+)(.*)$`)
var summaryStateMap = map[string]string{
"up": "success",
"down": "secondary",
"start": "danger",
"passive": "info",
}
func SummaryRowDataFromLine(line string) *SummaryRowData {
lineSplitted := splitSummaryLine.FindStringSubmatch(line)
if lineSplitted == nil {
return nil
}
var row SummaryRowData
row.Name = strings.TrimSpace(lineSplitted[1])
row.Proto = strings.TrimSpace(lineSplitted[2])
row.Table = strings.TrimSpace(lineSplitted[3])
row.State = strings.TrimSpace(lineSplitted[4])
row.Since = strings.TrimSpace(lineSplitted[5])
row.Info = strings.TrimSpace(lineSplitted[6])
if strings.Contains(row.Info, "Passive") {
row.MappedState = summaryStateMap["passive"]
} else {
row.MappedState = summaryStateMap[row.State]
}
return &row
}
type TemplateSummary struct {
ServerName string
Raw string
@@ -104,6 +148,12 @@ var requiredTemplates = [...]string{
"bird",
}
// define functions to be made available in templates
var funcMap = template.FuncMap{
"pathescape": url.PathEscape,
}
// import templates from embedded assets
func ImportTemplates() {
@@ -121,7 +171,7 @@ func ImportTemplates() {
}
// and add it to the template library
template, err := template.New(tmpl).Parse(string(def))
template, err := template.New(tmpl).Funcs(funcMap).Parse(string(def))
if err != nil {
panic("Unable to parse template (" + TEMPLATE_PATH + tmpl + ": " + err.Error())
}

View File

@@ -23,3 +23,67 @@ func TestSummaryRowDataNameContains(t *testing.T) {
assert.Equal(t, data.NameContains("oc"), true)
assert.Equal(t, data.NameContains("no"), false)
}
func TestSummaryRowDataFromLine(t *testing.T) {
data := SummaryRowDataFromLine("sys_device Device --- up 2025-06-27 21:23:08")
assert.Equal(t, data.Name, "sys_device")
assert.Equal(t, data.Proto, "Device")
assert.Equal(t, data.Table, "---")
assert.Equal(t, data.State, "up")
assert.Equal(t, data.Since, "2025-06-27 21:23:08")
}
func TestSummaryRowDataFromLineNumeric(t *testing.T) {
data := SummaryRowDataFromLine("12345 Device --- up 2025-06-27 21:23:08")
assert.Equal(t, data.Name, "12345")
assert.Equal(t, data.Proto, "Device")
assert.Equal(t, data.Table, "---")
assert.Equal(t, data.State, "up")
assert.Equal(t, data.Since, "2025-06-27 21:23:08")
}
func TestSummaryRowDataFromLinePipe(t *testing.T) {
data := SummaryRowDataFromLine("pipe Pipe --- up 2025-06-27 21:23:08 master4 <=> pipe_v4")
assert.Equal(t, data.Name, "pipe")
assert.Equal(t, data.Proto, "Pipe")
assert.Equal(t, data.Table, "---")
assert.Equal(t, data.State, "up")
assert.Equal(t, data.Since, "2025-06-27 21:23:08")
assert.Equal(t, data.Info, "master4 <=> pipe_v4")
}
func TestSummaryRowDataFromLineBGP(t *testing.T) {
data := SummaryRowDataFromLine("bgp BGP --- up 2025-06-30 20:45:33 Established")
assert.Equal(t, data.Name, "bgp")
assert.Equal(t, data.Proto, "BGP")
assert.Equal(t, data.Table, "---")
assert.Equal(t, data.State, "up")
assert.Equal(t, data.Since, "2025-06-30 20:45:33")
assert.Equal(t, data.Info, "Established")
}
func TestSummaryRowDataFromLineBGPPassive(t *testing.T) {
data := SummaryRowDataFromLine("passive BGP --- start 2025-06-27 21:23:08 Passive")
assert.Equal(t, data.Name, "passive")
assert.Equal(t, data.Proto, "BGP")
assert.Equal(t, data.Table, "---")
assert.Equal(t, data.State, "start")
assert.Equal(t, data.Since, "2025-06-27 21:23:08")
assert.Equal(t, data.Info, "Passive")
}
func TestSummaryRowDataFromLineWithDash(t *testing.T) {
data := SummaryRowDataFromLine("ibgp_test-01 BGP --- up 07:16:51.656 Established")
assert.Equal(t, data.Name, "ibgp_test-01")
assert.Equal(t, data.Proto, "BGP")
assert.Equal(t, data.Table, "---")
assert.Equal(t, data.State, "up")
assert.Equal(t, data.Since, "07:16:51.656")
assert.Equal(t, data.Info, "Established")
}

View File

@@ -12,19 +12,20 @@ import (
"net/url"
"os"
"strings"
"sync/atomic"
"github.com/gorilla/handlers"
)
var primitiveMap = map[string]string{
"summary": "show protocols",
"detail": "show protocols all %s",
"route_from_protocol": "show route protocol %s",
"route_from_protocol_all": "show route protocol %s all",
"route_from_protocol_primary": "show route protocol %s primary",
"route_from_protocol_all_primary": "show route protocol %s all primary",
"route_filtered_from_protocol": "show route filtered protocol %s",
"route_filtered_from_protocol_all": "show route filtered protocol %s all",
"detail": "show protocols all '%s'",
"route_from_protocol": "show route protocol '%s'",
"route_from_protocol_all": "show route protocol '%s' all",
"route_from_protocol_primary": "show route protocol '%s' primary",
"route_from_protocol_all_primary": "show route protocol '%s' all primary",
"route_filtered_from_protocol": "show route filtered protocol '%s'",
"route_filtered_from_protocol_all": "show route filtered protocol '%s' all",
"route_from_origin": "show route where bgp_path.last = %s",
"route_from_origin_all": "show route where bgp_path.last = %s all",
"route_from_origin_primary": "show route where bgp_path.last = %s primary",
@@ -39,8 +40,10 @@ var primitiveMap = map[string]string{
"traceroute": "%s",
}
var webServerPrepared uint32 = 0
// serve up a generic error
func serverError(w http.ResponseWriter, r *http.Request) {
func serverError(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("500 Internal Server Error"))
}
@@ -75,7 +78,6 @@ func webHandlerWhois(w http.ResponseWriter, r *http.Request) {
// serve up results from bird
func webBackendCommunicator(endpoint string, command string) func(w http.ResponseWriter, r *http.Request) {
backendCommandPrimitive, commandPresent := primitiveMap[command]
if !commandPresent {
panic("invalid command: " + command)
@@ -193,12 +195,11 @@ func webHandlerBGPMap(endpoint string, command string) func(w http.ResponseWrite
}
}
// set up routing paths and start webserver
func webServerStart(l net.Listener) {
// set up routing paths
func webServerPrepare() {
// redirect main page to all server summary
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/summary/"+url.PathEscape(strings.Join(setting.servers, "+")), 302)
http.Redirect(w, r, "/summary/"+url.PathEscape(strings.Join(setting.servers, "+")), http.StatusFound)
})
// serve static pages using embedded assets from template.go
@@ -237,7 +238,19 @@ func webServerStart(l net.Listener) {
http.HandleFunc("/whois/", webHandlerWhois)
http.HandleFunc("/api/", apiHandler)
http.HandleFunc("/telegram/", webHandlerTelegramBot)
// Start HTTP server
http.Serve(l, handlers.LoggingHandler(os.Stdout, http.DefaultServeMux))
}
// start webserver
func webServerStart(l net.Listener) {
if atomic.SwapUint32(&webServerPrepared, 1) == 0 {
webServerPrepare()
}
var handler http.Handler
handler = http.DefaultServeMux
if setting.trustProxyHeaders {
handler = handlers.ProxyHeaders(handler)
}
handler = handlers.LoggingHandler(os.Stdout, handler)
http.Serve(l, handler)
}

View File

@@ -25,13 +25,14 @@ func whois(s string) string {
cmd := exec.Command(args[0], args[1:]...)
output, err := cmd.CombinedOutput()
if err != nil {
return err.Error()
}
if len(output) > 65535 {
output = output[:65535]
}
return string(output)
if err != nil {
return err.Error() + "\n" + string(output)
} else {
return string(output)
}
} else {
buf := make([]byte, 65536)
@@ -50,7 +51,7 @@ func whois(s string) string {
n, err := io.ReadFull(conn, buf)
if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
return err.Error()
return err.Error() + "\n" + string(buf[:n])
}
return string(buf[:n])
}

View File

@@ -88,7 +88,7 @@ func TestWhoisWithoutServer(t *testing.T) {
}
func TestWhoisConnectionError(t *testing.T) {
setting.whoisServer = "127.0.0.1:0"
setting.whoisServer = "127.0.0.1:1"
result := whois("AS6939")
if !strings.Contains(result, "connect: connection refused") {
t.Errorf("Whois AS6939 without server produced output, got %s", result)

View File

@@ -1,4 +1,4 @@
FROM golang:buster AS step_0
FROM golang AS step_0
ENV CGO_ENABLED=0 GO111MODULE=on
WORKDIR /root
@@ -11,17 +11,18 @@ FROM alpine:edge AS step_1
WORKDIR /root
RUN apk add --no-cache build-base linux-headers
RUN wget https://sourceforge.net/projects/traceroute/files/traceroute/traceroute-2.1.0/traceroute-2.1.0.tar.gz/download \
-O traceroute-2.1.0.tar.gz
RUN tar xvf traceroute-2.1.0.tar.gz \
&& cd traceroute-2.1.0 \
RUN wget https://sourceforge.net/projects/traceroute/files/traceroute/traceroute-2.1.3/traceroute-2.1.3.tar.gz/download \
-O traceroute-2.1.3.tar.gz
RUN tar xvf traceroute-2.1.3.tar.gz \
&& cd traceroute-2.1.3 \
&& make -j4 LDFLAGS="-static" \
&& strip /root/traceroute-2.1.0/traceroute/traceroute
&& strip /root/traceroute-2.1.3/traceroute/traceroute
################################################################################
FROM scratch AS step_2
ENV PATH=/
COPY --from=step_0 /proxy /
COPY --from=step_1 /root/traceroute-2.1.0/traceroute/traceroute /
COPY --from=step_1 /root/traceroute-2.1.3/traceroute/traceroute /
ENTRYPOINT ["/proxy"]

31
proxy/Dockerfile.mtr Normal file
View File

@@ -0,0 +1,31 @@
FROM golang AS step_0
ENV CGO_ENABLED=0 GO111MODULE=on
WORKDIR /root
COPY . .
RUN go build -ldflags "-w -s" -o /proxy
################################################################################
FROM alpine:edge AS step_1
WORKDIR /root
RUN apk add --no-cache build-base linux-headers
RUN wget https://www.bitwizard.nl/mtr/files/mtr-0.94.tar.gz \
-O mtr-0.94.tar.gz
RUN tar xvf mtr-0.94.tar.gz \
&& cd mtr-0.94 \
&& ./configure --without-gtk --without-ncurses --without-jansson --without-ipinfo --disable-bash-completion \
&& make -j4 LDFLAGS="-static" \
&& strip /root/mtr-0.94/mtr \
&& strip /root/mtr-0.94/mtr-packet
################################################################################
FROM scratch AS step_2
ENV PATH=/
COPY --from=step_0 /proxy /
COPY --from=step_1 /root/mtr-0.94/mtr /
COPY --from=step_1 /root/mtr-0.94/mtr-packet /
ENTRYPOINT ["/proxy"]

View File

@@ -1,28 +1,26 @@
module github.com/xddxdd/bird-lg-go/proxy
go 1.17
go 1.23.0
require (
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/gorilla/handlers v1.5.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.15.0
github.com/gorilla/handlers v1.5.2
github.com/magiconair/properties v1.8.10
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.21.0
)
require (
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.28.0 // indirect
)

File diff suppressed because it is too large Load Diff

View File

@@ -22,8 +22,8 @@ func invalidHandler(httpW http.ResponseWriter, httpR *http.Request) {
}
func hasAccess(remoteAddr string) bool {
// setting.allowedIPs will always have at least one element because of how it's defined
if len(setting.allowedIPs) == 0 {
// setting.allowedNets will always have at least one element because of how it's defined
if len(setting.allowedNets) == 0 {
return true
}
@@ -40,8 +40,8 @@ func hasAccess(remoteAddr string) bool {
return false
}
for _, allowedIP := range setting.allowedIPs {
if ipObject.Equal(allowedIP) {
for _, net := range setting.allowedNets {
if net.Contains(ipObject) {
return true
}
}
@@ -49,7 +49,7 @@ func hasAccess(remoteAddr string) bool {
return false
}
// Access handler, check to see if client IP in allowed IPs, continue if it is, send to invalidHandler if not
// Access handler, check to see if client IP in allowed nets, continue if it is, send to invalidHandler if not
func accessHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(httpW http.ResponseWriter, httpR *http.Request) {
if hasAccess(httpR.RemoteAddr) {
@@ -61,12 +61,12 @@ func accessHandler(next http.Handler) http.Handler {
}
type settingType struct {
birdSocket string
listen string
allowedIPs []net.IP
tr_bin string
tr_flags []string
tr_raw bool
birdSocket string
listen []string
allowedNets []*net.IPNet
tr_bin string
tr_flags []string
tr_raw bool
}
var setting settingType
@@ -76,32 +76,40 @@ func main() {
parseSettings()
tracerouteAutodetect()
fmt.Printf("Listening on %s...\n", setting.listen)
mux := http.NewServeMux()
var l net.Listener
var err error
// Prepare HTTP server
mux.HandleFunc("/", invalidHandler)
mux.HandleFunc("/bird", birdHandler)
mux.HandleFunc("/bird6", birdHandler)
mux.HandleFunc("/traceroute", tracerouteHandler)
mux.HandleFunc("/traceroute6", tracerouteHandler)
if strings.HasPrefix(setting.listen, "/") {
// Delete existing socket file, ignore errors (will fail later anyway)
os.Remove(setting.listen)
l, err = net.Listen("unix", setting.listen)
} else {
listenAddr := setting.listen
if !strings.Contains(listenAddr, ":") {
listenAddr = ":" + listenAddr
}
l, err = net.Listen("tcp", listenAddr)
for _, listenAddr := range setting.listen {
go func(addr string) {
fmt.Printf("Listening on %s...\n", addr)
var l net.Listener
var err error
if strings.HasPrefix(addr, "/") {
// Delete existing socket file, ignore errors (will fail later anyway)
os.Remove(addr)
l, err = net.Listen("unix", addr)
} else {
if !strings.Contains(addr, ":") {
addr = ":" + addr
}
l, err = net.Listen("tcp", addr)
}
if err != nil {
panic(err)
}
http.Serve(l, handlers.LoggingHandler(os.Stdout, accessHandler(mux)))
}(listenAddr)
}
if err != nil {
panic(err)
}
// Start HTTP server
http.HandleFunc("/", invalidHandler)
http.HandleFunc("/bird", birdHandler)
http.HandleFunc("/bird6", birdHandler)
http.HandleFunc("/traceroute", tracerouteHandler)
http.HandleFunc("/traceroute6", tracerouteHandler)
http.Serve(l, handlers.LoggingHandler(os.Stdout, accessHandler(http.DefaultServeMux)))
select {}
}

View File

@@ -10,42 +10,61 @@ import (
)
func TestHasAccessNotConfigured(t *testing.T) {
setting.allowedIPs = []net.IP{}
setting.allowedNets = []*net.IPNet{}
assert.Equal(t, hasAccess("whatever"), true)
}
func TestHasAccessAllowIPv4(t *testing.T) {
setting.allowedIPs = []net.IP{net.ParseIP("1.2.3.4")}
_, netip, _ := net.ParseCIDR("1.2.3.4/32")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("1.2.3.4:4321"), true)
}
func TestHasAccessAllowIPv4Net(t *testing.T) {
_, netip, _ := net.ParseCIDR("1.2.3.0/24")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("1.2.3.4:4321"), true)
}
func TestHasAccessDenyIPv4(t *testing.T) {
setting.allowedIPs = []net.IP{net.ParseIP("4.3.2.1")}
_, netip, _ := net.ParseCIDR("4.3.2.1/32")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("1.2.3.4:4321"), false)
}
func TestHasAccessAllowIPv6(t *testing.T) {
setting.allowedIPs = []net.IP{net.ParseIP("2001:db8::1")}
_, netip, _ := net.ParseCIDR("2001:db8::1/128")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("[2001:db8::1]:4321"), true)
}
func TestHasAccessAllowIPv6Net(t *testing.T) {
_, netip, _ := net.ParseCIDR("2001:db8::/64")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("[2001:db8::1]:4321"), true)
}
func TestHasAccessAllowIPv6DifferentForm(t *testing.T) {
setting.allowedIPs = []net.IP{net.ParseIP("2001:0db8::1")}
_, netip, _ := net.ParseCIDR("2001:db8::1/128")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("[2001:db8::1]:4321"), true)
}
func TestHasAccessDenyIPv6(t *testing.T) {
setting.allowedIPs = []net.IP{net.ParseIP("2001:db8::2")}
_, netip, _ := net.ParseCIDR("2001:db8::2/128")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("[2001:db8::1]:4321"), false)
}
func TestHasAccessBadClientIP(t *testing.T) {
setting.allowedIPs = []net.IP{net.ParseIP("1.2.3.4")}
_, netip, _ := net.ParseCIDR("1.2.3.4/32")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("not an IP"), false)
}
func TestHasAccessBadClientIPPort(t *testing.T) {
setting.allowedIPs = []net.IP{net.ParseIP("1.2.3.4")}
_, netip, _ := net.ParseCIDR("1.2.3.4/32")
setting.allowedNets = []*net.IPNet{netip}
assert.Equal(t, hasAccess("not an IP:not a port"), false)
}
@@ -57,7 +76,8 @@ func TestAccessHandlerAllow(t *testing.T) {
r.RemoteAddr = "1.2.3.4:4321"
w := httptest.NewRecorder()
setting.allowedIPs = []net.IP{net.ParseIP("1.2.3.4")}
_, netip, _ := net.ParseCIDR("1.2.3.4/32")
setting.allowedNets = []*net.IPNet{netip}
wrappedHandler.ServeHTTP(w, r)
assert.Equal(t, w.Code, http.StatusNotFound)
@@ -71,7 +91,8 @@ func TestAccessHandlerDeny(t *testing.T) {
r.RemoteAddr = "1.2.3.4:4321"
w := httptest.NewRecorder()
setting.allowedIPs = []net.IP{net.ParseIP("4.3.2.1")}
_, netip, _ := net.ParseCIDR("4.3.2.1/32")
setting.allowedNets = []*net.IPNet{netip}
wrappedHandler.ServeHTTP(w, r)
assert.Equal(t, w.Code, http.StatusInternalServerError)

Some files were not shown because too many files have changed in this diff Show More