-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 421c0e9
Showing
12 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# ShadowsocksR-support | ||
一个在服务器端生成ShadowsockR服务器订阅的简单实现 | ||
|
||
### 设计目的 | ||
- 防止因为DNS解析导致SSR服务器ip被BAN | ||
- 降低因服务器新增/迁移,SSR设置更新等的工作量 | ||
|
||
### 部署方式 | ||
- 主服务器的部署 | ||
1. 拷贝php目录下文件到主服务器 | ||
2. 修改`config.json`配置文件 | ||
3. 配置Nginx/apache等Web服务器 | ||
- SSR服务器的部署 | ||
1. 将python目录下的拷贝到部署SSR的服务器 | ||
2. 修改`config.json`配置文件 | ||
3. 添加开机启动(必须设置时间延迟,否则会导致网络错误) | ||
1. 打开`/etc/rc.d/rc.local` | ||
2. 添加 | ||
``` | ||
( | ||
sleep 120 | ||
nohup python /项目路径/python/main.py > /项目路径/python/log.out 2>&1 | ||
)& | ||
``` | ||
4. 添加定时任务 | ||
1. 控制台输入`crontab -e` | ||
2. 添加 | ||
``` | ||
0 * * * * python /项目路径/python/main.py & | ||
``` | ||
### config.json配置文件 | ||
- 主服务器config.json | ||
``` | ||
{ | ||
"group": "PowerByBafflingBUG", //SSR GROUP | ||
"token": "password" //验证,用于确认权限(弱验证) | ||
} | ||
``` | ||
- SSR服务器config.json | ||
``` | ||
{ | ||
"ss-config-file": ["ss_config1","ss_config2"], //SS服务器的配置文件路径 | ||
"ssr-config-file": ["ssr_config1","ssr_config2"], //SSR服务器的配置文件路径 | ||
"main-server": "ssr.example.com", //主服务器的域名/IP | ||
"host": "0.0.0.0", //当前服务器的外网IP | ||
"token": "password", //验证,需与主服务器一致 | ||
"ssl": false //主服务器是否使用SSL(https) | ||
} | ||
``` | ||
### SSR服务器订阅地址 | ||
**http(s)://[main-server]/?token=[token]** | ||
示例:*http://example.com/?token=password* | ||
### 运行流程 | ||
1. SSR服务器每小时检测本地各配置文件(包括SS配置文件,SSR配置文件,SSRS配置文件)是否被更新 | ||
2. - 若有更新 向主服务器推送新的SSR链接 | ||
- 若无更新 向主服务器发送SSR服务器在线确认 | ||
> - 若主服务器不存在当前服务器的记录 重新推送SSR链接到主服务器 | ||
3. 主服务器记录各SSR服务器的推送/确认时间,且抛弃3小时未确认的服务器的SSR链接 | ||
### 写在最后 | ||
- 这个一个个人项目,没有做很多的兼容性判断。可能会在其他环境下无法运行 | ||
- python的运行环境是2.7 | ||
- 选择python和php的原因是我现在使用的两台服务器的运行环境 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
date_default_timezone_set('Asia/Shanghai'); | ||
$json = file_get_contents('./config.json'); | ||
$config = json_decode($json, true); | ||
if ($config["token"] !== $_POST["token"]){ | ||
echo "error:1"; | ||
}else{ | ||
$json = file_get_contents('./ssrURL.json'); | ||
$url = json_decode($json, true); | ||
if(array_key_exists("lasttime", $url[$_POST["host"]])){ | ||
$url[$_POST["host"]]["lasttime"] = date("y-m-d H:i:s"); | ||
$json = json_encode($url); | ||
file_put_contents('./ssrURL.json', $json); | ||
}else{ | ||
echo "error:2"; | ||
} | ||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"group": "PowerByBafflingBUG", | ||
"token": "password" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?php | ||
$json = file_get_contents('./config.json'); | ||
$config = json_decode($json, true); | ||
echo array_key_exists("group", $config)?$config["group"]:"PowerByBafflingBUG"; | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
date_default_timezone_set('Asia/Shanghai'); | ||
$json = file_get_contents('./config.json'); | ||
$config = json_decode($json, true); | ||
if ($config["token"] !== $_GET["token"]){ | ||
echo "error:1"; | ||
}else{ | ||
$json = file_get_contents('./ssrURL.json'); | ||
$url = json_decode($json, true); | ||
$ssr = ""; | ||
foreach($url as $host => $value){ | ||
if((strtotime(date("y-m-d H:i:s"))-strtotime($value["lasttime"]))/3600 < 3.0){ | ||
$ssr .= $value["ssr"]; | ||
} | ||
} | ||
echo base64_encode($ssr); | ||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
date_default_timezone_set('Asia/Shanghai'); | ||
$json = file_get_contents('./config.json'); | ||
$config = json_decode($json, true); | ||
if ($config["token"] !== $_POST["token"]){ | ||
echo "error:1"; | ||
}else{ | ||
$json = file_get_contents('./ssrURL.json'); | ||
$url = json_decode($json, true); | ||
echo "1"; | ||
$url[$_POST["host"]] = array( | ||
"ssr" => $_POST["ssr"], | ||
"lasttime" => date("y-m-d H:i:s") | ||
); | ||
$json = json_encode($url); | ||
file_put_contents('./ssrURL.json', $json); | ||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"ss-config-file": ["ss_config1","ss_config2"], | ||
"ssr-config-file": ["ssr_config1","ssr_config2"], | ||
"main-server": "ssr.example.com", | ||
"host": "0.0.0.0", | ||
"token": "password", | ||
"ssl": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import json | ||
import os | ||
from network import * | ||
from ssrs import * | ||
|
||
if __name__ == "__main__": | ||
update = False | ||
dir_path = os.path.dirname(os.path.realpath(__file__)) | ||
try: | ||
MD5_file = open(dir_path + '/MD5.json', 'r') | ||
fileMD5 = json.load(MD5_file) | ||
except: | ||
fileMD5 = {} | ||
update = True | ||
finally: | ||
MD5_file.close() | ||
update = new_config(dir_path + '/config.json', fileMD5, update) | ||
config_file = open(dir_path + '/config.json', 'r') | ||
config = json.load(config_file) | ||
config_file.close() | ||
group = getgroup('http://' if not config['ssl'] else 'https://' + config['main-server'] + '/group.php') | ||
if 'group' not in fileMD5.keys() or group != fileMD5['group']: | ||
print(group) | ||
update = True | ||
fileMD5['group'] = group | ||
ssr_url = '' | ||
for ss_config_file_name in config['ss-config-file']: | ||
update = new_config(ss_config_file_name, fileMD5, update) | ||
ssr_url += ss2URL(ss_config_file_name, config, group) | ||
for ssr_config_file_name in config['ssr-config-file']: | ||
update = new_config(ssr_config_file_name, fileMD5, update) | ||
ssr_url += ssr2URL(ssr_config_file_name, config, group) | ||
if update: | ||
print(ssr_url) | ||
MD5_file = open(dir_path + '/MD5.json', 'w') | ||
json.dump(fileMD5, MD5_file) | ||
MD5_file.close() | ||
res = post('http://' if not config['ssl'] else 'https://' + config['main-server'] + '/post.php', ssr_url, | ||
config['token'], config['host']) | ||
else: | ||
state = active('http://' if not config['ssl'] else 'https://' + config['main-server'] + '/active.php', config['token'], config['host']) | ||
if state.find('error:2') >= 0: | ||
MD5_file = open(dir_path + '/MD5.json', 'w') | ||
MD5_file.truncate() | ||
MD5_file.close() | ||
os.system('python ' + dir_path + '/ssrs.py') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import urllib | ||
import urllib2 | ||
|
||
|
||
def getgroup(url): | ||
res = urllib2.urlopen(url) | ||
return str(res.read()) | ||
|
||
|
||
def post(url, data, token, host): | ||
parm = urllib.urlencode({'ssr': data, "token": token, "host": host}) | ||
req = urllib2.Request(url, parm) | ||
res = urllib2.urlopen(req) | ||
return str(res.read()) | ||
|
||
|
||
def active(url, token, host): | ||
parm = urllib.urlencode({"token": token, "host": host}) | ||
req = urllib2.Request(url, parm) | ||
res = urllib2.urlopen(req) | ||
return str(res.read()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import base64 | ||
import json | ||
import hashlib | ||
from network import * | ||
|
||
def new_config(file, fileMD5, update): | ||
config_file = open(file, 'rb') | ||
md5 = hashlib.md5(config_file.read()).hexdigest() | ||
config_file.close() | ||
if file in fileMD5.keys() and fileMD5[file] == md5: | ||
return update | ||
fileMD5[file] = md5 | ||
return True | ||
|
||
|
||
def ssr2URL(file, config, group): | ||
ssr_config_file = open(file) | ||
ssr_config = json.load(ssr_config_file) | ||
param_str = "obfsparam=" + base64.urlsafe_b64encode(ssr_config['obfs_param'].encode() if not ssr_config['obfs_param'] is None else ''.encode()).decode().rstrip('=') | ||
if 'protocol_param' in ssr_config.keys() and (not ssr_config['protocol_param'] == ""): | ||
param_str += '&protoparam=' + base64.urlsafe_b64encode(ssr_config['protocol_param'].encode()).decode().rstrip('=') | ||
if 'remarks' in ssr_config.keys() and (not ssr_config['remarks'] == ""): | ||
param_str += '&remarks=' + base64.urlsafe_b64encode(ssr_config['remarks'].encode()).decode().rstrip('=') | ||
param_str += '&group=' + base64.urlsafe_b64encode(group.encode()).decode().rstrip('=') | ||
main_part = config["host"] + ':' + str(ssr_config['server_port']) + ':' + ssr_config['protocol'] + ':' + ssr_config['method'] + ':' + ssr_config['obfs'] + ':' + base64.urlsafe_b64encode(ssr_config['password'].encode()).decode().rstrip('=') | ||
ssr_config_file.close() | ||
b64 = base64.urlsafe_b64encode((main_part + '/?' + param_str).encode()).decode().rstrip('=') | ||
return 'ssr://' + b64 + '\n' | ||
|
||
|
||
def ss2URL(file, config, group): | ||
ss_config_file = open(file) | ||
ss_config = json.load(ss_config_file) | ||
param_str = "obfsparam=" + '' | ||
if 'remarks' in ss_config.keys() and (not ss_config['remarks'] == ""): | ||
param_str += '&remarks=' + base64.urlsafe_b64encode(ss_config['remarks'].encode()).decode().rstrip('=') | ||
param_str += '&group=' + base64.urlsafe_b64encode(group.encode()).decode().rstrip('=') | ||
main_part = config["host"] + ':' + str(ss_config['server_port']) + ':' + 'origin' + ':' + ss_config['method'] + ':' + 'plain' + ':' + base64.urlsafe_b64encode(ss_config['password'].encode()).decode().rstrip('=') | ||
ss_config_file.close() | ||
b64 = base64.urlsafe_b64encode((main_part + '/?' + param_str).encode()).decode().rstrip('=') | ||
return 'ssr://' + b64 + '\n' |