0

I'm currently starting a project using multiple Raspberry Pis. I have a system already in place where if the code fails, open an ssh tunnel on port 22. However, if two or more Raspberry Pis fail only one can open a tunnel on port 22 (tcp) in region 'au'. to access it via ssh

def ssh():
    ngrok.set_auth_token("MY_SECRET_TOKEN")
    conf.get_default().region = 'au'
    ssh = ngrok.connect(22, "tcp")
    ngrok_process = ngrok.get_ngrok_process()
    try:
        ngrok_process.proc.wait()
    except KeyboardInterrupt:
        ngrok.kill

I've been in touch with the support from Ngrok and they mentioned it is possible to have more than one tunnel on port 22 (tcp).

On a free plan you can only have one open ngrok "session" but you can run up to 4 tunnels through that one session. All of your tunnels could be to port 22, that would work fine. - Ngrok Support

and Possibly referring to having different port tunnels (22, 80)

yes you can open multiple tunnels in the "au" region within one session

Currently getting this error:

Traceback (most recent call last):
  File "/home/pi/main.py", line 210, in <module>
    ssh()
  File "/home/pi/main.py", line 30, in ssh
    ssh = ngrok.connect(22, "tcp")
  File "/usr/local/lib/python3.7/dist-packages/pyngrok/ngrok.py", line 245, in connect
    api_url = get_ngrok_process(pyngrok_config).api_url
  File "/usr/local/lib/python3.7/dist-packages/pyngrok/ngrok.py", line 162, in get_ngrok_process
    return process.get_process(pyngrok_config)
  File "/usr/local/lib/python3.7/dist-packages/pyngrok/process.py", line 295, in get_process
    return _start_process(pyngrok_config)
  File "/usr/local/lib/python3.7/dist-packages/pyngrok/process.py", line 465, in _start_process
    ngrok_process.startup_error)
pyngrok.exception.PyngrokNgrokError: The ngrok process errored on start: Your account is limited to 1 simultaneous ngrok client session.\nActive ngrok client sessions in region 'au':\n  - ts_1opHl3G90CmgGPiP6JM0IUpcXZM (IP)\r\n\r\nERR_NGROK_108\r\n.

Is it possible to have multiple ngrok.connect(22, "tcp") tunnels with the region 'AU' open in one session?

ClarkeFL
  • 131
  • 2
  • 13
  • 1
    Ignoring the bit about port numbers: You appear to be running more than one client (one client per Pi), and the error is "limited to 1 simultaneous ngrok client session", so that would imply your license doesn't allow two or more clients. – Anon Coward Feb 23 '21 at 00:27
  • @AnonCoward So what you are saying is that when pyngrok runs the connect method it opens its own session instead of attaching to an already open session? Or is that not possible? – ClarkeFL Feb 23 '21 at 00:29
  • Correct, each call to `ngrok.connect` is a new client session. It's not going to reuse an existing session (that'd require finding and connecting to another Pi, or something even more complex) – Anon Coward Feb 23 '21 at 00:36
  • Maybe you could consider alternatives to ngrok. [This repository](https://github.com/anderspitman/awesome-tunneling) has a list of some of them. – Hernán Alarcón Feb 23 '21 at 01:52
  • @HernánAlarcón Thank you. Will have a look – ClarkeFL Feb 23 '21 at 03:52
  • To clarify what @AnonCoward said, each `ngrok.connect()` is a new session _only because you're running this on two different Raspberry Pi's_. Issuing multiple `ngrok.connect()`'s within the same Python runtime _will_ attach the subsequent tunnels to the same session and this would work fine. The paid version would allow you to run both of these sessions on two different Pi's, but like he said, even then I don't think `ngrok` will accomplish what you're going for here. – alexdlaird Feb 24 '21 at 20:54

1 Answers1

0

Yes, this is possible with a paid ngrok account. You would simple call connect() more than once.

from pyngrok import ngrok, conf

ngrok.set_auth_token("MY_AUTH_TOKEN")
conf.get_default().region = "au"

ssh1 = ngrok.connect(22, "tcp")
print(ssh1.public_url)
ssh2 = ngrok.connect(22, "tcp")
print(ssh2.public_url)
ssh3 = ngrok.connect(22, "tcp")
print(ssh3.public_url)
ssh4 = ngrok.connect(3306, "tcp")
print(ssh4.public_url)
http1 = ngrok.connect(8080, bind_tls=True)
print(http1.public_url)
http2 = ngrok.connect(8080, bind_tls=True)
print(http2.public_url)

print(len(ngrok.get_tunnels()))

ngrok_process = ngrok.get_ngrok_process()
try:
    ngrok_process.proc.wait()
except KeyboardInterrupt:
    ngrok.kill()

The above example would result in 6 total tunnels, mixing multiple TCP tunnels (to the same and different ports) and multiple HTTP tunnels.

This will not work with a free account. Assuming your valid auth token is being successfully registered with pyngrok (maybe an issue here?), I'd send them the snippet ts_1opHl3G90CmgGPiP6JM0IUpcXZM (IP)\r\n\r\nERR_NGROK_108\r\n, as this looks like a debug code they've generated for your request. Perhaps providing this to ngrok support would help them narrow down where the issue is on their end.

alexdlaird
  • 1,174
  • 12
  • 34
  • Please note that I have two raspberry pi's so they both are running their own script. I am running a free account with Ngrok, so I'm able to have up to 4 tunnels per session. and my token does work. – ClarkeFL Feb 23 '21 at 00:24
  • From the comment above, it seems pyngrok opens its own session on create, instead of attaching a tunnel to an open session already. – ClarkeFL Feb 23 '21 at 00:31
  • The error about two sessions then is because you're doing this from two separate Pi's. There's no way for remote `ngrok` instances to connect to each other (that I'm aware of), so since this isn't supported with `ngrok` it's also not supported with `pyngrok`. – alexdlaird Feb 24 '21 at 20:57