Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于一些基本问题的讨论 #64

Closed
riobard opened this issue Apr 9, 2017 · 124 comments
Closed

关于一些基本问题的讨论 #64

riobard opened this issue Apr 9, 2017 · 124 comments

Comments

@riobard
Copy link
Contributor

riobard commented Apr 9, 2017

这串讨论源起于 @hellowingy 在 Twitter 引用 @zhuhaow 的文章《某些网络工具的安全性》。考虑到最近 Shadowsocks 的一些改动引起了不少的争议,有一些基本问题需要理清楚,才好让大家(至少是相关项目的开发者)对这些问题有一个正确的认识。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

先提一个最基本的问题:Shadowsocks (后文简称 ss)有没有(以及要不要)提供密码学意义的安全?

密码学意义的安全具体指保密性 (confidentiality)、完整性 (integrity)、真实性 (authenticity)。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

首先我不觉得integrity和authenticity有什么实质上的区别。
其次它们的必要性在ss中是值得怀疑的。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

《某些网络工具的安全性》中,@zhuhaow 认为

(ss 的) Confidentiality 从来都没有出过问题, Integrity 可以说在设计之初就并没有列入考量(这并没有问题,我懒得展开了,但是篡改数据没有任何意义), Authentication 其实是通过 TYPE 来实现的,也是出问题的地方所在

这里我认为是不对的。事实上 ss 在设计之初并没有考虑密码学意义的安全,因此使用 table 方式做了简单的替换,目的仅仅是为了绕过内容过滤审查。后来换用流加密(stream cipher)也没有考虑保密性的问题,因而保密性是有缺陷的,这个问题在 #36 里有讨论。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

我不觉得integrity和authenticity有什么实质上的区别。

这确实是个比较 tricky 的问题。可以参考 PGP 的解释 http://www.ac.uk.pgp.net/pgpnet/secemail/q4/node4.html

其次它们的必要性在ss中是值得怀疑的。

这个就是要不要的问题。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

有点事所以回的比较慢。

Confidentiality 这个问题其实是一个大家过于关注的问题了。事实上,也并没有什么实质的理论指出64 bits的nouce真正的不安全。

通常在加密这个领域大家说到可能weak,甚至是weak的时候,往往指的是,如果CIA/FBI/Mossad/whatever 在想的情况下,在可预见的未来,似乎有可能运用几年/月的运算时间破解出数据的内容。对于普通人而言,其实就是没有任何安全问题可言。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

当然table不安全,很难说这是加密了,但是自RC4-MD5之后的方法,没有任何理由说它们在实际的使用中会不安全,当然我坚决支持在性能可接受的情况下使用最新的加密方法。事实上,我不想为兼容性妥协任何安全性。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

说回integrity的问题,无所谓定义如何,我来定义我们想讨论的就是,是否有必要能够验证数据是由一个知道pre-shared key的用户发来的,且未经篡改。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

在谈integrity的必要性之前,我先说攻击者是否有兴趣篡改,或者伪造数据。
在我文章里提出的解决方案下,CCA是不可行的(至少我设计不出方案来)。那么攻击者伪造数据没有任何意义,他只可能想要篡改数据。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

那么对于攻击者而言,首先他要决定的是如此大量的数据面前,他要篡改什么数据。
显然不能随机选,那就必然已知这是ss的流量了。
在这种情况下,如果攻击者不希望用户正常使用,显然封服务器是最简单好用的策略,看不出任何篡改的意义。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

接下来我们再看,ss协议本身,是否有integrity的需求。
ss是做什么的呢,是用来传输数据流的,那只是一个代理的协议。我们可以看到,http代理也好,socks4/4a/5代理也好,均没有任何关于integrity的验证,尤其是socks4/4a/5这个数据流代理也没有。这是为什么呢?因为数据流的integrity是应当由application在需要的时候完成检查的。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

事实上,也并没有什么实质的理论指出64 bits的nouce真正的不安全。

这个陈述过于模糊了。64-bit nonce 安不安全取决于 nonce 是如何生成的,以及相关的 key 是如何使用的。初版 ss 使用 PSK 配合随机 64-bit nonce 的方式确实是(密码学意义)不安全的。这个有客观的方式可以度量。这个在 #40 里面有讨论。

通常在加密这个领域大家说到可能weak,甚至是weak的时候,往往指的是,如果CIA/FBI/Mossad/whatever 在想的情况下,在可预见的未来,似乎有可能在几年/月内破解出数据的内容。对于普通人而言,其实就是没有任何安全问题可言。

我认同这个大前提。但是因为这里讨论的是密码学意义的安全,我觉得还是有必要遵循主流的定义。至于说「不安全也影响不到某个个体,所以对这个个体是安全的」这种说法比较容易搅乱定义,不利于展开讨论,我倾向于反对这种说法。我们可以说「的确不安全,但影响不大」。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

为什么这么说呢?integrity的目的是什么,是为了确保中间通路的各个节点不能够修改数据。
如果application有这项需求,那么它自己就应当实现这一点,因为application是不可能会设想传输是通过一个安全代理完成的。如果它没有,它自然就不在意这个问题。
最常见的确保integrity的方法就是SSL/TLS,很显然,在意integrity的(理论上应该是所有网站,现实么),应当自行使用SSL/TLS来完成数据传输,在这时,ss并不会提供任何而外的价值。
对普通数据,设想即便ss提供了integrity的保障,数据依然要明文由ss服务器通过若干中间节点的传输,中间依然可以发生篡改,既然application不在意,ss提供的保障其实也没有起到意义。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

这个陈述过于模糊了。64-bit nonce 安不安全取决于 nonce 是如何生成的,以及相关的 key 是如何使用的。初版 ss 使用 PSK 配合随机 64-bit nonce 的方式确实是(密码学意义)不安全的。这个有客观的方式可以度量。这个在 #40 里面有讨论。

设想我有一任意快的计算机,那么所有加密技术都是没有区别的。加密的目的就是在于使得破解所需要的资源在当前和可预见的未来是不足够的。而当前的很多deprecated的加密算法其实也还是满足这一点的。

不过我依然建议使用更强的加密算法。只不过这个问题对普通用户完全不构成问题而已。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

其实,ss这些代理协议,完全可以看作是TCP流的代理版,从来没有听说有人想要检查TCP包的integrity(checksum都被取消了),因为本身这就不是TCP需要关注的问题。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

@zhuhaow 我先把加密的问题理一下哈,等下再说 integrity 的问题。

当然我坚决支持在性能可接受的情况下使用最新的加密方法

其实目前的两种 AEAD 的性能挺好的。在搭载 AES 硬件加速的机器上 AEAD_AES_128_GCM 的性能显著高于 AES-128-CTR/CFB。没有 AES 硬件加速的机器上 AEAD_CHACHA20_POLY1305 如果利用了较新的 CPU 指令集也能做到非常高的效率。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

ss 的 integrity 的意义就和我用UDP实现一个 reliable, ordered, and error-checked protocol一样无谓,这个gfw完全没有关系。
我已经说过了,篡改不会发生,因为没有意义,一件不会发生的事情为什么要未雨绸缪。

你看,我就从来没有设想过有钱了以后如何生活……

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

而且如果要“防止服务器行为检测“,那ssr真的做的好的不知哪里去了(虽然我觉得没有意义),就算有AEAD也没有起到任何obfuscation的作用啊。

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

以上两条评论是针对一些被删除了的回复的……

@bigboyq
Copy link

bigboyq commented Apr 9, 2017

我觉得ss的目的就是翻墙,这个是第一要务
如何更好的翻墙?
1.ss协议去特征化
2.ss内容在特征明显的时候可以降低访问对象的特征
其他的所谓
1.加密性问题,应该交由app层的协议去保障,例如tls
2.完整性问题,其实aead已经解决

我觉得现在的关键是如何在3.0的基础上降低特征即可

  1. 8位随机IV 加数据流的格式
    2.检验失败不返回断开

个人建议,在验证失败时返回随机结果,由客户端进行结果检验后判断后续处理就可以了

至于由此引发的慢速攻击,cc攻击等,交由防火墙,策略等按常规处理

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

说回integrity的问题,无所谓定义如何,我来定义我们想讨论的就是,是否有必要能够验证数据是由一个知道pre-shared key的用户发来的,且未经篡改。

这里稍微有点问题,已经是 integrity + authenticity 两个要求了。Integrity 指的是作为密文的接受方能确保密文未被不知道 PSK 的第三方篡改过。而密文的接收方能确保密文是由知道 PSK 的人发过来的则是属于 Authenticity 的范畴。Authenticity 暂时不是重点,待会再说。

Integrity 的问题最初是由 @breakwa11 提出可以通过篡改密文中 type 对应的那个字节然后观察服务器的反应,根据反应结果有极高的可信度判定是否为 ss 协议,并且提供了可用的测试工具。这个便是因为 Integrity 的缺失导致的行为侧漏 😂,因为服务器端在 3/255 的概率上不知道密文被篡改了。

很多人认为这个问题根本不需要解决,攻击者有那个空闲来探测不如直接封掉 IP 算了。在目前的情况下的确是可以这样认为……不过毕竟泄露行为不是什么好事吧,于是有了 OTA 这个补丁出现。然后就是如 @wongsyrone 所言这属于自己造的轮子不圆,不如用现成的、理论基础更完备的 AEAD,所以有了 SIP004 (#30)。

@bigboyq
Copy link

bigboyq commented Apr 9, 2017

至于obfs
我觉得 ss over tls就可以了,甚至iv都可以基于tls本身特定串hash生成
不要试图在一个翻墙工具里面解决所有问题

@zhuhaow
Copy link

zhuhaow commented Apr 9, 2017

这里稍微有点问题,已经是 integrity + authenticity 两个要求了。Integrity 指的是作为密文的接受方能确保密文未被不知道 PSK 的第三方篡改过。而密文的接收方能确保密文是由知道 PSK 的人发过来的则是属于 Authenticity 的范畴。Authenticity 暂时不是重点,待会再说。

你仔细想想这两件事是一件事,就是数据是由有key的人生成加密并发过来的。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

@zhuhaow 不是呀,篡改数据不需要有 key。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

我说一下我对「ss 有没有提供密码学意义的安全?」的理解吧:

  1. 初版 ss 没有提供保密性、完整性、真实性,因为安全根本不是设计目标。
  2. ss 采用 SIP007 (SIP007 - Per-session subkey #42) 后提供了保密性和完整性。真实性则取决于是否给多个用户共享同一个密码。至少在设计理念上 ss 是不鼓励多个用户共享密码的。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

从来没有听说有人想要检查TCP包的integrity(checksum都被取消了),因为本身这就不是TCP需要关注的问题

其实是有必要的……比如 TCP RST 攻击就是因为 integrity 缺失导致的 😢 SIP005 (#32) 试图解决这个问题,但在应用层面并不可行只好作罢。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

总体来说, AEAD 给 ss 带来的好处是大大提高了安全性,并且采用成熟的第三方库实现,避免了自己造轮子可能带来的潜在问题,同时又提供了极佳的性能和兼容性(只需要支持已经成为行业标准的 AEAD_CHACHA20_POLY1305)。我们应该鼓励客户端和服务端的开发者尽可能支持 AEAD 的加密方式。

至于其他的如混淆、伪装等问题,则应该通过 SIP003 (#28) 的插件机制实现,在保留核心功能不变的情况下提供更加灵活多变的组合以应对用户所处的不同的网络环境。

@hellowingy
Copy link

”我不管,反正它很好“ 哈哈哈...

@yjqiang
Copy link

yjqiang commented Apr 9, 2017

个人以为加密方式只是作为一种混淆方法存在,保密性自然的有上层的tls保障。甚至像 @breakwa11做的那样,认为混淆性已经足够好,加密还使用none。(https://breakwa11.blogspot.sg/2017/04/proxy-protocol-analyze.html ”一个小插曲,有个网友做了个实验,使用auth_aes128_md5协议,不带混淆,不带加密,直接祼跑超过了80G流量,还是啥事都没发生。“)

从这个方面来讲,我认为加密甚至可以不存在,混淆的意义远远大于保密。

@riobard
Copy link
Contributor Author

riobard commented Apr 9, 2017

@yjqiang 然而并非所有网站都是 TLS 连接。对于很多人而言,安不安全并不要紧。如果其他条件保持不变的话,安全总比不安全要好吧?在更好的基础上去解决混淆和伪装的问题,总强过在不牢靠的基础上修修补补。两者并不矛盾。

@yjqiang
Copy link

yjqiang commented Apr 9, 2017

同意,两者不矛盾,而且也同意本项目的混淆设计思路,去把混淆与安全区别开。
但是最近的obfs-simple更新中并没有多少混淆方面的加入,利用已经造好的tor的混淆思路是好的,但似乎还远远没完成,而且在各平台的客户端也都明显基本都没有跟上。
个人的意见只是从最近项目发展来看,似乎过于强调了安全。希望今后可以把大部分精力投入到混淆的方面。

@ccsexyz
Copy link

ccsexyz commented May 9, 2017

@ptpt52 这样吧,假定中间人在某个端口连接建立成功之后1s内立刻探测这个端口,该怎么办呢

@ptpt52
Copy link

ptpt52 commented May 9, 2017

@ccsexyz
用敲门技术吧,这样就不存在任何时刻 开放端口了

@ccsexyz
Copy link

ccsexyz commented May 9, 2017

@ptpt52 问题是,你能连接凭什么中间人不能连接?

@ptpt52
Copy link

ptpt52 commented May 9, 2017

@ccsexyz
我有密钥,根据密钥发送序列密码包后,连接才能建立成功
中间人 建立连接,发syn包,发到天黑都没人应答它

@ptpt52
Copy link

ptpt52 commented May 9, 2017

怎样构造密码包呢?
举个例子,发送syn包,带上tcp option timestamp
timestamp 就是敲门密码

当然,如何更安全,如何加密避免被伪造,还是需要深入研究一下,这只是一个简单的例子。

@ccsexyz
Copy link

ccsexyz commented May 9, 2017

@ptpt52 我的意思是,在你已经发送了一个特定序列把门敲开的情况下,如何辨别哪一个才是合法的连接请求呢?timestamp是每个新建的连接都带还是只是敲门包带?如果是敲门包带,那玩出花也没用的。

@ptpt52
Copy link

ptpt52 commented May 9, 2017

@ccsexyz
敲门包syn当然是每个新建连接都带有呀。当然只有当前连接能够连入成功呀。

@ccsexyz
Copy link

ccsexyz commented May 9, 2017

@ptpt52 中间人完全可以直接重放你的syn

@ptpt52
Copy link

ptpt52 commented May 9, 2017

哈,这就是要继续深入研究的避免它重放了
@ccsexyz

这个时候 TOTP 之类的技术派上用场了

当然安全不是绝对的,大幅增加它扫描检测的难度,就足够了。

@ccsexyz
Copy link

ccsexyz commented May 9, 2017

@ptpt52 基于时间序列是完全不靠谱的。
这个方案我个人认为唯一的作用就是坑开发人员了,并不能带来任何收益,只是把验证信息从一个地方移动到另一个地方。把ts放在tcp option里面和直接放在在应用层又有什么区别呢?

@ptpt52
Copy link

ptpt52 commented May 9, 2017

@ccsexyz
你可能不理解区别
这种方案,常用的扫描识别工具,根本无法扫描和识别了,你可以扫描一下我的服务器 81.171.7.119 感受一下。
这将大幅度增加被扫描的难度。

但是如果端口和传统服务器一样,常态开放的,扫描和识别就很容易了。

@ccsexyz
Copy link

ccsexyz commented May 9, 2017

@ptpt52 这防的是瞎比扫描者,或者说脚本小子们,而不是中间人.

@ptpt52
Copy link

ptpt52 commented May 9, 2017

@ccsexyz
我好像一开始就是说的这个目的呀。

中间人攻击才不需要关心你端口是否开放呢,直接在已经建立的TCP流 注入

@ccsexyz
Copy link

ccsexyz commented May 9, 2017

@ptpt52 额,这个issue讨论的是防止墙的探测吧。

@ptpt52
Copy link

ptpt52 commented May 9, 2017

主动扫描探测 也是探测的一种^_^

@ptpt52
Copy link

ptpt52 commented May 9, 2017

其实墙早就识别出ss流量了,人家只是不屏蔽你而已

某某说得很对,如果现在能用,没必要假象敌人出什么招数;

等到对方出招了,咱再接招。

@henrypijames
Copy link

从理念和原则上完全不能接受“我知道对方能出招,但是只要他没出我就当他不出;如果他真出了,我先挨几百上千招再去想怎么应对”。

@henrypijames
Copy link

henrypijames commented May 9, 2017

关于“理论不安全”不等于“实际不安全”的说法:这一说法根本就不适用于(泛)安全领域的应用。(什么叫泛安全领域?你整天和别人争一个东西会怎样被“探测”“封堵”“伪造”,还好意思说这个东西不属于泛安全领域?“影梭本来就不是安全应用”纯属文字游戏。)在(泛)安全领域中,理论不安全就是可能不安全,可能不安全就是实际不安全。再换一种表述方式:“很可能安全”就是不安全,只有“没有理由相信不安全”才算安全。

在王小云那个传奇的演示之前,绝大多数人都认为MD5是“理论不安全但实际暂时安全”,结果一夜之间天翻地覆,MD5从此成为防君子(无意混淆)不防小人(有意伪造)的算法。此前的“伪苟延残喘安全感”,在遭到如此无情的踩踏之后,居然至今仍有市场?所谓“理论不安全”,翻译成白话就是“随时可能出现一个王小云把它干掉”。(顺便说一下,王小云近年来消声觅迹,是江郎才尽,还是脱离江湖成为大内供奉了?阴谋论者请自行想象。)至于有人(见上)认为“随时有可能被干掉,但目前视野范围内尚未被干掉”的东西仍然可以称之为安全,对此我只能问:你买了一辆车,开了一段时间没事,某天突然在新闻里看到该款车被检测出安全隐患,厂家召回了,那么你是把车退回去修,还是说“安全隐患只有万分之一的概率,这车我先接着开,等真出了车祸再说”?

至于说“墙没必要这样大动干戈对付影梭用户”,就更是掩耳盗铃了。我们完全有理由相信,影梭用户中有一部分已经是或可能成为“国家敌人”级别的人(至少原作者本人众所周知已经是了)。在某些特定场景下,完全可以想象墙有针对性地动用国家级别的资源来对付这样的用户。TOR一开始就定位于保护“国家敌人”级别的用户(更不用说PGP不但做出如此定位,而且作者为了保护未知的潜在的不特定的“国家敌人”用户,不惜自己成为国家敌人),那么作为应用场景十分类似(类似到很多普通用户无法区别的地步)的影梭,没有理由不作相同的安全定位。

@ptpt52
Copy link

ptpt52 commented May 9, 2017

呃,我想表达的应该是,无论对方如何出招,我都能见招拆招

某某说得很对,如果现在能用,没必要假象敌人出什么招数;

何况,我的要求没那么高,能够访问被墙的目标网站就足够了,就达到目的了。

安全性,应该是应用层自己保证的,比如 起码一定程度上讲,用https访问谷歌(无论是否经过代理),安全系数相对很高,相反你用普通http经过SS代理访问百度,不见得安全。

ss不应该考虑这些安全性,只需要做到TCP一样,做简单“搬运工”就足够了。
ss的定位,最初的想法,就是类似TCP级别的搬运工角色

要不然我也可以讲,你用TCP协议传输数据本身就不安全,TCP可以轻易被中间人攻击(注入和篡改)

何况,我上面讨论的是 一种可能的 用来防止服务器被主动扫描和识别的 手段。这些手段都是初步的想法,不保证就100%安全可靠,有兴趣可以提出新的想法改进。

@henrypijames
Copy link

henrypijames commented May 9, 2017

@ptpt52 你真能见招拆招吗?你的程序有人工智能,会自动进化出应对措施是吗?你所谓的见招拆招不就是我说的“先挨几百上千招再去想怎么应对”。

@ptpt52
Copy link

ptpt52 commented May 9, 2017

是的

@chu8129
Copy link

chu8129 commented Jul 25, 2017

@ptpt52 赞同;
个人观点:各司其职,各尽其责;ss只需要做到不被识别就好;
就跟在ss后加上kcp一样,每个工具做好自己的工作就好了;

@skywang00
Copy link

现在国外主流网站都普及https了,安全性就不用ss管了
ss做好伪装就好了

@leonshaw
Copy link

@henrypijames 我觉得没什么太好的办法。
安全对于ss来说,第一位的是可用性,然后才是保密、完整性等等。可用性不是密码学要解决的问题。
上面之所以一直在讨论加密,因为好的加密能够增加检测难度所以更加不容易被封。但是我比较怀疑这一点,因为防火墙清楚地知道你在传输加密流量。至于要不要进一步检测是不是ss,要不要封,封什么范围完全是它权衡false positive/negative成本的策略。
我们真正需要的是隐写术而不是加密,当然有的话更好。理想的情况是能伪装或者嵌入合法流量,但是防火墙如何判断什么流量是“合法”的,我们只能试验和猜测。而且跟密码学不一样,很难证明某种方法是安全的,非常依赖方法的保密,又很容易暴露特征。防火墙也一直在更新,今天的方法可能明天就不能用了。
所以我持悲观的态度,个人觉得苟且偷生、见招拆招,跟墙共同进步可能是最好的办法了。

@zcyzcy88
Copy link

zcyzcy88 commented Oct 14, 2017

  1. 「密码学意义的安全」并没有多大用处,因为密码学基于柯克霍夫原则:敌人知道系统,但不知道密钥
    而SS的目标与密码学无关:不让敌人知道系统(不让GFW知道SS的存在)

  2. 加密本身就是一种混淆:由良好的加密算法产生的密文,密文应该看上去像随机数
    就算不需要「密码学意义的安全」,为了使流量看上去像随机数,加密是最方便的手段

  3. 综上所述,我支持SS提供简单的加密,但不要专注于加密
    如果需要专注于加密的代理,就不该使用SS,使用OpenVPN

@arthurkiller
Copy link

arthurkiller commented Oct 14, 2017 via email

@zcyzcy88
Copy link

目的不同,但看上去相同

@arthurkiller
Copy link

arthurkiller commented Oct 14, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests