ngrok / ngrok-go Goto Github PK
View Code? Open in Web Editor NEWEmbed ngrok secure ingress into your Go apps as a net.Listener with a single line of code.
License: MIT License
Embed ngrok secure ingress into your Go apps as a net.Listener with a single line of code.
License: MIT License
I am working on integrating ngrok in an internal workflow here. Because of particularities of the protocol used, I need it to use with TLS terminating the encryption at the edge aka ngrok tls --terminate-at edge
.
The Go SDK doesn't document how to achieve that and it seems to default to some other mode.
Appreciate the difference between these two setups:
tun, err := ngrok.Listen(ctx,
config.TLSEndpoint(
config.WithDomain(ngrokDomain),
config.WithTermination([]byte{}, []byte{}),
),
ngrok.WithAuthtokenFromEnv(),
)
vs
tun, err := ngrok.Listen(ctx,
config.TLSEndpoint(
config.WithDomain(ngrokDomain),
),
ngrok.WithAuthtokenFromEnv(),
)
What's happening:
Library rejects authentication tokens with additional newlines or whitespace before / after the token (e.g. <authtoken>\n
):
ERRO[0000] failed to reconnect session
err="authentication failed: The authtoken you specified does not look like a proper ngrok tunnel authtoken.\n
Your authtoken: <authtoken>\n\n
Instructions to install your authtoken are on your ngrok dashboard:\nhttps://dashboard.ngrok.com/get-started/your-authtoken\r\n\r\nERR_NGROK_105\r\n" id=974c591a9879 obj=csess
Expectation:
<authtoken>\n
)<authtoken>
)ngrok http 8080 --host-header=rewrite --request-header-add "ngrok-skip-browser-warning: t;"
Command doesn't work and i still refer to the warning ngrok page. How i can that fix. I need set this header from client side but websocket conn doesn't provide addition parameters for configure headers. How i can skip warning page and directly reference to the route
The standard library is growing a standardized structured logging interface at https://pkg.go.dev/golang.org/x/exp/slog which appears to be heavily based on log15
's design. It appears to at or near API stability. We should be good golang citizens and support a slog
adapter.
Either the fmt/generate steps aren't modifying files, the changes are getting reverted before the git diff --exit-code
step runs, or git diff
isn't operating on what we think it's operating on. Regardless, these CI tests do nothing currently.
Proxy-protocol may be included in plaintext streams from the ngrok edge, but it needs to come before TLS in the stream when forwarding to backends. This means we need to read the proxy header and send it before we initiate TLS to an https or tls backend when forwarding.
Currently implemented in Rust, just needs to be ported here.
we should have a getting started example inside of https://pkg.go.dev/github.com/ngrok/ngrok-go
The flow should be to kick off a github action if VERSION changes, and have the action create the proper tag for us, rather than the current situation where we can tag the repo and forget to update the VERSION (whoops).
This also brings it more in-line with how we manage releases in ngrok/kubernetes-ingress-controller and ngrok/ngrok-rust
I was using ngrok http 7373
from bash now I want to switch to this but I can't figure how.
This is how I use it
tun, err := ngrok.Listen(context.Background(),
config.HTTPEndpoint(),
ngrok.WithAuthtokenFromEnv(),
)
if err != nil {
log.Printf("ngrok error: %s", err.Error())
return
}
log.Println("tunnel created:", baseUrl)
Documentation on How to integrate ngrok with Gin and Echo frameworks would be helpful.
Periodically, a customers ngrok 3.31 agent on Arm is crashing.
Link to screenshot, I cannot attach for some reason.
https://files.slack.com/files-pri/T051C43HT-F06C84KS9PB/image.png
Here is the ZenDesk ticket: https://ngrok.zendesk.com/agent/tickets/16410
The customer also provided a agent log, but I think the screenshot might be enough to identify the problem.
INFO[12-28|17:58:50] no configuration paths supplied
DBUG[12-28|17:58:50] ngrok config file at legacy location does not exist legacy_path=/.config/ngrok/ngrok.yml
INFO[12-28|17:58:50] using configuration at default config path path=/.config/ngrok/ngrok.yml
INFO[12-28|17:58:50] open config file path=/.config/ngrok/ngrok.yml err=nil
t=2023-12-28T17:58:50+0000 lvl=dbug msg="ignoring manifest file with unhandled mimetype" name=assets/glyphicons-halflings-regular.ttf ext=.ttf
t=2023-12-28T17:58:50+0000 lvl=dbug msg="ignoring manifest file with unhandled mimetype" name=assets/glyphicons-halflings-regular.eot ext=.eot
t=2023-12-28T17:58:50+0000 lvl=warn msg="can't bind default web address, trying alternatives" obj=web addr=[127.0.0.1:4040](http://127.0.0.1:4040/)
t=2023-12-28T17:58:50+0000 lvl=dbug msg="starting component" obj=app name="Tunnel session"
t=2023-12-28T17:58:50+0000 lvl=dbug msg="starting component" obj=app name=web
t=2023-12-28T17:58:50+0000 lvl=info msg="starting web service" obj=web addr=[127.0.0.1:4041](http://127.0.0.1:4041/) allow_hosts=[]
t=2023-12-28T17:58:50+0000 lvl=dbug msg="starting component" obj=app name="signal handler"
t=2023-12-28T17:58:51+0000 lvl=dbug msg="connecting to" obj=tunnels.session addr=[connect.eu.ngrok-agent.com:443](http://connect.eu.ngrok-agent.com:443/)
t=2023-12-28T17:58:51+0000 lvl=dbug msg=dial obj=tunnels.session network=tcp address=[tunnel.eu.ngrok.com:443](http://tunnel.eu.ngrok.com:443/) timeout=10s
t=2023-12-28T17:58:51+0000 lvl=dbug msg="open stream" obj=tunnels.session obj=csess id=d0b9352af6f4 reqtype=0 err=nil
t=2023-12-28T17:58:51+0000 lvl=dbug msg="encode request" obj=tunnels.session obj=csess id=d0b9352af6f4 sid=3 req="&{Version:[2] ClientID: Extra:{OS:linux Arch:arm Authtoken:HIDDEN Version:3.3.1 Hostname: UserAgent:ngrok-agent-go/3.3.1 ({\"proxy_type\":\"none\",\"config_version\":\"2\"}) ngrok-go/1.1.0 Metadata: Cookie: HeartbeatInterval:10000000000 HeartbeatTolerance:15000000000 Fingerprint:<nil> UpdateUnsupportedError:0x280f368 StopUnsupportedError:0x280f2a8 RestartUnsupportedError:0x280f350 ProxyType: MutualTLS:false ServiceRun:false ConfigVersion: CustomInterface:false CustomCAs:false ClientType:ngrok-agent-go}}" err=nil
t=2023-12-28T17:58:51+0000 lvl=dbug msg="decoded response" obj=tunnels.session obj=csess id=d0b9352af6f4 sid=3 resp="&{Version:2 ClientID:3996dec297e9127d8d8ff0ce5ced7636 Error: Extra:{Version:prod Region:eu Cookie:BtnCf6OIZ5STrtvqBYhjZ6T9h585Rldq$zaNfuVpOBhTy8cIRCs9qBp/X29cX1Kx4/gaylYzitCELLiNqCHY8JatnCBfVBV/+29B8JJ+Zj7DxP72wuZfEbwmJcp5pSoLxQTlOQIDJdcNI0aw55Nv8MGReJKOq3IHO18IA6A8VCy+2T7WEm/ovFR0vn0C4qpCJFpUNxYJj7flXad6UtRmLzkU0EEXbHne+2xc8ZnmmVKYUfMIw0w== AccountName:Yossi Neiman SessionDuration:0 PlanName:Pro Banner:Build better APIs with ngrok. Early access: [ngrok.com/early-access}](http://ngrok.com/early-access%7D)}" err=nil
t=2023-12-28T17:58:51+0000 lvl=info msg="client session established" obj=tunnels.session obj=csess id=78d8bc87e742
t=2023-12-28T17:58:51+0000 lvl=info msg="tunnel session started" obj=tunnels.session
t=2023-12-28T17:58:51+0000 lvl=dbug msg="received extras" obj=tunnels.session region=eu version=prod
t=2023-12-28T17:58:51+0000 lvl=dbug msg="open stream" obj=tunnels.session obj=csess id=d0b9352af6f4 clientid=3996dec297e9127d8d8ff0ce5ced7636 reqtype=1 err=nil
t=2023-12-28T17:58:51+0000 lvl=dbug msg="encode request" obj=tunnels.session obj=csess id=d0b9352af6f4 clientid=3996dec297e9127d8d8ff0ce5ced7636 sid=7 req="&{ID: ClientID: Proto:https ForwardsTo:[http://localhost:80](http://localhost/) Opts:0x2d4c840 Extra:{Token: IPPolicyRef: Metadata:}}" err=nil
t=2023-12-28T17:58:51+0000 lvl=dbug msg="decoded response" obj=tunnels.session obj=csess id=d0b9352af6f4 clientid=3996dec297e9127d8d8ff0ce5ced7636 sid=7 resp="&{ClientID:06972402699776bfd0ebda17975a1883 URL:https://c7a22b6b26c6.ngrok.app/ Proto:https Opts:map[Auth: BasicAuth:<nil> CircuitBreaker:<nil> Compression:<nil> Domain: HostHeaderRewrite:false Hostname:[c7a22b6b26c6.ngrok.app](http://c7a22b6b26c6.ngrok.app/) IPRestriction:<nil> LocalURLScheme: MutualTLSCA:<nil> OAuth:<nil> OIDC:<nil> Policies:<nil> ProxyProto:0 RequestHeaders:<nil> ResponseHeaders:<nil> Subdomain: UpstreamCAPEM:<nil> UserAgentFilter:<nil> VerifyUpstreamTLS:false WebhookVerification:<nil> WebsocketTCPConverter:<nil>] Error: Extra:{Token:KXcIgeKA7BoTZ3z4574FivS4Lh18rJbs$wF7lKPVhfK2x/qX8BsnyK+i2l32CSb3JoR2tYLfbe1BxlyQZF17+iPvU1/A9L/Cgf7AiIbmyZnSSfyzX2P2Kjj0p1ihTHJHVXrEXE3mRBEj8SkoVdHrpVvKY3SZQV6YyLX4YRZsf3J/novSik2wbZCX/xR6zjzmvnfXcYMFHoRJBSKV6p9j700kdYVY5kLxzfI94U1y0CimUzcZIdx4pZejCYILLQ9IOopvrVl3vYfiu3tf2mU+BZuOX5rp6NmAfbY/0+ToKeIFXr3W2k6YeB9HKuI/vOtDTyj24WjwzCbfcSMcoYWiokB2faylMbSzuqQ6LGB6NK3gKnDfJLM3HjH4Cj26LJt0PSSONC4rzC6oECoQJkgH38sHdBh0SJxYlh0NxJnfBSZM9QJkpFzTnSfrezZsJKKGnAIhWANjOmfIf7jXd40k+Yfrm/qml+Y6MdcG4/Fsw3zK6p4X93rbVnydou+EZjDgavnsQFcHwq7lL/eX7w18lV36R8vtGDUCozBLqE50yuq1QE/G2Ag2N4j9csqeOcWht6P+b/5v/HdYwAIhFHqhb6x2B2EFP4erDY0I97PCkyVow4WisHuSo3mCw2PM+82Em3NN7nWnXAN5qIUc9w6bvurRbukf+A6fpdnnLYjqoO9NxKWryAsWkIp8AY5dU87lGiZvAG76VRDll4uUMZnRiaa/zwZWd8QN5qm4+mLCwe6oL1ekPB59n}}" err=nil
t=2023-12-28T17:58:51+0000 lvl=dbug msg="start tunnel listen" obj=tunnels.session name=command_line proto=https opts="&{Domain: Hostname: Subdomain: Auth: HostHeaderRewrite:false LocalURLScheme:http ProxyProto:0 Compression:<nil> CircuitBreaker:<nil> IPRestriction:<nil> BasicAuth:<nil> OAuth:<nil> OIDC:<nil> WebhookVerification:<nil> MutualTLSCA:<nil> RequestHeaders:<nil> ResponseHeaders:<nil> WebsocketTCPConverter:<nil>}" labels=map[] err=nil
t=2023-12-28T17:58:51+0000 lvl=info msg="started tunnel" obj=tunnels name=command_line addr=[http://localhost:80](http://localhost/) url=https://c7a22b6b26c6.ngrok.app/
udhcpd: sending OFFER of 192.168.10.182
udhcpd: sending OFFER of 192.168.10.182
t=2023-12-28T17:59:01+0000 lvl=dbug msg="heartbeat received" obj=tunnels.session obj=csess id=d0b9352af6f4 clientid=3996dec297e9127d8d8ff0ce5ced7636 latency_ms=100
udhcpd: sending OFFER of 192.168.10.182
t=2023-12-28T17:59:11+0000 lvl=dbug msg="heartbeat received" obj=tunnels.session obj=csess id=d0b9352af6f4 clientid=3996dec297e9127d8d8ff0ce5ced7636 latency_ms=114
t=2023-12-28T17:59:21+0000 lvl=dbug msg="heartbeat received" obj=tunnels.session obj=csess id=d0b9352af6f4 clientid=3996dec297e9127d8d8ff0ce5ced7636 latency_ms=140
udhcpd: sending OFFER of 192.168.10.182
^Ct=2023-12-28T17:59:28+0000 lvl=dbug msg="requested stop" obj=app
t=2023-12-28T17:59:28+0000 lvl=info msg="received stop request" obj=app stopReq="{err:<nil> restart:false}"
t=2023-12-28T17:59:28+0000 lvl=info msg="session closing" obj=tunnels.session err=nil
t=2023-12-28T17:59:28+0000 lvl=dbug msg="waiting for all components to stop" obj=app
t=2023-12-28T17:59:28+0000 lvl=dbug msg="waiting for components to stop" obj=app remaining=3
t=2023-12-28T17:59:28+0000 lvl=dbug msg="waiting for components to stop" obj=app remaining=2
t=2023-12-28T17:59:28+0000 lvl=dbug msg="waiting for components to stop" obj=app remaining=1
t=2023-12-28T17:59:28+0000 lvl=dbug msg="component stopped" obj=app name="Tunnel session" err=nil
t=2023-12-28T17:59:28+0000 lvl=dbug msg="component stopped" obj=app name=web err=nil
t=2023-12-28T17:59:28+0000 lvl=dbug msg="all components stopped" obj=app
cat ngrok.yaml
authtoken: xxx
version: 2
web_addr: localhost:4035
tunnels:
ngrok_abc:
proto: http
addr: 8080
ngrok_xyz:
proto: http
addr: 8081
ngrok_123:
proto: http
addr: 8082
then run.
then
def get_ngrok_tunnels(apikey):
"""获得通道信息"""
client = ngrok.Client(api_key=apikey)
for t in client.tunnels.list():
print(t)
print(t.public_url)
print(t.labels)
or run:
func GetNgrokItems(ctx context.Context, apiKey string) ([]*ngrok.Tunnel, error) {
config := ngrok.NewClientConfig(apiKey)
client := tunnels.NewClient(config)
iter := client.List(new(ngrok.Paging))
var results []*ngrok.Tunnel
for iter.Next(ctx) {
results = append(results, iter.Item())
}
if err := iter.Err(); err != nil {
return nil, errors.WithMessage(err, "wrong")
}
return results, nil
}
can not get the strings: ngrok_abc ngrok_xyz ngrok_123.
Hello man! How can i integrate ngrok-go in my Rails 7 App ? Maiby use case link...
Word on the street is that we can do this at the ngrok edge via some middleware and won't need to do it directly in "agent" code anymore. Should simplify things for us significantly!
Hi team!
We at Kubeifrst have been using ngrok-go quite a while, it works pretty well. the only issue we have is that 1 in ~50 times we create a tunnel, the tunnel fails, and we're having a hard time to identify the root cause.
We had a previously memory leak (we didnt close the channel and connection instances), but we fixed the memory leak issue in this PR[1].
Is there any possibility that you guys could have a look, and give us some direction of what could be causing the issue?
p.s:
we weren't able to reproduce the issue after this PR (so far).
We don't use a token(token is empty).
related report issue: kubefirst/kubefirst#939
Seems these were missed in the first pass. Shouldn't be too hard to add.
For ngrok-go/1.1.0 I try STOP agent from dashboard.ngrok.com then got:
ERR_NGROK_805 This ngrok agent does not support remote stopping: the agent has not defined a callback for this operation.
How to define a callback for this operation?
This should:
See #65
We can probably take the example code directly from my/euan's comment, or adapt our existing http example for fasthttp. It should end up looking more or less the same either way.
Hello
Both Connect()
and Listen()
are stuck forever when using account limited to 1 simultaneous ngrok agent session and a session is already ongoing.
When using context with timeout I receive duplicated errors:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
conn, err := ngrok.Connect(ctx, ngrok.WithAuthtoken("..."))
if err != nil {
fmt.Println(err)
return
}
conn.Close()
Out
authentication failed: Your account is limited to 1 simultaneous ngrok agent session.
You can run multiple tunnels on a single agent session using a configuration file.
To learn more, see https://ngrok.com/docs/ngrok-agent/config/
Active ngrok agent sessions in region 'eu':
- xxx
ERR_NGROK_108
; authentication failed: Your account is limited to 1 simultaneous ngrok agent session.
You can run multiple tunnels on a single agent session using a configuration file.
To learn more, see https://ngrok.com/docs/ngrok-agent/config/
Active ngrok agent sessions in region 'eu':
- xxx
ERR_NGROK_108
; authentication failed: Your account is limited to 1 simultaneous ngrok agent session.
You can run multiple tunnels on a single agent session using a configuration file.
To learn more, see https://ngrok.com/docs/ngrok-agent/config/
Active ngrok agent sessions in region 'eu':
- xxx
ERR_NGROK_108
; authentication failed: Your account is limited to 1 simultaneous ngrok agent session.
You can run multiple tunnels on a single agent session using a configuration file.
To learn more, see https://ngrok.com/docs/ngrok-agent/config/
Active ngrok agent sessions in region 'eu':
- xxx
ERR_NGROK_108
; authentication failed: Your account is limited to 1 simultaneous ngrok agent session.
You can run multiple tunnels on a single agent session using a configuration file.
To learn more, see https://ngrok.com/docs/ngrok-agent/config/
Active ngrok agent sessions in region 'eu':
- xxx
ERR_NGROK_108
; context deadline exceeded
This doesn't seem to be working properly, I'd expect fast fail with one error without a need to timeout the context.
Hello ngrok !
I am using a configuration file to launch the ngrok service. Inside this configuration, I set basic_auth to a single user:password. When I log to the website, it keeps asking for my password all the time. Here is the configuration :
authtoken: xxx
version: "2"
tunnels:
web-application:
proto: http
addr: 8080
basic_auth:
- "user:pwd"
Thank you,
Gabriel
i want achieve this same functionality when i use ngrok via ssh; like so : ngrok http 3000
how can i achieve this using this package.
a little peek from the node js ngrok library; i can achieve this by doing this const url = await ngrok.connect(9090);
.
i would appreciate if i can be pointed to in the right direction on how to achieve this.
Similar to the implementation for ngrok-rust, we'll need to augment the error structs within ngrok-go to also parse and return the associated error code.
This is to support http/2, and potentially other change-of-protocols that may occur.
See ngrok-private/ngrok#23863
tun, err := ngrok.Listen(
ngrokCtx,
ngrok_config.HTTPEndpoint(),
)
Cannot open tunnel due some ngrok api outage, this code never resolves.
My project is https://github.com/valyala/fasthttp based.
It'd be nice to serve ngrok tun via fasthttp.
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.