一个基于x-ui的魔改版本
简介
1、该魔改版本的修改分为两部分:(1)对本体进行了修改,(2)一个实现自动发送邮件提醒用户的脚本。
2、最开始只想用python写一堆脚本用crontab运行,直到我发现这种想法实在太蠢,于是开始自学恶补go,但是这个时候过期时间判断与邮件发送的部分已经写完了,于是出现了外挂一个脚本用crontab运行,后期打算用go重写并且合并到x-ui源码中。
开发计划
1、多服务器控制,计划将项目拆分为master和child。 管理员只需在主服务器上修改用户配置,修改后的配置将同步到子节点。 到期时间也会同步。
说明
对于x-ui项目的修改主要为:
1、在添加inbound时,允许填入联系方式,该联系方式保存在数据库中,我使用脚本调取这些联系方式利用gmail向各个用户发送到期提醒邮件。当然,也可以填入手机号保存进数据库,把下面的脚本改一改利用手机发送提醒。
2、添加了一个可以一键重置所有inbound流量的按钮,不用再一个个的点开“操作”去重置流量了。
3、这个修改版本只可用于"利用nginx转发vless与vmess流量"的架构,也就是俗称的"v2ray(xray)+tls+web"。如果你没有用什么脚本一键搭建nginx+x-ui那你就会发现,每次在x-ui添加inbound时,还要到nginx的配置文件中也添加相应的配置,这实在很麻烦,于是我对x-ui源码添加了一些function,令它可以在添加inbound的同时对nginx的配置文件作相应修改。注意:nginx的配置文件绝对路径必须是"/etc/nginx/sites-enabled/default"。
4、所有即将到期的用户的名称(备注)将被记录至一个mysql数据库中以供管理者查看。
项目与代码
1、x-ui修改项目源代码:x-ui_corpa_edition
在项目中有一个文件:x-ui,是我已经编译好的可执行文件(linux64_x86),可以直接下载下来,然后替换掉服务器中的"/usr/local/x-ui/x-ui",替换后记得"chmod +x x-ui"赋予可执行权限。
2、邮件提醒python脚本代码,注意这其中的"token.json"、"credentials.json",请换成该文件所在的绝对路径。以及注意填写mysql数据库的地址、用户、密码以及数据库名。
import moment,sqlite3,smtplib,base64,pymysql
from email.mime.text import MIMEText
#google auth about
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from apiclient import errors
#sqlite3 database connect
db_con = sqlite3.connect('a place to store the x-uis db file')
#create a cursor point for the connection has created
c = db_con.cursor()
#print("database connect successfully")
print("None will be expiring today|||%s" % moment.now().format("YYYY-M-D"))
#MySQL database connect(transport to japan database)
db_con_msq = pymysql.connect(host="",user="",password="",database="")
c1 = db_con_msq.cursor()
#select sql table
sql_table = c.execute("select id,remark,enable,expiry_time,contact from inbounds")
#math date
def date_math():
notice_date_3=moment.unix(row[3]).subtract(days=3).format("YYYY-M-D")
notice_date_2=moment.unix(row[3]).subtract(days=2).format("YYYY-M-D")
notice_date_1=moment.unix(row[3]).subtract(days=1).format("YYYY-M-D")
if(moment.now().format("YYYY-M-D")==notice_date_3):
return 3
elif(moment.now().format("YYYY-M-D")==notice_date_2):
return 2
elif(moment.now().format("YYYY-M-D")==notice_date_1):
return 1
else:
return 0
#gmail api
SCOPES = ['https://www.googleapis.com/auth/gmail.modify']
def get_auth():
creds = None
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
with open('token.json', 'w') as token:
token.write(creds.to_json())
return build('gmail', 'v1', credentials=creds)
#create mail
def create_message(sender,to,subject,message_text):
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
b64_bytes = base64.urlsafe_b64encode(message.as_bytes())
b64_string = b64_bytes.decode()
return {'raw': b64_string}
#send mail
def send_message(service,user_id,message):
try:
message = (service.users().messages().send(userId=user_id, body=message)
.execute())
print('Message Id: %s' % message['id'])
return message
except errors.HttpError as error:
print('An error occurred: %s' % error)
#mysql database insert
def mysql_insert(user):
try:
db_con_msq.ping(reconnect=True)
c1.execute("INSERT INTO `xui`.`%s` (`用户名`) VALUES ('%s');" % (moment.now().format("YYYY-M-D"),user))
db_con_msq.commit()
except pymysql.err.ProgrammingError:
db_con_msq.ping(reconnect=True)
c1.execute("CREATE TABLE `xui`.`%s` (`用户名` varchar(255) NULL);" % moment.now().format("YYYY-M-D"))
c1.execute("INSERT INTO `xui`.`%s` (`用户名`) VALUES ('%s');" % (moment.now().format("YYYY-M-D"),user))
db_con_msq.commit()
#get date and judge it,then send mail and msg
for row in sql_table:
if(date_math()==3 and row[2]==1 and row[4]!=None):
send_message(get_auth(),"me",create_message("sender@gmail.com","%s" % row[4],"提醒","用户“%s”还有三天到期" % row[1]))
mysql_insert(row[1])
elif(date_math()==2 and row[2]==1 and row[4]!=None):
send_message(get_auth(),"me",create_message("sender@gmail.com","%s" % row[4],"提醒","用户“%s”还有二天到期" % row[1]))
mysql_insert(row[1])
elif(date_math()==1 and row[2]==1 and row[4]!=None):
send_message(get_auth(),"me",create_message("sender@gmail.com","%s" % row[4],"提醒","用户“%s”还有一天到期" % row[1]))
mysql_insert(row[1])
else:
#print("%s|%s is well!" % ((moment.now().format("YYYY-M-D"),row[1])))
continue
db_con_msq.close()