Browse Source

implement --user

fix @278
master
clowwindy 10 years ago
parent
commit
ae99698b4e
  1. 32
      shadowsocks/daemon.py
  2. 1
      shadowsocks/local.py
  3. 2
      shadowsocks/server.py
  4. 22
      shadowsocks/utils.py

32
shadowsocks/daemon.py

@ -183,3 +183,35 @@ def daemon_stop(pid_file):
sys.exit(1) sys.exit(1)
print('stopped') print('stopped')
os.unlink(pid_file) os.unlink(pid_file)
def set_user(username):
if username is None:
return
import pwd
import grp
try:
pwrec = pwd.getpwnam(username)
except KeyError:
logging.error('user not found: %s' % username)
raise
user = pwrec[0]
uid = pwrec[2]
gid = pwrec[3]
cur_uid = os.getuid()
if uid == cur_uid:
return
if cur_uid != 0:
logging.error('can not set user as nonroot user')
# will raise later
# inspired by supervisor
if hasattr(os, 'setgroups'):
groups = [grprec[2] for grprec in grp.getgrall() if user in grprec[3]]
groups.insert(0, gid)
os.setgroups(groups)
os.setgid(gid)
os.setuid(uid)

1
shadowsocks/local.py

@ -73,6 +73,7 @@ def main():
sys.exit(1) sys.exit(1)
signal.signal(signal.SIGINT, int_handler) signal.signal(signal.SIGINT, int_handler)
daemon.set_user(config.get('user', None))
loop.run() loop.run()
except (KeyboardInterrupt, IOError, OSError) as e: except (KeyboardInterrupt, IOError, OSError) as e:
logging.error(e) logging.error(e)

2
shadowsocks/server.py

@ -86,6 +86,8 @@ def main():
loop = eventloop.EventLoop() loop = eventloop.EventLoop()
dns_resolver.add_to_loop(loop) dns_resolver.add_to_loop(loop)
list(map(lambda s: s.add_to_loop(loop), tcp_servers + udp_servers)) list(map(lambda s: s.add_to_loop(loop), tcp_servers + udp_servers))
daemon.set_user(config.get('user', None))
loop.run() loop.run()
except (KeyboardInterrupt, IOError, OSError) as e: except (KeyboardInterrupt, IOError, OSError) as e:
logging.error(e) logging.error(e)

22
shadowsocks/utils.py

@ -89,7 +89,11 @@ def check_config(config):
if config.get('password') in [b'mypassword']: if config.get('password') in [b'mypassword']:
logging.error('DON\'T USE DEFAULT PASSWORD! Please change it in your ' logging.error('DON\'T USE DEFAULT PASSWORD! Please change it in your '
'config.json!') 'config.json!')
exit(1) sys.exit(1)
if config.get('user', None) is not None:
if os.name != 'posix':
logging.error('user can be used only on Unix')
sys.exit(1)
def get_config(is_local): def get_config(is_local):
@ -97,11 +101,11 @@ def get_config(is_local):
format='%(levelname)-s: %(message)s') format='%(levelname)-s: %(message)s')
if is_local: if is_local:
shortopts = 'hd:s:b:p:k:l:m:c:t:vq' shortopts = 'hd:s:b:p:k:l:m:c:t:vq'
longopts = ['help', 'fast-open', 'pid-file=', 'log-file='] longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'user=']
else: else:
shortopts = 'hd:s:p:k:m:c:t:vq' shortopts = 'hd:s:p:k:m:c:t:vq'
longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'workers=',
'forbidden-ip='] 'forbidden-ip=', 'user=']
try: try:
config_path = find_config() config_path = find_config()
optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts)
@ -147,6 +151,8 @@ def get_config(is_local):
config['fast_open'] = True config['fast_open'] = True
elif key == '--workers': elif key == '--workers':
config['workers'] = int(value) config['workers'] = int(value)
elif key == '--user':
config['user'] = to_str(value)
elif key == '--forbidden-ip': elif key == '--forbidden-ip':
config['forbidden_ip'] = to_str(value).split(',') config['forbidden_ip'] = to_str(value).split(',')
elif key in ('-h', '--help'): elif key in ('-h', '--help'):
@ -247,9 +253,7 @@ def print_help(is_local):
def print_local_help(): def print_local_help():
print('''usage: sslocal [-h] -s SERVER_ADDR [-p SERVER_PORT] print('''usage: sslocal [OPTION]...
[-b LOCAL_ADDR] [-l LOCAL_PORT] -k PASSWORD [-m METHOD]
[-t TIMEOUT] [-c CONFIG] [--fast-open] [-v] -[d] [-q]
A fast tunnel proxy that helps you bypass firewalls. A fast tunnel proxy that helps you bypass firewalls.
You can supply configurations via either config file or command line arguments. You can supply configurations via either config file or command line arguments.
@ -270,6 +274,7 @@ General options:
-d start/stop/restart daemon mode -d start/stop/restart daemon mode
--pid-file PID_FILE pid file for daemon mode --pid-file PID_FILE pid file for daemon mode
--log-file LOG_FILE log file for daemon mode --log-file LOG_FILE log file for daemon mode
--user USER username to run as
-v, -vv verbose mode -v, -vv verbose mode
-q, -qq quiet mode, only show warnings/errors -q, -qq quiet mode, only show warnings/errors
@ -278,9 +283,7 @@ Online help: <https://github.com/shadowsocks/shadowsocks>
def print_server_help(): def print_server_help():
print('''usage: ssserver [-h] [-s SERVER_ADDR] [-p SERVER_PORT] -k PASSWORD print('''usage: ssserver [OPTION]...
-m METHOD [-t TIMEOUT] [-c CONFIG] [--fast-open]
[--workers WORKERS] [-v] [-d start] [-q]
A fast tunnel proxy that helps you bypass firewalls. A fast tunnel proxy that helps you bypass firewalls.
You can supply configurations via either config file or command line arguments. You can supply configurations via either config file or command line arguments.
@ -301,6 +304,7 @@ General options:
-d start/stop/restart daemon mode -d start/stop/restart daemon mode
--pid-file PID_FILE pid file for daemon mode --pid-file PID_FILE pid file for daemon mode
--log-file LOG_FILE log file for daemon mode --log-file LOG_FILE log file for daemon mode
--user USER username to run as
-v, -vv verbose mode -v, -vv verbose mode
-q, -qq quiet mode, only show warnings/errors -q, -qq quiet mode, only show warnings/errors

Loading…
Cancel
Save