Giter VIP home page Giter VIP logo

shadowsocks-org's Introduction

Intro

The official website of Project Shadowsocks.

Build

yarn install
yarn docs:build

shadowsocks-org's People

Contributors

aaronchen0 avatar al-x avatar alalamav avatar cpu avatar darienraymond avatar database64128 avatar dependabot[bot] avatar ed-asriyan avatar elnx avatar fortuna avatar higuoxing avatar joeytwiddle avatar khaledhassan avatar kimw avatar leesah avatar librehat avatar madeye avatar mygod avatar riobard avatar skeggse avatar suwmlee avatar ushuz avatar vinjn avatar xfq avatar zhou0 avatar zonyitoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shadowsocks-org's Issues

Follow IANA registry for AEAD ciphers

IANA has a dedicated AEAD registry defining numeric ID, common name, and reference specification for AEAD ciphers. Compliant Shadowsocks implementations should follow the naming scheme http://www.iana.org/assignments/aead-parameters/aead-parameters.xhtml

In particular, AEAD_CHACHA20_POLY1305 must be implemented as a common cipher. Implementations intending to run on devices with hardware AES acceleration should also implement AEAD_AES_128_GCM, AEAD_AES_192_GCM, and AEAD_AES_256_GCM.

For backward compatibility, alias

  • chacha20-ietf-poly1305 to AEAD_CHACHA20_POLY1305;
  • aes-128-gcm to AEAD_AES_128_GCM;
  • aes-192-gcm to AEAD_AES_192_GCM;
  • aes-256-gcm to AEAD_AES_256_GCM.

模拟微信协议混淆

猫猫通过mitmproxy见过一点微信是通过HTTP协议但又给自己信息内容加了个加密壳喵
所以猫猫想是否可以模拟微信交流方式作为SS的交流方式喵?

evaluete RC6 cipher

according to this paper at http://www.tmrfindia.org/ijcsa/v11i12.pdf

"The RC5 and RC6 ciphers [RSA Security (2005)] in EAX mode demonstrated the
best overall median (i.e. based on encryption of RMM files of all sizes) performance
on technical platform TP2 (i.e. generic Asus netbook) with both Windows and Linux
OS in both single processor 1Proc and multi processor MProc modes of CPU
operation (Table 3, columns ## 7-10). The second best ciphers on TP2 are TwoFish
and AES-128 ciphers; they demonstrated about 33% (on average) lower performance
with Windows OS, and about 47% with Linux OS in comparison with performance
of RC6 and RC5 ciphers."

RC6 US patent will expire on April 21 2017 which is less than 2 months away. Since RC6 in EAX mode ( one of AEAD modes ) has better performance for netbook than AES, so it is desireable to have RC6 support for nebook laptops.

SIP004 - Support for AEADs implemented by large libraries

Use AEADs to replace stream cipher + OTA. Previous discussion: #29.

Proposed AEAD algorithms:

  • ChaCha20-Poly1305 (see also: xSocks)
  • XChaCha20-Poly1305
  • Salsa20-Poly1305
  • AES-256-GCM (faster but not low-end-box-friendly)

Update: The following shows an example of TCP stream in chacha20-ietf-poly1305 mode (original idea by @breakwa11 and @Noisyfox). Other AEAD should follow the similar format.

Cipher: chacha20-ietf-poly1305

TCP request (after encryption, *ciphertext*)
+--------+----------------+--------------+--------------+---------------+
| NONCE  | PayloadLen_TAG | *PayloadLen* | Payload_TAG  |   *Payload*   |
+--------+----------------+--------------+--------------+---------------+
|  12    |       16       |       2      |     16       |    Variable   |
+--------+----------------+--------------+--------------+---------------+

TCP Chunk (after encryption, *ciphertext*)
+--------------+------------+-----------+----------+
| DATA_LEN_TAG | *DATA_LEN* |  DATA_TAG |  *DATA*  |
+--------------+------------+-----------+----------+
|      16      |     2      |     16    | Variable |
+--------------+------------+-----------+----------+

为什么应该用 SSL 翻墙

为了让更多人看懂,这篇文章使用中文撰写。
原文地址:https://gist.github.com/yvbbrjdr/ea80fc5ef21f1a518346c92bda611993

为什么应该用 SSL 翻墙

由Glype想到的


2013年7月8日,clowwindy写道:

为什么不应该用 SSL 翻墙

SSL 设计目标:

1. 防内容篡改
2. 防冒充服务器身份
3. 加密通信内容

而翻墙的目标:

1. 不被检测出客户端在访问什么网站
2. 不被检测出服务器在提供翻墙服务

SSL 和这个目标还是有一些出入。其中最大的问题是,2. 防冒充服务器身份 这个功能多余了。他会导致墙嗅探出证书信息,继而墙会知道服务器身份。如果墙知道一个服务器身份是用来翻墙的,它要做的仅仅是封掉使用这个证书的所有 IP。

墙看见的 SSL 握手响应头部如下:

(以下省略一个明显带有特征的Twitter HTTPS头)

这一段内容对翻墙的目标总结得非常到位:不被检测出客户端在访问什么网站以及不被检测出服务器在提供翻墙服务。具体来说:

不被检测出客户端在访问什么网站

是指即使翻墙包被截获并分析,也无法探知其中的内容。实现这一点非常容易,用加密算法就能实现。总之要让墙无法通过低成本的方法破解出内容即可。

不被检测出服务器在提供翻墙服务

这个比较复杂。半年来shadowsocks以及shadowsocksR的更新都是在做这件事情。它包含两个方面:

  1. 即使翻墙包被截获并分析,也无法区分其与其他数据包的区别(换言之,无法识别是否是翻墙包)。注意:识别翻墙包不一定需要解密其中的内容。
  2. 对于一个翻墙服务器,无法利用协议漏洞,通过各种攻击方式(重放攻击、篡改攻击、中间人攻击等等)来探测其是否是翻墙服务器。

现有的各种翻墙包结构基本无法实现上面的第2点,因为如果要自定义一个翻墙协议,一定会暴露出某些特征。我认为解决的方法是:不使用自定义的协议,而将翻墙协议建立在已有的、流行的、安全的协议之上,于是我想出一种利用SSL进行翻墙的方法,只是对原来的HTTPS进行一些不大的修改。

在阐述协议之前,我先利用clowwindy对于两个目标的描述说明为什么SSL适合翻墙:

SSL 设计目标:

  1. 防内容篡改 -- 防止篡改攻击
  2. 防冒充服务器身份 -- 防止中间人攻击
  3. 加密通信内容 -- 不被检测出客户端在访问什么网站

且因为每一次SSL协商时对称加密密钥都会不同,也顺便防止了重放攻击;因为HTTPS是一个非常常用的协议,HTTPS请求经过GFW时不会被怀疑,也无法检测是否是翻墙包。

下面用自然语言阐述这个翻墙协议:

众所周知,HTTPS是HTTP套了一层SSL。而由于SSL的加密特点,HTTP请求和响应的明文是不会被中间人截获的。事实上,不管SSL的下层协议是什么,其内容明文都不会被第三方获知。因此,我们可以将shadowsocks协议外套一层SSL来实现翻墙,唯一的改变是,将shadowsocks请求头的末尾加上\r\n(即HTTP行结束符)。如果GFW用HTTPS探测服务器,那么服务器返回一个正常的网站(比如Wordpress,甚至可以是自己真正的博客,可以用Nginx或者Apache实现),如果GFW用shadowsocks over SSL协议探测服务器,那么在收到第一个\r\n的时候服务器立即检查数据合法性,发现既不是HTTP协议又不是正确的(密码无误的)shadowsocks协议,那么立即关连接,或者返回HTTP 400 Bad Request(与HTTP处理不合法包的方法一样)。这样在不知道密码的情况下,GFW只能探测出这是一个HTTPS服务器,而不知道其是否运行shadowsocks over SSL。

剩下的问题是HTTPS证书。那么随便弄一个自签名证书,或者申请一个免费的就行了,再让客户端信任一下。

Experimental AES-SIV cipher

I've added an experimental AES-SIV cipher to my Go port here riobard/go-shadowsocks2@7bcc772

This should in theory mitigate the issue of nonce reuse in SIP004 since SIV is misuse-resistant. However the performance of SIV is pretty bad, as SIV is a non-online 2-pass cipher.

Benchmarking on my machine using AES-SIV-512 results in ~1Gbps throughput measured by iperf3, compared to >4Gbps throughput using AES-256-GCM. In most cases 1Gbps is more than good enough.

SIP005 - TCP MD5SIG to counter TCP RST MitM attack

Backgroud

Although we have Tor PT support (only proxy mode yet), someone may consider it's too heavy.

The original purpose for Tor PT support is to avoid TCP RST Man-in-the-middle attack, for some it's too heavy and considering there is already some report about DPI devices detecting obfs2/3/4 or screamblesuit, another lightweight implement won't hurt.

Lightweight alternative

And I just found that there is already RFC 2385 addressing this problem by introducing MD5 signature for TCP.
Which even covers TCP handshake, making it quite a good option for us to simply defend TCP RST MITM attack.

Furthermore, this option will only work if we use plain SS.
If we're using SIP003 plugin, such MD5SIG should be disabled as we're just wasting our CPU on localhost communication.

Further concern

The implementation should be even easier than Tor PT proxy mode, but I still have several concern on it.

  1. Insecure hash algorithm
    There is known attack against MD5, it's no longer considered as a safe hash algorithm.

  2. More obvious connection characteristic
    MD5SIG is normally strongly binded to BGP, which is far from common in normal use case.
    Use of MD5SIG will make connection super easy to be detected and blocked.

  3. Harder to debug
    Since kernel will just drop any TCP packet with wrong or no MD5 signature, including the hand shake packets, withouth informing user space, it will be quite hard to debug.

So I think it's better to be discussed before pushing a PR.

Review my new Go port

Initial attempt only included AEAD support. I rushed to add back the original stream ciphers. Now it's usable (only a few modern ciphers included; deprecated ones are left out), but lacks polish and usage documentation. Will follow up on that next.

To experiment, run go install github.com/riobard/go-shadowsocks2. Currently it supports SOCKS5 proxy, Netfilter TCP redirect (IPv6 support included but not tested), UDP and TCP tunneling.

Please review and criticize.

Code at https://github.com/riobard/go-shadowsocks2
Godoc at https://godoc.org/github.com/riobard/go-shadowsocks2

Proposal for a new backward-compatible ss protocol

The current ss protocol doesn't include One-Time Authentication feature which is essential to make a proper connection. I propose two possible solutions to this problem.

Here's a regex for current protocol which doesn't include OTA:

(?i)^ss://((?<method>.+?):(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))$
(?i)^ss://(?<base64_encoded_group_1>.+)$

And these are two possible upgrades that are backward compatible for the ones that haven't enabled OTA where -auth is appended to method:

(?i)^ss://((?<method>.+?)(?<auth>-auth)??:(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))$
(?i)^ss://(?<base64_encoded_group_1>.+)$

Or ?auth or /?auth is appended to the end of URL:

(?i)^ss://((?<method>.+?):(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))/??(?<auth>\?auth)??$
(?i)^ss://(?<base64_encoded_group_1>.+)/??(?<auth>\?auth)??$

I prefer the first one. What do you think?

Session key with counting nonce or short IV

In #36 I explained why using long-term key with short random nonce is a bad idea. Later in that discussion @wongsryone raised the issue that higher entropy consumption of SIP004 might be problematic on some VM and embedded devices.

Well, technically we are not consuming entropy faster in SIP004 as we are still generating one random number per TCP connection. However we are consuming available nonce space at a much faster pace because we're incrementing it as a counter twice per chunk, effectively increasing the probability of (key, nonce) pair reuse by a few orders of magnitude.

Now I think this is a design flaw which could be avoided by a minor change.


In #36 I proposed to deprecate ciphers with short nonce/IV to increase available nonce space. Unfortunately it eliminated some nice ciphers like chacha20 and chacha20-poly1305 (8-byte nonce/IV).

Actually there's a better way.


Instead, we could generate a random session key and encrypt it using the pre-shared key (with random nonce/IV if AEAD/stream cipher) and send it at the beginning of a connection. We then use the session key to encrypt the rest of the connection. As a result:

  • For stream ciphers, random IV is no longer necessary (but we could still use one) because the key is random.
  • For AEAD ciphers, random nonce is also no longer necessary, and we can use a simple counter from zero as nonce.

Since key size is usually longer than nonce/IV, we are free to use ciphers with short nonce/IV. We're looking at 128-bit randomness at least and 256-bit for chacha20, instead of 64-bit or 96-bit nonce/IV. Much, much larger space.

To summarize, here is a structure of a connection encrypted by a stream cipher

[fixed-length random IV to encrypt session key]
[fixed-length encrypted session key using pre-shared key and the random IV above]
[variable-length encrypted content using the session key above with optional IV]

And the structure of a connection encrypted by an AEAD cipher

[fixed-length random nonce]
[fixed-length encrypted session key using pre-shared key and the random nonce above]
[fixed-length tag]

[fixed-length encrypted payload length using session key and nonce 0]
[fixed-length encrypted payload length tag]
[variable-length encrypted payload using session key and nonce 1]
[fixed-length encrypted payload tag]

[fixed-length encrypted payload length using session key and nonce 2]
[fixed-length encrypted payload length tag]
[variable-length encrypted payload using session key and nonce 3]
[fixed-length encrypted payload tag]

...

Reduce chunk length overhead in AEAD

I just read a blog post by OpenSSH developer Damien Miller. The following two paragraphs are particularly interesting:

Both AES-GCM and the EtM MAC modes have a small downside though: because we no longer desire to decrypt the packet as we go, the packet length must be transmitted in plaintext. This unfortunately makes some forms of traffic analysis easier as the attacker can just read the packet lengths directly. OpenSSH takes some countermeasures to obscure the lengths of obvious secrets like passwords used for login or typed into an active session, but I haven't felt entirely comfortable with the protocol revealing the length of every packet sent on the wire.

The new [email protected] avoids this though. In addition to providing authenticated encryption with integrity-checking performed before unwrapping encrypted data, this mode uses a second stream cipher instance to separately encrypt the packet lengths to obscure them from eavesdroppers. An active attacker can still play games by fiddling with the packet lengths, but doing so will reveal nothing about the packet payloads themselves - they can make the receiving end read a smaller or larger packet than intended, but the MAC will be checked (and the check will fail) before anything is decrypted or used. Fortunately ChaCha20 is very fast and has quite small keys, so maintaining a separate instance is very cheap.

The blog post points to the [email protected] cipher spec with details about handling the packet length:

When receiving a packet, the length must be decrypted first. When 4 bytes of ciphertext length have been received, they may be decrypted using the K_1 key, a nonce consisting of the packet sequence number encoded as a uint64 under the usual SSH wire encoding and a zero block counter to obtain the plaintext length.

Currently we do double AEAD encryptions per chunk: one for the payload length, and one for the payload itself. The first AEAD encryption is to hide the payload length to get a uniform random stream output, at the cost of one tag overhead (16 bytes).

The OpenSSH approach quoted above does not have the extra overhead, but it requires an extra stream cipher. For chacha20-poly1305 they can just reuse the same chacha20 cipher. For AES-GCM there's no obvious choice so they do not attempt to hide packet length, and reveal it to adversaries.

I think their construction is interesting and worth study.

Defend against replay attack

https://en.wikipedia.org/wiki/Replay_attack

A replay attack (also known as playback attack) is a form of network attack in which a valid data transmission is maliciously or fraudulently repeated or delayed. This is carried out either by the originator or by an adversary who intercepts the data and re-transmits it, possibly as part of a masquerade attack by IP packet substitution.

Replay Attack potentially allows adversaries to identify a Shadowsocks server by observing and replaying the data streams between a valid client and the server. Ideally we want to recognize that a data stream is replayed, and react accordingly.

Secure single-port multi-user authentication

Summary

Current commercial deployments of Shadowsocks suffer from a social-engineering weakness that any client knows the Symmetric Pre-Shared Key (SPSK) and can use it to MitM attack other clients of the same server.

To counter this weakness, SPSK must be abandoned in favor of asymmetric private/public key pairs. The server's private key must be kept secret at all times. Clients only know the server's public key, and must derive a per-session subkey to talk to the server. No clients can pretend to be the server because it does not have the server's private key.

An additional benefit of using asymmetric key pairs is that multiple users can share the same port securely without revealing their own client identifiers.

Update

Please see #54 (comment) for the latest proposal. The following section is the original proposal without forward secrecy protection.

Details (OBSOLETED)

  1. The server randomly generates a pair of keys on Curve25519: a private key sk that must be kept secret, and a public key pk that is distributed to all clients beforehand.

    sk, pk = curve25519_keypair(random_seed)

  2. Each time a client wants to talk to the server, it randomly generates another pair of keys on Curve25519: a private key sk' that must be kept secret, and a public key pk' to be sent to the server.

    sk', pk' = curve25519_keypair(random_seed)

  3. The client computes the shared secret with the server using x25519 ECDH function:

    shared_secret = x25519(sk', pk)

  4. The client derives the per-session subkey using HKDF_SHA256:

    subkey = HKDF_SHA256(shared_secret || pk' || pk)

  5. The client encrypts payload using the subkey and sends the encrypted data to server.

  6. The server receives the client's public key pk' and computes the shared secret using x25519 ECDH function:

    shared_secret = x25519(sk, pk')

  7. The server derives the per-session subkey using HKDF_SHA256:

    subkey = HKDF_SHA256(shared_secret || pk' || pk)

  8. The server uses the subkey to decrypt the encrypted payload.

Note that x25519 ECDH function ensures x25519(sk, pk') == x25519(sk', pk).

To implement secure multiuser support, the client can include its Client Authentication (e.g. username/password) in the payload for the server to verify against a database. Detailed format will be discussed separately.

Unifying chacha20-poly1305 ciphers

Historically we have had three variants of chacha20-poly1305 AEAD ciphers:

  1. The original chacha20-poly1305 with 64-bit nonce.
  2. The IETF-variant chacha20-ietf-poly1305 with 96-bit nonce.
  3. The extended xchacha20-poly1305 with 192-bit nonce.

Before SIP007, the original variant was ditched due to high probability of nonce reuse. SIP007 introduced per-session key and counting nonce, effectively making the three variants equivalent in strength of security and the size of nonce irrelevant.

I propose we just use a single cipher called chacha20-poly1305 to refer to the IETF-variant since the original and the extended variants are rarely used in other places anyway. This will simplify the AEAD cipher choice and reduce confusion for users.

Reference ChaCha20 and Poly1305 for IETF Protocols

gnutls_handshake() failed when do apt-get update

VPS: KVM with Ubuntu 14.04 installed.

cat /etc/issue
Ubuntu 14.04.3 LTS \n \l

Add below to /etc/apt/sources.list
deb http://shadowsocks.org/ubuntu trusty main

then do apt-get update
apt-get reply as:

Err http://shadowsocks.org trusty/main amd64 Packages
Err http://shadowsocks.org trusty/main i386 Packages
Ign http://shadowsocks.org trusty/main Translation-en_US
Ign http://shadowsocks.org trusty/main Translation-en
Err http://shadowsocks.org trusty/main amd64 Packages
gnutls_handshake() failed: Handshake failed
Err http://shadowsocks.org trusty/main i386 Packages
gnutls_handshake() failed: Handshake failed
W: Failed to fetch http://shadowsocks.org/ubuntu/dists/trusty/main/binary-amd64/Packages gnutls_handshake() failed: Handshake failed

W: Failed to fetch http://shadowsocks.org/ubuntu/dists/trusty/main/binary-i386/Packages gnutls_handshake() failed: Handshake failed

E: Some index files failed to download. They have been ignored, or old ones used instead.

anything wrong in the website? or anything wrong in my env?

SHA1 collision

Google has accomplished practical SHA1 collision attack using 110 GPU-years (cost around $110,000 as of Feb 2017).

Currently we use SHA1 with HKDF to generate per-session key for AEAD ciphers. Due to the construction of HKDF using HMAC, SHA1 collision should not compromise our security.

However, we should not directly use SHA1 from now on. Specifically, if we are to attach message digest along with binary builds to release, we need to use SHA256 or SHA512 instead. SHA1 and MD5 are not acceptable.

This is a reminder just in case.

reduce the initial aead payload length limit to 2014, adjusting it dynamically

as revealed by these two emails

https://www.ietf.org/mail-archive/web/tls/current/msg18688.html

https://www.ietf.org/mail-archive/web/tls/current/msg18695.html

The aim of 16KB length limit of TLS record is for protection again DOS and not performance related consideration. Since it is blindly borrowed into shadowsocks AEAD . It is time for a serious consideration of it. I propose to reduce the length limit to buffer size limit minus 34 for improved latency , for example , if your implementation use a buffer size of 2048 , your payload length limit should be 2014. Please see shadowsocks/shadowsocks-libev#1462 and continue discussing here.

Can't run grunt

Freshly installed Fedora 23.

Get this error message. And it doesn't make any differences with --force

Loading "uglify.js" tasks...ERROR
>> Error: Cannot find module 'source-map'
Loading "less.js" tasks...ERROR
>> Error: Cannot find module 'lodash'
Loading "connect.js" tasks...ERROR
>> Error: Cannot find module 'connect'
Warning: Task "less:docs" not found. Use --force to continue.

SIP006 - Getting rid of key derivation once and for all

Instead of letting possibly dumb server masters choose password, we are going to choose secure password for them.

A truly high-entropy, secure key can be generated using GnuPG:

$ gpg --armor --gen-random 2 <count>

where count is the length of the key we wish to use. Server masters shouldn't specify key themselves but can request a key renewal.

This key will be directly used for AEAD proposed in SIP004 (#30). When putting in SS urls or JSON file it should be base64 url-friendly encoded.

Upgrade source to 2.4.5

Version 2.4.0-1 is outdated and insecure and there are two high urgency updates according to the changelog.

shadowsocks-libev (2.4.1-1) unstable; urgency=high

  • Fix a security bug.

shadowsocks-libev (2.4.3-1) unstable; urgency=high

  • Refine the buffer allocation.

Maybe you could add a separated source for Jessie by the way.

有关更新libev 2.4.2版本

网站上编译好的版本一直不更新..只能自己编译了吗QwQ
如果方便的话..希望可以更新一下呢
谢谢
Thanks

SIP001: Header obfuscating

Shadowsocks Improvement Proposal 001

SIP001 - Allow header obfuscating to cheat on QoS.

Recently, QoS of some ISPs becomes unreasonable. A cheap way to solve this problem is header obfuscating, which inserts some fake headers before shadowsocks handshake packets.

For example, before a shadowsocks request, we insert this HTTP GET header:

    POST / HTTP/1.1\r\n
    Host: www.baidu.com:8388\r\n
    User-Agent: curl/7.45.1\r\n
    Accept: */*\r\n
    Content-Type: application/octet-stream\r\n
    Content-Length: 176\r\n
    \r\n

Similarly, we insert this HTTP header before a shadowsocks response.

    HTTP/1.1 200 OK\r\n
    Server: nginx/1.0.2\r\n
    Date: Tue, 13 Dec 2016 13:25:12 GMT\r\n
    Content-Type: application/octet-stream\r\n
    Content-Length: 176\r\n
    Connection: keep-alive\r\n
    Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform\r\n
    Pragma: no-cache\r\n
    \r\n

With this SIP, we may cheat on most of QoS mechanisms, avoiding QoS related packets dropping or bandwidth limit.

A demonstration can be found here: https://github.com/shadowsocks/shadowsocks-libev/tree/obfs

Any suggestion is welcome.

Track AEAD support on website

Now the AEAD protocol has been finalized, most SS implementations will hopefully support it. However, it is very difficult for the regular user to know (or even track) which implementation has AEAD support, since most implementations do not provide clear information about it on their website (be it Github project page, AppStore page, or Google Play page).

Therefore, it would be good and useful to track the AEAD support status of different SS implementations on the shadowsocks.org website. And while we're at it, plugin support as well. This can be done in two ways (either or both):

  1. On the download/clients and download/servers pages, add footnotes to the name of every listed software that support AEAD and/or plugins, e. g. A for AEAD and P for plugin.

  2. On the spec/aead and spec/plugin pages, add a section at the bottom to list those software that support the respective protocol.

A possible attack to detect AEAD algorithms

About the packet structure implementing AEAD algorithms mentioned in #30 , I have come up with a possible attack to detect it, using a kind of modified replay attack.

Cipher: chacha20-ietf-poly1305

TCP request (after encryption, *ciphertext*)
+--------+----------------+--------------+--------------+---------------+
| NONCE  | PayloadLen_TAG | *PayloadLen* | Payload_TAG  |   *Payload*   |
+--------+----------------+--------------+--------------+---------------+
|  12    |       16       |       2      |     16       |    Variable   |
+--------+----------------+--------------+--------------+---------------+

TCP Chunk (after encryption, *ciphertext*)
+--------------+------------+-----------+----------+
| DATA_LEN_TAG | *DATA_LEN* |  DATA_TAG |  *DATA*  |
+--------------+------------+-----------+----------+
|      16      |     2      |     16    | Variable |
+--------------+------------+-----------+----------+

As you can see from the protocol (idea originating @breakwa11 ) above, the server will detect something wrong only after 30 bytes, when the encrypted PayloadLen is transferred. Before 30 bytes are transferred, the server will simply wait for data to reach 30 bytes, and if the first 30 bytes are authenticated, the server will wait for further data. But if the first 30 bytes aren't authenticated, the server will close the connection immediately.
So here is the attack: when GFW gets a request packet, it can replay the first 30 bytes, and nothing will go wrong. But then, the wall modifies one of the bytes in the first 30 bytes and send it again, the server will close the connection. It is a very obvious pattern. Actually the wall can send the first 29 bytes first and see if the server is waiting; then it can modify the last byte and send it to see if the server closes immediately, or it can send random 29 bytes to the server and send the last 1 random byte to see if the server closes upon receiving the last byte.
Further more, the same pattern appears in TCP Chunks. The wall can replay correct TCP request first, and do the same thing on the first 18 bytes as mentioned in the last paragraph. So that the wall can be sure of the function of the server.
There are loads of more ways to detect AEADs, since fixed header decides same length of one packet, and the server will notice something wrong only after it reads all the bytes needed. Same attack method can also be used to test payload and data, not limited to length.

Deprecate stream ciphers with insufficient IV length

Summary

For Shadowsocks deployment using stream ciphers, long-term key and randomly generated IV of insufficient length causes (key, IV) pair reuse with high probability, which allows Reused Key Attack. Adversaries can recover plaintext within reasonable budget constraint.

Proposal

  • Stream ciphers with IV length less than 12 bytes MUST be deprecated. Namely, bf-cfb, chacha20, and salsa20.
  • Users SHOULD choose stream ciphers with IV length of 16 or more bytes.
  • Users are RECOMMENDED to use the new AEAD ciphers.

Proposal for a random encrypt method

Idea from TrueCrypt.

A new method called random, which client establishes a connection using a random-selected method of all widely available methods, and server decrypt the first bytes (270 bytes at most), and try every method to decrypt it, then use same method to decrypt remaining bytes.

Pro:

  1. Obfuscate data flow on one server port.
    Cons:
  2. More flow when being attacked
  3. Will cost much more CPU when accepting connections.

Shadowsocks 1.4.2 AR71XX does not work with Openwrt 12.09 release

编译openwrt 12.09 release,包含 libpolarssl (称为固件A)
编译openwrt trunk@ 20130114, 包含libpolarssl (称为固件B)
make menuconfig 中两固件所选组件相同。

shadowsocks.org下载最新 ar71xx libpolarssl 版本,安装无问题。

http://travis-ci.s3-website-ap-northeast-1.amazonaws.com/nightly/shadowsocks-libev-polarssl_1.4.2-343940e6ffd2062b11dccab0894b73f7f32722f7_ar71xx.ipk

在固件A 上 启动 /etc/init.d/shadowsocks start 报错:
root@gate:~# /etc/init.d/shadowsocks start
/usr/bin/ss-local: can't load library 'libpolarssl.so.3'

在trunk版本上固件B 正常。

Protocol: TCP responses should include remotely resolved target address like UDP

In the current protocol, TCP responses from ss-remote do not contain the actual IP address of the target server.

It would be nice to include the actual IP address of the target server relayed back to ss-local so ss-local can provide functionality similar to ChinaDNS, making it easier for people to direct traffic automatically without using the unreliable gfwlist.

A typical use case:

  1. Client asks ss-local to connect to twitter.com.
  2. ss-local tries to directly connect to twitter.com using a locally resolved IP address. Because ss-local is located within GFW, the resolved IP is polluted and fake.
  3. ss-local also tries to connect to twitter.com via ss-remote, which is not affected by GFW, and resolves the actual IP of twitter.com.
  4. ss-local compares the address locally resolved and the address relayed from ss-remote, and see that both IPs are outside China IP range.
  5. ss-local prefers the connection via ss-remote because the it knows the locally resolved address is fake.

关于随机长度填充的讨论

是我看漏了,还是觉得这没有必要?为什么没有这个的讨论?
(以上指的是产生随机长度的随机数据附加于原数据包)
我看AEAD确定下来了都没有这块的内容

SIP002 - Optional extension configurations as query strings in ss URLs

Shadowsocks Improvement Proposal 002 (actually why don't we just use issue number to refer to them instead)

Optional configurations as query strings in ss URLs

Since #26, there are at least two optional extension for shadowsocks as far as I can tell:

  • Kcptun
  • HTTP/TLS obfuscation

There may be more extensions in the future. So what about adding them to ss URLs? For example, we can have ss://...?kcpport=8839&kcpcli=--crypt+none......#a+name for easier configuration. Clients that don't support the extensions can safely ignore them.

What should be included:

  • Values that should be consistent with server configuration.

What shouldn't:

  • Arbitrary values that can be configured by users, like whether the extension is enabled.
  • Values that could need changing when copying to other device (except that configuration for client and server can be different), like per-app proxy settings in Android client.

Problems:

  • Should client enable the extension that's been configured when importing?
  • Should client export the extension configuration even if it's not enabled?

Final version:

SIP002 purposed a new URL schema, following RFC3986:

SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" query ] [ "#" fragment ]
userinfo = websafe-base64-encode-utf8(method  ":" password)

The last / should be appended if query or fragment is present. Example: ss://[email protected]:8888/?plugin=url-encoded-plugin-argument-value&unsupported-arguments=should-be-ignored#Dummy+profile+name. This kind of URIs can be parsed by standard libraries provided by most languages.

For plugin argument, we use the similar format as TOR_PT_SERVER_TRANSPORT_OPTIONS, which have the format like simple-obfs;obfs=http;obfs-host=www.baidu.com where colons, semicolons, equal signs and backslashes MUST be escaped with a backslash.

HttpProxy proposal

I propose deploy and run HttpProxy (for example privoxy) at server side (at same host ss-server is running). This allows centralized ad-blocking and routing rules (for example redirect *.i2p to i2p-router and *.onion to tor).
In this deployment scenario shadowsocks can be used as socks4/5 server itself and as encrypted tunnel to http-proxy.

Every time shadowsocks-client (ss-local) accept connection from proxy-client (browser) it can distinguish protocol based on first byte.
If byte==5 serve as socks5. if byte==4 serve as socks4, otherwise tunnel data (just using it's own socks capabilities) to server-side 127.0.0.1:8118 (can be taken from configuration)

This proposal require such CLIENT software changes: to add additional logic when handling BROWSER-to-SHADOWSOCKSCLIENT iteraction:

  • add optional client configuration parameter: remoteHttpProxyPort
  • analyze first bytes from browser-to-ssclient handshake
  • if first byte==5 proceed as Socks5 server (as is) (SS-CLIENT acts as Socks5 server for browser) [browser]<--socks5-protocol-->[ss-local]<--ss-protocol-->[ss-server]<--tcp-->[remote-host]
  • (optional for old browsers) if first byte==4 proceed as Socks4a server (SS-CLIENT acts as Socks4a server for browser) [browser]<--socks4a-protocol-->[ss-local]<--ss-protocol-->[ss-server]<--tcp-->[remote-host]
  • otherwise establish tunnel [browser]<-->[ssclient]<-->[ssserver]<-->[127.0.0.1:remoteHttpProxyPort] (SS-CLIENT acts as ssh -L so browser interacts with HTTP proxy via encrypted SS tunnel) so full chain is [browser]<--http-proxy-protocol-->[ss-local]<--ss-protocol-->[ss-server]<--http-proxy-protocol-tunneled-from-browser-->[127.0.0.1:remoteHttpProxyPort]<--http-protocol-->[remote-host]

Yet again - those 3 modes can be autoselected by SS-CLIENT based onto first n bytes from browser. This (automatic protocol negotiation) require changes in SS-CLIENT

This proposal doesn't require SERVER software changes, just install any preferred HTTP proxy onto same host and make it listen onto 127.0.0.1:remoteHttpProxyPort address

Threat Model

I propose we document the Threat Model of the Shadowsocks project. The Threat Model should explain the scenarios to design for, and the assumptions about users, operators, and adversaries. It should help us better understand the goal of the project, and resolve conflicts and disputes in discussions.

At minimal, the Thread Model must answer the following questions (order does not matter):

  • Who are the users?
  • Why and how do they use our software?
  • Who are the adversaries?
  • Why and how do they attack the users?
  • How do we differ from other similar projects (e.g. OpenVPN and Tor)?

This is a very rough proposal. Please comment for feedback.

SIP003 - A simplified plugin design for shadowsocks

As discussed in #26, it's dirty to hack original shadowsocks protocol for additional transport features.

A proposal from @falseen , @Artoria2e5, and @anonymous-contributor is that we may support Pluggable Transport from Tor. However, I found PT seems too heavy for shadowsocks. As we never try to or plan to support distributed architecture, I propose a simplified design instead.

SIP003: A simplified plugin design for shadowsocks

  1. Architecture Overview

Dislike the socks5 proxy design in PT, every SIP003 plugin works like a tunnel (or called local port forwarding). This design aims to avoid per-connection arguments in PT, leading to much easier implementation.

     +------------+                    +---------------------------+
     |  SS Client +-- Local Loopback --+  Plugin Client (Tunnel)   +--+
     +------------+                    +---------------------------+  |
                                                                      |
                 Public Internet (Obfuscated/Transformed traffic) ==> |
                                                                      |
     +------------+                    +---------------------------+  |
     |  SS Server +-- Local Loopback --+  Plugin Server (Tunnel)   +--+
     +------------+                    +---------------------------+
  1. Life cycle of a plugin

Very similar to PT, the plugin client/server is started as child process of shadowsocks client/server.

If any error happens, the child process of plugin should exit with a error code. Then, the parent process of shadowsocks stops as well (SIGCHLD).

When a shadowsocks client/server is stopped by user, the child process of plugin will also be terminated.

  1. Passing arguments to a plugin

A plugin accepts arguments through environment variables.

a. Four MUST-HAVE environment variables are SS_REMOTE_HOST, SS_REMOTE_PORT, SS_LOCAL_HOST and SS_LOCAL_PORT. SS_REMOTE_HOST and SS_REMOTE_PORT are the hostname and port of the remote plugin service. SS_LOCAL_HOST and SS_LOCAL_PORT are the hostname and port of the local shadowsocks or plugin service.

b. One OPTIONAL environment variable is 'SS_PLUGIN_OPTIONS'. If a plugin requires additional arguments, like path to a config file, these arguments can be passed as extra options in a formatted string. An example is 'obfs=http;obfs-host=www.baidu.com', where semicolons, equal signs and backslashes MUST be escaped with a backslash.

  1. Compatibility with PT

For all the plugins from Tor projects, there are two possible ways to support them. 1) We can fork these plugins and modify them to support SIP003, e.g. obfs4-tunnel. 2) Implement a adapter of PT as SIP003 plugin.

  1. Licenses of plugins

As all plugin services should run in a separate process, they can pick any license they like. There is no GPL restrictions for any plugin providers.

  1. Restrictions

a. Plugin over plugin is NOT supported. Only one plugin can be enabled when a shadowsocks service is started. If you really need this feature, implement a plugin-over-plugin transport as a SIP003 plugin.
b. Only TCP traffic is forwarded. For now, there is no plan to support UDP traffic forwarding.

  1. Example projects
  1. Command line example

On the server:

ss-server --plugin obfs-server --plugin-opts "obfs=http"

On the client:

ss-local -c config.json --plugin obfs-local --plugin-opts "obfs=http;obfs-host=www.baidu.com"

Request to add Perl Shadowsocks

Hello!

I have contributed a Perl shadowsocks module ( client and server scripts included ) to CPAN at
https://metacpan.org/release/Net-Shadowsocks

as of version 0.8.0, The following are part of the ciphers being supported:
AES-128-CFB AES-128-CTR AES-192-CFB AES-192-CTR AES-256-CFB AES-256-CTR
Camellia-128-CFB Camellia-192-CFB Camellia-256-CFB
Chacha20-IETF
RC4-MD5

Please visit https://metacpan.org/release/Net-Shadowsocks to see a full list of supported ciphers. Supporting AEAD cipher is planned.

Is it O.K. for you guys to add this Perl implementation ( both client and server ) on your website?

SIP007 - Per-session subkey

Background

As discussed in #36 and #40, currently Shadowsocks has a fundamental design flaw of potential key-nonce pair reuse. Specifically, we are using a long-term M-bit pre-shared key and N-bit random nonces, resulting in a (M+N)-bit key-nonce pair containing only N-bit randomness, where N is usually insufficient (N < 128).

#36 proposed to deprecate ciphers where N <= 96, which unfortunately eliminated many good ciphers like Chacha20 and Chacha20-Poly1305 where N=64. However the problem still exists, albeit at slightly lower probability. Even when N=96, there are practical concerns about the safety margin. Needless to say, we are operating against best practices and security recommendations.

#40 identified the design flaw and paved the way to this SIP.

Proposal

I propose to introduce a per-session subkey derived from the pre-shared master key using HKDF, and use the subkey to encrypt/decrypt in both stream ciphers and AEAD ciphers. Essentially it means we are moving from (M+N)-bit (PSK, nonce) pair to (M+N)-bit (HKDF(PSK, salt), nonce) pair. Because HKDF is a PRF, the new construction significantly expands the amount of randomness (from N to at least M where M is much greater than N), thus correcting the previously mentioned design flaw.

Additionally, because the pre-shared key is usually generated from a human-chosen text password of insufficient entropy, the result is not very strong. HKDF gives us the benefit of producing cryptographically strong derived keys even if the input master key is weak.

Details

Assuming we already have a user-supplied pre-shared master key PSK.

Function HKDF_SHA1 is a HKDF constructed using SHA1 hash. Its signature is

HKDF_SHA1(secret_key, salt, info)

The "info" string argument allows us to bind the derived subkey to a specific application context.

For stream ciphers, the revised encryption scheme is:

  1. Pick a random R-bit salt (R = max(128, len(SK)))
  2. Derive subkey SK = HKDF_SHA1(PSK, salt, "ss-subkey")
  3. Derive initialization vector IV = HKDF_SHA1(PSK, salt, "ss-iv")
  4. Send salt
  5. Send StreamEncrypt(SK, IV, payload)

Note that even with the above changes, the old approach using stream ciphers is still not secure. We encourage users to switch to AEAD ciphers as soon as possible.

For compatibility reasons, we will probably NOT adding per-session key to stream ciphers.

For AEAD ciphers, the revised encryption scheme is:

  1. Pick a random R-bit salt (R = max(128, len(SK)))
  2. Derive subkey SK = HKDF_SHA1(PSK, salt, "ss-subkey")
  3. Send salt
  4. For each chunk, encrypt and authenticate payload using SK with a counting nonce (starting from 0 and increment by 1 after each use)
  5. Send encrypted chunk

Proposal for adding aes-ctr method in spec.

AES in CFB mode is not supported by WebCrypto in major browsers, so to implement a Chrome OS version of Shadowsocks, developers have to do encryption in JavaScript, which is slow even with asm.js(about 40MiB/s+ vs 300MiB/s+ with modern x86 processor, could be 1GiB+ with AES-NI intrinsics).
AES in CTR mode is supported by most WebCrypto implementations, and it is trivial to implement in most server side implementations of shadowsocks.
Some implementations(e.g shadowsocks-chromeapp) already have CTR mode support. I think it is best to add CTR mode to spec.

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.