{"id":23008373,"url":"https://github.com/mayuresh82/gocast","last_synced_at":"2026-01-12T06:04:20.902Z","repository":{"id":35513485,"uuid":"154246002","full_name":"mayuresh82/gocast","owner":"mayuresh82","description":"GoCast is a tool for controlled BGP route announcements from a host","archived":false,"fork":false,"pushed_at":"2023-10-04T22:46:56.000Z","size":16985,"stargazers_count":93,"open_issues_count":10,"forks_count":26,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-08-14T04:45:50.666Z","etag":null,"topics":["anycast","bgp","consul","docker","exabgp","golang","load-balancing","nomad","vip"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mayuresh82.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-23T02:02:23.000Z","updated_at":"2025-07-15T20:49:19.000Z","dependencies_parsed_at":"2024-06-18T22:41:40.044Z","dependency_job_id":"34697a45-7429-40a4-94f6-9bc4abe330f0","html_url":"https://github.com/mayuresh82/gocast","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/mayuresh82/gocast","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayuresh82%2Fgocast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayuresh82%2Fgocast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayuresh82%2Fgocast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayuresh82%2Fgocast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mayuresh82","download_url":"https://codeload.github.com/mayuresh82/gocast/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayuresh82%2Fgocast/sbom","scorecard":{"id":630499,"data":{"date":"2025-08-11","repo":{"name":"github.com/mayuresh82/gocast","commit":"6f26e869645fe63ff37278ba8fe3d63b0498dda9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":5,"reason":"Found 7/12 approved changesets -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/go.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: gocast:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.0.3 not signed: https://api.github.com/repos/mayuresh82/gocast/releases/23295685","Warn: release artifact v1.0.3 does not have provenance: https://api.github.com/repos/mayuresh82/gocast/releases/23295685"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/mayuresh82/gocast/go.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/mayuresh82/gocast/go.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:15: pin your Docker image by updating alpine:latest to alpine:latest@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Warn: goCommand not pinned by hash: vendor/github.com/pelletier/go-toml/benchmark.sh:10","Warn: goCommand not pinned by hash: vendor/github.com/pelletier/go-toml/benchmark.sh:11","Warn: goCommand not pinned by hash: vendor/github.com/pelletier/go-toml/test.sh:26","Warn: goCommand not pinned by hash: vendor/github.com/pelletier/go-toml/test.sh:27","Warn: goCommand not pinned by hash: vendor/github.com/pelletier/go-toml/test.sh:28","Warn: goCommand not pinned by hash: vendor/github.com/pelletier/go-toml/test.sh:29","Warn: goCommand not pinned by hash: vendor/google.golang.org/grpc/vet.sh:36","Warn: goCommand not pinned by hash: vendor/google.golang.org/grpc/vet.sh:47","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 containerImage dependencies pinned","Info:   0 out of   8 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 27 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"26 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2025-3372 / GHSA-6wxm-mpqj-6jpf","Warn: Project is vulnerable to: GO-2025-3631 / GHSA-7m35-vw2c-696v","Warn: Project is vulnerable to: GO-2025-3633 / GHSA-c5jg-wr5v-2wp2","Warn: Project is vulnerable to: GO-2025-3630 / GHSA-hqhq-hp5x-xp3w","Warn: Project is vulnerable to: GO-2025-3632 / GHSA-mfvv-mgf6-q25r","Warn: Project is vulnerable to: GO-2024-2611 / GHSA-8r3f-844c-mc37","Warn: Project is vulnerable to: GO-2022-0493 / GHSA-p782-xgp4-8hr8","Warn: Project is vulnerable to: GO-2020-0017 / GHSA-w73w-5m7g-f7qc","Warn: Project is vulnerable to: GO-2021-0053 / GHSA-c3h9-896r-86jm","Warn: Project is vulnerable to: GO-2022-0322 / GHSA-cg3q-j54f-5p7p","Warn: Project is vulnerable to: GO-2020-0036 / GHSA-wxc4-f4m6-wwqv","Warn: Project is vulnerable to: GO-2022-0536 / GHSA-39qc-96h7-956f / GHSA-hgr8-6h9x-f7q9","Warn: Project is vulnerable to: GO-2022-0236 / GHSA-h86h-8ppg-mxmh","Warn: Project is vulnerable to: GO-2021-0238 / GHSA-83g2-8m93-v3w7","Warn: Project is vulnerable to: GO-2022-0288","Warn: Project is vulnerable to: GO-2022-0969 / GHSA-69cg-p879-7622","Warn: Project is vulnerable to: GO-2022-1144 / GHSA-xrjj-mj9h-534m","Warn: Project is vulnerable to: GO-2023-1571 / GHSA-vvpx-j8f3-3w6h","Warn: Project is vulnerable to: GO-2023-1988 / GHSA-2wrh-6pvc-2jm9","Warn: Project is vulnerable to: GO-2023-2102 / GHSA-4374-p667-p6c8","Warn: Project is vulnerable to: GHSA-qppj-fm5r-hxr3","Warn: Project is vulnerable to: GO-2024-2687 / GHSA-4v7x-pqxf-cx7m","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2025-3488 / GHSA-6v2p-p543-phr9"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T07:47:32.227Z","repository_id":35513485,"created_at":"2025-08-21T07:47:32.227Z","updated_at":"2025-08-21T07:47:32.227Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28336084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"online","status_checked_at":"2026-01-12T02:00:08.677Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anycast","bgp","consul","docker","exabgp","golang","load-balancing","nomad","vip"],"created_at":"2024-12-15T09:00:51.821Z","updated_at":"2026-01-12T06:04:20.887Z","avatar_url":"https://github.com/mayuresh82.png","language":"Go","funding_links":[],"categories":["Plugins"],"sub_categories":["User Interfaces and Dashboards"],"readme":"# GoCast\n\nGocast is a tool that does controller BGP route advertisements from a host. It runs custom defined healthchecks and announces or withdraws routes (most commonly VIPs or Virtual IPs) to a BGP peer.\nThe most common use case for this is anycast (vip) based load balancing for infrastructure services such as DNS, Syslog etc where several instances are available in geographically diverse regions that announce the same anycast VIP, and clients then get sent to the closest instance.\n\nFor some practical examples and more details, check out this blog post : https://mayuresh82.github.io/2020/11/28/automatic_service_discovery_anycast/\n\n# Looking for code reviewers\nIf you are interested in being a reviewer and/or co-maintainer, please reach out to @mayuresh82 !\n\n## Installation\nUse the docker container at mayuresh82/gocast or compile from source:\n\n1. [Install Go](https://golang.org/doc/install)\n2. [Setup your GOPATH](https://golang.org/doc/code.html#GOPATH)\n3. Run `go get -d github.com/mayuresh82/gocast`\n4. Run `cd $GOPATH/src/github.com/mayuresh82/gocast`\n5. Run `make`\n\n## Design\n\nGoCast uses [GoBGP](https://github.com/osrg/gobgp) as a library to peer with remote neighbors and announce/withdraw prefixes. It really is just a healthcheck based wrapper around GoBGP. Remote peers can be autodiscovered or statically configured. A peer will most commonly be a Top-Of-Rack (TOR) switch.\n\nTypically you would run GoCast on the same hosts as the service that needs to be monitored.\nOnce an application \"registers\" with GoCast, GoCast then runs the predefined health monitors/checks and if they fail (e.g a service listening on a specific port), the routes are withdrawn thereby taking the node out of service.\n\nGoCast uses a config file to define agent parameters (http addr, consul server addr, timers etc) and BGP parameters (local/peer ASN, peer IP, origin/communnities). See example config.yaml.\n\n### Registration\nAn application can register with the GoCast instance running on the same host using one of the following methods:\n1. http call : Make an http get call with the required parameters. For example:\n```\nhttp://gocast-addr/register?name=\u003cappName\u003e\u0026vip=\u003caddr/mask\u003e\u0026monitor=port:tcp:5000\n```\nMultiple monitors can be defined and the healthcheck succeeds only when all the monitors pass.\n\n2. Custom defined apps in config.yaml. See the example config.yaml for syntax examples\n\n3. Consul based auto-discovery (see below)\n\n## Monitors\nA health monitor can either be a port monitor, an exec monitor or consul. Port monitors are specified as *port:protocol:portnum* , exec monitors run a script or arbitrary command and pass on successful exit (status code 0), specified as *exec:command* and consul monitors use consul's own healthchecks, specifed simply as *consul*\n\n## Consul Integration\nGoCast supports consul for automatic service discovery and healthchecking. For this to work, the following needs to be setup:\n- The host running GoCast needs to have the environment variable **CONSUL_NODE** set to the hostname in consul\n\n- The following tags must be set in consul for autodiscovery to work:\n\n`enable_gocast` : required\n\n`gocast_vip=\u003caddr/mask\u003e`: required\n\n`gocast_monitor=monitor:params`: optional\n\nIf `gocast_monitor=consul` is specified, then GoCast uses the defined healthchecks in consul as the health monitors for the service.\n\nIf `gocast_nat=protocol:listenPort:destinationPort` is specified, then GoCast will create NAT rules, via iptables, and map traffic destined to the assigned VIP and the specified `listenPort` to the physical IP and `destinationPort`.\n\nExample: `gocast_nat=tcp:53:8053` and `gocast_nat=udp:53:8053`\n\nAlternatively, if `gocast_nat=protocol:port` is specified, then GoCast will create NAT rules, via iptables, and map traffic destined to the assigned VIP and the specified `port` to the physical IP and `port`.\n\nExample: `gocast_nat=tcp:53` and `gocast_nat=udp:53`\n\n## Docker support\nThe docker image at mayuresh82/gocast can be used to run GoCast inside a container. In order for GoCast to manipulate the host network stack correctly, the container needs to run with NET_ADMIN capablity and host mode networking. For example:\n```\ndocker run -d --cap-add=NET_ADMIN --net=host -v /path/to/host-config:/path/to/container-config mayuresh82/gocast -config=/path/to/config.yaml -logtostderr\n```\n\n**Caveats and workarounds**\n\nThe service to be monitored can also be run inside a container, provided the published service ports are set to listen on 0.0.0.0 (not a specific IP.)\nCertain orchestration solutions such as Nomad run the docker containers with published ports listening only on the physical IP address. This will cause all requests to the app to fail, because the host does not listen on the loopback interface any more (which GoCast uses and assigns the VIP IP to). To work=around this there are 2 options:\n\n- Start the service container in host networking mode OR\n\n- Register NAT rules for your service with GoCast for the required protocol/port(s). GoCast will then create iptables NAT rules that map traffic destined to the assigned VIP to the physical IP address. This is achieved by adding the `nat=protocol:listenPort:destinationPort` in the http query or `gocast_nat=protocol:listenPort:destinationPort` tag(s) in consul, as shown in the Consul integration section above.\n\n**Why not just use ExaBGP or something similar ?**\n\nExaBGP is commonly used for this purpose, with bash scripts and such.  However, I found that there no standard way of doing things and there is little to no support for containerized services. Also ExaBGP's API is clunky and documentation is almost non existent. GoCast provides an out of the box solution without hacking together a bunch of scripts.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmayuresh82%2Fgocast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmayuresh82%2Fgocast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmayuresh82%2Fgocast/lists"}