完整错误信息:
INFO: loading config from /etc/shadowsocks.json
2019-07-25 02:26:47 INFO loading libcrypto from libcrypto.so.1.1
Traceback (most recent call last):
File "/usr/local/bin/ssserver", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python2.7/dist-packages/shadowsocks/server.py", line 34, in main
config = shell.get_config(False)
File "/usr/local/lib/python2.7/dist-packages/shadowsocks/shell.py", line 262, in get_config
check_config(config, is_local)
File "/usr/local/lib/python2.7/dist-packages/shadowsocks/shell.py", line 124, in check_config
encrypt.try_cipher(config['password'], config['method'])
File "/usr/local/lib/python2.7/dist-packages/shadowsocks/encrypt.py", line 44, in try_cipher
Encryptor(key, method)
File "/usr/local/lib/python2.7/dist-packages/shadowsocks/encrypt.py", line 83, in __init__
random_string(self._method_info[1]))
File "/usr/local/lib/python2.7/dist-packages/shadowsocks/encrypt.py", line 109, in get_cipher
return m[2](method, key, iv, op)
File "/usr/local/lib/python2.7/dist-packages/shadowsocks/crypto/openssl.py", line 76, in __init__
load_openssl()
File "/usr/local/lib/python2.7/dist-packages/shadowsocks/crypto/openssl.py", line 52, in load_openssl
libcrypto.EVP_CIPHER_CTX_cleanup.argtypes = (c_void_p,)
File "/usr/lib/python2.7/ctypes/__init__.py", line 379, in __getattr__
func = self.__getitem__(name)
File "/usr/lib/python2.7/ctypes/__init__.py", line 384, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1: undefined symbol: EVP_CIPHER_CTX_cleanup
这个问题是由于在openssl1.1.0版本中,废弃了EVP_CIPHER_CTX_cleanup函数,如OpenSSL官网中所说:
EVP_CIPHER_CTX was made opaque in OpenSSL 1.1.0.
As a result, EVP_CIPHER_CTX_reset() appeared and EVP_CIPHER_CTX_cleanup() disappeared.
EVP_CIPHER_CTX_init() remains as an alias for EVP_CIPHER_CTX_reset().
EVP_CIPHER_CTX_reset函数替代了EVP_CIPHER_CTX_cleanup函数
EVP_CIPHER_CTX_reset函数说明:
EVP_CIPHER_CTX_reset() clears all information from a cipher context and free up any allocated memory associate with it, except the ctx itself. This function should be called anytime ctx is to be reused for another EVP_CipherInit() / EVP_CipherUpdate() / EVP_CipherFinal() series of calls.
EVP_CIPHER_CTX_cleanup函数说明:
EVP_CIPHER_CTX_cleanup() clears all information from a cipher context and free up any allocated memory associate with it. It should be called after all operations using a cipher are complete so sensitive information does not remain in memory.
可以看出,二者功能基本上相同,都是释放内存,只是应该调用的时机稍有不同,所以用reset代替cleanup问题不大。
解决方案:
修改 /usr/local/lib/python2.7/dist-packages/shadowsocks/crypto/openssl.py
将所有
EVP_CIPHER_CTX_cleanup
替换为
EVP_CIPHER_CTX_reset
参考:
https://blog.lyz810.com/article/2016/09/shadowsocks-with-openssl-greater-than-110/