diff --git a/gui-config.json b/gui-config.json new file mode 100755 index 00000000..acff4b97 --- /dev/null +++ b/gui-config.json @@ -0,0 +1,35 @@ +{ + "configs" : [ + { + "remarks" : "", + "id" : "B02D90DFE5E7868A6D43D22DCEFC42B5", + "server" : "server host", + "server_port" : 8388, + "server_udp_port" : 0, + "password" : "0", + "method" : "aes-256-cfb", + "protocol" : "origin", + "protocolparam" : "", + "obfs" : "plain", + "obfsparam" : "", + "remarks_base64" : "", + "group" : "FreeSSR-public", + "enable" : true, + "udp_over_tcp" : false + } + ], + "nodeFeedAutoUpdate" : true, + "serverSubscribes" : [ + { + "URL" : "xx", + "Group" : "xxx", + "LastUpdateTime" : 1554836771 + } + ], + "token" : { + + }, + "portMap" : { + + } +} \ No newline at end of file diff --git a/shadowsocks/shell.py b/shadowsocks/shell.py index 6246d98a..0a81451d 100755 --- a/shadowsocks/shell.py +++ b/shadowsocks/shell.py @@ -26,7 +26,6 @@ from shadowsocks.common import to_bytes, to_str, IPNetwork, PortRange from shadowsocks import encrypt - VERBOSE_LEVEL = 5 verbose = 0 @@ -52,6 +51,7 @@ def print_exception(e): import traceback traceback.print_exc() + def __version(): version_str = '' try: @@ -65,16 +65,19 @@ def __version(): pass return version_str + def print_shadowsocks(): print('ShadowsocksR %s' % __version()) + def log_shadowsocks_version(): logging.info('ShadowsocksR %s' % __version()) -def find_config(): +def find_config(type='single'): user_config_path = 'user-config.json' config_path = 'config.json' + all_config_path = 'gui-config.json' def sub_find(file_name): if os.path.exists(file_name): @@ -82,8 +85,11 @@ def sub_find(file_name): file_name = os.path.join(os.path.abspath('..'), file_name) return file_name if os.path.exists(file_name) else None + if type == 'ALL': + return sub_find(all_config_path) return sub_find(user_config_path) or sub_find(config_path) + def check_config(config, is_local): if config.get('daemon', None) == 'stop': # no need to specify configuration for daemon stop @@ -110,13 +116,13 @@ def check_config(config, is_local): logging.warning('warning: local set to listen on 0.0.0.0, it\'s not safe') if config.get('server', '') in ['127.0.0.1', 'localhost']: logging.warning('warning: server set to listen on %s:%s, are you sure?' % - (to_str(config['server']), config['server_port'])) + (to_str(config['server']), config['server_port'])) if config.get('timeout', 300) < 100: logging.warning('warning: your timeout %d seems too short' % - int(config.get('timeout'))) + int(config.get('timeout'))) if config.get('timeout', 300) > 600: logging.warning('warning: your timeout %d seems too long' % - int(config.get('timeout'))) + int(config.get('timeout'))) if config.get('password') in [b'mypassword']: logging.error('DON\'T USE DEFAULT PASSWORD! Please change it in your ' 'config.json!') @@ -160,7 +166,6 @@ def get_config(is_local): if config_path is None: config_path = find_config() - if config_path: logging.debug('loading config from %s' % config_path) with open(config_path, 'rb') as f: @@ -170,7 +175,6 @@ def get_config(is_local): logging.error('found an error in config.json: %s', str(e)) sys.exit(1) - v_count = 0 for key, value in optlist: if key == '-p': @@ -398,6 +402,7 @@ def _decode_dict(data): rv[key] = value return rv + class JSFormat: def __init__(self): self.state = 0 @@ -435,6 +440,7 @@ def push(self, ch): return "\n" return "" + def remove_comment(json): fmt = JSFormat() return "".join([fmt.push(c) for c in json]) @@ -443,3 +449,31 @@ def remove_comment(json): def parse_json_in_str(data): # parse json and convert everything from unicode to str return json.loads(data, object_hook=_decode_dict) + + +def list_multi_config(): + config_path = find_config(type='ALL') + with open(config_path, 'rb') as f: + configs = json.loads(f.read().decode('utf8')) + configs = configs['configs'] + for index, config in enumerate(configs): + print(str([index]) + ':' + str(config['remarks'])) + + +def checkout_config(index): + config_path = find_config(type='ALL') + use_config_path = find_config() + with open(use_config_path, 'w+') as f0: + f0.truncate() + with open(config_path, 'rb') as f: + configs = json.loads(f.read().decode('utf8')) + configs = configs['configs'] + config = configs[index] + del config['remarks'] + del config['group'] + f0.write(json.dumps(config, ensure_ascii=False)) + print('config update successful') + + +if __name__ == '__main__': + checkout_config(29) diff --git a/ssr b/ssr new file mode 100755 index 00000000..5d030b84 --- /dev/null +++ b/ssr @@ -0,0 +1,78 @@ +#!/bin/bash +#使用方法:把该脚本放到$PATH里面并加入可执行权限就行(比如说放到/usr/local/bin) +#首次使用输入ssr install后安装时会自动安装到/usr/local/share/shadowsocksr +#输入ssr config进行配置,输入JSON格式的配置文件 +#输入ssr uninstall卸载 +#输入ssr help 帮助信息 +set -e +if [ -z $EDITOR ];then + EDITOR=vi +fi + +help() { + echo ShadowSocksR python client tool + echo -e if you have not install ssr, please run \"ssr install\" + echo Usage: + echo -e "\t" ssr help + echo -e "\t" ssr config : edit config.json + echo -e "\t" ssr install : install shadowsocksr client + echo -e "\t" ssr uninstall : uninstall shadowsocksr client + echo -e "\t" ssr start : start the shadowsocks service + echo -e "\t" ssr stop : stop the shadowsocks service + echo -e "\t" ssr list : list all the nodes available + echo -e "\t" ssr check[index] : check out one node + echo -e "\t" ssr restart : restart ssr client + +} +install_path=/usr/local/share/shadowsocksr +if [ $# == 0 ];then + help + +elif [ $1 == "help" ];then + help + +elif [ $1 == "install" ];then + sudo git clone -b manyuser https://github.com/shadowsocksr-backup/shadowsocksr.git $install_path + # sudo git clone -b rm https://github.com/the0demiurge/not-in-use.git $install_path + +elif [ $1 == "uninstall" ];then + echo "Danger! are you to remove $install_path forever?(y/N)" + read doit + if [ $doit == 'y' ];then + sudo rm -rvf $install_path + fi + +elif [ $1 == "config" ];then + sudo $EDITOR $install_path/config.json + cd $install_path/shadowsocks/ + ssr restart + +elif [ $1 == "start" ];then + cd $install_path/shadowsocks/ + sudo python local.py -d start + +elif [ $1 == "stop" ];then + cd $install_path/shadowsocks/ + sudo python local.py -d stop + +elif [ $1 == "restart" ];then + cd $install_path/shadowsocks/ + sudo python local.py -d stop + sudo python local.py -d start + +elif [ $1 == "list" ];then + cd $install_path + sudo python3 -c 'from shadowsocks.shell import list_multi_config;list_multi_config()' + +elif [ $1 == "check" ];then + cd $install_path + sudo python3 -c 'from shadowsocks.shell import checkout_config;checkout_config('$2')' + ssr restart + +elif [ $1 == "log" ];then + tail -f /var/log/shadowsocks.log + +elif [ $1 == "shell" ];then + cd $install_path/shadowsocks/ + sudo python local.py $@ +fi