presbrey/beyond
GitHub: presbrey/beyond
一个受 Google BeyondCorp 启发的轻量级访问代理,通过 SSO 认证在零信任过渡期替代 VPN 以安全暴露内网服务。
Stars: 254 | Forks: 25
[](https://github.com/presbrey/beyond/actions/workflows/go.yml)
[](https://github.com/presbrey/beyond/actions/workflows/docker-publish.yml)
[](https://goreportcard.com/report/github.com/presbrey/beyond)
[](https://opensource.org/licenses/Apache-2.0)
# 超越
控制对周边网络之外服务的访问。结合 split-DNS 进行部署,以在零信任过渡期间替代 VPN。受 Google BeyondCorp 研究启发:https://research.google.com/pubs/pub45728.html
## 功能
- 通过以下方式进行身份验证:
- OpenID Connect
- OAuth2 Tokens
- SAMLv2
- 通过 https://your.json 自动化配置
- 自定义 Nexthop 学习(通过 Favorite Ports:443, 80, ...)
- 支持 WebSockets
- 支持 GitHub Enterprise
- 支持 Private Docker Registry APIs (v2)
- 使用 ElasticSearch 进行分析
## 安装
```
$ docker pull presbrey/beyond
```
或者:
```
$ go get -u -x github.com/presbrey/beyond
```
## 使用方法
### 配置示例
#### 基础 OIDC 设置
```
docker run --rm -p 80:80 presbrey/beyond httpd \
-beyond-host beyond.example.com \
-cookie-domain .example.com \
-oidc-issuer https://your-idp.com/oidc \
-oidc-client-id your-client-id \
-oidc-client-secret your-client-secret
```
#### 带有访问控制的 OIDC
```
docker run --rm -p 80:80 presbrey/beyond httpd \
-beyond-host beyond.example.com \
-cookie-domain .example.com \
-oidc-issuer https://accounts.google.com \
-oidc-client-id your-google-client-id \
-oidc-client-secret your-google-client-secret \
-allowlist-url https://raw.githubusercontent.com/yourorg/config/main/allowlist.json \
-fence-url https://raw.githubusercontent.com/yourorg/config/main/fence.json \
-sites-url https://raw.githubusercontent.com/yourorg/config/main/sites.json
```
#### 带有 Docker Registry 支持的 SAML
```
docker run --rm -p 80:80 \
-v /path/to/certs:/certs \
presbrey/beyond httpd \
-beyond-host beyond.example.com \
-cookie-domain .example.com \
-saml-metadata-url https://your-idp.com/metadata \
-saml-cert-file /certs/saml.cert \
-saml-key-file /certs/saml.key \
-docker-urls https://harbor.example.com,https://ghcr.example.com
```
#### 带有 Token Auth 的 GitHub Enterprise
```
docker run --rm -p 80:80 presbrey/beyond httpd \
-beyond-host beyond.example.com \
-cookie-domain .example.com \
-oidc-issuer https://github.example.com \
-oidc-client-id your-github-app-id \
-oidc-client-secret your-github-app-secret \
-token-base https://api.github.example.com/user \
-docker-urls https://docker.pkg.github.example.com
```
#### 带有 Elasticsearch 日志记录的生产环境
```
docker run --rm -p 80:80 presbrey/beyond httpd \
-beyond-host beyond.example.com \
-cookie-domain .example.com \
-oidc-issuer https://login.example.com \
-oidc-client-id production-client-id \
-oidc-client-secret production-client-secret \
-allowlist-url https://config.example.com/allowlist.json \
-fence-url https://config.example.com/fence.json \
-sites-url https://config.example.com/sites.json \
-hosts-url https://config.example.com/hosts.json \
-log-elastic https://elasticsearch.example.com:9200 \
-log-json \
-error-email support@example.com
```
### Cookie 密钥管理
Beyond 需要一个加密密钥用于会话 cookie 加密。您有两种选择:
#### 选项 1:自动生成密钥(开发/测试)
如果未提供 cookie 密钥,Beyond 将在启动时自动生成一个安全的随机密钥并将其记录到日志中:
```
WARN[0000] No cookie key provided, generated random key for this session:
WARN[0000] -cookie-key a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
WARN[0000] IMPORTANT: Sessions will not persist across restarts. Set explicit key for production use.
```
#### 选项 2:显式密钥(生产环境)
对于生产环境部署,请始终设置显式密钥以保持会话持久性:
```
# 生成 key 一次并重复使用
export COOKIE_KEY=$(openssl rand -hex 32)
docker run --rm -p 80:80 presbrey/beyond httpd \
-cookie-key "$COOKIE_KEY" \
# ... other parameters
```
### 主机管理
Beyond 支持将后端主机名重写为不同的值,并限制仅对特定主机的访问。这对于遗留系统迁移、内部名称映射和创建安全的主机白名单非常有用。
#### 主机重写
您可以通过两种方式配置主机重写:
**选项 1:命令行**
替换值可以包含协议和端口,用于高级路由:
```
docker run --rm -p 80:80 presbrey/beyond httpd \
-hosts-csv "old-api.example.com=https://new-api.example.com:8443,legacy.corp=http://modern.corp.example.com:8080" \
# ... other parameters
```
**选项 2:JSON 配置文件**
创建一个包含主机名映射的 JSON 文件。替换值可以包含协议和端口:
```
{
"old-api.example.com": "new-api.example.com",
"legacy.mycompany.net": "https://modern.mycompany.net:8443",
"internal.corp": "http://internal.corp.example.com:8080",
"secure.app": "https://secure.app.example.com"
}
```
然后引用它:
```
docker run --rm -p 80:80 presbrey/beyond httpd \
-hosts-url https://config.example.com/hosts.json \
# ... other parameters
```
#### 协议和端口支持
当替换值包含完整 URL(带有 `http://` 或 `https://`)时,Beyond 会提取协议和端口信息用于后端连接:
- **简单主机名替换**:`"old.example.com": "new.example.com"` - 保留原始协议和端口
- **指定协议**:`"legacy.api": "https://modern.api"` - 强制与后端使用 HTTPS 连接
- **指定端口**:`"internal.app": "http://internal.app:8080"` - 连接到特定端口
- **完整 URL**:`"old.secure": "https://new.secure:9443"` - 同时指定协议和端口
子域名匹配会保留:如果 `api.legacy.com` 映射到 `https://api.modern.com:8443`,那么 `service.api.legacy.com` 将变为在 8443 端口上使用 HTTPS 的 `service.api.modern.com`。
#### 主机白名单(hosts-only 模式)
使用 `-hosts-only` 标志限制仅访问在您的主机映射中定义的主机:
```
docker run --rm -p 80:80 presbrey/beyond httpd \
-hosts-url https://config.example.com/hosts.json \
-hosts-only \
# ... other parameters
```
当 `hosts-only` 启用时:
- 仅允许在映射中的主机(来自 `-hosts-csv` 或 `-hosts-url`)
- 对未映射主机的请求将返回 403 "Host not allowed"
- 支持子域名匹配(例如,`api.example.com` 匹配 `example.com`)
命令行和 URL 映射可以同时使用 - 它们会在启动时合并。
### 命令行选项
```
$ docker run --rm -p 80:80 presbrey/beyond httpd --help
-401-code int
status to respond when a user needs authentication (default 418)
-404-message string
message to use when backend apps do not respond (default "Please contact the application administrators to setup access.")
-allowlist-url string
URL to site allowlist (eg. https://github.com/myorg/beyond-config/main/raw/allowlist.json)
-beyond-host string
hostname of self (default "beyond.myorg.net")
-cookie-age int
MaxAge setting in seconds (default 21600)
-cookie-domain string
session cookie domain (default ".myorg.net")
-cookie-key string
64-char hex key for cookie encryption (example: "t8yG1gmeEyeb7pQpw544UeCTyDfPkE6uQ599vrruZRhLFC144thCRZpyHM7qGDjt")
-cookie-name string
session cookie name (default "beyond")
-debug
set debug loglevel (default true)
-docker-auth-scheme string
(only for testing) (default "https")
-docker-url string
when there is only one (legacy option) (default "https://docker.myorg.net")
-docker-urls string
csv of docker server base URLs (default "https://harbor.myorg.net,https://ghcr.myorg.net")
-error-color string
css h1 color for errors (default "#69b342")
-error-email string
address for help (eg. support@mycompany.com)
-error-plain
disable html on error pages
-federate-access string
shared secret, 64 chars, enables federation
-federate-secret string
internal secret, 64 chars
-fence-url string
URL to user fencing config (eg. https://github.com/myorg/beyond-config/main/raw/fence.json)
-ghp-hosts string
CSV of github packages domains (default "ghp.myorg.net")
-header-prefix string
prefix extra headers with this string (default "Beyond")
-health-path string
URL of the health endpoint (default "/healthz/ping")
-health-reply string
response body of the health endpoint (default "ok")
-home-url string
redirect users here from root (default "https://google.com")
-host-masq string
rewrite nexthop hosts (format: from1=to1,from2=to2)
-http string
listen address (default ":80")
-insecure-skip-verify
allow TLS backends without valid certificates
-learn-dial-timeout duration
skip port after this connection timeout (default 8s)
-learn-http-ports string
after HTTPS, try these HTTP ports (csv) (default "80,8080,6000,6060,7000,7070,8000,9000,9200,15672")
-learn-https-ports string
try learning these backend HTTPS ports (csv) (default "443,4443,6443,8443,9443,9090")
-learn-nexthops
set false to require explicit allowlisting (default true)
-log-elastic string
csv of elasticsearch servers
-log-elastic-interval duration
how often to commit bulk updates (default 1s)
-log-elastic-prefix string
insert this on the front of elastic indexes (default "beyond")
-log-elastic-workers int
bulk commit workers (default 3)
-log-http
enable HTTP logging to stdout
-log-json
use json output (logrus)
-log-xff
include X-Forwarded-For in logs (default true)
-oidc-client-id string
OIDC client ID (default "f8b8b020-4ec2-0135-6452-027de1ec0c4e43491")
-oidc-client-secret string
OIDC client secret (default "cxLF74XOeRRFDJbKuJpZAOtL4pVPK1t2XGVrDbe5R")
-oidc-issuer string
OIDC issuer URL provided by IdP (default "https://accounts.google.com")
-saml-cert-file string
SAML SP path to cert.pem (default "example/myservice.cert")
-saml-entity-id string
SAML SP entity ID (blank defaults to beyond-host)
-saml-key-file string
SAML SP path to key.pem (default "example/myservice.key")
-saml-metadata-url string
SAML metadata URL from IdP (blank disables SAML)
-saml-nameid-format string
SAML SP option: {email, persistent, transient, unspecified} (default "email")
-saml-session-key string
SAML attribute to map from session (default "email")
-saml-sign-requests
SAML SP signs authentication requests
-saml-signature-method string
SAML SP option: {sha1, sha256, sha512}
-server-idle-timeout duration
max time to wait for the next request when keep-alives are enabled (default 3m0s)
-server-read-timeout duration
max duration for reading the entire request, including the body (default 1m0s)
-server-write-timeout duration
max duration before timing out writes of the response (default 2m0s)
-sites-url string
URL to allowed sites config (eg. https://github.com/myorg/beyond-config/main/raw/sites.json)
-token-base string
token server URL prefix (eg. https://api.github.com/user)
-token-graphql string
GraphQL URL for auth (eg. https://api.github.com/graphql)
-token-graphql-query string
(default "{\"query\": \"query { viewer { login }}\"}")
-websocket-compression
allow websocket transport compression (gorilla/experimental)
```
标签:BeyondCorp, CISA项目, Docker, Docker Registry, ElasticSearch, EVTX分析, GitHub Enterprise, Go语言, HTTPS反向代理, IAM, JSONLines, OAuth2, OpenID Connect, SAMLv2, Split-DNS, SSO, Streamlit, VPN替代, WebSockets, Zero Trust, 内部服务安全, 分割DNS, 单点登录, 安全防御评估, 微隔离, 日志审计, 程序破解, 网络安全, 网络边界安全, 虚拟专用网络替代, 访问代理, 访问控制, 请求拦截, 身份与访问管理, 隐私保护, 零信任