Fork me on GitHub

从0开始搭建ss多用户控流vps

我想这大概是对新手最完整的教程了….闲话不多说,开始正题

基础环境配置

这里我们使用的服务器为CentOS v7版本,相关配置为Nginx v1.12 + MySQL v5.7 + PHP v7.0.5 .其他版本大同小异,各自注意区分即可。
这里的服务器是全新的服务器,上面什么配置都没有的。所以首先我们安装一些必备的工具。
依次执行如下命令,
安装wget下载工具:
yum install wget
安装gcc编译工具:
yum install gcc
安装git服务:
yum install git
安装python pip:
yum install python-pip

Nginx安装配置

这里使用CentOS自带的yum命令安装:
首先,执行rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm ,可以通过变换上面的地址找到和自己服务器对应版本的 repo 的 rpm。
安装好 yum repo 之后,接下来用 yum 安装 nginx
yum install nginx
到此Nginx已经安装完成,可以执行 nginx -v 查看版本
设置开机启动:
systemctl enable nginx
立即启动Nginx
Systemctl start nginx
查看Nginx服务状态
Systemctl status nginx
到此,Nginx已经安装配置完成,可以在浏览器输入服务器ip访问,看到Nginx欢迎页面即为成功。

MySQL安装配置

这里同样用 yum 安装 MySQL.
rpm -Uvh http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
接着安装 MySQL
yum install mysql-community-server mysql-community-devel
安装完成的默认配置文件会在这个路径 /etc/my.cnf 可以根据实际需要修改里边的选项。
这里要注意的配置文件中如下位置,因为后面配置 PHP 的时候讲会用到:
socket=/var/lib/mysql/mysql.sock
看看下 MySQL 的状态
systemctl status mysqld
结果如下表示安装完成并且已经添加到了自启动:

1
2
3
4
mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
Active: inactive (dead)
...

启动MySQL:
systemctl start mysqld
MySQL v5.7版本是会自动为 root@localhost用户创建一个默认密码的,可以通过如下命令找到:

1
grep `temporary password` /var/log/mysqld.log

2016-04-07T15:39:59.942230Z 1 [Note] A temporary password is generated for root@localhost: UH!e%iTsIgs:

上面的 UH!e%iTsIgs 就是默认密码,现在可以登入MySQL并修改密码:
mysql -uroot -p

Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.11

MySQL 5.7 版本对密码的安全性要求很严格,必须至少包含1个大写字母、1个小写字母、1个数字和1个特殊字符,长度不得小于8个字符。
修改密码:

1
mysql> ALTER USER `root`@`localhost` IDENTIFIED BY `Lnmp.cn8`;

其中Lnmp.cn8 就是新密码。
退出MySQL:mysql> quit

PHP v7安装配置

下载源码到 usr/local/src,
cd usr/local/src
wget -c http://cn2.php.net/distributions/php-7.0.5.tar.gz
解压
tar -zxvf php-7.0.5.tar.gz
进入解压后的文件夹:
cd php-7.0.5/
可以通过./configure --help看到,有三百多个扩展选项,可以自己根据需要增减,
这里我们预先那些准备装的扩展要用到的软件模块
yum -y install libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel curl curl-devel openssl openssl-devel
接下来configure PHP
./configure --prefix=/usr/local/php7 --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx --with-pdo-mysql --with-mysql-sock=/var/lib/mysql/mysql.sock --with-zlib --with-curl --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-openssl --enable-mbstring --enable-xml --enable-session --enable-ftp --enable-pdo -enable-tokenizer --enable-zip

值得一提的是,PHP7已经删除了MySQL扩展,所以 -with-mysql 不再是一个有效的选项。这里用 PDO 代替。
其中 –prefix 是安装目录,如果需要在同一个服务器安装多个 PHP 版本,这个 –prefix 设定是很有必要的。
configure成功会有 Thank you for using PHP 字样。
编译:make
然后make install
如果安装 PHP 时没有指明 –prefix ,那么就 php.ini 路径就是 /usr/local/lib/php.ini 。刚才安装时有指明 –prefix ,所以是 /usr/local/php7/lib/php.ini
然后根据实际自己需要修改 php.ini。
vi /usr/local/php7/lib/php.ini
查找 mysqli.default_socket,修改成:
mysqli.default_socket = /var/lib/mysql/mysql.sock
其中 /var/lib/mysql/mysql.sock 就是上面安装 MySQL 时提到的。这个值必须填,否则会出现如下错误:
Warning: mysqli_connect(): (HY000/2002): No such file or directory
修改时区,查找 date.timezone,改成:
date.timezone = PRC
好了,PHP 7 已经安装好,下面验证一下: /usr/local/php7/bin/php -v
显示PHP版本即为成功。
例行拷贝配置文件,以备不时只需
cp /usr/local/php7/etc/php-fpm.conf.default /usr/local/php7/etc/php-fpm.conf
cp /usr/local/php7/etc/php-fpm.d/www.conf.default /usr/local/php7/etc/php-fpm.d/www.conf
可以打开/usr/local/php7/etc/php-fpm.d/www.conf看到如下字段

1
2
user = nginx
group = nginx

1
listen = 127.0.0.1:9000

如果文件中上述字段配置不一样,改为上述内容。
其中listen = 127.0.0.1:9000要注意,9000这个端口在配置网站时要用到。
配置 php-fpm 启动服务脚本:
在解压后的php文件目录下执行:cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/
修改启动脚本,把里边 prefix 相关的内容用实际路径代替:
vi /usr/lib/systemd/system/php-fpm.service

1
2
PIDFile=${prefix}/var/run/php-fpm.pid
ExecStart=${exec_prefix}/sbin/php-fpm --nodaemonize --fpm-config ${prefix}/etc/php-fpm.conf

修改成

1
2
PIDFile=/usr/local/php7/var/run/php-fpm.pid
ExecStart=/usr/local/php7/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php7/etc/php-fpm.conf

重新载入 systemd
systemctl daemon-reload
让 php-fpm 随机启动
systemctl enable php-fpm
立即启动 php-fpm
systemctl start php-fpm
查看状态:systemctl status php-fpm,看到服务running即可。

配置 Nginx 站点

先建立一个 lnmp 站点,路径是 /www/lnmp/web
mkdir -p /www/lnmp/web
并准备好 phpinfo 测试文件
vi /www/lnmp/web/phpinfo.php
输入如下内容保存:

1
2
3
<?php
phpinfo();
?>

每个站点建一个 Nginx 配置文件放到 /etc/nginx/conf.d/
cd /etc/nginx/conf.d/
vi lnmp.cn.conf
lnmp.cn.conf 中加入以下内容然后保存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name www.lnmp.cn;
root /www/lnmp/web;
location / {
index index.php index.html index.htm;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

其中 server_name www.lnmp.cn; 中的 www.lnmp.cn 改成你自己的域名
其中 root /www/lnmp/web; 就是刚才创建的站点目录
其中 fastcgi_pass 127.0.0.1:9000; 就是上面配置 php-fpm 提到要留意的值
修改配置后一定要记得 reload nginx 才能生效
systemctl reload nginx
好了,大功告成,就打开刚才的域名验证下(如果没有已经指向配置好的服务器 IP的域名,使用ip也可以)
如果打不开,或者报错dial tcp4 xxxxxx:80: getsockopt: no route to host
那么说明你的服务器80端口还没打开,你需要

1
2
3
4
firewall-cmd --zone=public --add-port=80/tcp --permanent
systemctl stop firewalld.service
systemctl start firewalld.service
systemctl status firewalld.service

安装并配置 ss-panel

环境要求

为前端的 ss-panel 是使用 PHP 编写的网页应用程序,它对你的主机运行环境有一定的要求。

  • PHP 5.6 或更高
  • MySQL 5.5 或更高
  • 支持 URL 重写的 Web 服务器(Nginx / Apache 均可)

下载 ss-panel 源码

ss-panel 的 GitHub 项目地址:orvice/ss-panel
cd到你的web根目录下,clone ss-panel:
git clone https://github.com/orvice/ss-panel.git -b v3
其中 -b v3是代表clone v3版本的ss-panel
当然你也可以下载源码再用 SCP/FPS 传到服务器上去。
注意源码下载完成后的目录结构,请务必保证 /public 目录在站点的根目录下。你可以使用 mv ss-panel/{.,}* ./ 命令将子目录的内容移动到当前目录来。

配置 ss-panel

这个时候访问你的站点是会得到403 Forbidden, 因为此时站点根目录下是没有index.php文件的。当然这样也很正常,大部分 MVC 框架都将 index.php 的入口文件放到其他子目录下了,这样做是为了保护根目录下的配置文件等可能会导致信息泄露的敏感文件无法被访问。
接下来可以按照官方文档来配置的你web

Step 1

1
2
$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar install

Step 2
将 .env.example 复制一份重命名为 .env,自行修改其中的数据库等信息。
cp .env.example .env
then edit .env
vi .env
你还需要修改 .env 中的 muKey 字段,修改为任意字符串(最好只包含 ASCII 字符),下面配置后端的时候我们需要使用到这个 muKey:
muKey = 'api_key_just_for_test'
then
chmod -R 777 storage

Step 3
Import the sql to you mysql database.
mysql -u root -p xxxxx < db.sql,其中xxxxx是你的数据库名字

Step 4
Nginx Config example:
if you download ss-panel on path /home/www/ss-panel

1
2
3
4
root /home/www/ss-panel/public;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}

现在访问你的站点,不出意外,就可以看到ss-panel首页了。

进入 ss-panel 后台

现在访问 http://your-domain/admin 就可以进入 ss-panel 后台了。
不过细心的你可能会注意到,刚才导入数据表的时候,user 表并没有添加记录,那要咋进管理后台呢?当然你可以在数据库中手动加一条记录,不过作者已经提供了一个更方便的方式:
php xcat createAdmin
在站点根目录下运行,根据提示即可创建管理员账号。探后根据提示输入账号密码就可以登入到自己的后台了。

部署并配置 shadowsocks-manyuser

安装 shadowsocks-manyuser

我们使用 fsgmhoward/shadowsocks-py-mu 这个版本的后端。这个后端支持使用 MultiUser API 与前端的 ss-panel 进行用户信息交互。

这个 API 的官方介绍在这里。简单来讲,如果你通过 API 来与前端通信,你就不需要修改后端的数据库配置了,并且可以使用「自定义加密」、「流量记录」等高级功能。下面我只介绍使用 API 的方法。

先将代码 clone 到本地:
git clone https://github.com/fsgmhoward/shadowsocks-py-mu.git
其中的 shadowsocks 子目录才是我们需要的,外面的是 setup.py 的相关文件。

配置 shadowsocks-manyuser

进入 shadowsocks 目录,将 config_example.py 复制一份到 config.py:
cp config_example.py config.py
修改其中的部分字段如下:

1
2
3
4
5
API_ENABLED = True

API_URL = 'http://xxxxxxx/mu'
# 就是上面在 .env 中填写的 muKey 把它填在这里
API_PASS = 'api_key_just_for_test'

此时我们就可以试着运行脚本了 python servers.py这里要注意是 servers.py,而不是server.py
如果没错的话,你大概会看到如下输出:

1
2
3
4
5
6
7
Dec 03 13:41:18 INFO -----------------------------------------
Dec 03 13:41:18 INFO Multi-User Shadowsocks Server Starting...
Dec 03 13:41:18 INFO Current Server Version: 3.4.0-dev
Dec 03 13:41:18 INFO Now using MultiUser API as the user interface
Dec 03 13:41:18 INFO Now starting manager thread...
Dec 03 13:41:23 INFO Now starting user pulling thread...
Dec 03 13:41:23 INFO Server Added: P[1025], M[aes-256-cfb], E[xxxxxxxx.com]

其中 P[XXX] 表示用户端口,M[XXX] 表示加密方式,E[XXX] 表示用户的邮箱地址。这些都会随着 ss-panel 前端中用户配置的改变而实时变化。

此时你虽然已经把 servers.py 跑起来了,但是你应该还不能翻墙,因为还没有打开端口,所以此时你需要打开刚才输出中的端口,ss-panel 新注册的用户所分配的端口均为其 id-1 的用户的端口号 + 1。比如说你把 admin 用户(uid 为1)的端口改为 12450,那么后面注册的新用户的端口就会是 12451, 12452 这样递增的。
所以此时你可以批量打开部分端口:

1
2
3
4
firewall-cmd --permanent --zone=public --add-port=xxxx-xxxx/tcp
systemctl stop firewalld.service
systemctl start firewalld.service
systemctl status firewalld.service

到此,应该可以正常科学上网了。

配置 ss-manyuser 守护进程

这里守护进程是希望servers.py在后台隐式运行,你可以:
pip install supervisor
创建 supervisor 配置文件:
echo_supervisord_conf > /etc/supervisord.conf
配置 supervisor 以监控 ss-manyuser 运行
/etc/supervisord.conf
在文件尾部添加如下内容并修改为自己的实际路径:

1
2
3
4
5
[program:ss-manyuser]
command = python /usr/local/src/shadowsocks-py-mu/shadowsocks/servers.py
user = root
autostart = true
autorestart = true

重启 supervisor 服务以加载配置
supervisorctl reload
查看 shadowsocks-manyuser 是否已经运行:
ps -ef | grep servers.py

1
root     10288  2781  0 13:41 ?        00:00:00 python /usr/local/src/shadowsocks-py-mu/shadowsocks/servers.py

也可以通过以下命令管理 shadowsock-manyuser 的状态
supervisorctl {start|stop|restart} ss-manyuser

至此,已经完成了多用户控流科学上网的配置了,叫上你的小伙伴一起享受冲浪的乐趣吧!

常见错误 FAQ

1 . 查看Nginx服务状态显示 Failed to read PID from file /run/nginx.pid: Invalid argument
因为 nginx 启动需要一点点时间,而 systemd 在 nginx 完成启动前就去读取 pid file
造成读取 pid 失败
解决方法很简单,让 systemd 在执行 ExecStart 的指令后等待一点点时间即可
如果你的 nginx 启动需要时间更长,可以把 sleep 时间改长一点
mkdir -p /etc/systemd/system/nginx.service.d
printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" > /etc/systemd/system/nginx.service.d/override.conf
然后
systemctl daemon-reload
systemctl restart nginx.service

2 . php: command not found
原因是你的php并没有配置全局路径,加上绝对路径即可,例如/usr/local/php7/bin/php

3 . 配置ss-panel前端的时候站点提示:502 Bad Gateway
因为 nginx 找不到php-fpm了,所以报错,一般是fastcgi_pass后面的路径配置错误了,后面可以是socket或者是ip:port
例如:修改php-fpm的配置文件 vi /usr/local/php7/etc/php-fpm.conf 里面的 listen = /tmp/php-fcgi.sock 改为 listen = 127.0.0.1:9000

4 . 站点页面空白,没有任何提示
检查你的nginx配置,我的如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 80;
server_name xx.xx.xxx.xxx; #这里隐藏了我的IP
index index.php index.html index.htm;

root /www/ssmu/public;

location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

5 . 创建管理员账号时:Uncaught PDOException: could not find driver in …
原因是缺少php pdo_mysql扩展 安装即可

6 . Slim Application Error
一般是缺少权限,相应的文件夹赋予权限即可

Enjoy it ? Donate for it ! 欣赏此文?求鼓励,求支持!
>