Skip to content

Forward the ports of Docker containers and leave your local ports untouched.

License

Notifications You must be signed in to change notification settings

useparagon/ssh-tunnel

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Description

This Docker image helps you forward ports of containers to remote servers. If you publish the forwarded ports of a container, you can use it to forward your local ports to the remote server through the container. Sometimes the previous way is undesired, since you want to keep the local ports free. In this case you should keep /etc/hosts up to date even if the ip addresses of the containers can be changed. This can be solved using itsziget/hosts-gen and itsziget/hosts-updater. With the help of these images you can have a VPN-like solution. So you can even mount a samba drive from a remote private network.

First of all you have to copy your SSH public key to each server you want to ssh.

The simplest example when a local port is forwarded to a remote server's local port. For instance, you have a remote web server with a virtual host accessible only from localhost or a MySQL server which is not published.

version: "2"

services:
  remote-mysql:
    image: itsziget/ssh-tunnel
    volumes:
      - "${HOME}/.ssh/id_rsa.pub:/root/.ssh/id_rsa.pub"
      - "${HOME}/.ssh/id_rsa:/root/.ssh/id_rsa"
    environment:
      VIRTUAL_HOST: remote-mysql
      TUNNEL_HOST: user@remotehost:2200
      TUNNEL_REMOTES: "127.0.0.1:3306"
      PUBLIC_KEY: some-long-public-key
      PRIVATE_KEY: some-long-private-key
      PRIVATE_KEY_PASSWORD: super-secure-password

In the above example the container's port 3306 is forwarded remotehost's local port 3306 via SSH tunnel through the port 2200. If you use the mentioned itsziget/hosts-gen and the updater, you will be able to access to the remote mysql using "remote-mysql" as host name.

The other case when you have a web server inside a remote private network and you wish to access it from the local machine.

version: "2"

services:
  remote-web:
    image: itsziget/ssh-tunnel
    volumes:
      - "${HOME}/.ssh/id_rsa.pub:/root/.ssh/id_rsa.pub"
      - "${HOME}/.ssh/id_rsa:/root/.ssh/id_rsa"
    environment:
      VIRTUAL_HOST: first.remote.host,second.remote.host
      TUNNEL_HOST: user@remotehost:2200
      TUNNEL_REMOTES: |
        first.remote.host:443
        second.remote.host:443
        second.remote.host:80

The "|" (pipe) character allows you to set a multiline text to a variable. If you have multiple host on the remote server, you can list them line by line. Each line is a host and port separated by colon.

There is a trickier way to use the SSH tunnel. If you forward the SSH port of a container to a remote SSH port, you can tunnel an other container's port through that. This way you can access a server's local port inside a remote private network which is inaccessible directly via SSH.

version: "2"

services:
  privatemysql-ssh:
    image: itsziget/ssh-tunnel
    volumes:
      - "${HOME}/.ssh/id_rsa.pub:/root/.ssh/id_rsa.pub"
      - "${HOME}/.ssh/id_rsa:/root/.ssh/id_rsa"
    environment:
      TUNNEL_HOST: user@publichost:2200
      TUNNEL_REMOTES: "mysql.private.lan:22"
    expose:
      - 22
  privatemysql:
    image: itsziget/ssh-tunnel
    volumes:
      - "${HOME}/.ssh/id_rsa.pub:/root/.ssh/id_rsa.pub"
      - "${HOME}/.ssh/id_rsa:/root/.ssh/id_rsa"
    links:
      - privatemysql-ssh
    environment:
      VIRTUAL_HOST: mysql.private.lan
      TUNNEL_HOST: user@privatemysql-ssh:22
      TUNNEL_REMOTES: "127.0.0.1:3306"

Now mysql.private.lan is accessible on port 3306 from your local machine.

As I mentioned at the top of the README, this image is can be used to mount a private samba drive.

version: "2"

services:
  privatesamba:
    image: itsziget/ssh-tunnel
    volumes:
      - "${HOME}/.ssh/id_rsa.pub:/root/.ssh/id_rsa.pub"
      - "${HOME}/.ssh/id_rsa:/root/.ssh/id_rsa"
    environment:
      VIRTUAL_HOST: privatesamba
      TUNNEL_REMOTES: |
        samba.private.lan:137
        samba.private.lan:138
        samba.private.lan:139
        samba.private.lan:445

Here every ports used by a samba server are forwarded to the private samba server. Now type the following in a file browser's address bar:

smb://privatesamba/sharedfolder

I assume you have many different private server. You can shorten the definitions by inheriting one container's definition:

version: "2"

services:
  publicserver:
    image: itsziget/ssh-tunnel
    volumes:
      - "${HOME}/.ssh/id_rsa.pub:/root/.ssh/id_rsa.pub"
      - "${HOME}/.ssh/id_rsa:/root/.ssh/id_rsa"
    environment:
      TUNNEL_HOST: user@publichost:2200
      TUNNEL_REMOTES: "127.0.0.1:2200"
  privatemysql-ssh:
    extends:
      service: publicserver
    environment:
      TUNNEL_HOST: user@publichost:2200
      TUNNEL_REMOTES: "mysql.private.lan:22"
    expose:
      - 22
  privatemysql:
    extends:
      service: publicserver
    links:
      - privatemysql-ssh
    environment:
      VIRTUAL_HOST: mysql.private.lan
      TUNNEL_HOST: user@privatemysql-ssh:22
      TUNNEL_REMOTES: "127.0.0.1:3306"
  privatesamba:
    extends:
      service: publicserver
    environment:
      VIRTUAL_HOST: privatesamba
      TUNNEL_REMOTES: |
        samba.private.lan:137
        samba.private.lan:138
        samba.private.lan:139
        samba.private.lan:445
  privateweb:
    extends:
      service: publicserver
    environment:
      VIRTUAL_HOST: web.private.lan
      TUNNEL_REMOTES: |
        web1.private.lan:443
        web2.private.lan:443
        web2.private.lan:80

In the above case the first container's definition is the base of the others. You need to redefine only the differences.

As you can see it is not so far from a VPN. You have to define more manually, but you get more control over the network. Your local private network and some ports of some remote machines from the remote network will be available at the same time. And this is more than a simple SSH tunnel, since your local ports will be untouched if you want.

About

Forward the ports of Docker containers and leave your local ports untouched.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Shell 79.0%
  • Dockerfile 16.8%
  • Makefile 4.2%