Skip to content

Instantly share code, notes, and snippets.

@padde
Last active September 8, 2022 06:03
Show Gist options
  • Select an option

  • Save padde/c3fc672a435fc71e621a to your computer and use it in GitHub Desktop.

Select an option

Save padde/c3fc672a435fc71e621a to your computer and use it in GitHub Desktop.

Revisions

  1. Patrick Oscity revised this gist Jul 3, 2014. 1 changed file with 81 additions and 40 deletions.
    121 changes: 81 additions & 40 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,8 @@

    # SSH Remote Port Forwarding

    TODO: intro

    ## Provision Server

    * DigitalOcean
    @@ -17,11 +19,15 @@ can be configured to use th wildcard address `0.0.0.0` instead, which
    means that we will be able to reach the forwarded port from the internet.
    On the server, add the following line to `/etc/ssh/sshd_config`:

    GatewayPorts yes
    ```
    GatewayPorts yes
    ```

    Then restart the ssh daemon

    sudo service ssh restart
    ```
    sudo service ssh restart
    ````
    ## Basic Firewall
    @@ -33,41 +39,51 @@ We only allow the following connections:
    On the server run:
    sudo iptables -I INPUT -i lo -j ACCEPT
    sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport http -j ACCEPT
    sudo iptables -A INPUT -j DROP
    sudo apt-get install iptables-persistent
    sudo service iptables-persistent start
    ```
    sudo iptables -I INPUT -i lo -j ACCEPT
    sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport http -j ACCEPT
    sudo iptables -A INPUT -j DROP
    sudo apt-get install iptables-persistent
    sudo service iptables-persistent start
    ```
    ## Check if forwarding works
    On your local machine, start a web server to test out forwarding. For example,
    `cd` to a directory and start a simple webserver using Python:
    cd ~/lolcats/
    python -m SimpleHTTPServer
    # Serving HTTP on 0.0.0.0 port 8000 ...
    ```
    cd ~/lolcats/
    python -m SimpleHTTPServer
    # Serving HTTP on 0.0.0.0 port 8000 ...
    ```
    Then set up remote port forwarding via SSH:
    ssh root@<your-server> -R 80:localhost:8000
    ```
    ssh root@<your-server> -R 80:localhost:8000
    ```
    If everything is ok, ssh should now listen on tcp 0.0.0.0:80 on the server and
    forward requests to port 8000 on your local machine, where the Python webserver
    is running. You can check whether SSHD uses the correct address on the server:
    netstat -tunelp
    ```
    netstat -tunelp
    ```
    It should look like this:
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
    tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 10643 1223/sshd
    tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 11653 1412/0
    tcp6 0 0 :::22 :::* LISTEN 0 10645 1223/sshd
    tcp6 0 0 :::80 :::* LISTEN 0 11654 1412/0
    ```
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
    tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 10643 1223/sshd
    tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 11653 1412/0
    tcp6 0 0 :::22 :::* LISTEN 0 10645 1223/sshd
    tcp6 0 0 :::80 :::* LISTEN 0 11654 1412/0
    ```
    Now open a web browser, navigate to `http://<your-server>` and you should
    see the directory listing produced by the Python webserver. If so, you have
    @@ -80,7 +96,9 @@ some things on the remote server, I would typically add the `-N` flag to the
    `ssh` command in order to prevent it from starting a shell session on the
    server, which really isn't necessary.
    ssh -N root@<your-server> -R 80:localhost:<local-port>
    ```
    ssh -N root@<your-server> -R 80:localhost:<local-port
    ```
    You might also want to add the `-f` flag, which runs the command as a background
    process. However, I tend to forget those processes and find it tedious to go
    @@ -95,32 +113,39 @@ However, I really wanted a command on my local machine that will allow
    me to spin up a new subdomain on my forwarding server with a one liner.
    Here's the interface I am aiming for:
    fwd 1234
    # creates random subdomain kh3451o5u3204.example.com on server and
    # forwards requests to port 1234 on the local machine
    ```
    fwd 1234
    # creates random subdomain kh3451o5u3204.example.com on server and
    # forwards requests to port 1234 on the local machine

    fwd 1234 foobar
    # creates random subdomain foobar.example.com on server and
    # forwards requests to port 1234 on the local machine
    fwd 1234 foobar
    # creates random subdomain foobar.example.com on server and
    # forwards requests to port 1234 on the local machine
    ```
    When the command is killed with Ctrl-C, the subdomain should disappear from
    the server in order not to clutter the configuration.
    When the command is killed with <kbd>Ctrl</kbd> + <kbd>C</kbd>, the
    subdomain should disappear from the server in order not to clutter
    the configuration.
    ### TODO
    Install nginx
    sudo apt-get install nginx
    ```
    sudo apt-get install nginx
    ````
    * Configure nginx
    server {
    listen 80;
    server_name dev.example.com;
    location / {
    proxy_pass http://127.0.0.1:10001;
    }
    }
    ```
    server {
    listen 80;
    server_name dev.example.com;
    location / {
    proxy_pass http://127.0.0.1:10001;
    }
    }
    ```
    * Add `/usr/local/bin/fwd` on local machine
    @@ -207,9 +232,25 @@ end
    * Make executable
    sudo chmod +x /usr/local/bin/fwd
    ```
    sudo chmod +x /usr/local/bin/fwd
    ```
    * Add `~/.fwdrc`
    ssh_host: example.com
    ssh_user: root
    ```
    ssh_host: example.com
    ssh_user: root
    ```
    * This can now be removed again from `/etc/ssh/sshd_config`
    ```
    GatewayPorts yes
    ```
    * Restart sshd
    ```
    sudo service ssh restart
    ```
  2. Patrick Oscity revised this gist Jul 3, 2014. 1 changed file with 67 additions and 64 deletions.
    131 changes: 67 additions & 64 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -124,83 +124,86 @@ Install nginx

    * Add `/usr/local/bin/fwd` on local machine

    #! /usr/bin/env ruby

    require 'securerandom'
    require 'yaml'
    require 'net/ssh'
    ```ruby
    #! /usr/bin/env ruby

    def ssh_exec!(ssh, command)
    stdout = ''
    stderr = ''
    exit_code = nil
    require 'securerandom'
    require 'yaml'
    require 'net/ssh'

    ssh.open_channel do |channel|
    channel.exec(command) do |*, success|
    abort "Could not execute #{command} on server." unless success
    def ssh_exec!(ssh, command)
    stdout = ''
    stderr = ''
    exit_code = nil

    channel.on_data do |*, data|
    stdout << data
    end
    ssh.open_channel do |channel|
    channel.exec(command) do |*, success|
    abort "Could not execute #{command} on server." unless success

    channel.on_extended_data do |*, data|
    stderr << data
    end

    channel.on_request('exit-status') do |*, data|
    exit_code = data.read_long
    end
    end
    channel.on_data do |*, data|
    stdout << data
    end

    ssh.loop

    [stdout, stderr, exit_code]
    end
    channel.on_extended_data do |*, data|
    stderr << data
    end

    local_port = ARGV.shift.to_i
    abort 'Must be root to forward ports' if local_port < 1024 && `whoami` != 'root'

    config = YAML.load_file "#{File.expand_path '~'}/.fwdrc"
    abort 'No host provided in ~/.fwdrc' unless config['ssh_host']
    abort 'No user provided in ~/.fwdrc' unless config['ssh_user']
    ssh_host = config['ssh_host']
    ssh_user = config['ssh_user']

    subdomain = ARGV.shift
    subdomain_length = 8
    subdomain ||= SecureRandom.random_number(32**subdomain_length).to_s(32).rjust(subdomain_length, '0')
    url = "http://#{subdomain}.#{ssh_host}"
    system "echo '#{url}' | pbcopy"
    puts 'URL copied to clipboard.'

    Net::SSH.start(ssh_host, ssh_user) do |ssh|
    remote_host = '0.0.0.0'
    remote_port = nil
    10_000.upto(11_000) do |port|
    print "Checking port #{port}... "
    stdout, * = ssh_exec! ssh, %Q(netstat -anp tcp | awk '$6 ~ "LISTEN" && $4 ~ "#{port}$"')
    if stdout.empty?
    puts 'ok.'
    remote_port = port
    break
    else
    puts 'already in use.'
    end
    channel.on_request('exit-status') do |*, data|
    exit_code = data.read_long
    end
    abort 'Could not find an open port.' unless remote_port
    end
    end

    ssh.loop

    [stdout, stderr, exit_code]
    end

    local_port = ARGV.shift.to_i
    abort 'Must be root to forward ports' if local_port < 1024 && `whoami` != 'root'

    config = YAML.load_file "#{File.expand_path '~'}/.fwdrc"
    abort 'No host provided in ~/.fwdrc' unless config['ssh_host']
    abort 'No user provided in ~/.fwdrc' unless config['ssh_user']
    ssh_host = config['ssh_host']
    ssh_user = config['ssh_user']

    subdomain = ARGV.shift
    subdomain_length = 8
    subdomain ||= SecureRandom.random_number(32**subdomain_length).to_s(32).rjust(subdomain_length, '0')
    url = "http://#{subdomain}.#{ssh_host}"
    system "echo '#{url}' | pbcopy"
    puts 'URL copied to clipboard.'

    Net::SSH.start(ssh_host, ssh_user) do |ssh|
    remote_host = '0.0.0.0'
    remote_port = nil
    10_000.upto(11_000) do |port|
    print "Checking port #{port}... "
    stdout, * = ssh_exec! ssh, %Q(netstat -anp tcp | awk '$6 ~ "LISTEN" && $4 ~ "#{port}$"')
    if stdout.empty?
    puts 'ok.'
    remote_port = port
    break
    else
    puts 'already in use.'
    end
    end
    abort 'Could not find an open port.' unless remote_port

    ssh.forward.remote_to(local_port, 'localhost', remote_port, remote_host)
    ssh.loop { !ssh.forward.active_remotes.include? [remote_port, remote_host] }
    ssh.forward.remote_to(local_port, 'localhost', remote_port, remote_host)
    ssh.loop { !ssh.forward.active_remotes.include? [remote_port, remote_host] }

    # create subdomain config
    # nginx reload
    # create subdomain config
    # nginx reload

    puts "Now forwarding requests from #{url} to local port #{local_port}."
    puts 'Hit Ctrl-C to stop.'
    puts "Now forwarding requests from #{url} to local port #{local_port}."
    puts 'Hit Ctrl-C to stop.'

    ssh.loop { true }
    end
    ssh.loop { true }
    end
    ```

    * Make executable

  3. Patrick Oscity revised this gist Jul 3, 2014. 1 changed file with 97 additions and 3 deletions.
    100 changes: 97 additions & 3 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -113,6 +113,100 @@ Install nginx
    sudo apt-get install nginx

    * Configure nginx
    * Install ssh-forward
    * Set ssh hosts in ~/.ssh/config
    * Configure ssh-forward

    server {
    listen 80;
    server_name dev.example.com;
    location / {
    proxy_pass http://127.0.0.1:10001;
    }
    }

    * Add `/usr/local/bin/fwd` on local machine

    #! /usr/bin/env ruby

    require 'securerandom'
    require 'yaml'
    require 'net/ssh'

    def ssh_exec!(ssh, command)
    stdout = ''
    stderr = ''
    exit_code = nil

    ssh.open_channel do |channel|
    channel.exec(command) do |*, success|
    abort "Could not execute #{command} on server." unless success

    channel.on_data do |*, data|
    stdout << data
    end

    channel.on_extended_data do |*, data|
    stderr << data
    end

    channel.on_request('exit-status') do |*, data|
    exit_code = data.read_long
    end
    end
    end

    ssh.loop

    [stdout, stderr, exit_code]
    end

    local_port = ARGV.shift.to_i
    abort 'Must be root to forward ports' if local_port < 1024 && `whoami` != 'root'

    config = YAML.load_file "#{File.expand_path '~'}/.fwdrc"
    abort 'No host provided in ~/.fwdrc' unless config['ssh_host']
    abort 'No user provided in ~/.fwdrc' unless config['ssh_user']
    ssh_host = config['ssh_host']
    ssh_user = config['ssh_user']

    subdomain = ARGV.shift
    subdomain_length = 8
    subdomain ||= SecureRandom.random_number(32**subdomain_length).to_s(32).rjust(subdomain_length, '0')
    url = "http://#{subdomain}.#{ssh_host}"
    system "echo '#{url}' | pbcopy"
    puts 'URL copied to clipboard.'

    Net::SSH.start(ssh_host, ssh_user) do |ssh|
    remote_host = '0.0.0.0'
    remote_port = nil
    10_000.upto(11_000) do |port|
    print "Checking port #{port}... "
    stdout, * = ssh_exec! ssh, %Q(netstat -anp tcp | awk '$6 ~ "LISTEN" && $4 ~ "#{port}$"')
    if stdout.empty?
    puts 'ok.'
    remote_port = port
    break
    else
    puts 'already in use.'
    end
    end
    abort 'Could not find an open port.' unless remote_port

    ssh.forward.remote_to(local_port, 'localhost', remote_port, remote_host)
    ssh.loop { !ssh.forward.active_remotes.include? [remote_port, remote_host] }

    # create subdomain config
    # nginx reload

    puts "Now forwarding requests from #{url} to local port #{local_port}."
    puts 'Hit Ctrl-C to stop.'

    ssh.loop { true }
    end

    * Make executable

    sudo chmod +x /usr/local/bin/fwd

    * Add `~/.fwdrc`

    ssh_host: example.com
    ssh_user: root
  4. Patrick Oscity revised this gist Jul 3, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -95,11 +95,11 @@ However, I really wanted a command on my local machine that will allow
    me to spin up a new subdomain on my forwarding server with a one liner.
    Here's the interface I am aiming for:

    forward 1234
    fwd 1234
    # creates random subdomain kh3451o5u3204.example.com on server and
    # forwards requests to port 1234 on the local machine

    forward 1234 foobar
    fwd 1234 foobar
    # creates random subdomain foobar.example.com on server and
    # forwards requests to port 1234 on the local machine

  5. Patrick Oscity revised this gist Jul 3, 2014. 1 changed file with 5 additions and 29 deletions.
    34 changes: 5 additions & 29 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -108,35 +108,11 @@ the server in order not to clutter the configuration.

    ### TODO

    * Remove GatewayPorts yes from sshd_config
    * Install nginx
    Install nginx

    sudo apt-get install nginx

    * Configure nginx
    * Install ssh-forward
    * Set ssh hosts in ~/.ssh/config
    * Configure ssh-forward

    ### frwrd specs

    * on client:
    * (create random subdomain name)
    * read forwarding-server from sshfwd config
    * (use ~/.ssh/conf to store username)

    * issued from client on server:
    * find lowest free port (internal ports 10080+)
    * create subdomain config
    * error if exists
    * nginx reload

    * on client:
    * start ssh forward daemon on specified port
    * store pid
    * copy url to clipboard
    * open browser

    * at exit on server:
    * remove subdomain config
    * nginx reload

    * at exit on client:
    * stop ssh daemon
    * Configure ssh-forward
  6. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 7 additions and 6 deletions.
    13 changes: 7 additions & 6 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -109,20 +109,21 @@ the server in order not to clutter the configuration.
    ### TODO

    * Remove GatewayPorts yes from sshd_config
    * Forward to internal ports 10080+
    * Uses nginx to handle subdomains and forwarding
    * Install sshfwd for command
    * Create ~/.sshfwdrc
    * Install nginx
    * Configure nginx
    * Install ssh-forward
    * Set ssh hosts in ~/.ssh/config
    * Configure ssh-forward

    ### sshfwd
    ### frwrd specs

    * on client:
    * (create random subdomain name)
    * read forwarding-server from sshfwd config
    * (use ~/.ssh/conf to store username)

    * issued from client on server:
    * find lowest free port
    * find lowest free port (internal ports 10080+)
    * create subdomain config
    * error if exists
    * nginx reload
  7. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -135,6 +135,7 @@ the server in order not to clutter the configuration.

    * at exit on server:
    * remove subdomain config
    * nginx reload

    * at exit on client:
    * stop ssh daemon
  8. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -128,7 +128,7 @@ the server in order not to clutter the configuration.
    * nginx reload

    * on client:
    * create ssh tunnel daemon
    * start ssh forward daemon on specified port
    * store pid
    * copy url to clipboard
    * open browser
    @@ -137,5 +137,4 @@ the server in order not to clutter the configuration.
    * remove subdomain config

    * at exit on client:
    * kill ssh daemon
    * remove-sshfwd-subdomain
    * stop ssh daemon
  9. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 12 additions and 12 deletions.
    24 changes: 12 additions & 12 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -117,24 +117,24 @@ the server in order not to clutter the configuration.
    ### sshfwd

    * on client:
    * (create random subdomain name)
    * read forwarding-server from sshfwd config
    * (use ~/.ssh/conf to store username)
    * (create random subdomain name)
    * read forwarding-server from sshfwd config
    * (use ~/.ssh/conf to store username)

    * issued from client on server:
    * find lowest free port
    * create subdomain config
    * error if exists
    * nginx reload
    * find lowest free port
    * create subdomain config
    * error if exists
    * nginx reload

    * on client:
    * create ssh tunnel daemon
    * store pid
    * copy url to clipboard
    * open browser
    * create ssh tunnel daemon
    * store pid
    * copy url to clipboard
    * open browser

    * at exit on server:
    * remove subdomain config
    * remove subdomain config

    * at exit on client:
    * kill ssh daemon
  10. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 2 additions and 9 deletions.
    11 changes: 2 additions & 9 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -137,12 +137,5 @@ the server in order not to clutter the configuration.
    * remove subdomain config

    * at exit on client:
    * kill ssh daemon
    * remove-sshfwd-subdomain

    ### cron job

    * on server
    * runs every 10 min
    * searches for subdomain config older than 10 min
    * if such config exists: delete and nginx reload
    * kill ssh daemon
    * remove-sshfwd-subdomain
  11. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 42 additions and 1 deletion.
    43 changes: 42 additions & 1 deletion SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -104,4 +104,45 @@ Here's the interface I am aiming for:
    # forwards requests to port 1234 on the local machine

    When the command is killed with Ctrl-C, the subdomain should disappear from
    the server in order not to clutter the configuration.
    the server in order not to clutter the configuration.

    ### TODO

    * Remove GatewayPorts yes from sshd_config
    * Forward to internal ports 10080+
    * Uses nginx to handle subdomains and forwarding
    * Install sshfwd for command
    * Create ~/.sshfwdrc

    ### sshfwd

    * on client:
    * (create random subdomain name)
    * read forwarding-server from sshfwd config
    * (use ~/.ssh/conf to store username)

    * issued from client on server:
    * find lowest free port
    * create subdomain config
    * error if exists
    * nginx reload

    * on client:
    * create ssh tunnel daemon
    * store pid
    * copy url to clipboard
    * open browser

    * at exit on server:
    * remove subdomain config

    * at exit on client:
    * kill ssh daemon
    * remove-sshfwd-subdomain

    ### cron job

    * on server
    * runs every 10 min
    * searches for subdomain config older than 10 min
    * if such config exists: delete and nginx reload
  12. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 14 additions and 1 deletion.
    15 changes: 14 additions & 1 deletion SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -73,7 +73,20 @@ Now open a web browser, navigate to `http://<your-server>` and you should
    see the directory listing produced by the Python webserver. If so, you have
    successfully forwarded the port from the remote server to your local machine.

    ssh root@<your-server> -R 80:localhost:8000
    ## Usage

    Although I ommitted it in the previous section, because I also wanted to check
    some things on the remote server, I would typically add the `-N` flag to the
    `ssh` command in order to prevent it from starting a shell session on the
    server, which really isn't necessary.

    ssh -N root@<your-server> -R 80:localhost:<local-port>

    You might also want to add the `-f` flag, which runs the command as a background
    process. However, I tend to forget those processes and find it tedious to go
    through the output of `ps aux | grep ssh` to find unterminated port forwardings
    in order to `kill` them afterwards. Instead, I prefer having a command line
    window open during the entire connection time, and when I am done I just hit Ctrl-C.

    ## Getting fancy

  13. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 23 additions and 3 deletions.
    26 changes: 23 additions & 3 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -52,7 +52,7 @@ On your local machine, start a web server to test out forwarding. For example,

    Then set up remote port forwarding via SSH:

    ssh root@<your-server-ip> -R 80:localhost:8000
    ssh root@<your-server> -R 80:localhost:8000

    If everything is ok, ssh should now listen on tcp 0.0.0.0:80 on the server and
    forward requests to port 8000 on your local machine, where the Python webserver
    @@ -69,6 +69,26 @@ It should look like this:
    tcp6 0 0 :::22 :::* LISTEN 0 10645 1223/sshd
    tcp6 0 0 :::80 :::* LISTEN 0 11654 1412/0

    Now open a web browser, navigate to `http://<your-server-ip>` and you should
    Now open a web browser, navigate to `http://<your-server>` and you should
    see the directory listing produced by the Python webserver. If so, you have
    successfully forwarded the port from the remote server to your local machine.
    successfully forwarded the port from the remote server to your local machine.

    ssh root@<your-server> -R 80:localhost:8000

    ## Getting fancy

    Maybe that's all you wanted, then you can stop reading now and be happy.
    However, I really wanted a command on my local machine that will allow
    me to spin up a new subdomain on my forwarding server with a one liner.
    Here's the interface I am aiming for:

    forward 1234
    # creates random subdomain kh3451o5u3204.example.com on server and
    # forwards requests to port 1234 on the local machine

    forward 1234 foobar
    # creates random subdomain foobar.example.com on server and
    # forwards requests to port 1234 on the local machine

    When the command is killed with Ctrl-C, the subdomain should disappear from
    the server in order not to clutter the configuration.
  14. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -70,4 +70,5 @@ It should look like this:
    tcp6 0 0 :::80 :::* LISTEN 0 11654 1412/0

    Now open a web browser, navigate to `http://<your-server-ip>` and you should
    see a directory listing produced by the Python webserver.
    see the directory listing produced by the Python webserver. If so, you have
    successfully forwarded the port from the remote server to your local machine.
  15. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -44,7 +44,7 @@ On the server run:
    ## Check if forwarding works

    On your local machine, start a web server to test out forwarding. For example,
    `cd` to a directory and start a simple webserver with Python that serves the files:
    `cd` to a directory and start a simple webserver using Python:

    cd ~/lolcats/
    python -m SimpleHTTPServer
  16. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -12,10 +12,10 @@

    SSH allows you to share ports forwarded to the server with other
    remote machines, not just the server itself. By default, SSH will
    open ports on the loopback address 127.0.0.1 on the server, but
    can be configured to use th wildcard address 0.0.0.0 instead, which
    open ports on the loopback address `127.0.0.1` on the server, but
    can be configured to use th wildcard address `0.0.0.0` instead, which
    means that we will be able to reach the forwarded port from the internet.
    On the server, add the following line to /etc/ssh/sshd_config:
    On the server, add the following line to `/etc/ssh/sshd_config`:

    GatewayPorts yes

  17. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -13,8 +13,8 @@
    SSH allows you to share ports forwarded to the server with other
    remote machines, not just the server itself. By default, SSH will
    open ports on the loopback address 127.0.0.1 on the server, but
    can be configured to use th wildcard address 0.0.0.0 instead. This
    means we can ultimately reach the forwarded port from the internet.
    can be configured to use th wildcard address 0.0.0.0 instead, which
    means that we will be able to reach the forwarded port from the internet.
    On the server, add the following line to /etc/ssh/sshd_config:

    GatewayPorts yes
  18. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # WIP
    # !!! WIP !!!

    # SSH Remote Port Forwarding

  19. Patrick Oscity revised this gist Jul 2, 2014. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    # WIP

    # SSH Remote Port Forwarding

    ## Provision Server
    @@ -67,5 +69,5 @@ It should look like this:
    tcp6 0 0 :::22 :::* LISTEN 0 10645 1223/sshd
    tcp6 0 0 :::80 :::* LISTEN 0 11654 1412/0

    Now open a web browser and navigate to `http://<your-server-ip>` and you should
    Now open a web browser, navigate to `http://<your-server-ip>` and you should
    see a directory listing produced by the Python webserver.
  20. Patrick Oscity created this gist Jul 2, 2014.
    71 changes: 71 additions & 0 deletions SSH-Remote-Port-Forwarding.markdown
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    # SSH Remote Port Forwarding

    ## Provision Server

    * DigitalOcean
    * 512 MB RAM
    * Ubuntu 14.04

    ## SSHD Config

    SSH allows you to share ports forwarded to the server with other
    remote machines, not just the server itself. By default, SSH will
    open ports on the loopback address 127.0.0.1 on the server, but
    can be configured to use th wildcard address 0.0.0.0 instead. This
    means we can ultimately reach the forwarded port from the internet.
    On the server, add the following line to /etc/ssh/sshd_config:

    GatewayPorts yes

    Then restart the ssh daemon

    sudo service ssh restart

    ## Basic Firewall

    We only allow the following connections:

    * Connections present at the time running the setup
    * Port 20 SSH
    * Port 80 HTTP

    On the server run:

    sudo iptables -I INPUT -i lo -j ACCEPT
    sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport http -j ACCEPT
    sudo iptables -A INPUT -j DROP
    sudo apt-get install iptables-persistent
    sudo service iptables-persistent start

    ## Check if forwarding works

    On your local machine, start a web server to test out forwarding. For example,
    `cd` to a directory and start a simple webserver with Python that serves the files:

    cd ~/lolcats/
    python -m SimpleHTTPServer
    # Serving HTTP on 0.0.0.0 port 8000 ...

    Then set up remote port forwarding via SSH:

    ssh root@<your-server-ip> -R 80:localhost:8000

    If everything is ok, ssh should now listen on tcp 0.0.0.0:80 on the server and
    forward requests to port 8000 on your local machine, where the Python webserver
    is running. You can check whether SSHD uses the correct address on the server:

    netstat -tunelp

    It should look like this:

    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
    tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 10643 1223/sshd
    tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 11653 1412/0
    tcp6 0 0 :::22 :::* LISTEN 0 10645 1223/sshd
    tcp6 0 0 :::80 :::* LISTEN 0 11654 1412/0

    Now open a web browser and navigate to `http://<your-server-ip>` and you should
    see a directory listing produced by the Python webserver.