以下shadowsocks を Python 3.10で動かすときのメモ
Pythonの3.10ではshadowsocksのサービスが動かない
# service shadowsocks status
サービスが起動してない理由のログを確認すると下記のようになっている。
# journalctl -xeu shadowsocks.service
...
Traceback (most recent call last):
File "/usr/local/shadowsocks/server.py", line 32, in <module>
from shadowsocks import shell, daemon, eventloop, tcprelay, udprelay, \
File "/usr/local/shadowsocks/../shadowsocks/shell.py", line 26, in <module>
from shadowsocks.common import to_bytes, to_str, IPNetwork, PortRange
File "/usr/local/shadowsocks/../shadowsocks/common.py", line 27, in <module>
from shadowsocks import lru_cache
File "/usr/local/shadowsocks/../shadowsocks/lru_cache.py", line 44, in <module>
class LRUCache(collections.MutableMapping):
AttributeError: module 'collections' has no attribute 'MutableMapping'
Starting ShadowsocksR failed
shadowsocks.service: Control process exited, code=exited, status=1/FAILURE
Subject: Unit process exited
...
AttributeError: module 'collections' has no attribute 'MutableMapping'を出さないように、変更する箇所は次
# diff lru_cache.py.org lru_cache.py
21c21
< import collections
---
> import collections.abc as collections
上記修正をしたあとで起動しようとするとcryptを使っている場合起動しない。ログを確認すると下記のようになっている。
# journalctl -xeu shadowsocks.service
...
IPv6 support
Traceback (most recent call last):
File "/usr/local/shadowsocks/server.py", line 221, in <module>
main()
File "/usr/local/shadowsocks/server.py", line 39, in main
config = shell.get_config(False)
File "/usr/local/shadowsocks/../shadowsocks/shell.py", line 303, in get_config
check_config(config, is_local)
File "/usr/local/shadowsocks/../shadowsocks/shell.py", line 132, in check_config
encrypt.try_cipher(config['password'], config['method'])
File "/usr/local/shadowsocks/../shadowsocks/encrypt.py", line 46, in try_cipher
Encryptor(key, method)
File "/usr/local/shadowsocks/../shadowsocks/encrypt.py", line 90, in __init__
self.cipher = self.get_cipher(key, method, 1,
File "/usr/local/shadowsocks/../shadowsocks/encrypt.py", line 120, in get_cipher
return m[2](method, key, iv, op)
File "/usr/local/shadowsocks/../shadowsocks/crypto/openssl.py", line 95, in __init__
load_openssl()
File "/usr/local/shadowsocks/../shadowsocks/crypto/openssl.py", line 39, in load_openssl
libcrypto = util.find_library(('crypto', 'eay32'),
File "/usr/local/shadowsocks/../shadowsocks/crypto/util.py", line 67, in find_library
path = ctypes.util.find_library(name)
File "/usr/lib/python3.10/ctypes/util.py", line 341, in find_library
_get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name))
File "/usr/lib/python3.10/ctypes/util.py", line 147, in _findLib_gcc
if not _is_elf(file):
File "/usr/lib/python3.10/ctypes/util.py", line 99, in _is_elf
with open(filename, 'br') as thefile:
FileNotFoundError: [Errno 2] No such file or directory: b'liblibcrypto.a'
Starting ShadowsocksR failed
shadowsocks.service: Control process exited, code=exited, status=1/FAILURE
aa Subject: Unit process exited
これは、ファイル
shadowsocks/crypto/util.py
等の
def find_library(possible_lib_names, search_symbol, library_name):
import ctypes.util
from ctypes import CDLL
...
等を直せばよいのだが、簡単に済ませるために
# locate libcrypto.so
/usr/lib/x86_64-linux-gnu/libcrypto.so
/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
/usr/lib/x86_64-linux-gnu/libcrypto.so.3
# cd /usr/lib/x86_64-linux-gnu/
# ln -s libcrypt.so liblibcrypto.so
これでとりあえずは起動する。