Total Pageviews

Sunday, 8 April 2012

Use sshuttle to Keep Safe on Insecure Wi-Fi(也可用sshuttle翻墙)

(在mac上。

运行brew install sshuttle来安装

sshuttle。然后,运行:

sshuttle --dns -r root@vps-ip:ssh_port_number 0.0.0.0/0  

会提示输入root用户的密码。

输入root用户的密码,回车,会显示:

client: Connected.

然后,你的整台mac机器就处于全局翻墙状态了。所以,

sshuttle其实是一个全局代理程序。

说明:
  • --dns 选项表示转发本地的 DNS 请求;
  • 0.0.0.0/0 表示需要转发本地的所有请求.
如果要停止使用这个全局代理,只需要 CTRL + C 终止命令即可。

另外:如果你用sshuttle --dns -r root@vps-ip:ssh_port_number 0.0.0.0/0 翻墙失败,显示“正在解析主机”,那么可以终止该命令,然后去掉--dns ,运行:
sshuttle -r root@vps-ip:ssh_port_number 0.0.0.0/0

sudo networksetup -setdnsservers "Wi-Fi" 127.0.0.1

运行ss

cd ~/goproxy-by-snail007 && sudo ./proxy dns -S socks -T tcp -P 127.0.0.1:1080 -p :53

通过最后的2步命令做dns解析,详见https://briteming.blogspot.com/2019/08/socks-proxydnsdns-proxy-by-snail007.html )
 

If you’ve ever used an insecure Wi-Fi connection in a public place (think coffee shop, airport, etc.), your personal information could be at risk. Anyone on the local network could potentially be monitoring your traffic and they could even hijack your sessions to control accounts that you’ve logged into.
Every week I meet up with some friends to work on personal projects, and the venue only offers an open wireless connection with no encryption. To mitigate the risk of leaking personal information, I’ve tried a handful of strategies and eventually settled on using sshuttle.

What is sshuttle?

The sshuttle utility is part transparent proxy, part Virtual Private Network (VPN), and part SSH. It solves a lot of common problems with encrypting your traffic, and it does so in a very efficient way.
There’s no need for a complicated pre-existing infrastructure. All you need is Python 2.x, and a remote machine you can SSH to that also has Python installed. You don’t even have to be an administrator on the remote machine. The project’s README has a lot more information on its theory, design, and alternate uses.

Previous Method

As an aside, I had previously relied on creating a SOCKS proxy with SSH, and then tunnelling my web traffic through it…
$ ssh -fqND 1080 example.com
But, you have to adjust your machine’s proxy configuration settings each time you set up the tunnel, and then tear it all down when you’re done. This method will not force absolutely all traffic over the tunnel, as things like DNS lookups and a lot of command-line tools will just ignore the proxy. You’re also encapsulating TCP-over-TCP, which can cause performance problems.
I briefly messed with the Sidestep project to automate these setup/teardown steps on OS X, but ran across repeated authentication issues and wasn’t overly impressed with its developer. Overall, I needed a more elegant solution.

Installation

I wanted to use sshuttle on OS X Lion, and even though it’s primarily a command-line utility, it also comes with a graphical user interface wrapper that will sit in the menu bar. If you just want the command-line script and already use Homebrew, brew install sshuttle is the way to go. If you don’t use Homebrew and/or want the GUI, I’ve got your back…

Building sshuttle from Source

Unfortunately, pre-compiled binaries are not made available for every release, and documentation for building sshuttle is non-existent. The project uses a build system called ‘redo’ instead of the more-customary ‘make’, so the process is a bit different than what most people are used to.
Luckily, the sshuttle repository includes a shell script named ‘do’, which is a simplified version of redo, so you won’t need to install any additional build software. The only real dependencies are Python and two Python modules to generate the man page (feel free to use pip install instead of easy_install, if you prefer):
$ easy_install markdown BeautifulSoup
Once you’ve installed those two modules, you’re all set to build…
NOTE: You may have to adjust paths or permissions slightly depending on your machine’s setup.
$ mkdir -p /usr/local/libexec
$ git clone git://github.com/apenwarr/sshuttle.git /usr/local/libexec/sshuttle
$ cd /usr/local/libexec/sshuttle/
$ ./do all
Once sshuttle is built, we just make symlinks so the binary and man page are in the proper places:
$ ln -s /usr/local/libexec/sshuttle/sshuttle /usr/local/bin
$ mkdir -p /usr/local/share/man/man8
$ ln -s /usr/local/libexec/sshuttle/Documentation/sshuttle.8 /usr/local/share/man/man8
For the GUI app, we need to create an alias instead a symlink, because Spotlight will not index symlinks. Yes, you could just copy Sshuttle VPN.app directly into /Applications, but then you’d have to remember to copy it every time you update/rebuild sshuttle.
Without getting too technical, aliases are a lot like symlinks but they use extra metadata called “resource forks” to follow a file (even when it’s moved) rather then blindly pointing to a path. More importantly, Spotlight will index them. There’s no way to create an alias from the command line, so you have to use Finder:
  1. Open Finder and press Command-Shift-G to open the “Go to the folder:” dialog box.
  2. Type /usr/local/libexec/sshuttle/ui-macos in the box and click the Go button.
    Go to the folder: Dialog Box
  3. Click and hold Sshuttle VPN.app, then while holding down both the Command and Option keys, drag the app over to Applications on the left and release the mouse button.
    Create the sshuttle Alias

Configuration

Due to some sysctl changes in OS X Lion, you will have to reboot your machine after you run sshuttle for the first time. An adjustment to the net.inet.ip.scopedroute kernel flag needs to be made, and it can no longer be done during runtime. This is required so forwarding rules will be honored by the firewall.
Everything should be handled automatically by sshuttle, but if your curious to see the change, you can display the boot kernel flags and current settings with the following commands:
$ defaults read /Library/Preferences/SystemConfiguration/com.apple.Boot
{
    "Kernel Flags" = "";
}
$ sysctl -a | grep scopedroute
net.inet.ip.scopedroute: 1
net.inet6.ip6.scopedroute: 1
After you run sshuttle for the first time and then reboot the machine, you can confirm the updated status:
$ defaults read /Library/Preferences/SystemConfiguration/com.apple.Boot
{
    "Kernel Flags" = "net.inet.ip.scopedroute=0";
}
$ sysctl -a | grep scopedroute
kern.bootargs: net.inet.ip.scopedroute=0
net.inet.ip.scopedroute: 0
net.inet6.ip6.scopedroute: 1

Usage

Finally we can get down to actually using sshuttle! It’s flexible enough to do fancier things, but for our particular use case, we just need to forward all traffic over the tunnel.
The basic command to achieve our goal looks like this:
$ sshuttle --dns -r example.com 0/0
NOTE: Sshuttle will honor your ~/.ssh/config connection settings, but you can also manually specify a different username/port, if necessary:
$ sshuttle --dns -r username@example.com:2222 0/0
Run that, and all of your traffic (including DNS requests) will be transparently proxied through an SSH connection to example.com. You can verify this by browsing to http://ifconfig.me.
To stop forwarding traffic, just press Ctrl-c back in the terminal. We can do a bit better though by forking the process into the background so we don’t tie up our terminal session. These are the aliases I use to make setting up and tearing down the tunnel easier:
alias tunnel='sshuttle --dns --daemon --pidfile=/tmp/sshuttle.pid --remote=example.com 0/0'
alias tunnelx='[[ -f /tmp/sshuttle.pid ]] && kill $(cat /tmp/sshuttle.pid) && echo "Disconnected."'
The Sshuttle VPN.app GUI is pretty self-explanatory, just make sure to enable the Send DNS requests through this server checkbox, and select Send all traffic through this server for the “Network routes:” option.

Known Bugs

You may see a bunch of “warning: closed channel …” messages when running sshuttle (either on STDOUT or in your system.log), but these warnings are safe to ignore. The developer knows about the issue and is thinking of the best way to suppress/eliminate the condition.
Also, prior to version 0.60 of sshuttle, there was a bug in the GUI application when disconnecting tunnels, where the controlling terminal would disappear before firewall rules could cleaned up. This would leave the network in an odd state and all DNS lookups would fail. It should be fixed now, but if you experience networking trouble after disconnecting a sshuttle tunnel, you can see the current firewall rules using:
$ sudo ipfw list
…and you can manually flush out those rules to fix connectivity by running:
$ sudo ipfw -f flush
Be aware though, this will flush out all rules, not just the rules set by sshuttle, so it may have unintended consequences. If you’re unsure, you can always reboot the machine to get connectivity back to normal.

Update sshuttle

Since our installation of sshuttle is managed via git, updating to the latest version is pretty straightforward:
$ cd /usr/local/libexec/sshuttle
$ git pull
$ ./do all

Conclusion

Admittedly, sshuttle takes a bit more work than other solutions to get up and running, but the security it provides gives me peace of mind when forced to use insecure Wi-Fi networks.

from http://elasticdog.com/2011/12/use-sshuttle-to-keep-safe-on-insecure-wi-fi/
--------------------------------------------------------------------------------------------

sshuttle: 穷人的VPN


如果你没钱买VPN,又没有服务器的root权限打开SSH的port forward,或者懒得去鼓捣那一大堆烦人的VPN配置,那你应该试试sshuttle,sshuttle是一个基于SSH的透明代理,支持DNS tunnel,并且不需要对服务端进行任何配置,只要你用的是Linux,Mac或者BSD系统,并且可以在本地执行sudo,su,或者有root权限就可以用它来实现透明代理。
使用很简单,在本地执行:
git clone git://github.com/apenwarr/sshuttle #需要支持python
./sshuttle --dns -vvr username@sshserver 0/0
然后你本地的所有连接就都会通过服务器了,除了不需要对Server进行任何配置外,sshuttle也使用了不同于sshtunnel的包传输策略(tcp-over-tcp),因此效率也更高,关于这一点,可以参看项目主页的原理介绍,也可以参看这篇”TCP Over TCP Is A Bad Idea“.我试了下,感觉不如tunnel快,不过对于没钱买vpn,也没钱买VPS的穷人,或者不愿倒腾VPN配置的懒人们,倒是不妨试试。 项目主页:https://github.com/apenwarr/sshuttle
注意: Mac OS 10.6下,第一次启动会出现10分钟内无法上网的现象,可以通过手动关闭无线网络然后再重新打开来解决,此现象只在第一次启动时存在,以后就不会了。
 from http://heikezhi.com/2011/04/04/sshuttle-vpn-for-poor-men/
--------------------------------------------------------------------------------------
 关闭ssh tunnel功能的shell帐号也可用来翻墙

我们一般所说的ssh翻墙是指使用ssh tunnel的动态转发来代理翻墙。

不过不少国外提供免费shell帐号的服务商都关闭了ssh tunnel(有的需要付费开启,有的付费也不能用),那么关闭ssh tunnel的shell帐号如果做代理呢?那就要用到sshuttle了。

以前的文章sshuttle: 穷人的VPN里提到过sshuttle,不过那时我还不知道他在关闭ssh tunnel时还能做代理,这个功能是在推特上看到有推友提到的。

不过这个只适用于Linux和mac os系统,而且需要ssh有shell权限,对于一般翻墙者来说有一定难度。

首先要有一个有shell权限的ssh帐号,不需要root权限也不需要开启ssh tunnel(不少网友免费提供的和免费php空间提供的ssh一般都是没有shell权限的),可以申请国外免费shell帐号的网站列表参考:http://www.bylur.net/free/和http://shells.red-pill.eu/(申请时不明白的就谷歌翻译吧,不过总体来说申请还是不容易的)。

然后下载sshuttle在Linux终端输入以下命令即可(需要支持python)

sudo git clone git://github.com/apenwarr/sshuttle

会提示你输入你操作系统的管理员密码,输入,等完成安装后在终端输入以下命令

sudo ./sshuttle/sshuttle --dns -vvr 用户名@服务器域名或IP:ssh端口 0/0

(其中红字修改为你的shell帐号的用户名、服务器地址和端口,这个命令是使用ssh服务器的DNS,相比以前文中那个可以防DNS污染)

会提示你保存ssh密钥,输入yes回车,稍等会提示你输入ssh的密码,输入密码后回车,稍等如果不出错就可以打开浏览翻墙浏览了。

(如果出错可以输入sudo ./sshuttle/sshuttle…这行命令再试一遍,sshuttle是类似VPN的全局代理不需对浏览器进行代理设置)

不使用时,在那个终端处按Ctrl+C键关闭sshuttle(如果不能关闭或关闭后出现网络问题,重启系统就可以了)。



在 ubuntu desktop下,运行sudo ./sshuttle/sshuttle --dns -vvr 用户名@服务器域名或IP:ssh端口 0/0,等到界面出现waiting…,ubuntu desktop就处于全局代理的环境下了(就好象处于vpn环境下一样)。

理论上sshuttle应该比ssh tunnel速度快,不过在以上配置下我具体测试中发现sshuttle速度比ssh tunnel慢很多尤其在观看在线视频和下载时。在官方论坛看到的解释是sshuttle有个内部控制以牺牲宽带来降低延迟,也就是上面的配置下,浏览网页很流畅不过看在线视频和下载会较慢,如果使用以下不限速的配置,看在线视频和下载速度很快不过浏览网页可能就没有那么流畅啦:
sudo ./sshuttle/sshuttle --dns -vvr 用户名@服务器域名或IP:ssh端口 0/0 --no-latency-control

https://github.com/foursquar/sshuttle,这个sshuttle跟这个
http://github.com/apenwarr/sshuttle是一回事。



--------------------------------
 

sshuttle is a better 'ssh -D' alternative

如果openvpn走tcp连接的话,隧道里的tcp的控制和重发岂不是就没用了?

今天HN上讨论了一个新东东 sshuttle,一句话介绍:
如果说ssh -D是tcp-over-tcp,那么sshuttle则是data-over-tcp。
详细介绍:
But you can't safely just forward TCP packets over a TCP session (like ssh), because TCP's performance depends fundamentally on packet loss; it must experience packet loss in order to know when to slow down! At the same time, the outer TCP session (ssh, in this case) is a reliable transport, which means that what you forward through the tunnel never experiences packet loss. The ssh session itself experiences packet loss, of course, but TCP fixes it up and ssh (and thus you) never know the difference. But neither does your inner TCP session, and extremely screwy performance ensues.
sshuttle assembles the TCP stream locally, multiplexes it statefully over an ssh session, and disassembles it back into packets at the other end. So it never ends up doing TCP-over-TCP. It's just data-over-TCP, which is safe.
和VPN相比sshuttle是stateful的,和ssh相比sshuttle lets you use the "real" IP addresses of each host rather than faking port numbers on localhost.
还有一篇essay说为神马TCP Over TCP Is A Bad Idea。简单的说,就是双层数据丢包性能底下。

from http://blog.est.im/archives/3875
-------------------------------------------------

Why TCP Over TCP Is A Bad Idea

A frequently occurring idea for IP tunneling applications is to run a protocol like PPP, which encapsulates IP packets in a format suited for a stream transport (like a modem line), over a TCP-based connection. This would be an easy solution for encrypting tunnels by running PPP over SSH, for which several recommendations already exist (one in the Linux HOWTO base, one on my own website, and surely several others). It would also be an easy way to compress arbitrary IP traffic, while datagram based compression has hard to overcome efficiency limits.
Unfortunately, it doesn't work well. Long delays and frequent connection aborts are to be expected. Here is why.

TCP's retransmission algorithm

TCP divides the data stream into segments which are sent as individual IP datagrams. The segments carry a sequence number which numbers the bytes in the stream, and an acknowledge number which tells the other side the last received sequence number. [RFC793]
Since IP datagrams may be lost, duplicated or reordered, the sequence numbers are used to reassemble the stream. The acknowledge number tells the sender, indirectly, if a segment was lost: when an acknowledge for a recently sent segment does not arrive in a certain amount of time, the sender assumes a lost packet and re-sends that segment.
Many other protocols using a similar approach, designed mostly for use over lines with relatively fixed bandwidth, have the "certain amount of time" fixed or configurable. In the Internet however, parameters like bandwidth, delay and loss rate are vastly different from one connection to another and even changing over time on a single connection. A fixed timeout in the seconds range would be inappropriate on a fast LAN and likewise inappropriate on a congested international link. In fact, it would increase the congestion and lead to an effect known as "meltdown".
For this reason, TCP uses adaptive timeouts for all timing-related parameters. They start at conservative estimates and change dynamically with every received segment. The actual algorithms used are described in [RFC2001]. The details are not important here but one critical property: when a segment timeouts, the following timeout is increased (exponentially, in fact, because that has been shown to avoid the meltdown effect).

Stacking TCPs

The TCP timeout policy works fine in the Internet over a vast range of different connection characteristics. Because TCP tries very hard not to break connections, the timeout can increase up to the range of several minutes. This is just what is sensible for unattended bulk data transfer. (For interactive applications, such slow connections are of course undesirable and likely the user will terminate them.)
This optimization for reliability breaks when stacking one TCP connection on top of another, which was never anticipated by the TCP designers. But it happens when running PPP over SSH or another TCP-based protocol, because the PPP-encapsulated IP datagrams likely carry TCP-based payload, like this:
(TCP over IP over PPP over SSH over TCP over IP)
Note that the upper and the lower layer TCP have different timers. When an upper layer connection starts fast, its timers are fast too. Now it can happen that the lower connection has slower timers, perhaps as a leftover from a period with a slow or unreliable base connection.
Imagine what happens when, in this situation, the base connection starts losing packets. The lower layer TCP queues up a retransmission and increases its timeouts. Since the connection is blocked for this amount of time, the upper layer (i.e. payload) TCP won't get a timely ACK, and will also queue a retransmission. Because the timeout is still less than the lower layer timeout, the upper layer will queue up more retransmissions faster than the lower layer can process them. This makes the upper layer connection stall very quickly and every retransmission just adds to the problem - an internal meltdown effect.
TCPs reliability provisions backfire here. The upper layer retransmissions are completely unnecessary, since the carrier guarantees delivery - but the upper layer TCP can't know this, because TCP always assumes an unreliable carrier.

Practical experience

The whole problem was the original incentive to start the CIPE project, because I used a PPP over SSH solution for some time and it proved to be fairly unusable. At that time it had to run over an optical link which suffered frequent packet loss, sometimes 10-20% over an extended period of time. With plain TCP, this was just bearable (because the link was not congested), but with the stacked protocols, connections would get really slow and then break very frequently.
This is the detailed reason why CIPE uses a datagram carrier. (The choice for UDP, instead of another IP-level protocol like IPsec does, is for several reasons: this allows to distinguish tunnels by their port number, and it adds the ability to run over SOCKS.) The datagram carrier has exactly the same characteristics as plain IP, for which TCP was designed to run over.

from http://sites.inka.de/bigred/devel/tcp-tcp.html
------------

用Sshuttle翻墙的速度没有snet(利用全局(指整台机器的)代理-SNET翻墙)那么快。
-------------

相关帖子:
https://briteming.blogspot.com/2013/02/using-sshuttle-in-daily-work.html
https://briteming.blogspot.com/2018/09/ssh-tips.html的Sshuttle部分。