- 使用 HTTP(S) 代理(HTTP CONNECT 命令)创建通讯通道
- 为 OpenSSH 写一个客户端驱动,并创建基于 SSH 连接的 HTTP(S) 代理
- 作为一个独立的应用,可以连接到远程服务器。
SSH over SSL, episode 2: replacing proxytunnel with socat
If you are reading this, you might be interested in the full list of my articles about doing SSH over SSL. I have been improving my configuration over the years, so the more recent, the better:
- 2010-11-12: Quick and minimal config
- 2010-11-15: Replacing proxytunnel with socat
- 2011-07-11: Avoiding using a patched Apache
- 2014-10-19: HAproxy based configuration
Last week, I wrote an article about how to quickly set up a server and a client for doing ssh over ssl. In this article, I was using proxytunnel, but I realized today that it could probably be replaced with socat (socat can do almost anything)...
The principle is simple: Following the first part of the tutorial, you make your server accept proxy_connect requests to its private port localhost:22 through its public port 443, encapsulating the whole thing in SSL (as a reminder, 22 and 443 are respectively the standard ports for ssh and ssl).
We now want to configure the ssh clients in order to connect through this ssl tunnel. I said I was configuring the clients with proxytunnel. The exact command (in .ssh/config) was:
proxytunnel -q -E -p server.com:443 -d 127.0.0.1:22
I'll explain it:
-q
is for quiet-E
is for encrypting between the proxy and us-p
is for choosing the proxy-d
is for requesting a destination (from the proxy point of view)
So basically, this means: "connect stdio to server.com on port 443 (-p server.com:443) , in an encrypted way (-E), then from this server, require to be connected to 127.0.0.1:22 (-d 127.0.0.1:22)".
For those who like to play with all sorts of streams, socat is really the best tool ever invented. I was wondering if I could reproduce proxytunnel's behavior with socat, and it turns out you can. Here is how to proceed: First, create an ssl tunnel between your client's localhost:1080 and server.com:443:
socat TCP-LISTEN:1080 OPENSSL:server.com:443
This way, the port 443 of server.com is now available unencrypted on localhost:1080 Then, use socat and its proxy mode to ask for localhost:1080 (which is actually server.com:443 unencrypted) to connect to localhost:22 (which is then server.com:22).
socat - PROXY:127.0.0.1:127.0.0.1:22,proxyport=1080
Bingo! You should see the ssh prompt. For the fun, I replaced in my .ssh/config the former
ProxyCommand proxytunnel -q -E -p server.com:443 -d 127.0.0.1:22
with
ProxyCommand socat TCP-LISTEN:1080 OPENSSL:server.com:443,verify=0 & socat - PROXY:127.0.0.1:127.0.0.1:22,proxyport=1080
Edit 2015-05-07: See Vincent's comment for a cool idea to wrap the ssh command with the -fMN
options.
It works just fine. There is however a flaw in what I did: I use a hardcoded port, thus I can't establish two ssh connections at the same time. Forwarding the server.com:443 on localhost:1080 fails the second time, since this port is already occupied by the first connection. The best way to fix that would be to use stdio for the proxy_connect requests, instead of a port of localhost (since the number of these port is limited). However, with my version of socat (1.7.1.3), I don't see how to proceed differently: the PROXY method requires three arguments and one of them is a port. If one of my readers has a suggestion, he/she's welcome. This remains a cool hack!
Edit: The great Marco Fontani gave a cool solution (see the comments). Here is how my .ssh/config looks like:
Host server.com
ProxyCommand socat TCP-LISTEN:1080 OPENSSL:server.com:443,verify=0 & sleep 1 && socat - PROXY:127.0.0.1:127.0.0.1:22,proxyport=1080
DynamicForward 1080
ServerAliveInterval 60
ControlMaster auto
ControlPath ~/.ssh/tmp/%h_%p_%r
from https://blog.chmd.fr/ssh-over-ssl-episode-2-replacing-proxytunnel-with-socat.html
-----------------------------
Stealth tunneling through HTTP(S) proxies.
http://proxytunnel.sf.net/
Proxytunnel
Author: Jos Visser josv@osp.nl, Mark Janssen maniac@maniac.nl
Hi all,
This is proxytunnel, a program that connects stdin and stdout to an origin server somewhere in the Internet through an industry standard HTTPS proxy. I originally wrote this program to be used as an extension to SSH, to be able to SSH to my box at home. In this file, I will describe the use with SSH. If you want to use it with some other application, feel free, and let me know!
here
Build docs ishere):
Usage (man page isProxytunnel is very easy to use, when running proxytunnel with the help option it specifies it's command-line options.
$ ./proxytunnel --help
proxytunnel 1.9.9 Copyright 2001-2018 Proxytunnel Project
Usage: proxytunnel [OPTIONS]...
Build generic tunnels through HTTPS proxies using HTTP authentication
Standard options:
-i, --inetd Run from inetd (default: off)
-a, --standalone=INT Run as standalone daemon on specified port
-p, --proxy=STRING Local proxy host:port combination
-r, --remproxy=STRING Remote proxy host:port combination (using 2 proxies)
-d, --dest=STRING Destination host:port combination
-e, --encrypt SSL encrypt data between local proxy and destination
-E, --encrypt-proxy SSL encrypt data between client and local proxy
-X, --encrypt-remproxy SSL encrypt data between local and remote proxy
-W, --wa-bug-29744 workaround ASF Bugzilla 29744, if SSL is active stop
using it after CONNECT (might not work on all setups;
see /usr/share/doc/proxytunnel/README.Debian.gz)
-B, --buggy-encrypt-proxy Equivalent to -E -W, provided for backwards
compatibility
-L (legacy) enforce TLSv1 connection
-T, --no-ssl3 Do not connect using SSLv3
Additional options for specific features:
-z, --no-check-certificate Don't verify server SSL certificate
-C, --cacert=STRING Path to trusted CA certificate or directory
-F, --passfile=STRING File with credentials for proxy authentication
-P, --proxyauth=STRING Proxy auth credentials user:pass combination
-R, --remproxyauth=STRING Remote proxy auth credentials user:pass combination
-N, --ntlm Use NTLM based authentication
-t, --domain=STRING NTLM domain (default: autodetect)
-H, --header=STRING Add additional HTTP headers to send to proxy
-o STRING send custom Host Header
-x, --proctitle=STRING Use a different process title
Miscellaneous options:
-v, --verbose Turn on verbosity
-q, --quiet Suppress messages
-h, --help Print help and exit
-V, --version Print version and exit
To use this program with OpenSSH to connect to a host somewhere, create a $HOME/.ssh/config file with the following content:
Host foobar
ProtocolKeepAlives 30
ProxyCommand /path/to/proxytunnel -p proxy:8080 -P username
-d mybox.athome.nl:443
With:
- foobar The symbolic name of the host you want to connect to
- proxy The host name of the proxy you want to connect through
- 8080 The port number where the proxy software listens to
- username Your proxy userid (password will be prompted)
- mybox.athome.nl The hostname of the box you want to connect to (ultimately)
- 443 The port number of the SSH daemon on mybox.athome.nl
If your proxy doesn't require the username and password for using it, you can skip these options. If you don't provide the password on the command-line (which is recommended) you will be prompted for it by proxytunnel. If you are on a trusted system you can also put the password in an environment variable, and tell proxytunnel where to find it with '-S'.
If you want to run proxytunnel from inetd add the '--inetd' option.
Most HTTPS proxies do not allow access to ports other than 443 (HTTPS) and 563 (SNEWS), so some hacking is necessary to start the SSH daemon on the required port. (On the server side add an extra Port statement in the sshd_config file, or use a redirect rule in your firewall.)
When your proxy uses NTLM authentication (like Microsoft IIS proxy) you need to specify -N to enable NTLM, and then specify your username and password (and optionally domain, if autodetection fails). The NT domain can be specified on the commandline if the auto-detection doesn't work for you (which is usually doesn't)
If you want to have the first proxy connect to another http proxy (like one you can control, specify -r proxy2:port. The first proxy will then connect to this remote proxy, which will be asked to connect to the requested destination. Note that authentication doesn't (yet) work on this remote proxy. For more information regarding this feature, check out http://dag.wieers.com/howto/ssh-http-tunneling/
If your proxy is more advanced, and does protocol inspection it will detect that your connection is not a real HTTPS/SSL connection. You can enable SSL encryption (using -e), which will work around this problem, however, you need to setup stunnel4 on the other side, or connect to a process that understands SSL itself.
When all this is in place, execute an "ssh foobar" and you're in business!
Environment Variables
Proxytunnel can make use of the following environment variables:
PROXYUSER Username for the proxy-authentication
PROXYPASS Password for the proxy-authentication
REMPROXYUSER Username for remote proxy-authentication
REMPROXYPASS Password for remote proxy-authentication
HTTP_PROXY Primary proxy host and port information
Format: HTTP_PROXY=http://<host>:<port>/
Authentication File
Proxytunnel can read authentication data from a file (-F/--passfile)
The format for this file is:
<field> = <value>
<field> = <value>
etc
One entry per line, 1 space before and after the equal sign.
The accepted fields are:
- proxy_user
- proxy_passwd
- remproxy_user
- remproxy_passwd
Share and Enjoy!
Jos Visser josv@osp.nl Mark Janssen maniac@maniac.nl
from https://github.com/proxytunnel/proxytunnel