Skip to content

Commit

Permalink
正式添加 TLS1.3 支持
Browse files Browse the repository at this point in the history
  • Loading branch information
SeaHOH committed Jan 5, 2021
1 parent a1e98d5 commit dfbded2
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 32 deletions.
1 change: 1 addition & 0 deletions config/ActionFilter.ini
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ facebook.net$ = @none
.tgchannels.org = @none
tumblr.com$ = @none
travis-ci.org$ = @none
wikipedia.org = @none
.wikipedia.org = @none
cn.nytimes.com = [email protected]
.nytimes.com = *.cloudfront.net
Expand Down
8 changes: 5 additions & 3 deletions config/Config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ maxperip = 6
recvbuffer = 131072
#对谷歌域名进行 CA 公钥验证
verifygpk = 1
#本地加密 SSLv2、SSLv3、TLS、TLSv1、TLSv1.1、TLSv1.2,默认 TLS
#本地加密 SSLv2、SSLv3、TLS、TLSv1、TLSv1.1、TLSv1.2、TLSv1.3,默认 TLS
#兼容模式 TLS 禁用 SSLv3 及以下版本
#当设置不支持的 TLSv1.3 时自动回落 TLSv1.2
localssl =
#远程加密 TLS、TLSv1、TLSv1.1、TLSv1.2,默认 TLSv1.2
#兼容模式 TLS 禁用 TLSv1 及以下版本
#远程加密 TLS、TLSv1、TLSv1.1、TLSv1.2、TLSv1.3,默认 TLS
#兼容模式 TLS 禁用 TLSv1.1 及以下版本
#当设置不支持的 TLSv1.3 时自动回落 TLSv1.2
remotessl =
#强制请求压缩内容,解压缩后无法提供原始内容大小信息,可能会不兼容某些应用
#未安装 brotlipy 时会自动关闭
Expand Down
19 changes: 12 additions & 7 deletions local/GlobalConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
}

_SSLv = {
'SSLv2' : 1,
'SSLv3' : 2,
'SSLv23' : 3,
'TLS' : 3,
'TLSv1' : 4,
'TLSv1.3' : 7,
'TLSv1.2' : 6,
'TLSv1.1' : 5,
'TLSv1.2' : 6
'TLSv1' : 4,
'TLS' : 3,
'SSLv3' : 2,
'SSLv2' : 1
}

def _servers_2_addresses(servers, default_port):
Expand Down Expand Up @@ -115,9 +115,14 @@ class GC:
LINK_RECVBUFFER = max(min(CONFIG.getint('link', 'recvbuffer', fallback=1024 * 128), 1024 * 1024 *4), 1024 * 32)
LINK_VERIFYGPK = CONFIG.getboolean('link', 'verifygpk', fallback=True)
LINK_LOCALSSLTXT = CONFIG.get('link', 'localssl', fallback='TLS')
LINK_REMOTESSLTXT = CONFIG.get('link', 'remotessl', fallback='TLSv1.2')
LINK_REMOTESSLTXT = CONFIG.get('link', 'remotessl', fallback='TLS')
LINK_LOCALSSL = _SSLv[LINK_LOCALSSLTXT]
LINK_REMOTESSL = max(_SSLv[LINK_REMOTESSLTXT], _SSLv['TLS'])
for k, v in _SSLv.items():
if LINK_LOCALSSL == v:
LINK_REMOTESSLTXT = k
if LINK_REMOTESSL == v:
LINK_REMOTESSLTXT = k
LINK_REQUESTCOMPRESS = _brotli and CONFIG.getboolean('link', 'requestcompress', fallback=False)
LINK_TIMEOUT = max(CONFIG.getint('link', 'timeout', fallback=5), 3)
LINK_FWDTIMEOUT = max(CONFIG.getint('link', 'fwdtimeout', fallback=8), 3)
Expand Down
36 changes: 22 additions & 14 deletions local/HTTPUtil.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import OpenSSL
import logging
import threading
from select import select
from time import time, sleep
from queue import Queue
from threading import _start_new_thread as start_new_thread
Expand Down Expand Up @@ -202,19 +201,26 @@ def get_context(self, server_hostname):
except KeyError:
pass
if self.gws:
#强制 GWS 使用 TLSv1.2
context = SSL.Context(SSL.TLSv1_2_METHOD)
#强制 GWS 使用 TLSv1.3
ssl_method = SSL.TLSv1_3_METHOD
else:
context = SSL.Context(GC.LINK_REMOTESSL)
#兼容模式 TLS 禁用 TLSv1 及以下版本
if GC.LINK_REMOTESSL == SSL.SSLv23_METHOD:
context.set_options(SSL.OP_NO_SSLv2)
context.set_options(SSL.OP_NO_SSLv3)
context.set_options(SSL.OP_NO_TLSv1)
ssl_method = GC.LINK_REMOTESSL
ssl_options = 0
#使用兼容模式来指定 TLSv1.3
if ssl_method == SSL.TLSv1_3_METHOD:
ssl_method = SSL.SSLv23_METHOD
ssl_options |= SSL.OP_NO_TLSv1_2
#兼容模式 TLS 禁用 TLSv1 及以下版本
if ssl_method == SSL.SSLv23_METHOD:
ssl_options |= SSL.OP_NO_SSLv2
ssl_options |= SSL.OP_NO_SSLv3
ssl_options |= SSL.OP_NO_TLSv1
ssl_options |= SSL.OP_NO_TLSv1_1
context = SSL.Context(ssl_method)
#不使用压缩
context.set_options(SSL.OP_NO_COMPRESSION)
ssl_options |= SSL.OP_NO_COMPRESSION
#通用问题修复
context.set_options(SSL.OP_ALL)
ssl_options |= SSL.OP_ALL
#会话重用
context.set_session_cache_mode(SSL.SESS_CACHE_CLIENT)
context.lock = threading.Lock()
Expand All @@ -223,6 +229,8 @@ def get_context(self, server_hostname):
context.set_verify(SSL.VERIFY_PEER, self._verify_callback)
#加密选择
context.set_cipher_list(self.ssl_ciphers)
#应用设置
context.set_options(ssl_options)
self.context_cache[server_hostname] = context
return context

Expand Down Expand Up @@ -982,18 +990,18 @@ def request(self, request_params, payload=b'', headers={}, bufsize=8192, connect
# CBC
# AES128-SHA
# ECDHE-RSA-AES128-SHA
# http://docs.python.org/dev/library/ssl.html
# https://docs.python.org/dev/library/ssl.html
# https://www.openssl.org/docs/manmaster/man1/openssl-ciphers.html
# 以下 GWS ciphers 设置用于 TLS v1.2 连接
# 以下 GWS ciphers 设置用于 TLS v1.3 连接
gws_ciphers = (
'TLSv1.3:'
'ECDHE+AES256+AESGCM:'
'ECDHE+AESGCM:'
'ECDHE+HIGH:'
'RSA+AES256+AESGCM:'
'RSA+AESGCM:'
'RSA+HIGH:'
'HIGH:MEDIUM:'
'TLSv1.2:'
'!AES128-GCM-SHA256:'
'!ECDHE-RSA-AES128-GCM-SHA256:'
'!ECDHE-RSA-AES128-SHA:'
Expand Down
25 changes: 18 additions & 7 deletions local/ProxyHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1500,26 +1500,37 @@ def get_context(self, servername=None, callback=lambda *x: 1):
return self.context_cache[host]
except KeyError:
certfile = cert.get_cert(host, ip)
self.context_cache[host] = context = SSL.Context(GC.LINK_LOCALSSL)
ssl_method = GC.LINK_LOCALSSL
ssl_options = 0
#使用兼容模式来指定 TLSv1.3
if ssl_method == SSL.TLSv1_3_METHOD:
ssl_method = SSL.SSLv23_METHOD
ssl_options |= SSL.OP_NO_TLSv1
ssl_options |= SSL.OP_NO_TLSv1_1
ssl_options |= SSL.OP_NO_TLSv1_2
#兼容模式 TLS 禁用 SSLv3 及以下版本
if GC.LINK_LOCALSSL == SSL.SSLv23_METHOD:
context.set_options(SSL.OP_NO_SSLv2)
context.set_options(SSL.OP_NO_SSLv3)
if ssl_method == SSL.SSLv23_METHOD:
ssl_options |= SSL.OP_NO_SSLv2
ssl_options |= SSL.OP_NO_SSLv3
context = SSL.Context(ssl_method)
#不使用压缩
context.set_options(SSL.OP_NO_COMPRESSION)
ssl_options |= SSL.OP_NO_COMPRESSION
#通用问题修复
context.set_options(SSL.OP_ALL)
ssl_options |= SSL.OP_ALL
#假证书
context.use_privatekey_file(cert.sub_keyfile)
context.use_certificate_file(certfile)
#无客户端验证
context.set_verify(SSL.VERIFY_NONE, callback)
#加密选择
context.set_cipher_list(res_ciphers)
context.set_options(SSL.OP_CIPHER_SERVER_PREFERENCE)
ssl_options |= SSL.OP_CIPHER_SERVER_PREFERENCE
#会话重用
context.set_session_id(os.urandom(16))
context.set_session_cache_mode(SSL.SESS_CACHE_SERVER)
#应用设置
context.set_options(ssl_options)
self.context_cache[host] = context
return context

def send_CA(self):
Expand Down
2 changes: 1 addition & 1 deletion local/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.6.2'
__version__ = '3.6.3'
1 change: 1 addition & 0 deletions local/compat/openssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from ssl import _inet_paton as ip_address # py3.7+
except ImportError:
from ipaddress import ip_address
SSL.TLSv1_3_METHOD = SSL.TLSv1_2_METHOD + 1
_DEFAULT_CIPHERS += ':!SSLv3'
_RESTRICTED_SERVER_CIPHERS += ':!SSLv3'
zero_errno = errno.ECONNABORTED, errno.ECONNRESET, errno.ENOTSOCK
Expand Down
6 changes: 6 additions & 0 deletions local/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
compat.single_instance('gotox.server')
compat.init()

from OpenSSL import SSL
try:
SSL.OP_NO_TLSv1_3
except AttributeError:
GC._SSLv['TLSv1.3'] = GC._SSLv['TLSv1.2']

import logging
from .GlobalConfig import GC

Expand Down

0 comments on commit dfbded2

Please sign in to comment.