{"id":17102575,"url":"https://github.com/igor47/pitunnel","last_synced_at":"2025-07-05T07:32:29.039Z","repository":{"id":145755532,"uuid":"200583304","full_name":"igor47/pitunnel","owner":"igor47","description":"reliable reverse-ssh tunnel for raspberry pi","archived":false,"fork":false,"pushed_at":"2024-06-22T16:37:57.000Z","size":10,"stargazers_count":37,"open_issues_count":1,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-15T06:33:09.901Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","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/igor47.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":"2019-08-05T04:40:36.000Z","updated_at":"2024-11-12T20:25:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"46f860d0-fd84-4a4a-8713-c36aec257584","html_url":"https://github.com/igor47/pitunnel","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igor47%2Fpitunnel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igor47%2Fpitunnel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igor47%2Fpitunnel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igor47%2Fpitunnel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/igor47","download_url":"https://codeload.github.com/igor47/pitunnel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240002226,"owners_count":19732165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-14T15:29:29.627Z","updated_at":"2025-02-22T14:31:14.310Z","avatar_url":"https://github.com/igor47.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nReverse SSH Tunnel\n------------------\n\nSuppose you have a machine (like a Raspberry Pi) that lives behind a home router or on another inaccessible network.\nOr, maybe this machine occasionally changes it's IP address.\nThis repo will set up a tunnel from the machine (called the `local` machine) to another machine (called `remote`) that has a reliable internet-connectible address.\nYou will be able to reliably connect to `local` by first connecting to `remote` and then jumping from `remote` to `local` via the configured `remote_port`.\n\n## Remote setup ##\n\nMake sure the `remote` machine is reliably online.\nI use a server with a static IP address, but you can also use a dynamic DNS name.\n\nCreate a `remote_user` for the tunnel; here, I use `pitunnel`.\nReplace `\u003cssh_key\u003e` with the SSH key you create in the [Local setup](#local-setup) section. \n\n```bash\n$ sudo useradd -m pitunnel\n$ sudo su - pitunnel\n$ mkdir ~/.ssh\n$ chmod 700 ~/.ssh\n$ echo \u003cssh_key\u003e \u003e .ssh/authorized_keys\n$ chmod 600 .ssh/authorized_keys\n$ exit\n```\n\nThis user is only used for tunnels, so we can deny it interactive access.\n\n```console\n$ tee /etc/ssh/sshd_config.d/pitunnel \u003c\u003c DONE\nMatch User pitunnel\n  AllowTcpForwarding yes\n  X11Forwarding no\n  PermitTunnel yes\n  AllowAgentForwarding no\n  PermitTTY no\n  ForceCommand /usr/sbin/nologin\nDONE\n```\n\nYou should also configure the SSH service to time out stale connections.\nEdit `/etc/ssh/sshd_config` and make add a section like so:\n\n```\n# disconnect idle clients after a minute\nClientAliveInterval 20s\nClientAliveCountMax 3\n```\n\nThis will cause the SSH server to ping connected clients every 20 seconds, and disconnect if 3 pings fail.\nMake sure your `sshd_config` is still valid by running:\n\n```bash\n$ sudo sshd -t \u0026\u0026 echo 'looks good' || echo 'sshd config is invalid'\n```\n\nIf it outputs `looks good` then you can go ahead and restart `sshd`:\n\n```bash\n$ sudo systemctl reload sshd\n```\n\n## Local setup ##\n\nFirst, install `autossh`:\n\n```bash\n$ sudo apt-get install -y autossh\n```\n\nNext, create an SSH key for your tunnel.\nDon't specify a password.\n\n```bash\n$ ssh-keygen -t ed25519\n$ cat ~/.ssh/id_ed25519.pub\n\u003cssh_key\u003e\n```\n\nCopy the output (`\u003cssh_key\u003e`) and paste it into the `/home/\u003cremote_user\u003e/.ssh/authorized_keys` file on `remote`.\n\nNext, clone this repo and edit `tunnel.sh`.\nYou will need to customize these variables:\n* `remote_host` -- the hostname or IP of the `remote` server\n* `remote_port` -- the port on the `remote` server where `local` will be available\n* `remote_user` -- the user you created in the [remote setup](#remote-setup) section\n\nIf you're not running on a Raspberry Pi, you should also edit `tunnel.service` and customize this line:\n\n```\nUser=pi\n```\n\nReplace `pi` with the local username (output of `whoami`).\n\nOnce configured, you can run `install.sh`:\n\n```bash\n$ sudo ./install.sh\n```\n\nThis will begin running the SSH tunnel.\n\n## Usage ##\n\nTo connect to the `local` machine, first connect to `remote`.\nThen, on `remote`, run:\n\n```bash\n$ ssh pi@localhost -p \u003cremote_port\u003e\n```\n\nReplace `pi` with your `local` username (whatever you put as `User=` in [local setup](#local-setup).\n\n## Troubleshooting ##\n\nSo long as `local` can communicate with `remote`, the tunnel will be re-created if it does for any reason.\nIt might take a minute or two for existing connections to time out, so keep trying if it doesn't work at first.\n\nTo check on the status of the tunnel, you can run:\n\n```bash\n$ systemctl status tunnel\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figor47%2Fpitunnel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figor47%2Fpitunnel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figor47%2Fpitunnel/lists"}