The official website of Project Shadowsocks.
yarn install
yarn docs:build
www.shadowsocks.org
License: MIT License
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.
If the password which is user provided or randomly generated by Shadowsocks is disclosed in future, does it can be used to decrypt the already transferred messages which are recorded by a third party?
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:
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.
http://shadowsocks.org/en/download/clients.html 里:
与 shadowsocks-go 相关的链接都挂了.
从shadowsocks-go 项目发现都升级到 1.1.3 版本了.
Use AEADs to replace stream cipher + OTA. Previous discussion: #29.
Proposed AEAD algorithms:
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 |
+--------------+------------+-----------+----------+
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?
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?
网站上编译好的版本一直不更新..只能自己编译了吗QwQ
如果方便的话..希望可以更新一下呢
谢谢
Thanks
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.
Please see #54 (comment) for the latest proposal. The following section is the original proposal without forward secrecy protection.
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)
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)
The client computes the shared secret with the server using x25519 ECDH function:
shared_secret = x25519(sk', pk)
The client derives the per-session subkey using HKDF_SHA256:
subkey = HKDF_SHA256(shared_secret || pk' || pk)
The client encrypts payload using the subkey and sends the encrypted data to server.
The server receives the client's public key pk'
and computes the shared secret using x25519 ECDH function:
shared_secret = x25519(sk, pk')
The server derives the per-session subkey using HKDF_SHA256:
subkey = HKDF_SHA256(shared_secret || pk' || pk)
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.
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.
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.
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:
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:
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.
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.
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.
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.
为了让更多人看懂,这篇文章使用中文撰写。
原文地址:https://gist.github.com/yvbbrjdr/ea80fc5ef21f1a518346c92bda611993
由Glype想到的
2013年7月8日,clowwindy写道:
为什么不应该用 SSL 翻墙
SSL 设计目标:
1. 防内容篡改
2. 防冒充服务器身份
3. 加密通信内容
而翻墙的目标:
1. 不被检测出客户端在访问什么网站
2. 不被检测出服务器在提供翻墙服务
SSL 和这个目标还是有一些出入。其中最大的问题是,2. 防冒充服务器身份 这个功能多余了。他会导致墙嗅探出证书信息,继而墙会知道服务器身份。如果墙知道一个服务器身份是用来翻墙的,它要做的仅仅是封掉使用这个证书的所有 IP。
墙看见的 SSL 握手响应头部如下:
(以下省略一个明显带有特征的Twitter HTTPS头)
这一段内容对翻墙的目标总结得非常到位:不被检测出客户端在访问什么网站以及不被检测出服务器在提供翻墙服务。具体来说:
是指即使翻墙包被截获并分析,也无法探知其中的内容。实现这一点非常容易,用加密算法就能实现。总之要让墙无法通过低成本的方法破解出内容即可。
这个比较复杂。半年来shadowsocks以及shadowsocksR的更新都是在做这件事情。它包含两个方面:
现有的各种翻墙包结构基本无法实现上面的第2点,因为如果要自定义一个翻墙协议,一定会暴露出某些特征。我认为解决的方法是:不使用自定义的协议,而将翻墙协议建立在已有的、流行的、安全的协议之上,于是我想出一种利用SSL进行翻墙的方法,只是对原来的HTTPS进行一些不大的修改。
在阐述协议之前,我先利用clowwindy对于两个目标的描述说明为什么SSL适合翻墙:
SSL 设计目标:
且因为每一次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证书。那么随便弄一个自签名证书,或者申请一个免费的就行了,再让客户端信任一下。
As discussed in shadowsocks/shadowsocks-android#989 (comment), we may use # for tag/remark in the SS URL schema. For example:
(?i)^ss://((?<method>.+?)(?<auth>-auth)??:(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))(#(?<tag>.+?))*$
(?i)^ss://(?<base64_encoded_group_1>.+)$
For more details: https://www.debuggex.com/r/y70l3GyYFSoim4Uc
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):
This is a very rough proposal. Please comment for feedback.
这串讨论源起于 @hellowingy 在 Twitter 引用 @zhuhaow 的文章《某些网络工具的安全性》。考虑到最近 Shadowsocks 的一些改动引起了不少的争议,有一些基本问题需要理清楚,才好让大家(至少是相关项目的开发者)对这些问题有一个正确的认识。
When running apt-get update
I get this error:
E: GPG error: http://shadowsocks.org wheezy Release: The following signatures were invalid: NODATA 1 NODATA 2
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.
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:
[browser]<--socks5-protocol-->[ss-local]<--ss-protocol-->[ss-server]<--tcp-->[remote-host]
[browser]<--socks4a-protocol-->[ss-local]<--ss-protocol-->[ss-server]<--tcp-->[remote-host]
[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
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.
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.
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:
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]
...
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:
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:
What shouldn't:
Problems:
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.
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
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) +--+
+------------+ +---------------------------+
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.
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.
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.
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.
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.
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"
Historically we have had three variants of chacha20-poly1305 AEAD ciphers:
chacha20-poly1305
with 64-bit nonce.chacha20-ietf-poly1305
with 96-bit nonce.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
编译openwrt 12.09 release,包含 libpolarssl (称为固件A)
编译openwrt trunk@ 20130114, 包含libpolarssl (称为固件B)
make menuconfig 中两固件所选组件相同。
shadowsocks.org下载最新 ar71xx libpolarssl 版本,安装无问题。
在固件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 正常。
I've tried to install Potatso today but it was not free and MobileShadowSocks require jailbreak. So I ended up installing and testing LiFi. It's very simple shadowsocks VPN enabler for iOS. Works quite OK. https://itunes.apple.com/us/app/lifi-shadowsocks-and-shadowsocksr-vpn-client/id1153372559?mt=8
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.
For example in https://shadowsocks.org/en/config/quick-guide.html
ss://method:password@hostname:port
is base64 encoded to
ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4Cg
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.
只看到了 SIP001, SIP003 和 SIP004.
I'm thinking about moving and organizing development-related documents (like protocol details, cipher nuances, etc). This makes it easier to track up-to-date changes.
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.
bf-cfb
, chacha20
, and salsa20
.as a standard in the new version protocol
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
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.
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:
猫猫通过mitmproxy见过一点微信是通过HTTP协议但又给自己信息内容加了个加密壳喵
所以猫猫想是否可以模拟微信交流方式作为SS的交流方式喵?
是我看漏了,还是觉得这没有必要?为什么没有这个的讨论?
(以上指的是产生随机长度的随机数据附加于原数据包)
我看AEAD确定下来了都没有这块的内容
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.
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.
The implementation should be even easier than Tor PT proxy mode, but I still have several concern on it.
Insecure hash algorithm
There is known attack against MD5, it's no longer considered as a safe hash algorithm.
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.
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.
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?
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
.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):
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.
On the spec/aead
and spec/plugin
pages, add a section at the bottom to list those software that support the respective protocol.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.