1
2
3
4
环境:
OS: Linux
release: Ubuntu 18.04.1
version: generic 5.0.0-36

0x00 shadowsocks

由于众所周知的原因,我们无法正常访问互联网,对一些职业比如程序员的工作造成了极大的障碍,所以学会科学上网是必须的。具体的方法比较多, 个人一直使用shadowsocks(以下简称ss). ss上网原理如下图所示:

ss

可见, ss分为服务器和客户端两部分,为了能科学上网,需要先在远端部署代理服务器,然后在本地启动代理客户端,由客户端代理访问外网的流量。

0x01 服务器

个人在vultr上搭建了ss服务器.

0x02 客户端

window和MacOS版本都比较好用,ubuntu下一直没找到比较好用的客户端。之前一直用shadowsocks-qt5,下载之后双击即可启动。但是无法(没找到方法)开机启动,每次系统重启都要手动开客户端,比较麻烦。今天在这个网站上看到ubuntu下可以直接用apt安装shadowsocks-libev,决定试一下。

安装shadowsocks-libev

1
$ sudo apt install shadowsocks-libev

Note:
目前不太清楚shadowsocks与shadowsocks-libev的区别,有空再看吧。

systemd

systemd的设计目标是,为系统的启动和管理提供一套完整的解决方案。主要用来管理守护进程.
关于systemd,可以看一下耗子叔写的这篇LINUX PID 1 和 SYSTEMD以及阮一峰老师写的Systemd 入门教程.如有兴趣,可以继续深入探索。

使用apt安装之后,shadowsock-libevsystemd自动接管.

参数配置

systemd管理下的shadowsocks-libev,配置文件路径为

1
/etc/shadowsocks-libev/config.json

编辑config.json文件,写入自己的配置,比如:

1
2
3
4
5
6
7
8
{
"server":"服务器域名或ip",
"server_port":8311, // ss服务器端口,数值类型
"local_port":1080, // ss客户端端口,数值类型
"password":"密码", // 密码
"timeout":60,
"method":"aes-256-cfb" // 加密方式
}

启动客户端

apt安装shadowsocks-libev之后,自动配置了如下的service:

1
2
3
4
5
shadowsocks-libev-local@.service   
shadowsocks-libev-server@.service
shadowsocks-libev-tunnel@.service
shadowsocks-libev-redir@.service
shadowsocks-libev.service

看名字,觉得shadowsocks-libev-local@.service应该是客户端服务,执行命令:

1
systemctl start shadowsocks-libev-local@.service

没想到报了以下错误:

1
Failed to get properties: Unit name shadowsocks-libev-local@.service is neither a valid invocation ID nor unit name.

2019-12-03 update

打开/lib/systemd/system/shadowsocks-libev-local@.service, 加入user, group,修改ExecStart为:

1
ExecStart=/usr/bin/ss-local -c /etc/shadowsocks-libev/config.json

修改后的/lib/systemd/system/shadowsocks-libev-local@.service内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#  This file is part of shadowsocks-libev.
#
# Shadowsocks-libev is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This is a template unit file. Users may copy and rename the file into
# config directories to make new service instances. See systemd.unit(5)
# for details.

[Unit]
Description=Shadowsocks-Libev Custom Client Service for %I
Documentation=man:ss-local(1)
After=network.target

[Service]
Type=simple
# CapabilityBoundingSet=CAP_NET_BIND_SERVICE
User=nobody
Group=nogroup
LimitNOFILE=32768
ExecStart=/usr/bin/ss-local -c /etc/shadowsocks-libev/config.json
# ExecStart=/usr/bin/ss-local -c $CONFFILE $DAEMON_ARGS


[Install]
WantedBy=multi-user.target

重载service配置:

1
systemctl daemon-reload

启动ss-local:

1
systemctl start shadowsocks-libev-local@service

查看shadowsocks-libev-local状态:

1
systemctl status shadowsocks-libev-local@service

结果如下:

1
2
3
4
5
6
7
8
9
10
● shadowsocks-libev-local@service.service - Shadowsocks-Libev Custom Client Service for service
Loaded: loaded (/lib/systemd/system/shadowsocks-libev-local@.service; disabled; vendor preset: enabled)
Active: active (running) since Tue 2019-12-03 14:27:34 CST; 25min ago
Docs: man:ss-local(1)
Main PID: 13981 (ss-local)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/system-shadowsocks\x2dlibev\x2dlocal.slice/shadowsocks-libev-local@service.service
└─13981 /usr/bin/ss-local -c /etc/shadowsocks-libev/config.json

12月 03 14:27:34 lfn-Lenovo systemd[1]: Started Shadowsocks-Libev Custom Client Service for service

颜色为绿,Activeactive(running),说明应该没问题了。

登录谷歌验证。

开机启动

执行下面命令,开机自动激活单元(服务).

1
systemctl enable shadowsocks-libev-local@service

0x03 小结

本文记录了用systemd管理shadowsocks-libev客户端时遇到的一些问题和解决办法。
其实很简答,修改
/lib/systemd/system/shadowsocks-libev-local@.service 中部分内容即可。

通过本次折腾:

  • 了解了systemdsystemdctljournalctl部分命令的用法;

  • 验证了/etc/init.d/下的文件与systemd系统无关。

0x04 参考文章

全文完。


=====以下内容无效==========

不太知道怎么回事,试一下shadowsocks-libev.service, 执行命令:

1
systemctl start shadowsocks-libev.service

发现可以启动成功,不过被启动的却是服务端程序. 执行获取状态命令:

1
systemctl status shadowsocks-libev.service
1
2
3
4
5
6
7
8
9
10
● shadowsocks-libev.service - Shadowsocks-libev Default Server Service
Loaded: loaded (/lib/systemd/system/shadowsocks-libev.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-12-02 16:03:52 CST; 4h 46min ago
Docs: man:shadowsocks-libev(8)
Main PID: 31885 (ss-server)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/shadowsocks-libev.service
└─31885 /usr/bin/ss-server -c /etc/shadowsocks-libev/config.json -u

12月 02 16:03:52 lfn-Lenovo systemd[1]: Started Shadowsocks-libev Default Server Service.

根据status返回结果,我们可以知道,systemdshadowsocks-libev.service中,启动的是/user/bin/ss-server. 那么我们将其修改成/user/bin/ss-local不就行了。

service的配置路径在哪里呢?再看一下status返回结果中的loaded一行,可以发现路径为:

1
/lib/systemd/system/shadowsocks-libev.service

打开service文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#  This file is part of shadowsocks-libev.
#
# Shadowsocks-libev is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This file is default for Debian packaging. See also
# /etc/default/shadowsocks-libev for environment variables.

[Unit]
Description=Shadowsocks-libev Default Server Service
Documentation=man:shadowsocks-libev(8)
After=network.target

[Service]
Type=simple
EnvironmentFile=/etc/default/shadowsocks-libev
User=nobody
Group=nogroup
LimitNOFILE=32768
ExecStart=/usr/bin/ss-server -c $CONFFILE $DAEMON_ARGS

[Install]
WantedBy=multi-user.target

[service]下,我们看到启动命令是:

1
ExecStart=/usr/bin/ss-server -c $CONFFILE $DAEMON_ARGS

修改为

1
ExecStart=/usr/bin/ss-local -c $CONFFILE $DAEMON_ARGS

这样应该就可以了吧?not really!

是的。


=========作废分割线================

### start-stop-daemon

经过进一步调查研究,systemd管理守护进程与/etc/init.d/shadowsocks-libev 没有直接关系,本节作废。

[service]下有一行是EnvironmentFile=/etc/default/shadowsocks-libev,打开这个文件,我们看到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Defaults for shadowsocks initscript
# sourced by /etc/init.d/shadowsocks-libev
# installed at /etc/default/shadowsocks-libev by the maintainer scripts

#
# This is a POSIX shell fragment
#
# Note: `START', `GROUP' and `MAXFD' options are not recognized by systemd.
# Please change those settings in the corresponding systemd unit file.

# Enable during startup?
START=yes

# Configuration file
CONFFILE="/etc/shadowsocks-libev/config.json"

# Extra command line arguments
DAEMON_ARGS="-u"

# User and group to run the server as
USER=nobody
GROUP=nogroup

# Number of maximum file descriptors
MAXFD=32768

注意,这里注释中有一句:

1
# sourced by /etc/init.d/shadowsocks-libev

打开/etc/init.d/shadowsocks-libev, 其中有一行是:

1
DAEMON=/usr/bin/ss-server    # Introduce the server's location here

可见这个脚本中可执行程序还是配置为了/usr/bin/ss-server, 将其改为ss-local:

1
DAEMON=/usr/bin/ss-local    # Introduce the server's location here

仔细阅读/etc/init.d/shadowsocks-libev,发现实际上启动shadowsocks-libev守护进程的是case中的start)中的do_start函数:

1
2
3
4
5
6
7
8
9
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;

do_start函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
do_start()
{
# Modify the file descriptor limit
ulimit -n ${MAXFD}

# Take care of pidfile permissions
mkdir /var/run/$NAME 2>/dev/null || true
chown "$USER:$GROUP" /var/run/$NAME

# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$GROUP --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$GROUP --exec $DAEMON -- \
-c "$CONFFILE" -u -f $PIDFILE $DAEMON_ARGS \
|| return 2
}

可得出来,do_start中实际干活的是start-stop-daemon命令。

start-stop-daemon 为系统自带函数,可以将普通程序以守护进程 方式运行.

看了下自己的/etc/init.d目录,发现redis, docker, mysql等知名软件都是用start-stop-daemon命令启动管理的。

========作废分割线=============


启动shadowsocks-libev.service

到这里,将shadowsocks-libev中可执行目标程序的/usr/bin/ss-server换成/usr/bin/ss-local的目标就完成了。执行start

1
systemctl start shadowsocks-libev

查看服务状态

1
systemctl status shadowsocks-libev
1
2
3
4
5
6
7
8
9
10
● shadowsocks-libev.service - Shadowsocks-libev Default local  Service
Loaded: loaded (/lib/systemd/system/shadowsocks-libev.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-12-02 16:03:52 CST; 5h 6min ago
Docs: man:shadowsocks-libev(8)
Main PID: 31885 (ss-local)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/shadowsocks-libev.service
└─31885 /usr/bin/ss-local -c /etc/shadowsocks-libev/config.json -u

12月 02 16:03:52 lfn-Lenovo systemd[1]: Started Shadowsocks-libev Default Server Service.

Active为绿色,值为active (running)
访问谷歌测试,一切ok.

0x03 小结

本文记录了用systemd管理shadowsocks-libev客户端时遇到的一些问题和解决办法。
总的来说,修改
/lib/systemd/system/shadowsocks-libev.service
文件中下处内容即可直接用shadowsocks-libev.service启动ss-local:

1
ExecStart=/usr/bin/ss-server -c $CONFFILE $DAEMON_ARGS

可能在ubuntu下运行客户端存在更简单直接的方法,如果您知道,请不吝告知,谢谢~~

code

完结。