Browse Source

Merge pull request #2259 from simonsmh/master

[ss-manager] Custom working directory
pull/2264/head
Max Lv 6 years ago
committed by GitHub
parent
commit
bbc420611a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 69 additions and 25 deletions
  1. 27
      README.md
  2. 10
      doc/ss-manager.asciidoc
  3. 3
      src/common.h
  4. 2
      src/jconf.c
  5. 1
      src/jconf.h
  6. 48
      src/manager.c
  7. 1
      src/manager.h
  8. 2
      src/utils.c

27
README.md

@ -383,7 +383,7 @@ you may refer to the man pages of the applications, respectively.
-k <password> Password of your remote server. -k <password> Password of your remote server.
-m <encrypt_method> Encrypt method: rc4-md5,
-m <encrypt_method> Encrypt method: rc4-md5,
aes-128-gcm, aes-192-gcm, aes-256-gcm, aes-128-gcm, aes-192-gcm, aes-256-gcm,
aes-128-cfb, aes-192-cfb, aes-256-cfb, aes-128-cfb, aes-192-cfb, aes-256-cfb,
aes-128-ctr, aes-192-ctr, aes-256-ctr, aes-128-ctr, aes-192-ctr, aes-256-ctr,
@ -395,13 +395,13 @@ you may refer to the man pages of the applications, respectively.
The default cipher is chacha20-ietf-poly1305. The default cipher is chacha20-ietf-poly1305.
[-a <user>] Run as another user. [-a <user>] Run as another user.
[-f <pid_file>] The file path to store pid. [-f <pid_file>] The file path to store pid.
[-t <timeout>] Socket timeout in seconds. [-t <timeout>] Socket timeout in seconds.
[-c <config_file>] The path to config file. [-c <config_file>] The path to config file.
[-n <number>] Max number of open files. [-n <number>] Max number of open files.
[-i <interface>] Network interface to bind. [-i <interface>] Network interface to bind.
@ -423,32 +423,35 @@ you may refer to the man pages of the applications, respectively.
[-d <addr>] Name servers for internal DNS resolver. [-d <addr>] Name servers for internal DNS resolver.
(only available in server mode) (only available in server mode)
[--reuse-port] Enable port reuse. [--reuse-port] Enable port reuse.
[--fast-open] Enable TCP fast open. [--fast-open] Enable TCP fast open.
with Linux kernel > 3.7.0. with Linux kernel > 3.7.0.
(only available in local and server mode) (only available in local and server mode)
[--acl <acl_file>] Path to ACL (Access Control List). [--acl <acl_file>] Path to ACL (Access Control List).
(only available in local and server mode) (only available in local and server mode)
[--manager-address <addr>] UNIX domain socket address. [--manager-address <addr>] UNIX domain socket address.
(only available in server and manager mode) (only available in server and manager mode)
[--mtu <MTU>] MTU of your network interface. [--mtu <MTU>] MTU of your network interface.
[--mptcp] Enable Multipath TCP on MPTCP Kernel. [--mptcp] Enable Multipath TCP on MPTCP Kernel.
[--no-delay] Enable TCP_NODELAY. [--no-delay] Enable TCP_NODELAY.
[--executable <path>] Path to the executable of ss-server. [--executable <path>] Path to the executable of ss-server.
(only available in manager mode) (only available in manager mode)
[-D <path>] Path to the working directory of ss-manager.
(only available in manager mode)
[--key <key_in_base64>] Key of your remote server. [--key <key_in_base64>] Key of your remote server.
[--plugin <name>] Enable SIP003 plugin. (Experimental) [--plugin <name>] Enable SIP003 plugin. (Experimental)
[--plugin-opts <options>] Set SIP003 plugin options. (Experimental) [--plugin-opts <options>] Set SIP003 plugin options. (Experimental)
[-v] Verbose mode. [-v] Verbose mode.

10
doc/ss-manager.asciidoc

@ -12,7 +12,7 @@ SYNOPSIS
[-s <server_host>] [-p <server_port>] [-l <local_port>] [-s <server_host>] [-p <server_port>] [-l <local_port>]
[-k <password>] [-m <encrypt_method>] [-f <pid_file>] [-k <password>] [-m <encrypt_method>] [-f <pid_file>]
[-t <timeout>] [-c <config_file>] [-i <interface>] [-t <timeout>] [-c <config_file>] [-i <interface>]
[-b <local_addr>] [-a <user_name>]
[-b <local_addr>] [-a <user_name>] [-D <path>]
[--manager-address <path_to_unix_domain>] [--manager-address <path_to_unix_domain>]
[--executable <path_to_server_executable>] [--executable <path_to_server_executable>]
[--fast-open] [--reuse-port] [--fast-open] [--reuse-port]
@ -116,6 +116,11 @@ Specify the executable path of ss-server.
+ +
Only available in manager mode. Only available in manager mode.
--executable <path_to_server_executable>::
Specify the working directory of ss-manager.
+
Only available in manager mode.
--plugin <plugin_name>:: --plugin <plugin_name>::
Enable SIP003 plugin. (Experimental) Enable SIP003 plugin. (Experimental)
@ -148,7 +153,7 @@ The format of the traffic statistics: ::::
stat: {"8001":11370} stat: {"8001":11370}
There is no way to reset the traffic statistics, unless you remove the port and add it again There is no way to reset the traffic statistics, unless you remove the port and add it again
EXAMPLE EXAMPLE
------- -------
To use `ss-manager`(1), First start it and specify necessary information. To use `ss-manager`(1), First start it and specify necessary information.
@ -178,4 +183,3 @@ SEE ALSO
`shadowsocks-libev`(8), `shadowsocks-libev`(8),
`iptables`(8), `iptables`(8),
/etc/shadowsocks-libev/config.json /etc/shadowsocks-libev/config.json

3
src/common.h

@ -69,7 +69,8 @@ enum {
GETOPT_VAL_PASSWORD, GETOPT_VAL_PASSWORD,
GETOPT_VAL_KEY, GETOPT_VAL_KEY,
GETOPT_VAL_MANAGER_ADDRESS, GETOPT_VAL_MANAGER_ADDRESS,
GETOPT_VAL_EXECUTABLE
GETOPT_VAL_EXECUTABLE,
GETOPT_VAL_WORKDIR,
}; };
#endif // _COMMON_H #endif // _COMMON_H

2
src/jconf.c

@ -328,6 +328,8 @@ read_jconf(const char *file)
value, json_boolean, value, json_boolean,
"invalid config file: option 'no_delay' must be a boolean"); "invalid config file: option 'no_delay' must be a boolean");
conf.no_delay = value->u.boolean; conf.no_delay = value->u.boolean;
} else if (strcmp(name, "workdir") == 0) {
conf.workdir = to_string(value);
} }
} }
} else { } else {

1
src/jconf.h

@ -85,6 +85,7 @@ typedef struct {
int mptcp; int mptcp;
int ipv6_first; int ipv6_first;
int no_delay; int no_delay;
char *workdir;
} jconf_t; } jconf_t;
jconf_t *read_jconf(const char *file); jconf_t *read_jconf(const char *file);

48
src/manager.c

@ -212,6 +212,11 @@ construct_command_line(struct manager_ctx *manager, struct server *server)
int len = strlen(cmd); int len = strlen(cmd);
snprintf(cmd + len, BUF_SIZE - len, " -d \"%s\"", manager->nameservers); snprintf(cmd + len, BUF_SIZE - len, " -d \"%s\"", manager->nameservers);
} }
if (manager->workdir)
{
int len = strlen(cmd);
snprintf(cmd + len, BUF_SIZE - len, " -D \"%s\"", manager->workdir);
}
for (i = 0; i < manager->host_num; i++) { for (i = 0; i < manager->host_num; i++) {
int len = strlen(cmd); int len = strlen(cmd);
snprintf(cmd + len, BUF_SIZE - len, " -s %s", manager->hosts[i]); snprintf(cmd + len, BUF_SIZE - len, " -s %s", manager->hosts[i]);
@ -856,6 +861,7 @@ main(int argc, char **argv)
char *manager_address = NULL; char *manager_address = NULL;
char *plugin = NULL; char *plugin = NULL;
char *plugin_opts = NULL; char *plugin_opts = NULL;
char *workdir = NULL;
int fast_open = 0; int fast_open = 0;
int no_delay = 0; int no_delay = 0;
@ -888,6 +894,7 @@ main(int argc, char **argv)
{ "plugin", required_argument, NULL, GETOPT_VAL_PLUGIN }, { "plugin", required_argument, NULL, GETOPT_VAL_PLUGIN },
{ "plugin-opts", required_argument, NULL, GETOPT_VAL_PLUGIN_OPTS }, { "plugin-opts", required_argument, NULL, GETOPT_VAL_PLUGIN_OPTS },
{ "password", required_argument, NULL, GETOPT_VAL_PASSWORD }, { "password", required_argument, NULL, GETOPT_VAL_PASSWORD },
{ "workdir", required_argument, NULL, GETOPT_VAL_WORKDIR },
{ "help", no_argument, NULL, GETOPT_VAL_HELP }, { "help", no_argument, NULL, GETOPT_VAL_HELP },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
@ -896,7 +903,7 @@ main(int argc, char **argv)
USE_TTY(); USE_TTY();
while ((c = getopt_long(argc, argv, "f:s:l:k:t:m:c:i:d:a:n:6huUvA",
while ((c = getopt_long(argc, argv, "f:s:l:k:t:m:c:i:d:a:n:D:6huUvA",
long_options, NULL)) != -1) long_options, NULL)) != -1)
switch (c) { switch (c) {
case GETOPT_VAL_REUSE_PORT: case GETOPT_VAL_REUSE_PORT:
@ -966,6 +973,10 @@ main(int argc, char **argv)
case '6': case '6':
ipv6first = 1; ipv6first = 1;
break; break;
case GETOPT_VAL_WORKDIR:
case 'D':
workdir = optarg;
break;
case 'v': case 'v':
verbose = 1; verbose = 1;
break; break;
@ -1039,6 +1050,10 @@ main(int argc, char **argv)
if (ipv6first == 0) { if (ipv6first == 0) {
ipv6first = conf->ipv6_first; ipv6first = conf->ipv6_first;
} }
if (workdir == NULL)
{
workdir = conf->workdir;
}
#ifdef HAVE_SETRLIMIT #ifdef HAVE_SETRLIMIT
if (nofile == 0) { if (nofile == 0) {
nofile = conf->nofile; nofile = conf->nofile;
@ -1119,6 +1134,7 @@ main(int argc, char **argv)
manager.plugin = plugin; manager.plugin = plugin;
manager.plugin_opts = plugin_opts; manager.plugin_opts = plugin_opts;
manager.ipv6first = ipv6first; manager.ipv6first = ipv6first;
manager.workdir = workdir;
#ifdef HAVE_SETRLIMIT #ifdef HAVE_SETRLIMIT
manager.nofile = nofile; manager.nofile = nofile;
#endif #endif
@ -1126,21 +1142,35 @@ main(int argc, char **argv)
// initialize ev loop // initialize ev loop
struct ev_loop *loop = EV_DEFAULT; struct ev_loop *loop = EV_DEFAULT;
#ifndef __MINGW32__
// setuid
if (user != NULL && !run_as(user)) {
FATAL("failed to switch user");
}
if (geteuid() == 0) { if (geteuid() == 0) {
LOGI("running from root user"); LOGI("running from root user");
} }
#endif
struct passwd *pw = getpwuid(getuid()); struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
if (homedir == NULL || strlen(homedir) == 0)
{
// if home dir not defined, fall back to /tmp
homedir = "/tmp";
if (workdir == NULL || strlen(workdir) == 0) {
workdir = pw->pw_dir;
// If home dir is still not defined or set to nologin/nonexistent, fall back to /tmp
if (strstr(workdir, "nologin") || strstr(workdir, "nonexistent") || workdir == NULL || strlen(workdir) == 0) {
workdir = "/tmp";
}
working_dir_size = strlen(workdir) + 15;
working_dir = ss_malloc(working_dir_size);
snprintf(working_dir, working_dir_size, "%s/.shadowsocks", workdir);
} else {
working_dir_size = strlen(workdir) + 2;
working_dir = ss_malloc(working_dir_size);
snprintf(working_dir, working_dir_size, "%s", workdir);
} }
working_dir_size = strlen(homedir) + 15;
working_dir = ss_malloc(working_dir_size);
snprintf(working_dir, working_dir_size, "%s/.shadowsocks", homedir);
LOGI("working directory points to %s", working_dir);
int err = mkdir(working_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); int err = mkdir(working_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (err != 0 && errno != EEXIST) { if (err != 0 && errno != EEXIST) {

1
src/manager.h

@ -59,6 +59,7 @@ struct manager_ctx {
char *nameservers; char *nameservers;
int mtu; int mtu;
int ipv6first; int ipv6first;
char *workdir;
#ifdef HAVE_SETRLIMIT #ifdef HAVE_SETRLIMIT
int nofile; int nofile;
#endif #endif

2
src/utils.c

@ -388,6 +388,8 @@ usage()
#ifdef MODULE_MANAGER #ifdef MODULE_MANAGER
printf( printf(
" [--executable <path>] Path to the executable of ss-server.\n"); " [--executable <path>] Path to the executable of ss-server.\n");
printf(
" [-D <path>] Path to the working directory of ss-manager.\n");
#endif #endif
printf( printf(
" [--mtu <MTU>] MTU of your network interface.\n"); " [--mtu <MTU>] MTU of your network interface.\n");

Loading…
Cancel
Save