GithubHelp home page GithubHelp logo

sshproxy's Introduction

sshproxy: (Yet Another) SSH Wire Protocol Pluggable Transport
Yawning Angel <yawning at schwanenlied dot me>

This is a Twisted/pyptlib based rewrite of obfsproxyssh.  It also has the
unique "feature" of using a platform native OpenSSH binary instead of a SSH
wire protocol library, so it's essentially a gigantic roll of duct tape tying
Tor and OpenSSH together.

Why write this:
 * libssh2's code was questionable from a security standpoint.
 * Twisted Conch/Paramiko both are lacking features neccecary for sshproxy to
   not stand out as a unique SSH client.  The one benefit to using the
   OpenSSH is added fingerprinting resistance.

Drawbacks to this approach:
 * This writes a bunch of data to disk (known_hosts and the id_rsa files) and
   there's no way to avoid writing a bunch of data to disk.
 * The author feels that forking OpenSSH and talking to the remote host over a
   pipe is really lame.
 * OpenSSH by default does not support SOCKS which will make stacking this on
   other things harder.
 * It depends on the user's system ssh to be sane.
 * I'm a C programmer, not a python one.

PT Bridge Line Arguments:
 * "user=<USERNAME>" - The user on the bridge to authenticate as
 * "orport=<ORPORT>" - The OR port on the bridge's loopback interface
 * "privkey=<PRIVKEY>" - The RSA private key to use when authenticating (The
   code expects a PEM format RSA key, with the header/footer/newlines removed)
 * "hostkey-rsa=<RSA HOST KEY>" - The RSA host key (Base64 encoded)
 * "hostkey-dss=<DSA HOST KEY>" - (Optional) The DSA host key (Base64 encoded)
 * "hostkey-nisp256=<ECDSA KEY>" - (Optional) The ECDSA 256 bit host key
 * "hostkey-nisp384=<ECDSA KEY>" - (Optional) The ECDSA 384 bit host key
 * "hostkey-nisp521=<ECDSA KEY>" - (Optional) The ECDSA 521 bit host key

Command Line Arguments:
 * "--no-ecdsa" - Force disable ECDSA support.
 * "--debug" - Enable verbose ssh client logging.
 * "--user=<USERNAME>" - The user on the bridge to authenticate as
 * "--orport=<ORPORT>" - The OR port on the bridge's loopback interface
 * "--privkey=<PRIVKEY>" - The RSA private key to use when authenticating (The
   code expects a PEM format RSA key, with the header/footer/newlines removed)
 * "--hostkey-rsa=<RSA HOST KEY>" - The RSA host key (Base64 encoded)
 * "--hostkey-dss=<DSA HOST KEY>" - (Optional) The DSA host key (Base64 encoded)
 * "--hostkey-nisp256=<ECDSA KEY>" - (Optional) The ECDSA 256 bit host key
 * "--hostkey-nisp384=<ECDSA KEY>" - (Optional) The ECDSA 384 bit host key
 * "--hostkey-nisp521=<ECDSA KEY>" - (Optional) The ECDSA 521 bit host key

 Note: The command line arguments should only be used when Tor PT argument
 passing is broken in some way.
  * Tor 0.2.4.x - PT arguments are unsupported
  * Current bleeding edge Tor - SOCKSv4 length is too limited (#9163)

Bridge Side Configuration:
 1) Add a user (Eg: sshproxy).  The password MUST be disabled, and
    /sbin/nologin or similar MUST be used as a shell.

 2) Generate a RSA keypair for the user, add the public key to the
    authorized_keys file, and generate the privkey argument.

    Eg:
      # su sshproxy
      $ ssh-keygen -t rsa
      $ cat ~sshproxy/.ssh/id_rsa.pub > ~sshproxy/.ssh/authorized_keys
      $ chmod 600 ~sshproxy/.ssh/authorized_keys
      $ cat ~sshproxy/.ssh/id_rsa | sed '1d;$d' | tr -d '\n'
        (The gigantic Base64 blob is what should be passed as the Bridge's
	 privkey PT argument.)

    Note: For this release, no passphrase should be specified for the private
    key.

 3) Modify /etc/ssh/sshd_config to limit the user's capabilities.
    Eg:
      # Disconnect sessions that have been idle for > 600s (Optional)
      # Warning: This is a global setting.
      ClientAliveCountMax 0
      ClientAliveInterval 600

      Match User sshproxy
	PasswordAuthentication no
        AllowTcpForwarding yes
        AllowAgentForwarding no
        X11Forwarding no
        PermitTunnel no
        GatewayPorts no
        MaxSessions 1
        PermitOpen 127.0.0.1:9001
        ForceCommand echo 'Shell access is not permited'

    Note: PermitOpen allows both forward and reverse tunnels.  It is possible
    for a malicious user to ssh -R 9001:127.0.0.1:9001 if tor is not running
    and tie up the OR port.  This failure case is fairly obvious (tor doesn't
    start up) and is easily solved by killing the offending sshd instance.

    Once tor is running the ssh -R will fail, so the window in which this can
    occur is rather limited.  To eliminate the issue entirely grsecurity or
    SELinux are possible options.

 4) Obtain the information that is needed for a bridge line.
    * user -> The user account added in step 1
    * orport -> The OR port that your copy of tor is listening on
                (9001 by default)
    * privkey -> The RSA privage key generated in step 2, with the PEM
                 header/footer and newlines removed.
    * hostkey-<type> -> The SSH public hostkeys for your host Base64 encoded.
                        Either extract from /etc/ssh/ssh_host_*_key.pub or
			use ssh-keyscan.
      Eg:
        $ ssh-keyscan localhost
	# localhost SSH-2.0-OpenSSH_5.8p2_hpn13v11 FreeBSD-20110503
	localhost ssh-rsa AAAAB3Nz....(Long Base64 string snipped)
	# localhost SSH-2.0-OpenSSH_5.8p2_hpn13v11 FreeBSD-20110503
	localhost ecdsa-sha2-nistp256 AAAAE2Vj....(Long Base64 string snipped)

	Translates to:
	  hostkey-rsa=AAAAB3Nz....
	  hostkey-nistp256=AAAAE2Vj....

    By default OpenSSH will use ECDSA->RSA->DSA as the hostkey algorithm, thus
    the hostkey-dss argument is not strictly required.  However if your sshd is
    configured to use ECDSA, then you MUST provide a ECDSA hostkey as part of
    the bridge line.

 5) Annoynymize ssh logs.
    * Systems using syslog-ng >= 3.0 can use Rewrite
        https://docs.indymedia.org/Devel/AnonIPSyslogNg
    * Systems using older versions of syslog-ng can use the patches from
      riseup.net.
        https://we.riseup.net/debian/syslog
    * Systems using rsyslog can use mmannon.
        http://www.rsyslog.com/doc/mmanon.html
    * Another option would be to run a separate instance of sshd just for the
      sshproxy user started up with the "-q" option which disables logging
      entirely (AllowUsers/DenyUsers can be used to limit which users can use
      the given sshd instance).

    Which strategy you chose is dependent on what you consider to be best for
    your system.  The author recommends sshd with -q, but as that requires
    running one of the system's sshd instances on a non-standard port, the
    author understands that this is not a valid option for everyone.

Windows notes:
 * If the generated executable fails to find zope.interface, chances are
   Lib/site-packages/zope does not have a __init__.py, create one, and rerun
   py2exe to regenerate the executable.
 * I have not managed to find a port of OpenSSH to windows that has -W that
   actually works.  Thus on windows this uses -L and the code there is
   considerably more... involved.
 * BUG: It shouldn't open a console window, there's probably a py2exe option
   that can hide it (Happens on TBB 3.0 Alpha versions...)
 * tor_terminate_process which handles PT cleanup uses TerminateProcess.
   Per http://msdn.microsoft.com/en-us/library/ms686722%28VS.85%29
    * "When the system is terminating a process, it does not terminate any
       child processes that the process has created." -> if any ssh.exe child
       processes are active, they will remain.
    * "all threads of the process are terminated immediately with no chance to
       run additional code" -> my atexit hook will never be called.

   To work around this, a second instance of sshproxy.exe is spawned who's sole
   job is to blow away the state directory and lingering ssh.exe instances when
   the primary copy dies.  This solution appears to work, but is far from ideal
   (To know more look at sshproxy/monitor.py).

TODO:
 * Improve documentation
 * Fix the Windows issues somehow

sshproxy's People

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.