2018-11-08 17:05:34 +00:00
|
|
|
#!/usr/bin/env python3
|
2020-03-05 14:02:20 +00:00
|
|
|
#
|
2020-06-19 13:49:07 +00:00
|
|
|
# Copyright (C) 2018-2020 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter
|
2018-11-16 13:14:08 +00:00
|
|
|
#
|
|
|
|
# This is free software, licensed under the GNU General Public License v3.0.
|
|
|
|
# See /LICENSE for more information.
|
|
|
|
#
|
2018-11-08 17:05:34 +00:00
|
|
|
|
2018-11-08 12:55:20 +00:00
|
|
|
import json
|
|
|
|
import base64
|
2019-12-27 20:42:47 +00:00
|
|
|
import secrets
|
2018-11-08 12:55:20 +00:00
|
|
|
import uuid
|
|
|
|
import configparser
|
2021-02-25 09:44:34 +00:00
|
|
|
import argparse
|
2018-11-14 16:34:13 +00:00
|
|
|
import subprocess
|
2018-11-08 17:05:34 +00:00
|
|
|
import os
|
2020-01-06 20:18:29 +00:00
|
|
|
import sys
|
2019-07-13 05:30:58 +00:00
|
|
|
import socket
|
2018-11-29 21:43:02 +00:00
|
|
|
import re
|
2019-06-02 21:11:58 +00:00
|
|
|
import hashlib
|
2020-06-19 13:49:07 +00:00
|
|
|
import pathlib
|
2020-09-11 18:58:38 +00:00
|
|
|
import psutil
|
2019-08-30 05:52:59 +00:00
|
|
|
import time
|
2020-11-15 18:56:56 +00:00
|
|
|
import uuid
|
2020-03-03 12:49:23 +00:00
|
|
|
from pprint import pprint
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
from tempfile import mkstemp
|
|
|
|
from typing import List, Optional
|
|
|
|
from shutil import move
|
|
|
|
from enum import Enum
|
2020-08-10 18:49:47 +00:00
|
|
|
from os import path
|
2020-03-03 12:49:23 +00:00
|
|
|
import logging
|
2019-11-02 17:10:10 +00:00
|
|
|
import uvicorn
|
|
|
|
import jwt
|
2019-12-20 15:19:07 +00:00
|
|
|
from jwt import PyJWTError
|
2020-01-13 20:47:29 +00:00
|
|
|
from netaddr import *
|
2019-10-10 19:13:14 +00:00
|
|
|
from netjsonconfig import OpenWrt
|
2020-04-22 16:00:07 +00:00
|
|
|
from fastapi import Depends, FastAPI, HTTPException, Security, Query, Request
|
2020-03-03 12:49:23 +00:00
|
|
|
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm, SecurityScopes, OAuth2
|
2019-11-02 17:10:10 +00:00
|
|
|
from passlib.context import CryptContext
|
2020-03-03 12:49:23 +00:00
|
|
|
from fastapi.encoders import jsonable_encoder
|
|
|
|
from fastapi.security.base import SecurityBase
|
|
|
|
from fastapi.security.utils import get_authorization_scheme_param
|
|
|
|
from fastapi.openapi.docs import get_swagger_ui_html
|
|
|
|
from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
|
|
|
|
from fastapi.openapi.utils import get_openapi
|
|
|
|
from fastapi.openapi.models import SecurityBase as SecurityBaseModel
|
2020-07-16 07:55:19 +00:00
|
|
|
from fastapi.responses import StreamingResponse
|
2020-03-05 14:02:20 +00:00
|
|
|
from pydantic import BaseModel, ValidationError # pylint: disable=E0611
|
2020-03-03 12:49:23 +00:00
|
|
|
from starlette.status import HTTP_403_FORBIDDEN
|
|
|
|
from starlette.responses import RedirectResponse, Response, JSONResponse
|
2020-06-20 07:08:51 +00:00
|
|
|
#from starlette.requests import Request
|
|
|
|
import netifaces
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG = logging.getLogger('api')
|
2020-07-03 14:27:09 +00:00
|
|
|
LOG.setLevel(logging.ERROR)
|
|
|
|
#LOG.setLevel(logging.DEBUG)
|
2018-11-08 12:55:20 +00:00
|
|
|
|
|
|
|
# Generate a random secret key
|
2019-11-02 17:10:10 +00:00
|
|
|
SECRET_KEY = uuid.uuid4().hex
|
|
|
|
JWT_SECRET_KEY = uuid.uuid4().hex
|
|
|
|
PERMANENT_SESSION_LIFETIME = timedelta(hours=24)
|
2019-11-13 07:39:00 +00:00
|
|
|
ACCESS_TOKEN_EXPIRE_MINUTES = 1440
|
2019-11-02 17:10:10 +00:00
|
|
|
ALGORITHM = "HS256"
|
2018-11-08 12:55:20 +00:00
|
|
|
|
|
|
|
# Get main net interface
|
2020-03-03 12:49:23 +00:00
|
|
|
FILE = open('/etc/shorewall/params.net', "r")
|
|
|
|
READ = FILE.read()
|
|
|
|
IFACE = None
|
|
|
|
for line in READ.splitlines():
|
2018-11-08 12:55:20 +00:00
|
|
|
if 'NET_IFACE=' in line:
|
2020-03-03 12:49:23 +00:00
|
|
|
IFACE = line.split('=', 1)[1]
|
2020-05-14 08:44:16 +00:00
|
|
|
FILE.close()
|
|
|
|
|
|
|
|
# Get ipv6 net interface
|
|
|
|
FILE = open('/etc/shorewall6/params.net', "r")
|
|
|
|
READ = FILE.read()
|
|
|
|
IFACE6 = None
|
|
|
|
for line in READ.splitlines():
|
|
|
|
if 'NET_IFACE=' in line:
|
|
|
|
IFACE6 = line.split('=', 1)[1]
|
|
|
|
FILE.close()
|
2018-11-08 12:55:20 +00:00
|
|
|
|
|
|
|
# Get interface rx/tx
|
|
|
|
def get_bytes(t, iface='eth0'):
|
2020-08-10 18:49:47 +00:00
|
|
|
if path.exists('/sys/class/net/' + iface + '/statistics/' + t + '_bytes'):
|
|
|
|
with open('/sys/class/net/' + iface + '/statistics/' + t + '_bytes', 'r') as f:
|
|
|
|
data = f.read()
|
|
|
|
return int(data)
|
|
|
|
return 0
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2019-12-26 19:25:11 +00:00
|
|
|
def get_bytes_ss(port):
|
2020-05-20 16:23:24 +00:00
|
|
|
try:
|
|
|
|
ss_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
2020-06-26 09:18:59 +00:00
|
|
|
ss_socket.settimeout(1)
|
2020-05-20 16:23:24 +00:00
|
|
|
ss_socket.sendto('ping'.encode(), ("127.0.0.1", 8839))
|
|
|
|
ss_recv = ss_socket.recv(1024)
|
|
|
|
except socket.timeout as err:
|
2020-06-21 07:06:52 +00:00
|
|
|
LOG.debug("Shadowsocks stats timeout (" + str(err) + ")")
|
2020-05-20 16:23:24 +00:00
|
|
|
return 0
|
|
|
|
except socket.error as err:
|
2020-06-21 07:06:52 +00:00
|
|
|
LOG.debug("Shadowsocks stats error (" + str(err) + ")")
|
2020-05-20 16:23:24 +00:00
|
|
|
return 0
|
2020-03-03 12:49:23 +00:00
|
|
|
json_txt = ss_recv.decode("utf-8").replace('stat: ', '')
|
|
|
|
result = json.loads(json_txt)
|
2020-01-17 20:32:48 +00:00
|
|
|
if str(port) in result:
|
|
|
|
return result[str(port)]
|
2020-06-20 07:08:51 +00:00
|
|
|
return 0
|
2019-12-26 19:25:11 +00:00
|
|
|
|
2020-08-10 18:49:47 +00:00
|
|
|
def get_bytes_v2ray(t,user):
|
|
|
|
if t == "tx":
|
|
|
|
side="downlink"
|
|
|
|
else:
|
|
|
|
side="uplink"
|
2020-09-11 18:58:38 +00:00
|
|
|
try:
|
2021-01-07 12:22:46 +00:00
|
|
|
data = subprocess.check_output('/usr/bin/v2ctl api --server=127.0.0.1:10085 StatsService.GetStats ' + "'" + 'name: "user>>>' + user + '>>>traffic>>>' + side + '"' + "'" + ' 2>/dev/null | grep value | cut -d: -f2 | tr -d " "', shell = True)
|
2020-09-11 18:58:38 +00:00
|
|
|
except:
|
|
|
|
return 0
|
|
|
|
if data.decode("utf-8") != '':
|
2020-08-20 18:31:29 +00:00
|
|
|
return int(data.decode("utf-8"))
|
|
|
|
else:
|
|
|
|
return 0
|
2020-08-10 18:49:47 +00:00
|
|
|
|
2020-09-11 18:58:38 +00:00
|
|
|
def checkIfProcessRunning(processName):
|
|
|
|
for proc in psutil.process_iter():
|
|
|
|
try:
|
|
|
|
if processName.lower() in proc.name().lower():
|
|
|
|
return True
|
|
|
|
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
|
|
pass
|
|
|
|
return False;
|
|
|
|
|
2020-06-19 13:49:07 +00:00
|
|
|
def file_as_bytes(file):
|
|
|
|
with file:
|
|
|
|
return file.read()
|
|
|
|
|
2020-06-30 15:02:02 +00:00
|
|
|
def get_username_from_userid(userid):
|
|
|
|
if userid == 0:
|
|
|
|
return 'openmptcprouter'
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = f.read()
|
|
|
|
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
|
|
|
|
try:
|
|
|
|
data = json.loads(content)
|
|
|
|
except ValueError as e:
|
|
|
|
return {'error': 'Config file not readable', 'route': 'get_username'}
|
2020-12-02 08:22:17 +00:00
|
|
|
for user in data['users'][0]:
|
2020-12-04 19:05:35 +00:00
|
|
|
if 'userid' in data['users'][0][user] and int(data['users'][0][user]['userid']) == userid:
|
2020-06-30 15:02:02 +00:00
|
|
|
return user
|
|
|
|
return ''
|
|
|
|
|
2020-11-23 15:54:46 +00:00
|
|
|
def check_username_serial(username, serial):
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = f.read()
|
|
|
|
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
|
|
|
|
try:
|
|
|
|
data = json.loads(content)
|
|
|
|
except ValueError as e:
|
|
|
|
return {'error': 'Config file not readable', 'route': 'check_serial'}
|
2020-12-02 08:22:17 +00:00
|
|
|
if 'serial_enforce' not in data or data['serial_enforce'] == False:
|
2020-11-23 15:54:46 +00:00
|
|
|
return True
|
2020-12-02 08:22:17 +00:00
|
|
|
if 'serial' not in data['users'][0][username]:
|
|
|
|
data['users'][0][username]['serial'] = serial
|
2021-02-05 13:33:43 +00:00
|
|
|
if data:
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as outfile:
|
|
|
|
json.dump(data, outfile, indent=4)
|
2020-11-23 15:54:46 +00:00
|
|
|
return True
|
2020-12-02 08:22:17 +00:00
|
|
|
if data['users'][0][username]['serial'] == serial:
|
2020-11-23 15:54:46 +00:00
|
|
|
return True
|
2020-12-02 08:22:17 +00:00
|
|
|
if 'serial_error' not in data['users'][0][username]:
|
2020-12-11 20:40:39 +00:00
|
|
|
data['users'][0][username]['serial_error'] = 1
|
2020-11-23 15:54:46 +00:00
|
|
|
else:
|
2020-12-04 19:05:35 +00:00
|
|
|
data['users'][0][username]['serial_error'] = int(data['users'][0][username]['serial_error']) + 1
|
2021-02-05 13:33:43 +00:00
|
|
|
if data:
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as outfile:
|
|
|
|
json.dump(data, outfile, indent=4)
|
2021-02-05 14:28:56 +00:00
|
|
|
else:
|
|
|
|
LOG.debug("Empty data for check_username_serial")
|
2020-11-23 15:54:46 +00:00
|
|
|
return False
|
|
|
|
|
2020-06-19 13:49:07 +00:00
|
|
|
def set_global_param(key, value):
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = f.read()
|
|
|
|
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
|
|
|
|
try:
|
|
|
|
data = json.loads(content)
|
|
|
|
except ValueError as e:
|
|
|
|
return {'error': 'Config file not readable', 'route': 'global_param'}
|
|
|
|
data[key] = value
|
2021-02-05 13:33:43 +00:00
|
|
|
if data:
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as outfile:
|
|
|
|
json.dump(data, outfile, indent=4)
|
2021-02-05 14:28:56 +00:00
|
|
|
else:
|
|
|
|
LOG.debug("Empty data for set_global_param")
|
2020-06-19 13:49:07 +00:00
|
|
|
|
|
|
|
def modif_config_user(user, changes):
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = json.load(f)
|
2020-06-20 07:08:51 +00:00
|
|
|
content['users'][0][user].update(changes)
|
2021-02-05 14:28:56 +00:00
|
|
|
if content:
|
2021-02-05 13:33:43 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as f:
|
|
|
|
json.dump(content, f, indent=4)
|
2021-02-05 14:28:56 +00:00
|
|
|
else:
|
|
|
|
LOG.debug("Empty data for modif_config_user")
|
2020-06-19 13:49:07 +00:00
|
|
|
|
2020-10-19 14:49:27 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
def add_ss_user(port, key, userid=0, ip=''):
|
2020-06-20 07:08:51 +00:00
|
|
|
with open('/etc/shadowsocks-libev/manager.json') as f:
|
|
|
|
content = f.read()
|
|
|
|
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
|
|
|
|
data = json.loads(content)
|
|
|
|
if ip == '' and 'port_key' in data:
|
2020-08-21 17:50:34 +00:00
|
|
|
if port is None or port == '' or port == 0 or port == 'None':
|
2020-06-21 07:06:52 +00:00
|
|
|
port = int(max(data['port_key'], key=int)) + 1
|
2020-06-20 07:08:51 +00:00
|
|
|
data['port_key'][str(port)] = key
|
|
|
|
else:
|
2020-07-16 08:46:49 +00:00
|
|
|
if 'port_conf' not in data:
|
|
|
|
data['port_conf'] = {}
|
2020-06-20 07:08:51 +00:00
|
|
|
if 'port_key' in data:
|
|
|
|
for old_port in data['port_key']:
|
|
|
|
data['port_conf'][old_port] = {'key': data['port_key'][old_port]}
|
|
|
|
del data['port_key']
|
2020-08-21 17:50:34 +00:00
|
|
|
if port == '' or port == "None" or port is None or port == 0:
|
2020-06-21 07:06:52 +00:00
|
|
|
port = int(max(data['port_conf'], key=int)) + 1
|
2020-06-20 07:08:51 +00:00
|
|
|
if ip != '':
|
2020-06-26 09:18:59 +00:00
|
|
|
data['port_conf'][str(port)] = {'key': key, 'local_address': ip, 'userid': userid}
|
2020-06-20 07:08:51 +00:00
|
|
|
else:
|
2020-06-26 09:18:59 +00:00
|
|
|
data['port_conf'][str(port)] = {'key': key, 'userid': userid}
|
2020-06-20 07:08:51 +00:00
|
|
|
with open('/etc/shadowsocks-libev/manager.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
try:
|
|
|
|
ss_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
2020-06-21 07:06:52 +00:00
|
|
|
if ip != '':
|
2020-06-26 09:18:59 +00:00
|
|
|
data = 'add: {"server_port": ' + str(port) + ', "key": "' + key + '", "local_addr": "' + ip + '"}'
|
2020-06-21 07:06:52 +00:00
|
|
|
else:
|
2020-06-26 09:18:59 +00:00
|
|
|
data = 'add: {"server_port": ' + str(port) + ', "key": "' + key + '"}'
|
|
|
|
ss_socket.settimeout(1)
|
2020-06-20 07:08:51 +00:00
|
|
|
ss_socket.sendto(data.encode(), ("127.0.0.1", 8839))
|
|
|
|
except socket.timeout as err:
|
2020-06-21 07:06:52 +00:00
|
|
|
LOG.debug("Shadowsocks add timeout (" + str(err) + ")")
|
2020-06-20 07:08:51 +00:00
|
|
|
except socket.error as err:
|
2020-06-21 07:06:52 +00:00
|
|
|
LOG.debug("Shadowsocks add error (" + str(err) + ")")
|
2020-06-20 07:08:51 +00:00
|
|
|
return port
|
|
|
|
|
|
|
|
def remove_ss_user(port):
|
|
|
|
with open('/etc/shadowsocks-libev/manager.json') as f:
|
|
|
|
content = f.read()
|
|
|
|
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
|
|
|
|
data = json.loads(content)
|
|
|
|
if 'port_key' in data:
|
2020-06-26 09:18:59 +00:00
|
|
|
del data['port_key'][str(port)]
|
2020-06-20 07:08:51 +00:00
|
|
|
else:
|
2020-06-26 09:18:59 +00:00
|
|
|
del data['port_conf'][str(port)]
|
2020-06-20 07:08:51 +00:00
|
|
|
with open('/etc/shadowsocks-libev/manager.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
2020-06-21 07:06:52 +00:00
|
|
|
try:
|
|
|
|
ss_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
2020-06-26 09:18:59 +00:00
|
|
|
data = 'remove: {"server_port": ' + str(port) + '}'
|
|
|
|
ss_socket.settimeout(1)
|
2020-06-21 07:06:52 +00:00
|
|
|
ss_socket.sendto(data.encode(), ("127.0.0.1", 8839))
|
|
|
|
except socket.timeout as err:
|
|
|
|
LOG.debug("Shadowsocks remove timeout (" + str(err) + ")")
|
|
|
|
except socket.error as err:
|
|
|
|
LOG.debug("Shadowsocks remove error (" + str(err) + ")")
|
2020-06-20 07:08:51 +00:00
|
|
|
|
2020-11-15 18:56:56 +00:00
|
|
|
def v2ray_add_user(user, restart=1):
|
|
|
|
v2rayuuid = str(uuid.uuid1())
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
data = json.load(f)
|
|
|
|
exist = 0
|
|
|
|
for inbounds in data['inbounds']:
|
|
|
|
if inbounds['tag'] == 'omrin-tunnel':
|
|
|
|
inbounds['settings']['clients'].append({'id': v2rayuuid, 'level': 0, 'alterId': 0, 'email': user})
|
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5 and restart == 1:
|
|
|
|
os.system("systemctl -q restart v2ray")
|
2020-11-23 15:54:46 +00:00
|
|
|
return v2rayuuid
|
2020-11-15 18:56:56 +00:00
|
|
|
|
|
|
|
def v2ray_del_user(user, restart=1):
|
|
|
|
v2rayuuid = str(uuid.uuid1())
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
data = json.load(f)
|
|
|
|
for inbounds in data['inbounds']:
|
|
|
|
if inbounds['tag'] == 'omrin-tunnel':
|
|
|
|
for v2rayuser in inbounds['settings']['clients']:
|
|
|
|
if v2rayuser['email'] == user:
|
|
|
|
inbounds['settings']['clients'].remove(v2rayuser)
|
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5 and restart == 1:
|
|
|
|
os.system("systemctl -q restart v2ray")
|
|
|
|
|
|
|
|
def v2ray_add_outbound(tag,ip, restart=1):
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
data = json.load(f)
|
|
|
|
data['outbounds'].append({'protocol': 'freedom', 'settings': { 'userLevel': 0 }, 'tag': tag, 'sendThrough': ip})
|
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5 and restart == 1:
|
|
|
|
os.system("systemctl -q restart v2ray")
|
|
|
|
|
|
|
|
def v2ray_del_outbound(tag, restart=1):
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
data = json.load(f)
|
|
|
|
for outbounds in data['outbounds']:
|
|
|
|
if outbounds['tag'] == tag:
|
|
|
|
data['outbounds'].remove(outbounds)
|
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5 and restart == 1:
|
|
|
|
os.system("systemctl -q restart v2ray")
|
|
|
|
|
|
|
|
def v2ray_add_routing(tag, restart=1):
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
data = json.load(f)
|
|
|
|
data['routing']['rules'].append({'type': 'field', 'inboundTag': ( 'omrintunnel' ), 'outboundTag': tag})
|
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5 and restart == 1:
|
|
|
|
os.system("systemctl -q restart v2ray")
|
|
|
|
|
|
|
|
def v2ray_del_routing(tag, restart=1):
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
data = json.load(f)
|
|
|
|
for rules in data['routing']['rules']:
|
|
|
|
if rules['outboundTag'] == tag:
|
|
|
|
data['routing']['rules'].remove(rules)
|
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5 and restart == 1:
|
|
|
|
os.system("systemctl -q restart v2ray")
|
|
|
|
|
2020-06-19 13:49:07 +00:00
|
|
|
|
|
|
|
def add_gre_tunnels():
|
|
|
|
nbip = 0
|
|
|
|
allips = []
|
|
|
|
for intf in netifaces.interfaces():
|
|
|
|
addrs = netifaces.ifaddresses(intf)
|
|
|
|
try:
|
|
|
|
ipv4_addr_list = addrs[netifaces.AF_INET]
|
|
|
|
for ip_info in ipv4_addr_list:
|
|
|
|
addr = ip_info['addr']
|
|
|
|
if not IPAddress(addr).is_private() and not IPAddress(addr).is_reserved():
|
|
|
|
allips.append(addr)
|
|
|
|
nbip = nbip + 1
|
|
|
|
except Exception as exception:
|
|
|
|
pass
|
|
|
|
|
|
|
|
if nbip > 1:
|
|
|
|
nbgre = 0
|
|
|
|
nbip = 0
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/snat', 'rb'))).hexdigest()
|
|
|
|
for intf in netifaces.interfaces():
|
|
|
|
addrs = netifaces.ifaddresses(intf)
|
|
|
|
try:
|
|
|
|
ipv4_addr_list = addrs[netifaces.AF_INET]
|
|
|
|
for ip_info in ipv4_addr_list:
|
|
|
|
addr = ip_info['addr']
|
|
|
|
if not IPAddress(addr).is_private() and not IPAddress(addr).is_reserved():
|
|
|
|
netmask = ip_info['netmask']
|
|
|
|
ip = IPNetwork('10.255.249.0/24')
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = json.load(f)
|
|
|
|
for user in content['users'][0]:
|
|
|
|
if user != "admin":
|
|
|
|
subnets = ip.subnet(30)
|
|
|
|
network = list(subnets)[nbgre]
|
|
|
|
nbgre = nbgre + 1
|
|
|
|
userid = 0
|
|
|
|
username = user
|
2020-09-20 06:31:04 +00:00
|
|
|
iface = intf.split(':')[0]
|
2020-06-19 13:49:07 +00:00
|
|
|
if 'userid' in content['users'][0][user]:
|
|
|
|
userid = content['users'][0][user]['userid']
|
|
|
|
if 'username' in content['users'][0][user]:
|
|
|
|
username = content['users'][0][user]['username']
|
2020-06-21 07:06:52 +00:00
|
|
|
gre_intf = 'gre-user' + str(userid) + '-ip' + str(nbip)
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/intf/' + gre_intf, 'w') as n:
|
2020-06-19 13:49:07 +00:00
|
|
|
n.write('INTF=' + str(intf.split(':')[0]) + "\n")
|
|
|
|
n.write('INTFADDR=' + str(addr) + "\n")
|
|
|
|
n.write('INTFNETMASK=' + str(netmask) + "\n")
|
|
|
|
n.write('NETWORK=' + str(network) + "\n")
|
|
|
|
n.write('LOCALIP=' + str(list(network)[1]) + "\n")
|
|
|
|
n.write('REMOTEIP=' + str(list(network)[2]) + "\n")
|
|
|
|
n.write('NETMASK=255.255.255.252' + "\n")
|
|
|
|
n.write('BROADCASTIP=' + str(network.broadcast) + "\n")
|
|
|
|
n.write('USERNAME=' + str(username) + "\n")
|
|
|
|
n.write('USERID=' + str(userid) + "\n")
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-06-20 07:08:51 +00:00
|
|
|
with open('/etc/shorewall/snat', 'r') as h, open(tmpfile, 'a+') as n:
|
|
|
|
for line in h:
|
2020-06-26 09:18:59 +00:00
|
|
|
if not '# OMR GRE for public IP ' + str(addr) + ' for user ' + str(user) in line:
|
2020-06-19 13:49:07 +00:00
|
|
|
n.write(line)
|
2020-09-20 06:31:04 +00:00
|
|
|
n.write('SNAT(' + str(addr) + ') ' + str(network) + ' ' + str(iface) + ' # OMR GRE for public IP ' + str(addr) + ' for user ' + str(user) + "\n")
|
2020-06-19 13:49:07 +00:00
|
|
|
os.close(fd)
|
|
|
|
move(tmpfile, '/etc/shorewall/snat')
|
2020-07-25 14:16:55 +00:00
|
|
|
#fd, tmpfile = mkstemp()
|
|
|
|
#with open('/etc/shorewall/interfaces', 'r') as h, open(tmpfile, 'a+') as n:
|
|
|
|
# for line in h:
|
|
|
|
# if not 'gre-user' + str(userid) + '-ip' + str(nbip) in line:
|
|
|
|
# n.write(line)
|
|
|
|
# n.write('vpn gre-user' + str(userid) + '-ip' + str(nbip) + ' nosmurfs,tcpflags' + "\n")
|
|
|
|
#os.close(fd)
|
|
|
|
#move(tmpfile, '/etc/shorewall/interfaces')
|
2020-09-20 06:31:04 +00:00
|
|
|
if str(iface) != IFACE:
|
|
|
|
fd, tmpfile = mkstemp()
|
|
|
|
with open('/etc/shorewall/interfaces', 'r') as h, open(tmpfile, 'a+') as n:
|
|
|
|
for line in h:
|
|
|
|
if not str(iface) in line:
|
|
|
|
n.write(line)
|
|
|
|
n.write('net ' + str(iface) + ' dhcp,nosmurfs,tcpflags,routefilter,sourceroute=0' + "\n")
|
|
|
|
os.close(fd)
|
|
|
|
move(tmpfile, '/etc/shorewall/interfaces')
|
2020-07-03 14:27:09 +00:00
|
|
|
user_gre_tunnels = {}
|
2020-06-23 18:26:08 +00:00
|
|
|
if 'gre_tunnels' in content['users'][0][user]:
|
|
|
|
user_gre_tunnels = content['users'][0][user]['gre_tunnels']
|
2020-06-21 07:06:52 +00:00
|
|
|
if not gre_intf in user_gre_tunnels or user_gre_tunnels[gre_intf]['public_ip'] != str(addr):
|
2020-06-20 07:08:51 +00:00
|
|
|
with open('/etc/shadowsocks-libev/manager.json') as g:
|
|
|
|
contentss = g.read()
|
|
|
|
contentss = re.sub(",\s*}", "}", contentss) # pylint: disable=W1401
|
|
|
|
datass = json.loads(contentss)
|
|
|
|
ss_port = content['users'][0][user]['shadowsocks_port']
|
|
|
|
if 'port_key' in datass:
|
|
|
|
ss_key = datass['port_key'][str(ss_port)]
|
|
|
|
if 'port_conf' in datass:
|
|
|
|
ss_key = datass['port_conf'][str(ss_port)]['key']
|
2020-06-23 18:26:08 +00:00
|
|
|
if gre_intf not in user_gre_tunnels:
|
|
|
|
user_gre_tunnels[gre_intf] = {}
|
2020-07-03 14:27:09 +00:00
|
|
|
user_gre_tunnels[gre_intf] = {'shadowsocks_port': str(add_ss_user('', ss_key, userid, str(addr))), 'local_ip': str(list(network)[1]), 'remote_ip': str(list(network)[2]), 'public_ip': str(addr)}
|
2020-06-23 18:26:08 +00:00
|
|
|
#user_gre_tunnels[gre_intf] = {'local_ip': str(list(network)[1]), 'remote_ip': str(list(network)[2]), 'public_ip': str(addr)}
|
2020-07-03 14:27:09 +00:00
|
|
|
modif_config_user(user, {'gre_tunnels': user_gre_tunnels})
|
2020-06-19 13:49:07 +00:00
|
|
|
nbip = nbip + 1
|
|
|
|
except Exception as exception:
|
|
|
|
pass
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/snat', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5:
|
|
|
|
os.system("systemctl -q reload shorewall")
|
2021-02-01 14:44:26 +00:00
|
|
|
os.system("systemctl -q restart shadowsocks-libev-manager@manager")
|
2020-07-03 14:27:09 +00:00
|
|
|
set_global_param('allips', allips)
|
2020-06-19 13:49:07 +00:00
|
|
|
|
|
|
|
add_gre_tunnels()
|
|
|
|
|
2019-12-26 19:25:11 +00:00
|
|
|
|
2020-01-09 08:48:02 +00:00
|
|
|
def add_glorytun_tcp(userid):
|
|
|
|
port = '650{:02d}'.format(userid)
|
2020-01-25 20:53:58 +00:00
|
|
|
ip = IPNetwork('10.255.255.0/24')
|
|
|
|
subnets = ip.subnet(30)
|
|
|
|
network = list(subnets)[userid]
|
2020-03-05 14:02:20 +00:00
|
|
|
with open('/etc/glorytun-tcp/tun0', 'r') as f, \
|
|
|
|
open('/etc/glorytun-tcp/tun' + str(userid), 'w') as n:
|
2020-01-09 08:48:02 +00:00
|
|
|
for line in f:
|
|
|
|
if 'PORT' in line:
|
|
|
|
n.write('PORT=' + port + "\n")
|
|
|
|
elif 'DEV' in line:
|
|
|
|
n.write('DEV=tun' + str(userid) + "\n")
|
2020-03-05 14:02:20 +00:00
|
|
|
elif (not 'LOCALIP' in line
|
|
|
|
and not 'REMOTEIP' in line
|
|
|
|
and not 'BROADCASTIP' in line
|
|
|
|
and not line == "\n"):
|
2020-01-09 08:48:02 +00:00
|
|
|
n.write(line)
|
2020-01-27 19:15:30 +00:00
|
|
|
n.write("\n" + 'LOCALIP=' + str(list(network)[1]) + "\n")
|
|
|
|
n.write('REMOTEIP=' + str(list(network)[2]) + "\n")
|
|
|
|
n.write('BROADCASTIP=' + str(network.broadcast) + "\n")
|
2020-01-09 08:48:02 +00:00
|
|
|
glorytun_tcp_key = secrets.token_hex(32)
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/glorytun-tcp/tun' + str(userid) + '.key', 'w') as f:
|
2020-01-25 20:53:58 +00:00
|
|
|
f.write(glorytun_tcp_key.upper())
|
2020-03-03 12:49:23 +00:00
|
|
|
os.system("systemctl -q enable glorytun-tcp@tun" + str(userid))
|
2020-01-09 08:48:02 +00:00
|
|
|
os.system("systemctl -q restart glorytun-tcp@tun" + str(userid))
|
|
|
|
|
2020-02-14 20:46:05 +00:00
|
|
|
def remove_glorytun_tcp(userid):
|
2020-03-03 12:49:23 +00:00
|
|
|
os.system("systemctl -q disable glorytun-tcp@tun" + str(userid))
|
2020-02-14 20:46:05 +00:00
|
|
|
os.system("systemctl -q stop glorytun-tcp@tun" + str(userid))
|
|
|
|
os.remove('/etc/glorytun-tcp/tun' + str(userid) + '.key')
|
|
|
|
os.remove('/etc/glorytun-tcp/tun' + str(userid))
|
|
|
|
|
2020-01-09 08:48:02 +00:00
|
|
|
def add_glorytun_udp(userid):
|
|
|
|
port = '650{:02d}'.format(userid)
|
2020-01-25 20:53:58 +00:00
|
|
|
ip = IPNetwork('10.255.254.0/24')
|
|
|
|
subnets = ip.subnet(30)
|
|
|
|
network = list(subnets)[userid]
|
2020-03-05 14:02:20 +00:00
|
|
|
with open('/etc/glorytun-udp/tun0', 'r') as f, \
|
|
|
|
open('/etc/glorytun-udp/tun' + str(userid), 'w') as n:
|
2020-01-09 08:48:02 +00:00
|
|
|
for line in f:
|
|
|
|
if 'BIND_PORT' in line:
|
|
|
|
n.write('BIND_PORT=' + port + "\n")
|
|
|
|
elif 'DEV' in line:
|
|
|
|
n.write('DEV=tun' + str(userid) + "\n")
|
2020-03-05 14:02:20 +00:00
|
|
|
elif (not 'LOCALIP' in line
|
|
|
|
and not 'REMOTEIP' in line
|
|
|
|
and not 'BROADCASTIP' in line
|
|
|
|
and not line == "\n"):
|
2020-01-09 08:48:02 +00:00
|
|
|
n.write(line)
|
2020-01-27 19:15:30 +00:00
|
|
|
n.write("\n" + 'LOCALIP=' + str(list(network)[1]) + "\n")
|
|
|
|
n.write('REMOTEIP=' + str(list(network)[2]) + "\n")
|
|
|
|
n.write('BROADCASTIP=' + str(network.broadcast) + "\n")
|
2020-03-05 14:02:20 +00:00
|
|
|
with open('/etc/glorytun-tcp/tun' + str(userid) + '.key', 'r') as f, \
|
|
|
|
open('/etc/glorytun-udp/tun' + str(userid) + '.key', 'w') as n:
|
2020-01-25 20:53:58 +00:00
|
|
|
for line in f:
|
|
|
|
n.write(line)
|
2020-03-03 12:49:23 +00:00
|
|
|
os.system("systemctl -q enable glorytun-udp@tun" + str(userid))
|
2020-01-09 08:48:02 +00:00
|
|
|
os.system("systemctl -q restart glorytun-udp@tun" + str(userid))
|
|
|
|
|
2020-02-14 20:46:05 +00:00
|
|
|
def remove_glorytun_udp(userid):
|
2020-03-03 12:49:23 +00:00
|
|
|
os.system("systemctl -q disable glorytun-udp@tun" + str(userid))
|
2020-02-14 20:46:05 +00:00
|
|
|
os.system("systemctl -q stop glorytun-udp@tun" + str(userid))
|
|
|
|
os.remove('/etc/glorytun-udp/tun' + str(userid) + '.key')
|
|
|
|
os.remove('/etc/glorytun-udp/tun' + str(userid))
|
|
|
|
|
|
|
|
|
2020-01-12 17:41:34 +00:00
|
|
|
def add_dsvpn(userid):
|
|
|
|
port = '654{:02d}'.format(userid)
|
2020-01-25 20:53:58 +00:00
|
|
|
ip = IPNetwork('10.255.251.0/24')
|
|
|
|
subnets = ip.subnet(30)
|
|
|
|
network = list(subnets)[userid]
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/dsvpn/dsvpn0', 'r') as f, open('/etc/dsvpn/dsvpn' + str(userid), 'w') as n:
|
2020-01-12 17:41:34 +00:00
|
|
|
for line in f:
|
|
|
|
if 'PORT' in line:
|
|
|
|
n.write('PORT=' + port + "\n")
|
|
|
|
elif 'DEV' in line:
|
|
|
|
n.write('DEV=dsvpn' + str(userid) + "\n")
|
|
|
|
elif 'LOCALTUNIP' in line:
|
2020-01-25 20:53:58 +00:00
|
|
|
n.write('LOCALTUNIP=' + str(list(network)[1]) + "\n")
|
|
|
|
elif 'REMOTETUNIP' in line:
|
|
|
|
n.write('REMOTETUNIP=' + str(list(network)[2]) + "\n")
|
2020-01-12 17:41:34 +00:00
|
|
|
else:
|
|
|
|
n.write(line)
|
|
|
|
dsvpn_key = secrets.token_hex(32)
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/dsvpn/dsvpn' + str(userid) + '.key', 'w') as f:
|
2020-01-25 20:53:58 +00:00
|
|
|
f.write(dsvpn_key.upper())
|
2020-03-03 12:49:23 +00:00
|
|
|
os.system("systemctl -q enable dsvpn@dsvpn" + str(userid))
|
2020-01-12 17:41:34 +00:00
|
|
|
os.system("systemctl -q restart dsvpn@dsvpn" + str(userid))
|
|
|
|
|
2020-02-14 20:46:05 +00:00
|
|
|
def remove_dsvpn(userid):
|
2020-03-03 12:49:23 +00:00
|
|
|
os.system("systemctl -q disable dsvpn@dsvpn" + str(userid))
|
2020-02-14 20:46:05 +00:00
|
|
|
os.system("systemctl -q stop dsvpn@dsvpn" + str(userid))
|
|
|
|
os.remove('/etc/dsvpn/dsvpn' + str(userid))
|
|
|
|
os.remove('/etc/dsvpn/dsvpn' + str(userid) + '.key')
|
|
|
|
|
|
|
|
|
2018-11-08 12:55:20 +00:00
|
|
|
def ordered(obj):
|
|
|
|
if isinstance(obj, dict):
|
|
|
|
return sorted((k, ordered(v)) for k, v in obj.items())
|
|
|
|
if isinstance(obj, list):
|
|
|
|
return sorted(ordered(x) for x in obj)
|
|
|
|
else:
|
|
|
|
return obj
|
|
|
|
|
2020-10-20 18:01:10 +00:00
|
|
|
def v2ray_add_port(user, port, proto, name, destip, destport):
|
2020-10-19 14:49:27 +00:00
|
|
|
userid = user.userid
|
|
|
|
if userid is None:
|
|
|
|
userid = 0
|
|
|
|
tag = user.username + '_redir_' + proto + '_' + str(port)
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
data = json.load(f)
|
|
|
|
exist = 0
|
|
|
|
for inbounds in data['inbounds']:
|
|
|
|
LOG.debug(inbounds)
|
|
|
|
if inbounds['tag'] == tag:
|
|
|
|
exist = 1
|
|
|
|
if exist == 0:
|
2020-10-20 18:01:10 +00:00
|
|
|
inbounds = {'tag': user.username + '_redir_' + proto + '_' + str(port), 'port': int(port), 'protocol': 'dokodemo-door', 'settings': {'network': proto, 'port': int(destport), 'address': destip}}
|
2020-10-19 14:49:27 +00:00
|
|
|
data['inbounds'].append(inbounds)
|
|
|
|
routing = {'type': 'field','inboundTag': [user.username + '_redir_' + proto + '_' + str(port)], 'outboundTag': 'OMRLan'}
|
|
|
|
data['routing']['rules'].append(routing)
|
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5:
|
|
|
|
os.system("systemctl -q restart v2ray")
|
|
|
|
|
|
|
|
|
|
|
|
def v2ray_del_port(username, port, proto, name):
|
|
|
|
userid = user.userid
|
|
|
|
if userid is None:
|
|
|
|
userid = 0
|
|
|
|
tag = user.username + '_redir_' + proto + '_' + str(port)
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
data = json.load(f)
|
|
|
|
exist = 0
|
2020-11-02 19:39:18 +00:00
|
|
|
for inbounds in data['inbounds']:
|
|
|
|
if inbounds['tag'] == tag:
|
|
|
|
data['inbounds'].remove(inbounds)
|
2020-10-19 14:49:27 +00:00
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as f:
|
|
|
|
json.dump(data, f, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5:
|
|
|
|
os.system("systemctl -q restart v2ray")
|
2019-06-02 21:11:58 +00:00
|
|
|
|
2020-09-29 13:41:48 +00:00
|
|
|
def shorewall_add_port(user, port, proto, name, fwtype='ACCEPT', source_dip='', dest_ip='', vpn='default'):
|
2020-01-20 20:05:40 +00:00
|
|
|
userid = user.userid
|
2020-03-03 12:49:23 +00:00
|
|
|
if userid is None:
|
2020-01-20 20:05:40 +00:00
|
|
|
userid = 0
|
2019-06-02 21:11:58 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/rules', 'rb'))).hexdigest()
|
2019-04-18 19:09:26 +00:00
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-05 14:02:20 +00:00
|
|
|
with open('/etc/shorewall/rules', 'r') as f, \
|
|
|
|
open(tmpfile, 'a+') as n:
|
2019-04-18 19:09:26 +00:00
|
|
|
for line in f:
|
2020-06-19 13:49:07 +00:00
|
|
|
if source_dip == '' and dest_ip == '':
|
2020-06-15 13:53:03 +00:00
|
|
|
if (fwtype == 'ACCEPT' and not port + ' # OMR open ' + name + ' port ' + proto in line and not port + ' # OMR ' + user.username + ' open ' + name + ' port ' + proto in line):
|
|
|
|
n.write(line)
|
|
|
|
elif fwtype == 'DNAT' and not port + ' # OMR redirect ' + name + ' port ' + proto in line and not port + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto in line:
|
|
|
|
n.write(line)
|
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
comment = ''
|
|
|
|
if source_dip == '':
|
|
|
|
comment = ' to ' + source_dip
|
|
|
|
if dest_ip == '':
|
|
|
|
comment = comment + ' from ' + dest_ip
|
|
|
|
if (fwtype == 'ACCEPT' and not '# OMR ' + user.username + ' open ' + name + ' port ' + proto + comment in line):
|
2020-06-15 13:53:03 +00:00
|
|
|
n.write(line)
|
2020-06-19 13:49:07 +00:00
|
|
|
elif fwtype == 'DNAT' and not '# OMR ' + user.username + ' redirect ' + name + ' port ' + proto + comment in line:
|
2020-06-15 13:53:03 +00:00
|
|
|
n.write(line)
|
2020-06-19 13:49:07 +00:00
|
|
|
if source_dip == '' and dest_ip == '':
|
2020-06-15 13:53:03 +00:00
|
|
|
if fwtype == 'ACCEPT':
|
|
|
|
n.write('ACCEPT net $FW ' + proto + ' ' + port + ' # OMR ' + user.username + ' open ' + name + ' port ' + proto + "\n")
|
|
|
|
elif fwtype == 'DNAT' and userid == 0:
|
|
|
|
n.write('DNAT net vpn:$OMR_ADDR ' + proto + ' ' + port + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + "\n")
|
|
|
|
elif fwtype == 'DNAT' and userid != 0:
|
|
|
|
n.write('DNAT net vpn:$OMR_ADDR_USER' + str(userid) + ' ' + proto + ' ' + port + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + "\n")
|
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
net = 'net'
|
|
|
|
comment = ''
|
|
|
|
if source_dip != '':
|
|
|
|
comment = ' to ' + source_dip
|
|
|
|
if dest_ip != '':
|
|
|
|
comment = comment + ' from ' + dest_ip
|
|
|
|
net = 'net:' + dest_ip
|
2020-06-15 13:53:03 +00:00
|
|
|
if fwtype == 'ACCEPT':
|
2020-06-19 13:49:07 +00:00
|
|
|
n.write('ACCEPT ' + net + ' $FW ' + proto + ' ' + port + ' - ' + source_dip + ' # OMR ' + user.username + ' open ' + name + ' port ' + proto + comment + "\n")
|
2020-09-29 13:41:48 +00:00
|
|
|
elif fwtype == 'DNAT' and vpn != 'default':
|
2020-12-29 19:13:29 +00:00
|
|
|
#n.write('DNAT ' + net + ' vpn:' + vpn + ' ' + proto + ' ' + port + ' - ' + source_dip + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + comment + "\n")
|
|
|
|
n.write('DNAT ' + net + ' vpn:$OMR_ADDR' + ' ' + proto + ' ' + port + ' - ' + source_dip + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + comment + "\n")
|
2020-06-15 13:53:03 +00:00
|
|
|
elif fwtype == 'DNAT' and userid == 0:
|
2020-06-19 13:49:07 +00:00
|
|
|
n.write('DNAT ' + net + ' vpn:$OMR_ADDR ' + proto + ' ' + port + ' - ' + source_dip + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + comment + "\n")
|
2020-06-15 13:53:03 +00:00
|
|
|
elif fwtype == 'DNAT' and userid != 0:
|
2020-06-19 13:49:07 +00:00
|
|
|
n.write('DNAT ' + net + ' vpn:$OMR_ADDR_USER' + str(userid) + ' ' + proto + ' ' + port + ' - ' + source_dip + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + comment + "\n")
|
2019-09-29 18:54:54 +00:00
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall/rules')
|
2019-09-29 18:54:54 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/rules', 'rb'))).hexdigest()
|
2020-03-03 12:49:23 +00:00
|
|
|
if initial_md5 != final_md5:
|
2019-09-29 18:54:54 +00:00
|
|
|
os.system("systemctl -q reload shorewall")
|
|
|
|
|
2020-06-19 13:49:07 +00:00
|
|
|
def shorewall_del_port(username, port, proto, name, fwtype='ACCEPT', source_dip='', dest_ip=''):
|
2019-09-29 18:54:54 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/rules', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall/rules', 'r') as f, open(tmpfile, 'a+') as n:
|
2019-09-29 18:54:54 +00:00
|
|
|
for line in f:
|
2020-07-25 14:16:55 +00:00
|
|
|
if source_dip == '' and dest_ip == '':
|
2020-06-15 13:53:03 +00:00
|
|
|
if fwtype == 'ACCEPT' and not port + ' # OMR open ' + name + ' port ' + proto in line and not port + ' # OMR ' + username + ' open ' + name + ' port ' + proto in line:
|
|
|
|
n.write(line)
|
|
|
|
elif fwtype == 'DNAT' and not port + ' # OMR redirect ' + name + ' port ' + proto in line and not port + ' # OMR ' + username + ' redirect ' + name + ' port ' + proto in line:
|
|
|
|
n.write(line)
|
|
|
|
else:
|
2020-11-23 15:54:46 +00:00
|
|
|
comment = ''
|
2020-07-25 14:16:55 +00:00
|
|
|
if source_dip != '':
|
|
|
|
comment = ' to ' + source_dip
|
|
|
|
if dest_ip != '':
|
|
|
|
comment = comment + ' from ' + dest_ip
|
|
|
|
if fwtype == 'ACCEPT' and not '# OMR ' + username + ' open ' + name + ' port ' + proto + comment in line:
|
2020-06-15 13:53:03 +00:00
|
|
|
n.write(line)
|
2020-07-25 14:16:55 +00:00
|
|
|
elif fwtype == 'DNAT' and not '# OMR ' + username + ' redirect ' + name + ' port ' + proto + comment in line:
|
2020-06-15 13:53:03 +00:00
|
|
|
n.write(line)
|
2019-04-18 19:09:26 +00:00
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall/rules')
|
2019-06-02 21:11:58 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/rules', 'rb'))).hexdigest()
|
2020-03-03 12:49:23 +00:00
|
|
|
if initial_md5 != final_md5:
|
2019-06-02 21:11:58 +00:00
|
|
|
os.system("systemctl -q reload shorewall")
|
2019-04-18 19:09:26 +00:00
|
|
|
|
2020-06-19 13:49:07 +00:00
|
|
|
def shorewall6_add_port(user, port, proto, name, fwtype='ACCEPT', source_dip='', dest_ip=''):
|
2020-01-20 20:05:40 +00:00
|
|
|
userid = user.userid
|
2020-03-05 14:02:20 +00:00
|
|
|
if userid is None:
|
2020-01-20 20:05:40 +00:00
|
|
|
userid = 0
|
2020-01-09 08:48:02 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall6/rules', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall6/rules', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-09 08:48:02 +00:00
|
|
|
for line in f:
|
2020-06-15 13:53:03 +00:00
|
|
|
if source_dip == '':
|
|
|
|
if fwtype == 'ACCEPT' and not port + ' # OMR open ' + name + ' port ' + proto in line and not port + ' # OMR ' + user.username + ' open ' + name + ' port ' + proto in line:
|
|
|
|
n.write(line)
|
|
|
|
elif fwtype == 'DNAT' and not port + ' # OMR redirect ' + name + ' port ' + proto in line and not port + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto in line:
|
|
|
|
n.write(line)
|
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
comment = ''
|
|
|
|
if source_dip == '':
|
|
|
|
comment = ' to ' + source_dip
|
|
|
|
if dest_ip == '':
|
|
|
|
comment = comment + ' from ' + dest_ip
|
|
|
|
if fwtype == 'ACCEPT' and not port + '# OMR ' + user.username + ' open ' + name + ' port ' + proto + comment in line:
|
2020-06-15 13:53:03 +00:00
|
|
|
n.write(line)
|
2020-06-19 13:49:07 +00:00
|
|
|
elif fwtype == 'DNAT' and not port + '# OMR ' + user.username + ' redirect ' + name + ' port ' + proto + comment in line:
|
2020-06-15 13:53:03 +00:00
|
|
|
n.write(line)
|
|
|
|
if source_dip == '':
|
|
|
|
if fwtype == 'ACCEPT':
|
|
|
|
n.write('ACCEPT net $FW ' + proto + ' ' + port + ' # OMR ' + user.username + ' open ' + name + ' port ' + proto + "\n")
|
|
|
|
elif fwtype == 'DNAT' and userid == 0:
|
|
|
|
n.write('DNAT net vpn:$OMR_ADDR ' + proto + ' ' + port + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + "\n")
|
|
|
|
elif fwtype == 'DNAT' and userid != 0:
|
|
|
|
n.write('DNAT net vpn:$OMR_ADDR_USER' + str(userid) + ' ' + proto + ' ' + port + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + "\n")
|
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
net = 'net'
|
|
|
|
comment = ''
|
|
|
|
if source_dip == '':
|
|
|
|
comment = ' to ' + source_dip
|
|
|
|
if dest_ip == '':
|
|
|
|
comment = comment + ' from ' + dest_ip
|
|
|
|
net = 'net:' + dest_ip
|
2020-06-15 13:53:03 +00:00
|
|
|
if fwtype == 'ACCEPT':
|
2020-06-19 13:49:07 +00:00
|
|
|
n.write('ACCEPT ' + net + ' $FW ' + proto + ' ' + port + ' - ' + source_dip + ' # OMR ' + user.username + ' open ' + name + ' port ' + proto + comment+ "\n")
|
2020-06-15 13:53:03 +00:00
|
|
|
elif fwtype == 'DNAT' and userid == 0:
|
2020-06-19 13:49:07 +00:00
|
|
|
n.write('DNAT ' + net + ' vpn:$OMR_ADDR ' + proto + ' ' + port + ' - ' + source_dip + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + comment + "\n")
|
2020-06-15 13:53:03 +00:00
|
|
|
elif fwtype == 'DNAT' and userid != 0:
|
2020-06-19 13:49:07 +00:00
|
|
|
n.write('DNAT ' + net + ' vpn:$OMR_ADDR_USER' + str(userid) + ' ' + proto + ' ' + port + ' - ' + source_dip + ' # OMR ' + user.username + ' redirect ' + name + ' port ' + proto + comment + "\n")
|
2020-01-09 08:48:02 +00:00
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall6/rules')
|
2020-01-09 08:48:02 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall6/rules', 'rb'))).hexdigest()
|
2020-03-03 12:49:23 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-09 08:48:02 +00:00
|
|
|
os.system("systemctl -q reload shorewall6")
|
|
|
|
|
2020-06-19 13:49:07 +00:00
|
|
|
def shorewall6_del_port(username, port, proto, name, fwtype='ACCEPT', source_dip='', dest_ip=''):
|
2020-01-09 08:48:02 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall6/rules', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall6/rules', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-09 08:48:02 +00:00
|
|
|
for line in f:
|
2020-06-15 13:53:03 +00:00
|
|
|
if source_dip == '':
|
|
|
|
if fwtype == 'ACCEPT' and not port + ' # OMR open ' + name + ' port ' + proto in line and not port + ' # OMR ' + username + ' open ' + name + ' port ' + proto in line:
|
|
|
|
n.write(line)
|
|
|
|
elif fwtype == 'DNAT' and not port + ' # OMR redirect ' + name + ' port ' + proto in line and not port + ' # OMR ' + username + ' redirect ' + name + ' port ' + proto in line:
|
|
|
|
n.write(line)
|
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
if fwtype == 'ACCEPT' and not '# OMR ' + username + ' open ' + name + ' port ' + proto + ' to ' + source_dip in line:
|
2020-06-15 13:53:03 +00:00
|
|
|
n.write(line)
|
2020-06-19 13:49:07 +00:00
|
|
|
elif fwtype == 'DNAT' and not '# OMR ' + username + ' redirect ' + name + ' port ' + proto + ' to ' + source_dip in line:
|
2020-06-15 13:53:03 +00:00
|
|
|
n.write(line)
|
2020-01-09 08:48:02 +00:00
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall6/rules')
|
2020-01-09 08:48:02 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall6/rules', 'rb'))).hexdigest()
|
2020-03-03 12:49:23 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-09 08:48:02 +00:00
|
|
|
os.system("systemctl -q reload shorewall6")
|
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
def set_lastchange(sync=0):
|
2019-08-12 14:43:05 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = f.read()
|
2020-03-03 13:06:18 +00:00
|
|
|
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
|
2019-08-12 14:43:05 +00:00
|
|
|
try:
|
|
|
|
data = json.loads(content)
|
|
|
|
except ValueError as e:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'error': 'Config file not readable', 'route': 'lastchange'}
|
2019-12-26 19:25:11 +00:00
|
|
|
data["lastchange"] = time.time() + sync
|
2021-02-05 13:33:43 +00:00
|
|
|
if data:
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as outfile:
|
|
|
|
json.dump(data, outfile, indent=4)
|
2021-02-05 14:28:56 +00:00
|
|
|
else:
|
|
|
|
LOG.debug("Empty data for set_last_change")
|
2019-04-18 19:09:26 +00:00
|
|
|
|
2019-12-26 19:25:11 +00:00
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
omr_config_data = json.load(f)
|
2020-07-03 14:27:09 +00:00
|
|
|
if 'debug' in omr_config_data and omr_config_data['debug']:
|
|
|
|
LOG.setLevel(logging.DEBUG)
|
2019-04-18 19:09:26 +00:00
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
fake_users_db = omr_config_data['users'][0]
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2019-11-16 19:49:26 +00:00
|
|
|
def verify_password(plain_password, user_password):
|
|
|
|
if plain_password == user_password:
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug("password true")
|
2019-11-02 17:10:10 +00:00
|
|
|
return True
|
|
|
|
return False
|
2018-11-08 17:05:34 +00:00
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
def get_password_hash(password):
|
|
|
|
return password
|
|
|
|
|
|
|
|
def get_user(db, username: str):
|
|
|
|
if username in db:
|
|
|
|
user_dict = db[username]
|
|
|
|
return UserInDB(**user_dict)
|
|
|
|
|
|
|
|
def authenticate_user(fake_db, username: str, password: str):
|
|
|
|
user = get_user(fake_db, username)
|
|
|
|
if not user:
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug("user doesn't exist")
|
2019-11-02 17:10:10 +00:00
|
|
|
return False
|
2019-11-16 19:49:26 +00:00
|
|
|
if not verify_password(password, user.user_password):
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug("wrong password")
|
2019-11-02 17:10:10 +00:00
|
|
|
return False
|
|
|
|
return user
|
|
|
|
|
|
|
|
class Token(BaseModel):
|
2020-03-03 12:49:23 +00:00
|
|
|
access_token: str = None
|
|
|
|
token_type: str = None
|
2019-11-02 17:10:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TokenData(BaseModel):
|
|
|
|
username: str = None
|
|
|
|
|
|
|
|
class User(BaseModel):
|
|
|
|
username: str
|
2019-12-26 19:25:11 +00:00
|
|
|
vpn: str = None
|
|
|
|
vpn_port: int = None
|
|
|
|
vpn_client_ip: str = None
|
2020-01-13 20:47:29 +00:00
|
|
|
permissions: str = 'rw'
|
2019-11-13 07:39:00 +00:00
|
|
|
shadowsocks_port: int = None
|
2020-01-09 08:48:02 +00:00
|
|
|
disabled: bool = 'false'
|
|
|
|
userid: int = None
|
2019-11-02 17:10:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
class UserInDB(User):
|
2019-11-16 19:49:26 +00:00
|
|
|
user_password: str
|
2019-11-02 17:10:10 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
# Add support for auth before seeing doc
|
|
|
|
class OAuth2PasswordBearerCookie(OAuth2):
|
|
|
|
def __init__(
|
2020-03-03 13:06:18 +00:00
|
|
|
self,
|
|
|
|
tokenUrl: str,
|
|
|
|
scheme_name: str = None,
|
|
|
|
scopes: dict = None,
|
|
|
|
auto_error: bool = True,
|
2020-03-03 12:49:23 +00:00
|
|
|
):
|
|
|
|
if not scopes:
|
|
|
|
scopes = {}
|
|
|
|
flows = OAuthFlowsModel(password={"tokenUrl": tokenUrl, "scopes": scopes})
|
|
|
|
super().__init__(flows=flows, scheme_name=scheme_name, auto_error=auto_error)
|
|
|
|
|
|
|
|
async def __call__(self, request: Request) -> Optional[str]:
|
|
|
|
header_authorization: str = request.headers.get("Authorization")
|
|
|
|
cookie_authorization: str = request.cookies.get("Authorization")
|
|
|
|
|
|
|
|
header_scheme, header_param = get_authorization_scheme_param(
|
|
|
|
header_authorization
|
|
|
|
)
|
|
|
|
cookie_scheme, cookie_param = get_authorization_scheme_param(
|
|
|
|
cookie_authorization
|
|
|
|
)
|
|
|
|
|
|
|
|
if header_scheme.lower() == "bearer":
|
|
|
|
authorization = True
|
|
|
|
scheme = header_scheme
|
|
|
|
param = header_param
|
|
|
|
|
|
|
|
elif cookie_scheme.lower() == "bearer":
|
|
|
|
authorization = True
|
|
|
|
scheme = cookie_scheme
|
|
|
|
param = cookie_param
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
else:
|
|
|
|
authorization = False
|
|
|
|
|
|
|
|
if not authorization or scheme.lower() != "bearer":
|
|
|
|
if self.auto_error:
|
|
|
|
raise HTTPException(
|
|
|
|
status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
return param
|
|
|
|
|
|
|
|
class BasicAuth(SecurityBase):
|
|
|
|
def __init__(self, scheme_name: str = None, auto_error: bool = True):
|
|
|
|
self.scheme_name = scheme_name or self.__class__.__name__
|
|
|
|
self.model = SecurityBaseModel(type="http")
|
|
|
|
self.auto_error = auto_error
|
|
|
|
|
|
|
|
async def __call__(self, request: Request) -> Optional[str]:
|
|
|
|
authorization: str = request.headers.get("Authorization")
|
|
|
|
scheme, param = get_authorization_scheme_param(authorization)
|
|
|
|
if not authorization or scheme.lower() != "basic":
|
|
|
|
if self.auto_error:
|
|
|
|
raise HTTPException(
|
|
|
|
status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
return param
|
|
|
|
|
|
|
|
basic_auth = BasicAuth(auto_error=False)
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
oauth2_scheme = OAuth2PasswordBearerCookie(tokenUrl="/token")
|
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None, title="OpenMPTCProuter Server API")
|
2020-03-03 12:49:23 +00:00
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
|
|
|
|
def create_access_token(*, data: dict, expires_delta: timedelta = None):
|
|
|
|
to_encode = data.copy()
|
|
|
|
if expires_delta:
|
|
|
|
expire = datetime.utcnow() + expires_delta
|
|
|
|
else:
|
2020-02-15 12:44:35 +00:00
|
|
|
expire = datetime.utcnow() + timedelta(minutes=60)
|
2019-11-02 17:10:10 +00:00
|
|
|
to_encode.update({"exp": expire})
|
|
|
|
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
|
|
|
|
return encoded_jwt
|
|
|
|
|
|
|
|
async def get_current_user(token: str = Depends(oauth2_scheme)):
|
|
|
|
credentials_exception = HTTPException(
|
2020-03-03 12:49:23 +00:00
|
|
|
status_code=HTTP_403_FORBIDDEN,
|
2019-11-02 17:10:10 +00:00
|
|
|
detail="Could not validate credentials",
|
|
|
|
headers={"WWW-Authenticate": "Bearer"},
|
|
|
|
)
|
|
|
|
try:
|
|
|
|
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
|
|
|
username: str = payload.get("sub")
|
|
|
|
if username is None:
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug("get_current_user: Username not found")
|
2019-11-02 17:10:10 +00:00
|
|
|
raise credentials_exception
|
|
|
|
token_data = TokenData(username=username)
|
|
|
|
except PyJWTError:
|
|
|
|
raise credentials_exception
|
|
|
|
user = get_user(fake_users_db, username=token_data.username)
|
|
|
|
if user is None:
|
|
|
|
raise credentials_exception
|
|
|
|
return user
|
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
async def get_current_active_user(current_user: User = Depends(get_current_user)):
|
|
|
|
if current_user.disabled:
|
|
|
|
raise HTTPException(status_code=400, detail="Inactive user")
|
|
|
|
return current_user
|
|
|
|
|
|
|
|
# Show something at homepage
|
|
|
|
@app.get("/")
|
|
|
|
async def homepage():
|
|
|
|
return "Welcome to OpenMPTCProuter Server part"
|
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
# Provide a method to create access tokens. The create_jwt()
|
|
|
|
# function is used to actually generate the token
|
|
|
|
@app.post('/token', response_model=Token)
|
|
|
|
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
|
|
|
|
user = authenticate_user(fake_users_db, form_data.username, form_data.password)
|
|
|
|
if not user:
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug("Incorrect username or password")
|
2019-11-02 17:10:10 +00:00
|
|
|
raise HTTPException(status_code=400, detail="Incorrect username or password")
|
2018-11-08 12:55:20 +00:00
|
|
|
|
|
|
|
# Identity can be any data that is json serializable
|
2019-11-02 17:10:10 +00:00
|
|
|
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
|
|
|
access_token = create_access_token(
|
2020-03-03 13:06:18 +00:00
|
|
|
data={"sub": form_data.username}, expires_delta=access_token_expires
|
2019-11-02 17:10:10 +00:00
|
|
|
)
|
|
|
|
return {"access_token": access_token, "token_type": "bearer"}
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
@app.get("/logout")
|
|
|
|
async def route_logout_and_remove_cookie():
|
|
|
|
response = RedirectResponse(url="/")
|
|
|
|
response.delete_cookie("Authorization")
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
|
# Login for doc
|
|
|
|
@app.get("/login_basic")
|
|
|
|
async def login_basic(auth: BasicAuth = Depends(basic_auth)):
|
|
|
|
if not auth:
|
|
|
|
response = Response(headers={"WWW-Authenticate": "Basic"}, status_code=401)
|
|
|
|
return response
|
|
|
|
|
|
|
|
try:
|
|
|
|
decoded = base64.b64decode(auth).decode("ascii")
|
|
|
|
username, _, password = decoded.partition(":")
|
|
|
|
user = authenticate_user(fake_users_db, username, password)
|
|
|
|
if not user:
|
|
|
|
raise HTTPException(status_code=400, detail="Incorrect email or password")
|
|
|
|
|
|
|
|
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
|
|
|
access_token = create_access_token(
|
|
|
|
data={"sub": username}, expires_delta=access_token_expires
|
|
|
|
)
|
|
|
|
|
|
|
|
token = jsonable_encoder(access_token)
|
|
|
|
|
|
|
|
response = RedirectResponse(url="/docs")
|
|
|
|
response.set_cookie(
|
|
|
|
"Authorization",
|
|
|
|
value=f"Bearer {token}",
|
|
|
|
httponly=True,
|
|
|
|
max_age=1800,
|
|
|
|
expires=1800,
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
except:
|
|
|
|
response = Response(headers={"WWW-Authenticate": "Basic"}, status_code=401)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/openapi.json")
|
|
|
|
async def get_open_api_endpoint(current_user: User = Depends(get_current_active_user)):
|
|
|
|
return JSONResponse(get_openapi(title="FastAPI", version=1, routes=app.routes))
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/docs")
|
|
|
|
async def get_documentation(current_user: User = Depends(get_current_active_user)):
|
|
|
|
return get_swagger_ui_html(openapi_url="/openapi.json", title="docs")
|
|
|
|
|
2020-04-22 16:00:07 +00:00
|
|
|
# Get Client IP
|
|
|
|
@app.get('/clienthost')
|
|
|
|
async def status(request: Request):
|
|
|
|
client_host = request.client.host
|
|
|
|
return {"client_host": client_host}
|
2020-03-03 12:49:23 +00:00
|
|
|
|
2018-11-08 12:55:20 +00:00
|
|
|
# Get VPS status
|
2020-06-30 15:02:02 +00:00
|
|
|
@app.get('/status', summary="Get current server load average, uptime and release")
|
2020-11-23 15:54:46 +00:00
|
|
|
async def status(userid: Optional[int] = Query(None), serial: Optional[str] = Query(None), current_user: User = Depends(get_current_user)):
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get status...')
|
2020-06-30 14:44:13 +00:00
|
|
|
if not current_user.permissions == "admin":
|
|
|
|
userid = current_user.userid
|
|
|
|
if userid is None:
|
|
|
|
userid = 0
|
2020-06-30 15:02:02 +00:00
|
|
|
username = get_username_from_userid(userid)
|
2020-11-23 15:54:46 +00:00
|
|
|
if not current_user.permissions == "admin" and serial is not None:
|
|
|
|
if not check_username_serial(username, serial):
|
|
|
|
return {'error': 'False serial number'}
|
2018-11-29 13:47:05 +00:00
|
|
|
vps_loadavg = os.popen("cat /proc/loadavg | awk '{print $1\" \"$2\" \"$3}'").read().rstrip()
|
|
|
|
vps_uptime = os.popen("cat /proc/uptime | awk '{print $1}'").read().rstrip()
|
2019-07-13 05:30:58 +00:00
|
|
|
vps_hostname = socket.gethostname()
|
2019-11-13 07:39:00 +00:00
|
|
|
vps_current_time = time.time()
|
2019-12-26 19:25:11 +00:00
|
|
|
vps_kernel = os.popen('uname -r').read().rstrip()
|
|
|
|
vps_omr_version = os.popen("grep -s 'OpenMPTCProuter VPS' /etc/* | awk '{print $4}'").read().rstrip()
|
2018-12-06 09:48:23 +00:00
|
|
|
mptcp_enabled = os.popen('sysctl -n net.mptcp.mptcp_enabled').read().rstrip()
|
2020-05-20 16:23:24 +00:00
|
|
|
shadowsocks_port = current_user.shadowsocks_port
|
|
|
|
if not shadowsocks_port == None:
|
|
|
|
ss_traffic = get_bytes_ss(current_user.shadowsocks_port)
|
|
|
|
else:
|
|
|
|
ss_traffic = 0
|
2020-08-20 18:31:29 +00:00
|
|
|
v2ray_tx = 0
|
|
|
|
v2ray_rx = 0
|
2020-09-11 20:37:16 +00:00
|
|
|
if os.path.isfile('/etc/v2ray/v2ray-server.json') and checkIfProcessRunning('v2ray'):
|
2020-08-20 18:31:29 +00:00
|
|
|
v2ray_tx = get_bytes_v2ray('tx',username)
|
|
|
|
v2ray_rx = get_bytes_v2ray('rx',username)
|
2020-06-30 15:02:02 +00:00
|
|
|
vpn = 'glorytun_tcp'
|
2020-09-28 15:22:53 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
try:
|
|
|
|
omr_config_data = json.load(f)
|
|
|
|
except ValueError as e:
|
|
|
|
omr_config_data = {}
|
2020-06-30 15:02:02 +00:00
|
|
|
if 'vpn' in omr_config_data['users'][0][username]:
|
|
|
|
vpn = omr_config_data['users'][0][username]['vpn']
|
2020-06-30 14:44:13 +00:00
|
|
|
vpn_traffic_rx = 0
|
|
|
|
vpn_traffic_tx = 0
|
|
|
|
if vpn == 'glorytun_tcp':
|
|
|
|
vpn_traffic_rx = get_bytes('rx', 'gt-tun' + str(userid))
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'gt-tun' + str(userid))
|
|
|
|
elif vpn == 'glorytun_udp':
|
|
|
|
vpn_traffic_rx = get_bytes('rx', 'gt-udp-tun' + str(userid))
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'gt-udp-tun' + str(userid))
|
|
|
|
elif vpn == 'mlvpn':
|
|
|
|
vpn_traffic_rx = get_bytes('rx', 'mlvpn' + str(userid))
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'mlvpn' + str(userid))
|
|
|
|
elif vpn == 'dsvpn':
|
|
|
|
vpn_traffic_rx = get_bytes('rx', 'dsvpn' + str(userid))
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'dsvpn' + str(userid))
|
2020-12-21 14:17:26 +00:00
|
|
|
elif vpn == 'openvpn':
|
|
|
|
vpn_traffic_rx = get_bytes('rx', 'tun0')
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'tun0')
|
|
|
|
elif vpn == 'openvpn_bonding':
|
|
|
|
vpn_traffic_rx = get_bytes('rx', 'omr-bonding')
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'omr-bonding')
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get status: done')
|
|
|
|
if IFACE:
|
2020-08-20 18:31:29 +00:00
|
|
|
return {'vps': {'time': vps_current_time, 'loadavg': vps_loadavg, 'uptime': vps_uptime, 'mptcp': mptcp_enabled, 'hostname': vps_hostname, 'kernel': vps_kernel, 'omr_version': vps_omr_version}, 'network': {'tx': get_bytes('tx', IFACE), 'rx': get_bytes('rx', IFACE)}, 'shadowsocks': {'traffic': ss_traffic}, 'vpn': {'tx': vpn_traffic_tx, 'rx': vpn_traffic_rx}, 'v2ray': {'tx': v2ray_tx, 'rx': v2ray_rx}}
|
2018-11-08 12:55:20 +00:00
|
|
|
else:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'error': 'No iface defined', 'route': 'status'}
|
2018-11-08 12:55:20 +00:00
|
|
|
|
|
|
|
# Get VPS config
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.get('/config', summary="Get full server configuration for current user")
|
2020-11-23 15:54:46 +00:00
|
|
|
async def config(userid: Optional[int] = Query(None), serial: Optional[str] = Query(None), current_user: User = Depends(get_current_user)):
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config...')
|
2020-06-30 14:44:13 +00:00
|
|
|
if not current_user.permissions == "admin":
|
|
|
|
userid = current_user.userid
|
2020-03-03 12:49:23 +00:00
|
|
|
if userid is None:
|
2020-01-09 08:48:02 +00:00
|
|
|
userid = 0
|
2020-06-30 15:02:02 +00:00
|
|
|
username = get_username_from_userid(userid)
|
2020-11-23 15:54:46 +00:00
|
|
|
if not current_user.permissions == "admin" and serial is not None:
|
|
|
|
if not check_username_serial(username, serial):
|
|
|
|
return {'error': 'False serial number'}
|
2019-03-27 20:28:18 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
try:
|
|
|
|
omr_config_data = json.load(f)
|
|
|
|
except ValueError as e:
|
|
|
|
omr_config_data = {}
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config... shadowsocks')
|
2019-11-16 19:49:26 +00:00
|
|
|
with open('/etc/shadowsocks-libev/manager.json') as f:
|
2018-11-29 21:43:02 +00:00
|
|
|
content = f.read()
|
2020-03-03 13:06:18 +00:00
|
|
|
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
|
2018-12-06 09:48:23 +00:00
|
|
|
try:
|
|
|
|
data = json.loads(content)
|
|
|
|
except ValueError as e:
|
2020-05-10 19:02:18 +00:00
|
|
|
data = {'port_key': '', 'server_port': 65101, 'method': 'chacha20'}
|
2019-11-16 19:49:26 +00:00
|
|
|
#shadowsocks_port = data["server_port"]
|
|
|
|
shadowsocks_port = current_user.shadowsocks_port
|
2020-04-21 12:55:35 +00:00
|
|
|
if shadowsocks_port is not None:
|
2020-06-19 13:49:07 +00:00
|
|
|
if 'port_key' in data:
|
|
|
|
shadowsocks_key = data["port_key"][str(shadowsocks_port)]
|
|
|
|
else:
|
|
|
|
shadowsocks_key = data["port_conf"][str(shadowsocks_port)]["key"]
|
2019-12-27 20:42:47 +00:00
|
|
|
else:
|
|
|
|
shadowsocks_key = ''
|
2018-11-08 12:55:20 +00:00
|
|
|
shadowsocks_method = data["method"]
|
2018-11-29 22:14:23 +00:00
|
|
|
if 'fast_open' in data:
|
|
|
|
shadowsocks_fast_open = data["fast_open"]
|
|
|
|
else:
|
|
|
|
shadowsocks_fast_open = False
|
2019-01-02 14:10:38 +00:00
|
|
|
if 'reuse_port' in data:
|
2018-11-29 22:14:23 +00:00
|
|
|
shadowsocks_reuse_port = data["reuse_port"]
|
|
|
|
else:
|
|
|
|
shadowsocks_reuse_port = False
|
|
|
|
if 'no_delay' in data:
|
|
|
|
shadowsocks_no_delay = data["no_delay"]
|
|
|
|
else:
|
|
|
|
shadowsocks_no_delay = False
|
|
|
|
if 'mptcp' in data:
|
|
|
|
shadowsocks_mptcp = data["mptcp"]
|
|
|
|
else:
|
|
|
|
shadowsocks_mptcp = False
|
2019-01-02 14:10:38 +00:00
|
|
|
if 'ebpf' in data:
|
|
|
|
shadowsocks_ebpf = data["ebpf"]
|
|
|
|
else:
|
|
|
|
shadowsocks_ebpf = False
|
2018-11-08 12:55:20 +00:00
|
|
|
if "plugin" in data:
|
|
|
|
shadowsocks_obfs = True
|
2019-01-25 19:43:49 +00:00
|
|
|
if 'v2ray' in data["plugin"]:
|
|
|
|
shadowsocks_obfs_plugin = 'v2ray'
|
|
|
|
else:
|
|
|
|
shadowsocks_obfs_plugin = 'obfs'
|
|
|
|
if 'tls' in data["plugin_opts"]:
|
|
|
|
shadowsocks_obfs_type = 'tls'
|
|
|
|
else:
|
2019-01-25 21:17:55 +00:00
|
|
|
shadowsocks_obfs_type = 'http'
|
2018-11-08 12:55:20 +00:00
|
|
|
else:
|
|
|
|
shadowsocks_obfs = False
|
2019-01-25 19:43:49 +00:00
|
|
|
shadowsocks_obfs_plugin = ''
|
|
|
|
shadowsocks_obfs_type = ''
|
2019-12-30 19:49:39 +00:00
|
|
|
shadowsocks_port = current_user.shadowsocks_port
|
2020-05-20 16:23:24 +00:00
|
|
|
if not shadowsocks_port == None:
|
|
|
|
ss_traffic = get_bytes_ss(current_user.shadowsocks_port)
|
|
|
|
else:
|
|
|
|
ss_traffic = 0
|
2020-02-15 12:44:35 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config... glorytun')
|
2020-01-09 08:48:02 +00:00
|
|
|
if os.path.isfile('/etc/glorytun-tcp/tun' + str(userid) +'.key'):
|
|
|
|
glorytun_key = open('/etc/glorytun-tcp/tun' + str(userid) + '.key').readline().rstrip()
|
2018-12-06 09:48:23 +00:00
|
|
|
else:
|
|
|
|
glorytun_key = ''
|
|
|
|
glorytun_port = '65001'
|
2019-05-23 19:55:49 +00:00
|
|
|
glorytun_chacha = False
|
2020-01-25 21:04:14 +00:00
|
|
|
glorytun_tcp_host_ip = ''
|
|
|
|
glorytun_tcp_client_ip = ''
|
|
|
|
glorytun_udp_host_ip = ''
|
|
|
|
glorytun_udp_client_ip = ''
|
2020-01-09 08:48:02 +00:00
|
|
|
if os.path.isfile('/etc/glorytun-tcp/tun' + str(userid)):
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/glorytun-tcp/tun' + str(userid), "r") as glorytun_file:
|
2018-12-06 09:48:23 +00:00
|
|
|
for line in glorytun_file:
|
|
|
|
if 'PORT=' in line:
|
|
|
|
glorytun_port = line.replace(line[:5], '').rstrip()
|
2020-01-25 21:04:14 +00:00
|
|
|
if 'LOCALIP=' in line:
|
|
|
|
glorytun_tcp_host_ip = line.replace(line[:8], '').rstrip()
|
|
|
|
if 'REMOTEIP=' in line:
|
|
|
|
glorytun_tcp_client_ip = line.replace(line[:9], '').rstrip()
|
2019-05-23 19:55:49 +00:00
|
|
|
if 'chacha' in line:
|
|
|
|
glorytun_chacha = True
|
2020-01-25 21:04:14 +00:00
|
|
|
if userid == 0 and glorytun_tcp_host_ip == '':
|
2020-01-09 08:48:02 +00:00
|
|
|
if 'glorytun_tcp_type' in omr_config_data:
|
|
|
|
if omr_config_data['glorytun_tcp_type'] == 'static':
|
|
|
|
glorytun_tcp_host_ip = '10.255.255.1'
|
|
|
|
glorytun_tcp_client_ip = '10.255.255.2'
|
|
|
|
else:
|
|
|
|
glorytun_tcp_host_ip = 'dhcp'
|
|
|
|
glorytun_tcp_client_ip = 'dhcp'
|
|
|
|
else:
|
2019-03-27 20:28:18 +00:00
|
|
|
glorytun_tcp_host_ip = '10.255.255.1'
|
|
|
|
glorytun_tcp_client_ip = '10.255.255.2'
|
2020-01-25 21:04:14 +00:00
|
|
|
if os.path.isfile('/etc/glorytun-udp/tun' + str(userid)):
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/glorytun-udp/tun' + str(userid), "r") as glorytun_file:
|
2020-01-25 21:04:14 +00:00
|
|
|
for line in glorytun_file:
|
|
|
|
if 'LOCALIP=' in line:
|
|
|
|
glorytun_udp_host_ip = line.replace(line[:8], '').rstrip()
|
|
|
|
if 'REMOTEIP=' in line:
|
|
|
|
glorytun_udp_client_ip = line.replace(line[:9], '').rstrip()
|
|
|
|
|
|
|
|
if userid == 0 and glorytun_udp_host_ip == '':
|
2020-01-09 08:48:02 +00:00
|
|
|
if 'glorytun_udp_type' in omr_config_data:
|
|
|
|
if omr_config_data['glorytun_udp_type'] == 'static':
|
|
|
|
glorytun_udp_host_ip = '10.255.254.1'
|
|
|
|
glorytun_udp_client_ip = '10.255.254.2'
|
|
|
|
else:
|
|
|
|
glorytun_udp_host_ip = 'dhcp'
|
|
|
|
glorytun_udp_client_ip = 'dhcp'
|
|
|
|
else:
|
2019-05-07 19:45:11 +00:00
|
|
|
glorytun_udp_host_ip = '10.255.254.1'
|
|
|
|
glorytun_udp_client_ip = '10.255.254.2'
|
2020-03-09 21:00:42 +00:00
|
|
|
available_vpn = ["glorytun_tcp", "glorytun_udp"]
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config... dsvpn')
|
2020-01-12 17:41:34 +00:00
|
|
|
if os.path.isfile('/etc/dsvpn/dsvpn' + str(userid) + '.key'):
|
|
|
|
dsvpn_key = open('/etc/dsvpn/dsvpn' + str(userid) + '.key').readline().rstrip()
|
2019-08-02 15:22:43 +00:00
|
|
|
available_vpn.append("dsvpn")
|
|
|
|
else:
|
|
|
|
dsvpn_key = ''
|
2020-01-12 17:41:34 +00:00
|
|
|
dsvpn_port = '65401'
|
2020-01-25 21:04:14 +00:00
|
|
|
dsvpn_host_ip = ''
|
|
|
|
dsvpn_client_ip = ''
|
2020-01-12 17:41:34 +00:00
|
|
|
if os.path.isfile('/etc/dsvpn/dsvpn' + str(userid)):
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/dsvpn/dsvpn' + str(userid), "r") as dsvpn_file:
|
2020-01-12 17:41:34 +00:00
|
|
|
for line in dsvpn_file:
|
|
|
|
if 'PORT=' in line:
|
|
|
|
dsvpn_port = line.replace(line[:5], '').rstrip()
|
2020-01-25 21:04:14 +00:00
|
|
|
if 'LOCALTUNIP=' in line:
|
|
|
|
dsvpn_host_ip = line.replace(line[:11], '').rstrip()
|
|
|
|
if 'REMOTETUNIP=' in line:
|
|
|
|
dsvpn_client_ip = line.replace(line[:12], '').rstrip()
|
2020-01-12 17:41:34 +00:00
|
|
|
|
2020-01-25 21:04:14 +00:00
|
|
|
if userid == 0 and dsvpn_host_ip == '':
|
2020-01-12 17:41:34 +00:00
|
|
|
dsvpn_host_ip = '10.255.251.1'
|
|
|
|
dsvpn_client_ip = '10.255.251.2'
|
2018-11-23 14:19:30 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config... iperf3')
|
2019-03-28 19:17:06 +00:00
|
|
|
if os.path.isfile('/etc/iperf3/public.pem'):
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/iperf3/public.pem', "rb") as iperfkey_file:
|
2019-03-27 20:28:18 +00:00
|
|
|
iperf_keyb = base64.b64encode(iperfkey_file.read())
|
|
|
|
iperf3_key = iperf_keyb.decode('utf-8')
|
|
|
|
else:
|
|
|
|
iperf3_key = ''
|
|
|
|
|
2019-04-18 19:09:26 +00:00
|
|
|
if os.path.isfile('/etc/pihole/setupVars.conf'):
|
|
|
|
pihole = True
|
|
|
|
else:
|
|
|
|
pihole = False
|
2019-03-27 20:28:18 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config... openvpn')
|
2019-11-13 07:39:00 +00:00
|
|
|
#if os.path.isfile('/etc/openvpn/server/static.key'):
|
|
|
|
# with open('/etc/openvpn/server/static.key',"rb") as ovpnkey_file:
|
|
|
|
# openvpn_keyb = base64.b64encode(ovpnkey_file.read())
|
|
|
|
# openvpn_key = openvpn_keyb.decode('utf-8')
|
|
|
|
# available_vpn.append("openvpn")
|
|
|
|
#else:
|
|
|
|
# openvpn_key = ''
|
|
|
|
openvpn_key = ''
|
2020-06-30 15:02:02 +00:00
|
|
|
if os.path.isfile('/etc/openvpn/ca/pki/private/' + username + '.key'):
|
|
|
|
with open('/etc/openvpn/ca/pki/private/' + username + '.key', "rb") as ovpnkey_file:
|
2019-10-25 18:22:00 +00:00
|
|
|
openvpn_keyb = base64.b64encode(ovpnkey_file.read())
|
|
|
|
openvpn_client_key = openvpn_keyb.decode('utf-8')
|
|
|
|
else:
|
|
|
|
openvpn_client_key = ''
|
2020-06-30 15:02:02 +00:00
|
|
|
if os.path.isfile('/etc/openvpn/ca/pki/issued/' + username + '.crt'):
|
|
|
|
with open('/etc/openvpn/ca/pki/issued/' + username + '.crt', "rb") as ovpnkey_file:
|
2019-10-25 18:22:00 +00:00
|
|
|
openvpn_keyb = base64.b64encode(ovpnkey_file.read())
|
|
|
|
openvpn_client_crt = openvpn_keyb.decode('utf-8')
|
2019-11-13 07:39:00 +00:00
|
|
|
available_vpn.append("openvpn")
|
2019-10-25 18:22:00 +00:00
|
|
|
else:
|
|
|
|
openvpn_client_crt = ''
|
2019-12-27 20:42:47 +00:00
|
|
|
if os.path.isfile('/etc/openvpn/ca/pki/ca.crt'):
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/openvpn/ca/pki/ca.crt', "rb") as ovpnkey_file:
|
2019-10-25 18:22:00 +00:00
|
|
|
openvpn_keyb = base64.b64encode(ovpnkey_file.read())
|
|
|
|
openvpn_client_ca = openvpn_keyb.decode('utf-8')
|
|
|
|
else:
|
|
|
|
openvpn_client_ca = ''
|
2018-12-06 09:48:23 +00:00
|
|
|
openvpn_port = '65301'
|
2020-07-02 16:12:31 +00:00
|
|
|
openvpn_cipher = 'AES-256-CBC'
|
2018-12-06 09:48:23 +00:00
|
|
|
if os.path.isfile('/etc/openvpn/openvpn-tun0.conf'):
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/openvpn/openvpn-tun0.conf', "r") as openvpn_file:
|
2018-12-06 09:48:23 +00:00
|
|
|
for line in openvpn_file:
|
|
|
|
if 'port ' in line:
|
|
|
|
openvpn_port = line.replace(line[:5], '').rstrip()
|
2020-07-02 16:12:31 +00:00
|
|
|
if 'cipher ' in line:
|
|
|
|
openvpn_cipher = line.replace(line[:7], '').rstrip()
|
2019-04-20 16:16:22 +00:00
|
|
|
openvpn_host_ip = '10.255.252.1'
|
2019-11-13 07:39:00 +00:00
|
|
|
#openvpn_client_ip = '10.255.252.2'
|
|
|
|
openvpn_client_ip = 'dhcp'
|
2018-11-23 14:19:30 +00:00
|
|
|
|
2020-12-11 20:40:39 +00:00
|
|
|
if os.path.isfile('/etc/openvpn/bonding1.conf'):
|
|
|
|
available_vpn.append("openvpn_bonding")
|
|
|
|
|
2020-03-03 13:06:18 +00:00
|
|
|
LOG.debug('Get config... mlvpn')
|
2018-11-23 14:19:30 +00:00
|
|
|
if os.path.isfile('/etc/mlvpn/mlvpn0.conf'):
|
|
|
|
mlvpn_config = configparser.ConfigParser()
|
2019-11-13 07:39:00 +00:00
|
|
|
mlvpn_config.read_file(open(r'/etc/mlvpn/mlvpn0.conf'))
|
2020-03-03 12:49:23 +00:00
|
|
|
mlvpn_key = mlvpn_config.get('general', 'password').strip('"')
|
2021-03-15 14:07:25 +00:00
|
|
|
mlvpn_timeout = mlvpn_config.get('general', 'timeout')
|
|
|
|
mlvpn_reorder_buffer_size = mlvpn_config.get('general', 'reorder_buffer_size')
|
|
|
|
mlvpn_loss_tolerence = mlvpn_config.get('general', 'loss_tolerence')
|
2021-03-15 19:37:05 +00:00
|
|
|
if mlvpn_config.has_option('general', 'cleartext_data'):
|
|
|
|
mlvpn_cleartext_data = mlvpn_config.get('general', 'cleartext_data')
|
|
|
|
else:
|
|
|
|
mlvpn_cleartext_data = ''
|
2018-12-03 10:07:03 +00:00
|
|
|
available_vpn.append("mlvpn")
|
2018-11-23 14:19:30 +00:00
|
|
|
else:
|
|
|
|
mlvpn_key = ''
|
2021-03-15 14:07:25 +00:00
|
|
|
mlvpn_timeout = ''
|
|
|
|
mlvpn_reorder_buffer_size = ''
|
|
|
|
mlvpn_loss_tolerence = ''
|
|
|
|
mlvpn_cleartext_data = ''
|
2019-04-20 16:16:22 +00:00
|
|
|
mlvpn_host_ip = '10.255.253.1'
|
|
|
|
mlvpn_client_ip = '10.255.253.2'
|
2018-12-03 10:07:03 +00:00
|
|
|
|
2021-03-02 13:28:35 +00:00
|
|
|
LOG.debug('Get config... wireguard')
|
2021-03-02 17:24:22 +00:00
|
|
|
if os.path.isfile('/etc/wireguard/vpn-server-public.key'):
|
|
|
|
with open('/etc/wireguard/vpn-server-public.key', "rb") as wgkey_file:
|
2021-03-02 13:28:35 +00:00
|
|
|
wireguard_key = wgkey_file.read()
|
|
|
|
else:
|
|
|
|
wireguard_key = ''
|
|
|
|
wireguard_host_ip = '10.255.247.1'
|
|
|
|
wireguard_port = '65311'
|
|
|
|
|
2020-06-19 13:49:07 +00:00
|
|
|
gre_tunnel = False
|
|
|
|
gre_tunnel_conf = []
|
2020-06-20 07:08:51 +00:00
|
|
|
# for tunnel in pathlib.Path('/etc/openmptcprouter-vps-admin/intf').glob('gre-user' + str(userid) + '-ip*'):
|
|
|
|
# gre_tunnel = True
|
|
|
|
# with open(tunnel, "r") as tunnel_conf:
|
|
|
|
# for line in tunnel_conf:
|
|
|
|
# if 'LOCALIP=' in line:
|
|
|
|
# gre_tunnel_localip = line.replace(line[:8], '').rstrip()
|
|
|
|
# if 'REMOTEIP=' in line:
|
|
|
|
# gre_tunnel_remoteip = line.replace(line[:9], '').rstrip()
|
|
|
|
# if 'NETMASK=' in line:
|
|
|
|
# gre_tunnel_netmask = line.replace(line[:8], '').rstrip()
|
|
|
|
# if 'INTFADDR=' in line:
|
|
|
|
# gre_tunnel_intfaddr = line.replace(line[:9], '').rstrip()
|
|
|
|
# gre_tunnel_conf.append("{'local_ip': '" + gre_tunnel_localip + "', 'remote_ip': '" + gre_tunnel_remoteip + "', 'netmask': '" + gre_tunnel_netmask + "', 'public_ip': '" + gre_tunnel_intfaddr + "'}")
|
|
|
|
|
2020-06-30 15:02:02 +00:00
|
|
|
if 'gre_tunnels' in omr_config_data['users'][0][username]:
|
2020-06-19 13:49:07 +00:00
|
|
|
gre_tunnel = True
|
2020-06-30 15:02:02 +00:00
|
|
|
gre_tunnel_conf = omr_config_data['users'][0][username]['gre_tunnels']
|
2020-06-19 13:49:07 +00:00
|
|
|
|
2020-06-30 15:02:02 +00:00
|
|
|
if 'vpnremoteip' in omr_config_data['users'][0][username]:
|
|
|
|
vpn_remote_ip = omr_config_data['users'][0][username]['vpnremoteip']
|
2020-03-06 19:09:04 +00:00
|
|
|
else:
|
|
|
|
vpn_remote_ip = ''
|
2020-06-30 15:02:02 +00:00
|
|
|
if 'vpnlocalip' in omr_config_data['users'][0][username]:
|
|
|
|
vpn_local_ip = omr_config_data['users'][0][username]['vpnlocalip']
|
2020-03-06 19:09:04 +00:00
|
|
|
else:
|
|
|
|
vpn_local_ip = ''
|
2018-11-14 16:34:13 +00:00
|
|
|
|
2020-08-10 18:49:47 +00:00
|
|
|
v2ray = False
|
|
|
|
v2ray_conf = []
|
|
|
|
v2ray_tx = 0
|
|
|
|
v2ray_rx = 0
|
|
|
|
if os.path.isfile('/etc/v2ray/v2ray-server.json'):
|
|
|
|
v2ray = True
|
|
|
|
if not 'v2ray' in omr_config_data['users'][0][username]:
|
|
|
|
v2ray_key = os.popen('jq -r .inbounds[0].settings.clients[0].id /etc/v2ray/v2ray-server.json').read().rstrip()
|
|
|
|
v2ray_port = os.popen('jq -r .inbounds[0].port /etc/v2ray/v2ray-server.json').read().rstrip()
|
|
|
|
v2ray_conf = { 'key': v2ray_key, 'port': v2ray_port}
|
|
|
|
modif_config_user(username, {'v2ray': v2ray_conf})
|
|
|
|
else:
|
|
|
|
v2ray_conf = omr_config_data['users'][0][username]['v2ray']
|
2020-09-11 18:58:38 +00:00
|
|
|
if checkIfProcessRunning('v2ray'):
|
|
|
|
v2ray_tx = get_bytes_v2ray('tx',username)
|
|
|
|
v2ray_rx = get_bytes_v2ray('rx',username)
|
2020-08-10 18:49:47 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config... mptcp')
|
2018-11-21 09:00:00 +00:00
|
|
|
mptcp_enabled = os.popen('sysctl -n net.mptcp.mptcp_enabled').read().rstrip()
|
2018-11-14 16:34:13 +00:00
|
|
|
mptcp_checksum = os.popen('sysctl -n net.mptcp.mptcp_checksum').read().rstrip()
|
|
|
|
mptcp_path_manager = os.popen('sysctl -n net.mptcp.mptcp_path_manager').read().rstrip()
|
|
|
|
mptcp_scheduler = os.popen('sysctl -n net.mptcp.mptcp_scheduler').read().rstrip()
|
|
|
|
mptcp_syn_retries = os.popen('sysctl -n net.mptcp.mptcp_syn_retries').read().rstrip()
|
|
|
|
|
|
|
|
congestion_control = os.popen('sysctl -n net.ipv4.tcp_congestion_control').read().rstrip()
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config... ipv6')
|
2020-05-10 19:02:18 +00:00
|
|
|
if 'ipv6_network' in omr_config_data:
|
|
|
|
ipv6_network = omr_config_data['ipv6_network']
|
|
|
|
else:
|
2020-05-14 08:44:16 +00:00
|
|
|
ipv6_network = os.popen('ip -6 addr show ' + IFACE6 +' | grep -oP "(?<=inet6 ).*(?= scope global)"').read().rstrip()
|
2019-02-28 07:26:37 +00:00
|
|
|
#ipv6_addr = os.popen('wget -6 -qO- -T 2 ipv6.openmptcprouter.com').read().rstrip()
|
2020-05-10 19:02:18 +00:00
|
|
|
if 'ipv6_addr' in omr_config_data:
|
|
|
|
ipv6_addr = omr_config_data['ipv6_addr']
|
|
|
|
else:
|
2020-05-14 08:44:16 +00:00
|
|
|
ipv6_addr = os.popen('ip -6 addr show ' + IFACE6 +' | grep -oP "(?<=inet6 ).*(?= scope global)" | cut -d/ -f1').read().rstrip()
|
2019-07-25 06:25:12 +00:00
|
|
|
#ipv4_addr = os.popen('wget -4 -qO- -T 1 https://ip.openmptcprouter.com').read().rstrip()
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('get server IPv4')
|
2020-03-24 20:07:41 +00:00
|
|
|
if 'ipv4' in omr_config_data:
|
2020-03-27 19:09:24 +00:00
|
|
|
ipv4_addr = omr_config_data['ipv4']
|
2020-04-21 12:55:35 +00:00
|
|
|
elif 'internet' in omr_config_data and not omr_config_data['internet']:
|
|
|
|
ipv4_addr = os.popen('ip -4 addr show ' + IFACE +' | grep -oP "(?<=inet ).*(?= scope global)" | cut -d/ -f1').read().rstrip()
|
2020-03-24 20:07:41 +00:00
|
|
|
else:
|
|
|
|
ipv4_addr = os.popen("dig -4 TXT +timeout=2 +tries=1 +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'\"' '{ print $2}'").read().rstrip()
|
2020-11-27 13:48:48 +00:00
|
|
|
if ipv4_addr == '':
|
|
|
|
ipv4_addr = os.popen('wget -4 -qO- -T 1 http://ip.openmptcprouter.com').read().rstrip()
|
2020-03-24 20:07:41 +00:00
|
|
|
if ipv4_addr == '':
|
|
|
|
ipv4_addr = os.popen('wget -4 -qO- -T 1 http://ifconfig.co').read().rstrip()
|
|
|
|
if ipv4_addr != '':
|
|
|
|
set_global_param('ipv4', ipv4_addr)
|
2019-07-25 06:25:12 +00:00
|
|
|
#ipv4_addr = ""
|
2018-11-21 09:00:00 +00:00
|
|
|
|
2019-06-15 18:31:01 +00:00
|
|
|
test_aes = os.popen('cat /proc/cpuinfo | grep aes').read().rstrip()
|
|
|
|
if test_aes == '':
|
|
|
|
vps_aes = False
|
|
|
|
else:
|
|
|
|
vps_aes = True
|
2018-11-21 09:00:00 +00:00
|
|
|
vps_kernel = os.popen('uname -r').read().rstrip()
|
|
|
|
vps_machine = os.popen('uname -m').read().rstrip()
|
2019-03-29 17:27:58 +00:00
|
|
|
vps_omr_version = os.popen("grep -s 'OpenMPTCProuter VPS' /etc/* | awk '{print $4}'").read().rstrip()
|
2018-11-29 13:47:05 +00:00
|
|
|
vps_loadavg = os.popen("cat /proc/loadavg | awk '{print $1" "$2" "$3}'").read().rstrip()
|
|
|
|
vps_uptime = os.popen("cat /proc/uptime | awk '{print $1}'").read().rstrip()
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('get hostname')
|
2020-03-24 20:07:41 +00:00
|
|
|
if 'hostname' in omr_config_data:
|
2020-03-27 19:26:49 +00:00
|
|
|
vps_domain = omr_config_data['hostname']
|
2020-04-21 12:55:35 +00:00
|
|
|
elif 'internet' in omr_config_data and not omr_config_data['internet']:
|
|
|
|
vps_domain = ''
|
2020-03-24 20:07:41 +00:00
|
|
|
else:
|
|
|
|
vps_domain = os.popen('wget -4 -qO- -T 1 http://hostname.openmptcprouter.com').read().rstrip()
|
|
|
|
if vps_domain != '':
|
|
|
|
set_global_param('hostname', vps_domain)
|
2019-07-25 06:25:12 +00:00
|
|
|
#vps_domain = os.popen('dig -4 +short +times=3 +tries=1 -x ' + ipv4_addr + " | sed 's/\.$//'").read().rstrip()
|
2020-01-13 20:47:29 +00:00
|
|
|
user_permissions = current_user.permissions
|
2018-11-16 13:14:08 +00:00
|
|
|
|
2020-04-22 16:00:07 +00:00
|
|
|
internet = True
|
|
|
|
if 'internet' in omr_config_data and not omr_config_data['internet']:
|
|
|
|
internet = False
|
|
|
|
|
2020-03-03 12:49:23 +00:00
|
|
|
localip6 = ''
|
|
|
|
remoteip6 = ''
|
2020-05-14 08:44:16 +00:00
|
|
|
ula = ''
|
2020-01-20 20:05:40 +00:00
|
|
|
if userid == 0:
|
2020-01-28 20:32:29 +00:00
|
|
|
if os.path.isfile('/etc/openmptcprouter-vps-admin/omr-6in4/user' + str(userid)):
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-6in4/user' + str(userid), "r") as omr6in4_file:
|
2020-01-28 20:32:29 +00:00
|
|
|
for line in omr6in4_file:
|
|
|
|
if 'LOCALIP6=' in line:
|
|
|
|
localip6 = line.replace(line[:9], '').rstrip()
|
|
|
|
if 'REMOTEIP6=' in line:
|
|
|
|
remoteip6 = line.replace(line[:10], '').rstrip()
|
2020-05-14 08:44:16 +00:00
|
|
|
if 'ULA=' in line:
|
|
|
|
ula = line.replace(line[:4], '').rstrip()
|
2020-01-20 20:05:40 +00:00
|
|
|
else:
|
2020-05-22 09:09:04 +00:00
|
|
|
locaip6 = 'fe80::a00:1'
|
|
|
|
remoteip6 = 'fe80::a00:2'
|
2020-01-20 20:05:40 +00:00
|
|
|
|
2020-08-10 18:49:47 +00:00
|
|
|
proxy = 'shadowsocks'
|
|
|
|
if 'proxy' in omr_config_data['users'][0][username]:
|
|
|
|
proxy = omr_config_data['users'][0][username]['proxy']
|
|
|
|
|
2020-02-24 09:27:15 +00:00
|
|
|
vpn = 'glorytun_tcp'
|
2020-06-30 15:02:02 +00:00
|
|
|
if 'vpn' in omr_config_data['users'][0][username]:
|
|
|
|
vpn = omr_config_data['users'][0][username]['vpn']
|
2020-05-20 16:23:24 +00:00
|
|
|
|
2020-06-30 14:44:13 +00:00
|
|
|
vpn_traffic_rx = 0
|
|
|
|
vpn_traffic_tx = 0
|
2020-05-20 16:23:24 +00:00
|
|
|
if vpn == 'glorytun_tcp':
|
2020-06-19 13:49:07 +00:00
|
|
|
vpn_traffic_rx = get_bytes('rx', 'gt-tun' + str(userid))
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'gt-tun' + str(userid))
|
2020-05-20 16:23:24 +00:00
|
|
|
elif vpn == 'glorytun_udp':
|
2020-06-19 13:49:07 +00:00
|
|
|
vpn_traffic_rx = get_bytes('rx', 'gt-udp-tun' + str(userid))
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'gt-udp-tun' + str(userid))
|
2020-05-20 16:23:24 +00:00
|
|
|
elif vpn == 'mlvpn':
|
2020-06-19 13:49:07 +00:00
|
|
|
vpn_traffic_rx = get_bytes('rx', 'mlvpn' + str(userid))
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'mlvpn' + str(userid))
|
2020-05-20 16:23:24 +00:00
|
|
|
elif vpn == 'dsvpn':
|
2020-06-19 13:49:07 +00:00
|
|
|
vpn_traffic_rx = get_bytes('rx', 'dsvpn' + str(userid))
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'dsvpn' + str(userid))
|
2020-12-21 14:17:26 +00:00
|
|
|
elif vpn == 'openvpn':
|
|
|
|
vpn_traffic_rx = get_bytes('rx', 'tun0')
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'tun0')
|
|
|
|
elif vpn == 'openvpn_bonding':
|
|
|
|
vpn_traffic_rx = get_bytes('rx', 'omr-bonding')
|
|
|
|
vpn_traffic_tx = get_bytes('tx', 'omr-bonding')
|
2020-05-20 16:23:24 +00:00
|
|
|
|
2020-01-28 20:32:29 +00:00
|
|
|
#vpn = current_user.vpn
|
2020-08-10 18:49:47 +00:00
|
|
|
available_proxy = ["shadowsocks", "v2ray"]
|
2020-03-05 14:02:20 +00:00
|
|
|
if user_permissions == 'ro':
|
2020-01-09 08:48:02 +00:00
|
|
|
del available_vpn
|
|
|
|
available_vpn = [vpn]
|
2020-08-10 18:49:47 +00:00
|
|
|
del available_proxy
|
|
|
|
available_proxy = [proxy]
|
2019-06-24 16:14:16 +00:00
|
|
|
|
2020-01-28 20:32:29 +00:00
|
|
|
alllanips = []
|
|
|
|
client2client = False
|
2020-03-03 12:49:23 +00:00
|
|
|
if 'client2client' in omr_config_data and omr_config_data['client2client']:
|
2020-01-28 20:32:29 +00:00
|
|
|
client2client = True
|
|
|
|
for users in omr_config_data['users'][0]:
|
2020-06-30 15:02:02 +00:00
|
|
|
if 'lanips' in omr_config_data['users'][0][users] and users != username and omr_config_data['users'][0][users]['lanips'][0] not in alllanips:
|
2020-03-05 14:02:20 +00:00
|
|
|
alllanips.append(omr_config_data['users'][0][users]['lanips'][0])
|
2020-01-28 20:32:29 +00:00
|
|
|
|
2018-11-14 14:10:42 +00:00
|
|
|
shorewall_redirect = "enable"
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall/rules', 'r') as f:
|
2018-11-08 17:22:43 +00:00
|
|
|
for line in f:
|
|
|
|
if '#DNAT net vpn:$OMR_ADDR tcp 1-64999' in line:
|
2018-11-14 14:10:42 +00:00
|
|
|
shorewall_redirect = "disable"
|
2020-03-03 12:49:23 +00:00
|
|
|
LOG.debug('Get config: done')
|
2021-03-15 14:07:25 +00:00
|
|
|
return {'vps': {'kernel': vps_kernel, 'machine': vps_machine, 'omr_version': vps_omr_version, 'loadavg': vps_loadavg, 'uptime': vps_uptime, 'aes': vps_aes}, 'shadowsocks': {'traffic': ss_traffic, 'key': shadowsocks_key, 'port': shadowsocks_port, 'method': shadowsocks_method, 'fast_open': shadowsocks_fast_open, 'reuse_port': shadowsocks_reuse_port, 'no_delay': shadowsocks_no_delay, 'mptcp': shadowsocks_mptcp, 'ebpf': shadowsocks_ebpf, 'obfs': shadowsocks_obfs, 'obfs_plugin': shadowsocks_obfs_plugin, 'obfs_type': shadowsocks_obfs_type}, 'glorytun': {'key': glorytun_key, 'udp': {'host_ip': glorytun_udp_host_ip, 'client_ip': glorytun_udp_client_ip}, 'tcp': {'host_ip': glorytun_tcp_host_ip, 'client_ip': glorytun_tcp_client_ip}, 'port': glorytun_port, 'chacha': glorytun_chacha}, 'dsvpn': {'key': dsvpn_key, 'host_ip': dsvpn_host_ip, 'client_ip': dsvpn_client_ip, 'port': dsvpn_port}, 'openvpn': {'key': openvpn_key, 'client_key': openvpn_client_key, 'client_crt': openvpn_client_crt, 'client_ca': openvpn_client_ca, 'host_ip': openvpn_host_ip, 'client_ip': openvpn_client_ip, 'port': openvpn_port, 'cipher': openvpn_cipher},'wireguard': {'key': wireguard_key, 'host_ip': wireguard_host_ip, 'port': wireguard_port}, 'mlvpn': {'key': mlvpn_key, 'host_ip': mlvpn_host_ip, 'client_ip': mlvpn_client_ip,'timeout': mlvpn_timeout,'reorder_buffer_size': mlvpn_reorder_buffer_size,'loss_tolerence': mlvpn_loss_tolerence,'cleartext_data': mlvpn_cleartext_data}, 'shorewall': {'redirect_ports': shorewall_redirect}, 'mptcp': {'enabled': mptcp_enabled, 'checksum': mptcp_checksum, 'path_manager': mptcp_path_manager, 'scheduler': mptcp_scheduler, 'syn_retries': mptcp_syn_retries}, 'network': {'congestion_control': congestion_control, 'ipv6_network': ipv6_network, 'ipv6': ipv6_addr, 'ipv4': ipv4_addr, 'domain': vps_domain, 'internet': internet}, 'vpn': {'available': available_vpn, 'current': vpn, 'remoteip': vpn_remote_ip, 'localip': vpn_local_ip, 'rx': vpn_traffic_rx, 'tx': vpn_traffic_tx}, 'iperf': {'user': 'openmptcprouter', 'password': 'openmptcprouter', 'key': iperf3_key}, 'pihole': {'state': pihole}, 'user': {'name': username, 'permission': user_permissions}, 'ip6in4': {'localip': localip6, 'remoteip': remoteip6, 'ula': ula}, 'client2client': {'enabled': client2client, 'lanips': alllanips}, 'gre_tunnel': {'enabled': gre_tunnel, 'config': gre_tunnel_conf}, 'v2ray': {'enabled': v2ray, 'config': v2ray_conf, 'tx': v2ray_tx, 'rx': v2ray_rx}, 'proxy': {'available': available_proxy, 'current': proxy}}
|
2018-11-08 12:55:20 +00:00
|
|
|
|
|
|
|
# Set shadowsocks config
|
2020-07-03 14:27:09 +00:00
|
|
|
class OBFSPLUGIN(str, Enum):
|
|
|
|
v2ray = "v2ray"
|
|
|
|
obfs = "obfs"
|
|
|
|
|
|
|
|
class OBFSTYPE(str, Enum):
|
|
|
|
tls = "tls"
|
|
|
|
http = "http"
|
|
|
|
|
|
|
|
|
2019-11-02 17:32:35 +00:00
|
|
|
class ShadowsocksConfigparams(BaseModel):
|
2020-07-03 14:27:09 +00:00
|
|
|
port: int = Query(..., gt=0, lt=65535)
|
2019-11-02 17:32:35 +00:00
|
|
|
method: str
|
2019-11-24 18:48:22 +00:00
|
|
|
fast_open: bool
|
2019-11-02 17:32:35 +00:00
|
|
|
reuse_port: bool
|
|
|
|
no_delay: bool
|
2020-07-03 14:27:09 +00:00
|
|
|
mptcp: bool = Query(True, title="Enable/Disable MPTCP support")
|
|
|
|
obfs: bool = Query(False, title="Enable/Disable obfuscation support")
|
|
|
|
obfs_plugin: OBFSPLUGIN = Query("v2ray", title="Choose obfuscation plugin")
|
|
|
|
obfs_type: OBFSTYPE = Query("tls", title="Choose obfuscation method")
|
2019-11-02 17:32:35 +00:00
|
|
|
key: str
|
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/shadowsocks', summary="Modify Shadowsocks-libev configuration")
|
2020-03-03 12:49:23 +00:00
|
|
|
def shadowsocks(*, params: ShadowsocksConfigparams, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2019-12-26 19:25:11 +00:00
|
|
|
set_lastchange(10)
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'shadowsocks'}
|
2020-05-14 08:44:16 +00:00
|
|
|
ipv6_network = os.popen('ip -6 addr show ' + IFACE6 +' | grep -oP "(?<=inet6 ).*(?= scope global)"').read().rstrip()
|
2020-10-28 16:47:50 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shadowsocks-libev/manager.json', 'rb'))).hexdigest()
|
2019-11-16 19:49:26 +00:00
|
|
|
with open('/etc/shadowsocks-libev/manager.json') as f:
|
2018-11-29 21:43:02 +00:00
|
|
|
content = f.read()
|
2020-03-03 13:06:18 +00:00
|
|
|
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
|
2018-12-06 09:48:23 +00:00
|
|
|
try:
|
|
|
|
data = json.loads(content)
|
|
|
|
except ValueError as e:
|
|
|
|
data = {'timeout': 600, 'verbose': 0, 'prefer_ipv6': False}
|
2018-11-29 21:43:02 +00:00
|
|
|
#key = data["key"]
|
2018-12-06 09:48:23 +00:00
|
|
|
if 'timeout' in data:
|
|
|
|
timeout = data["timeout"]
|
2018-11-29 22:14:23 +00:00
|
|
|
if 'verbose' in data:
|
|
|
|
verbose = data["verbose"]
|
|
|
|
else:
|
|
|
|
verbose = 0
|
2018-11-08 12:55:20 +00:00
|
|
|
prefer_ipv6 = data["prefer_ipv6"]
|
2019-11-02 17:32:35 +00:00
|
|
|
port = params.port
|
|
|
|
method = params.method
|
|
|
|
fast_open = params.fast_open
|
|
|
|
reuse_port = params.reuse_port
|
|
|
|
no_delay = params.no_delay
|
|
|
|
mptcp = params.mptcp
|
|
|
|
obfs = params.obfs
|
|
|
|
obfs_plugin = params.obfs_plugin
|
|
|
|
obfs_type = params.obfs_type
|
2019-11-24 18:48:22 +00:00
|
|
|
ebpf = 0
|
2019-11-02 17:32:35 +00:00
|
|
|
key = params.key
|
2020-06-19 13:49:07 +00:00
|
|
|
if 'port_key' in data:
|
|
|
|
portkey = data["port_key"]
|
2020-06-21 07:06:52 +00:00
|
|
|
portkey[str(port)] = key
|
2020-06-19 13:49:07 +00:00
|
|
|
if 'port_conf' in data:
|
|
|
|
portconf = data["port_conf"]
|
2020-06-21 07:06:52 +00:00
|
|
|
portconf[str(port)]['key'] = key
|
2020-06-20 07:08:51 +00:00
|
|
|
modif_config_user(current_user.username, {'shadowsocks_port': port})
|
2020-04-01 19:17:31 +00:00
|
|
|
userid = current_user.userid
|
|
|
|
if userid is None:
|
|
|
|
userid = 0
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
try:
|
|
|
|
omr_config_data = json.load(f)
|
|
|
|
except ValueError as e:
|
|
|
|
omr_config_data = {}
|
|
|
|
|
2019-08-29 20:39:22 +00:00
|
|
|
#ipv4_addr = os.popen('wget -4 -qO- -T 2 http://ip.openmptcprouter.com').read().rstrip()
|
2020-04-01 19:17:31 +00:00
|
|
|
if 'hostname' in omr_config_data:
|
|
|
|
vps_domain = omr_config_data['hostname']
|
|
|
|
else:
|
|
|
|
vps_domain = os.popen('wget -4 -qO- -T 1 http://hostname.openmptcprouter.com').read().rstrip()
|
|
|
|
if vps_domain != '':
|
|
|
|
set_global_param('hostname', vps_domain)
|
2019-04-18 19:09:26 +00:00
|
|
|
|
2019-01-06 17:53:06 +00:00
|
|
|
if port is None or method is None or fast_open is None or reuse_port is None or no_delay is None or key is None:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'shadowsocks'}
|
2020-06-19 13:49:07 +00:00
|
|
|
if 'port_key' in data:
|
|
|
|
if ipv6_network == '':
|
|
|
|
if obfs:
|
|
|
|
if obfs_plugin == "v2ray":
|
|
|
|
if obfs_type == "tls":
|
|
|
|
if vps_domain == '':
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server;tls'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server;tls;host=' + vps_domain}
|
2019-12-17 18:10:09 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server'}
|
2019-04-18 19:09:26 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
if obfs_type == 'tls':
|
|
|
|
if vps_domain == '':
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=tls;mptcp;fast-open;t=400'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=tls;mptcp;fast-open;t=400;host=' + vps_domain}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=http;mptcp;fast-open;t=400'}
|
2019-01-25 19:43:49 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl'}
|
|
|
|
else:
|
|
|
|
if obfs:
|
|
|
|
if obfs_plugin == "v2ray":
|
|
|
|
if obfs_type == "tls":
|
|
|
|
if vps_domain == '':
|
|
|
|
shadowsocks_config = {'server': '::0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server;tls'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': '::0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server;tls;host=' + vps_domain}
|
2019-12-17 18:10:09 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
shadowsocks_config = {'server': '::0', 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server'}
|
2019-12-17 18:10:09 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
if obfs_type == 'tls':
|
|
|
|
if vps_domain == '':
|
|
|
|
shadowsocks_config = {'server': ('[::0]', '0.0.0.0'), 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=tls;mptcp;fast-open;t=400'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': ('[::0]', '0.0.0.0'), 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=tls;mptcp;fast-open;t=400;host=' + vps_domain}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': ('[::0]', '0.0.0.0'), 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=http;mptcp;fast-open;t=400'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': ('[::0]', '0.0.0.0'), 'port_key': portkey, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl'}
|
2019-12-17 18:10:09 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
if ipv6_network == '':
|
|
|
|
if obfs:
|
|
|
|
if obfs_plugin == "v2ray":
|
|
|
|
if obfs_type == "tls":
|
|
|
|
if vps_domain == '':
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server;tls'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server;tls;host=' + vps_domain}
|
2019-12-17 18:10:09 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server'}
|
2019-04-18 19:09:26 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
if obfs_type == 'tls':
|
|
|
|
if vps_domain == '':
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=tls;mptcp;fast-open;t=400'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=tls;mptcp;fast-open;t=400;host=' + vps_domain}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=http;mptcp;fast-open;t=400'}
|
2019-01-25 19:43:49 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
shadowsocks_config = {'server': '0.0.0.0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl'}
|
|
|
|
else:
|
|
|
|
if obfs:
|
|
|
|
if obfs_plugin == "v2ray":
|
|
|
|
if obfs_type == "tls":
|
|
|
|
if vps_domain == '':
|
|
|
|
shadowsocks_config = {'server': '::0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server;tls'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': '::0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server;tls;host=' + vps_domain}
|
2019-12-17 18:10:09 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
shadowsocks_config = {'server': '::0', 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/v2ray-plugin', 'plugin_opts': 'server'}
|
2019-12-17 18:10:09 +00:00
|
|
|
else:
|
2020-06-19 13:49:07 +00:00
|
|
|
if obfs_type == 'tls':
|
|
|
|
if vps_domain == '':
|
|
|
|
shadowsocks_config = {'server': ('[::0]', '0.0.0.0'), 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=tls;mptcp;fast-open;t=400'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': ('[::0]', '0.0.0.0'), 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=tls;mptcp;fast-open;t=400;host=' + vps_domain}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': ('[::0]', '0.0.0.0'), 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl', 'plugin': '/usr/local/bin/obfs-server', 'plugin_opts': 'obfs=http;mptcp;fast-open;t=400'}
|
|
|
|
else:
|
|
|
|
shadowsocks_config = {'server': ('[::0]', '0.0.0.0'), 'port_conf': portconf, 'local_port': 1081, 'mode': 'tcp_and_udp', 'timeout': timeout, 'method': method, 'verbose': verbose, 'ipv6_first': True, 'prefer_ipv6': prefer_ipv6, 'fast_open': fast_open, 'no_delay': no_delay, 'reuse_port': reuse_port, 'mptcp': mptcp, 'ebpf': ebpf, 'acl': '/etc/shadowsocks-libev/local.acl'}
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2020-10-28 16:47:50 +00:00
|
|
|
with open('/etc/shadowsocks-libev/manager.json', 'w') as outfile:
|
|
|
|
json.dump(shadowsocks_config, outfile, indent=4)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shadowsocks-libev/manager.json', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5:
|
2019-11-16 19:49:26 +00:00
|
|
|
os.system("systemctl restart shadowsocks-libev-manager@manager.service")
|
2020-03-07 21:57:11 +00:00
|
|
|
#for x in range(1, os.cpu_count()):
|
|
|
|
# os.system("systemctl restart shadowsocks-libev-manager@manager" + str(x) + ".service")
|
2020-03-03 12:49:23 +00:00
|
|
|
shorewall_add_port(current_user, str(port), 'tcp', 'shadowsocks')
|
|
|
|
shorewall_add_port(current_user, str(port), 'udp', 'shadowsocks')
|
2019-08-12 14:43:05 +00:00
|
|
|
set_lastchange()
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied', 'route': 'shadowsocks'}
|
2018-11-08 12:55:20 +00:00
|
|
|
else:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'done', 'reason': 'no changes', 'route': 'shadowsocks'}
|
2018-11-08 12:55:20 +00:00
|
|
|
|
2018-11-08 17:05:34 +00:00
|
|
|
# Set shorewall config
|
2020-07-03 14:27:09 +00:00
|
|
|
class IPPROTO(str, Enum):
|
|
|
|
ipv4 = "ipv4"
|
|
|
|
ipv6 = "ipv6"
|
|
|
|
|
2019-11-02 17:32:35 +00:00
|
|
|
class ShorewallAllparams(BaseModel):
|
2020-07-03 14:27:09 +00:00
|
|
|
redirect_ports: str = Query(..., title="Port or ports range")
|
|
|
|
ipproto: IPPROTO = Query("ipv4", title="Protocol IP to apply changes")
|
2019-11-02 17:32:35 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/shorewall', summary="Redirect all ports from Server to router")
|
2020-03-03 12:49:23 +00:00
|
|
|
def shorewall(*, params: ShorewallAllparams, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewall'}
|
2019-11-02 17:32:35 +00:00
|
|
|
state = params.redirect_ports
|
2019-01-06 17:53:06 +00:00
|
|
|
if state is None:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'shorewall'}
|
2020-01-09 08:48:02 +00:00
|
|
|
if params.ipproto == 'ipv4':
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/rules', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall/rules', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-09 08:48:02 +00:00
|
|
|
for line in f:
|
|
|
|
if state == 'enable' and line == '#DNAT net vpn:$OMR_ADDR tcp 1-64999\n':
|
|
|
|
n.write(line.replace(line[:1], ''))
|
|
|
|
elif state == 'enable' and line == '#DNAT net vpn:$OMR_ADDR udp 1-64999\n':
|
|
|
|
n.write(line.replace(line[:1], ''))
|
|
|
|
elif state == 'disable' and line == 'DNAT net vpn:$OMR_ADDR tcp 1-64999\n':
|
|
|
|
n.write('#' + line)
|
|
|
|
elif state == 'disable' and line == 'DNAT net vpn:$OMR_ADDR udp 1-64999\n':
|
|
|
|
n.write('#' + line)
|
|
|
|
else:
|
|
|
|
n.write(line)
|
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall/rules')
|
2020-01-09 08:48:02 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/rules', 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-09 08:48:02 +00:00
|
|
|
os.system("systemctl -q reload shorewall")
|
|
|
|
else:
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall6/rules', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall6/rules', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-09 08:48:02 +00:00
|
|
|
for line in f:
|
|
|
|
if state == 'enable' and line == '#DNAT net vpn:$OMR_ADDR tcp 1-64999\n':
|
|
|
|
n.write(line.replace(line[:1], ''))
|
|
|
|
elif state == 'enable' and line == '#DNAT net vpn:$OMR_ADDR udp 1-64999\n':
|
|
|
|
n.write(line.replace(line[:1], ''))
|
|
|
|
elif state == 'disable' and line == 'DNAT net vpn:$OMR_ADDR tcp 1-64999\n':
|
|
|
|
n.write('#' + line)
|
|
|
|
elif state == 'disable' and line == 'DNAT net vpn:$OMR_ADDR udp 1-64999\n':
|
|
|
|
n.write('#' + line)
|
|
|
|
else:
|
|
|
|
n.write(line)
|
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall6/rules')
|
2020-01-09 08:48:02 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall6/rules', 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-09 08:48:02 +00:00
|
|
|
os.system("systemctl -q reload shorewall6")
|
2018-11-08 17:05:34 +00:00
|
|
|
# Need to do the same for IPv6...
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied'}
|
2018-11-08 17:05:34 +00:00
|
|
|
|
2019-11-02 17:32:35 +00:00
|
|
|
class ShorewallListparams(BaseModel):
|
|
|
|
name: str
|
2020-07-03 14:27:09 +00:00
|
|
|
ipproto: IPPROTO = Query("ipv4", title="Protocol IP to list")
|
2019-11-02 17:32:35 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/shorewalllist', summary="Display all OpenMPTCProuter rules in Shorewall config")
|
2020-03-03 12:49:23 +00:00
|
|
|
def shorewall_list(*, params: ShorewallListparams, current_user: User = Depends(get_current_user)):
|
2019-11-02 17:32:35 +00:00
|
|
|
name = params.name
|
2019-09-29 18:54:54 +00:00
|
|
|
if name is None:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'shorewalllist'}
|
2019-09-29 18:54:54 +00:00
|
|
|
fwlist = []
|
2020-01-09 08:48:02 +00:00
|
|
|
if params.ipproto == 'ipv4':
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall/rules', 'r') as f:
|
2020-01-09 08:48:02 +00:00
|
|
|
for line in f:
|
2020-03-09 14:52:15 +00:00
|
|
|
if '# OMR ' + current_user.username + ' ' + name in line:
|
2020-01-09 08:48:02 +00:00
|
|
|
fwlist.append(line)
|
|
|
|
else:
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall6/rules', 'r') as f:
|
2020-01-09 08:48:02 +00:00
|
|
|
for line in f:
|
2020-03-09 14:52:15 +00:00
|
|
|
if '# OMR ' + current_user.username + ' ' + name in line:
|
2020-01-09 08:48:02 +00:00
|
|
|
fwlist.append(line)
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'list': fwlist}
|
2019-09-29 18:54:54 +00:00
|
|
|
|
2019-11-02 17:32:35 +00:00
|
|
|
class Shorewallparams(BaseModel):
|
|
|
|
name: str
|
2019-12-17 18:10:09 +00:00
|
|
|
port: str
|
2019-11-02 17:32:35 +00:00
|
|
|
proto: str
|
|
|
|
fwtype: str
|
2020-07-03 14:27:09 +00:00
|
|
|
ipproto: IPPROTO = Query("ipv4", title="Protocol IP for changes")
|
2020-06-15 13:53:03 +00:00
|
|
|
source_dip: str = ""
|
2020-07-25 14:16:55 +00:00
|
|
|
source_ip: str = ""
|
2019-11-02 17:32:35 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/shorewallopen', summary="Redirect a port from Server to Router")
|
2020-03-03 12:49:23 +00:00
|
|
|
def shorewall_open(*, params: Shorewallparams, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewallopen'}
|
2020-09-29 13:41:48 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
try:
|
|
|
|
omr_config_data = json.load(f)
|
|
|
|
except ValueError as e:
|
|
|
|
omr_config_data = {}
|
2019-11-02 17:32:35 +00:00
|
|
|
name = params.name
|
|
|
|
port = params.port
|
|
|
|
proto = params.proto
|
|
|
|
fwtype = params.fwtype
|
2020-06-15 13:53:03 +00:00
|
|
|
source_dip = params.source_dip
|
2020-07-25 14:16:55 +00:00
|
|
|
source_ip = params.source_ip
|
2020-09-29 13:41:48 +00:00
|
|
|
vpn = "default"
|
2020-10-19 14:49:27 +00:00
|
|
|
username = current_user.username
|
2019-09-29 18:54:54 +00:00
|
|
|
if name is None:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'shorewallopen'}
|
2020-10-19 14:49:27 +00:00
|
|
|
#proxy = 'shadowsocks'
|
|
|
|
#if 'proxy' in omr_config_data['users'][0][username]:
|
|
|
|
# proxy = omr_config_data['users'][0][username]['proxy']
|
|
|
|
#if proxy == 'v2ray':
|
|
|
|
# v2ray_add_port(current_user, str(port), proto, name)
|
|
|
|
# fwtype = 'ACCEPT'
|
2020-01-09 08:48:02 +00:00
|
|
|
if params.ipproto == 'ipv4':
|
2020-09-29 13:41:48 +00:00
|
|
|
if 'gre_tunnels' in omr_config_data['users'][0][current_user.username]:
|
|
|
|
for tunnel in omr_config_data['users'][0][current_user.username]['gre_tunnels']:
|
|
|
|
if omr_config_data['users'][0][current_user.username]['gre_tunnels'][tunnel]['public_ip'] == source_dip:
|
|
|
|
vpn = omr_config_data['users'][0][current_user.username]['gre_tunnels'][tunnel]['remote_ip']
|
|
|
|
shorewall_add_port(current_user, str(port), proto, name, fwtype, source_dip, source_ip, vpn)
|
2020-01-09 08:48:02 +00:00
|
|
|
else:
|
2020-07-25 14:16:55 +00:00
|
|
|
shorewall6_add_port(current_user, str(port), proto, name, fwtype, source_dip, source_ip)
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied'}
|
2019-09-29 18:54:54 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/shorewallclose', summary="Remove a redirected port")
|
2020-03-03 12:49:23 +00:00
|
|
|
def shorewall_close(*, params: Shorewallparams, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewallclose'}
|
2019-11-02 17:32:35 +00:00
|
|
|
name = params.name
|
|
|
|
port = params.port
|
|
|
|
proto = params.proto
|
|
|
|
fwtype = params.fwtype
|
2020-06-15 13:53:03 +00:00
|
|
|
source_dip = params.source_dip
|
2020-07-25 14:16:55 +00:00
|
|
|
source_ip = params.source_ip
|
2019-09-29 18:54:54 +00:00
|
|
|
if name is None:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'shorewallclose'}
|
2020-10-19 14:49:27 +00:00
|
|
|
#v2ray_del_port(current_user.username, str(port), proto, name)
|
2020-01-09 08:48:02 +00:00
|
|
|
if params.ipproto == 'ipv4':
|
2020-10-19 14:49:27 +00:00
|
|
|
shorewall_del_port(current_user.username, str(port), proto, name, 'DNAT', source_dip, source_ip)
|
|
|
|
shorewall_del_port(current_user.username, str(port), proto, name, 'ACCEPT', source_dip, source_ip)
|
2020-01-09 08:48:02 +00:00
|
|
|
else:
|
2020-10-19 14:49:27 +00:00
|
|
|
shorewall6_del_port(current_user.username, str(port), proto, name, 'DNAT', source_dip, source_ip)
|
|
|
|
shorewall6_del_port(current_user.username, str(port), proto, name, 'ACCEPT', source_dip, source_ip)
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied', 'route': 'shorewallclose'}
|
2019-09-29 18:54:54 +00:00
|
|
|
|
2020-11-02 19:39:18 +00:00
|
|
|
class V2rayconfig(BaseModel):
|
|
|
|
userid: str
|
|
|
|
|
|
|
|
@app.post('/v2ray', summary="Set v2ray settings")
|
|
|
|
def v2ray(*, params: V2rayconfig, current_user: User = Depends(get_current_user)):
|
|
|
|
if current_user.permissions == "ro":
|
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'v2rayredirect'}
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
|
|
|
with open('/etc/v2ray/v2ray-server.json') as f:
|
|
|
|
v2ray_config = json.load(f)
|
2020-11-10 14:02:02 +00:00
|
|
|
v2ruserid = params.userid
|
2020-11-02 19:39:18 +00:00
|
|
|
for inbounds in v2ray_config['inbounds']:
|
|
|
|
if inbounds['tag'] == 'omrin-tunnel':
|
2020-11-10 14:02:02 +00:00
|
|
|
inbounds['settings']['clients'][0]['id'] = v2ruserid
|
2020-11-02 19:39:18 +00:00
|
|
|
with open('/etc/v2ray/v2ray-server.json', 'w') as outfile:
|
|
|
|
json.dump(v2ray_config, outfile, indent=4)
|
2020-11-10 14:05:53 +00:00
|
|
|
username = current_user.username
|
2020-11-02 19:39:18 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/v2ray/v2ray-server.json', 'rb'))).hexdigest()
|
2020-11-10 14:02:02 +00:00
|
|
|
v2ray_key = os.popen('jq -r .inbounds[0].settings.clients[0].id /etc/v2ray/v2ray-server.json').read().rstrip()
|
|
|
|
v2ray_port = os.popen('jq -r .inbounds[0].port /etc/v2ray/v2ray-server.json').read().rstrip()
|
|
|
|
v2ray_conf = { 'key': v2ray_key, 'port': v2ray_port}
|
|
|
|
modif_config_user(username, {'v2ray': v2ray_conf})
|
2020-11-02 19:39:18 +00:00
|
|
|
if initial_md5 != final_md5:
|
|
|
|
os.system("systemctl restart v2ray")
|
|
|
|
set_lastchange()
|
|
|
|
return {'result': 'done', 'reason': 'changes applied', 'route': 'v2ray'}
|
|
|
|
else:
|
|
|
|
return {'result': 'done', 'reason': 'no changes', 'route': 'v2ray'}
|
|
|
|
|
|
|
|
|
2020-10-19 14:49:27 +00:00
|
|
|
class V2rayparams(BaseModel):
|
|
|
|
name: str
|
|
|
|
port: str
|
|
|
|
proto: str
|
|
|
|
destip: str
|
2020-10-20 18:01:10 +00:00
|
|
|
destport: str
|
2020-10-19 14:49:27 +00:00
|
|
|
|
|
|
|
@app.post('/v2rayredirect', summary="Redirect a port from Server to Router with V2Ray")
|
|
|
|
def v2ray_redirect(*, params: V2rayparams, current_user: User = Depends(get_current_user)):
|
|
|
|
if current_user.permissions == "ro":
|
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'v2rayredirect'}
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
try:
|
|
|
|
omr_config_data = json.load(f)
|
|
|
|
except ValueError as e:
|
|
|
|
omr_config_data = {}
|
|
|
|
name = params.name
|
|
|
|
port = params.port
|
|
|
|
proto = params.proto
|
|
|
|
destip = params.destip
|
2020-10-20 18:01:10 +00:00
|
|
|
destport = params.destport
|
2020-10-19 14:49:27 +00:00
|
|
|
username = current_user.username
|
|
|
|
if name is None:
|
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'v2rayredirect'}
|
2020-10-20 18:01:10 +00:00
|
|
|
v2ray_add_port(current_user, port, proto, name, destip, destport)
|
2020-10-19 14:49:27 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied'}
|
|
|
|
|
|
|
|
@app.post('/v2rayunredirect', summary="Remove a redirected port from Server to Router with V2Ray")
|
|
|
|
def v2ray_unredirect(*, params: V2rayparams, current_user: User = Depends(get_current_user)):
|
|
|
|
if current_user.permissions == "ro":
|
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'v2rayredirect'}
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
try:
|
|
|
|
omr_config_data = json.load(f)
|
|
|
|
except ValueError as e:
|
|
|
|
omr_config_data = {}
|
|
|
|
name = params.name
|
|
|
|
port = params.port
|
|
|
|
proto = params.proto
|
|
|
|
username = curent_user.username
|
|
|
|
if name is None:
|
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'v2rayunredirect'}
|
|
|
|
v2ray_del_port(current_user, port, proto, name)
|
|
|
|
return {'result': 'done', 'reason': 'changes applied'}
|
|
|
|
|
2018-11-14 16:34:13 +00:00
|
|
|
# Set MPTCP config
|
2019-11-02 17:32:35 +00:00
|
|
|
class MPTCPparams(BaseModel):
|
|
|
|
checksum: str
|
|
|
|
path_manager: str
|
|
|
|
scheduler: str
|
|
|
|
syn_retries: int
|
|
|
|
congestion_control: str
|
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/mptcp', summary="Modify MPTCP configuration of the server")
|
2020-03-03 12:49:23 +00:00
|
|
|
def mptcp(*, params: MPTCPparams, current_user: User = Depends(get_current_user)):
|
2019-12-26 19:25:11 +00:00
|
|
|
if current_user.permissions == "ro":
|
|
|
|
set_lastchange(10)
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'mptcp'}
|
2019-11-02 17:32:35 +00:00
|
|
|
checksum = params.checksum
|
|
|
|
path_manager = params.path_manager
|
|
|
|
scheduler = params.scheduler
|
|
|
|
syn_retries = params.syn_retries
|
|
|
|
congestion_control = params.congestion_control
|
2019-01-06 18:00:45 +00:00
|
|
|
if not checksum or not path_manager or not scheduler or not syn_retries or not congestion_control:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'mptcp'}
|
2018-12-28 07:55:46 +00:00
|
|
|
os.system('sysctl -qw net.mptcp.mptcp_checksum=' + checksum)
|
|
|
|
os.system('sysctl -qw net.mptcp.mptcp_path_manager=' + path_manager)
|
|
|
|
os.system('sysctl -qw net.mptcp.mptcp_scheduler=' + scheduler)
|
2020-02-19 18:29:17 +00:00
|
|
|
os.system('sysctl -qw net.mptcp.mptcp_syn_retries=' + str(syn_retries))
|
2018-12-28 07:55:46 +00:00
|
|
|
os.system('sysctl -qw net.ipv4.tcp_congestion_control=' + congestion_control)
|
2019-08-12 14:43:05 +00:00
|
|
|
set_lastchange()
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied'}
|
2019-11-02 17:10:10 +00:00
|
|
|
|
2020-07-03 14:27:09 +00:00
|
|
|
class VPN(str, Enum):
|
|
|
|
openvpn = "openvpn"
|
2020-12-11 20:40:39 +00:00
|
|
|
openvpnbonding = "openvpn_bonding"
|
2020-07-03 14:27:09 +00:00
|
|
|
glorytuntcp = "glorytun_tcp"
|
|
|
|
glorytunudp = "glorytun_udp"
|
|
|
|
dsvpn = "dsvpn"
|
2020-08-20 18:31:29 +00:00
|
|
|
mlvpn = "mlvpn"
|
|
|
|
none = "none"
|
2020-07-03 14:27:09 +00:00
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
class Vpn(BaseModel):
|
2020-07-03 14:27:09 +00:00
|
|
|
vpn: VPN
|
2018-11-14 16:34:13 +00:00
|
|
|
|
2019-06-24 16:14:16 +00:00
|
|
|
# Set global VPN config
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/vpn', summary="Set VPN used by the current user")
|
2020-03-03 12:49:23 +00:00
|
|
|
def vpn(*, vpnconfig: Vpn, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2019-12-26 19:25:11 +00:00
|
|
|
set_lastchange(10)
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'vpn'}
|
2019-11-02 17:10:10 +00:00
|
|
|
vpn = vpnconfig.vpn
|
2019-06-24 16:14:16 +00:00
|
|
|
if not vpn:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'vpn'}
|
2019-06-24 16:14:16 +00:00
|
|
|
os.system('echo ' + vpn + ' > /etc/openmptcprouter-vps-admin/current-vpn')
|
2020-06-20 07:08:51 +00:00
|
|
|
modif_config_user(current_user.username, {'vpn': vpn})
|
2019-12-26 19:25:11 +00:00
|
|
|
current_user.vpn = vpn
|
2019-08-12 14:43:05 +00:00
|
|
|
set_lastchange()
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied'}
|
2019-11-02 17:10:10 +00:00
|
|
|
|
2020-08-10 18:49:47 +00:00
|
|
|
class PROXY(str, Enum):
|
|
|
|
v2ray = "v2ray"
|
|
|
|
shadowsockslibev = "shadowsocks"
|
|
|
|
none = "none"
|
|
|
|
|
|
|
|
class Proxy(BaseModel):
|
|
|
|
proxy: PROXY
|
|
|
|
|
|
|
|
# Set global Proxy config
|
|
|
|
@app.post('/proxy', summary="Set Proxy used by the current user")
|
|
|
|
def proxy(*, proxyconfig: Proxy, current_user: User = Depends(get_current_user)):
|
|
|
|
if current_user.permissions == "ro":
|
|
|
|
set_lastchange(10)
|
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'proxy'}
|
2020-08-20 18:31:29 +00:00
|
|
|
proxy = proxyconfig.proxy
|
2020-08-10 18:49:47 +00:00
|
|
|
if not proxy:
|
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'proxy'}
|
|
|
|
os.system('echo ' + proxy + ' > /etc/openmptcprouter-vps-admin/current-proxy')
|
|
|
|
modif_config_user(current_user.username, {'proxy': proxy})
|
2020-09-11 18:58:38 +00:00
|
|
|
#current_user.proxy = proxy
|
2020-08-10 18:49:47 +00:00
|
|
|
set_lastchange()
|
|
|
|
return {'result': 'done', 'reason': 'changes applied'}
|
|
|
|
|
2019-06-24 16:14:16 +00:00
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
class GlorytunConfig(BaseModel):
|
|
|
|
key: str
|
2020-07-03 14:27:09 +00:00
|
|
|
port: int = Query(..., gt=0, lt=65535, title="Glorytun TCP and UDP port")
|
|
|
|
chacha: bool = Query(True, title="Enable of disable chacha20, if disable AEGIS is used")
|
2018-11-14 16:34:13 +00:00
|
|
|
|
2018-12-06 09:48:23 +00:00
|
|
|
# Set Glorytun config
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/glorytun', summary="Modify Glorytun configuration")
|
2020-03-03 12:49:23 +00:00
|
|
|
def glorytun(*, glorytunconfig: GlorytunConfig, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2019-12-26 19:25:11 +00:00
|
|
|
set_lastchange(10)
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'glorytun'}
|
2020-01-10 19:50:06 +00:00
|
|
|
userid = current_user.userid
|
2020-04-21 12:55:35 +00:00
|
|
|
if userid is None:
|
2020-01-10 19:50:06 +00:00
|
|
|
userid = 0
|
2019-11-02 17:10:10 +00:00
|
|
|
key = glorytunconfig.key
|
|
|
|
port = glorytunconfig.port
|
|
|
|
chacha = glorytunconfig.chacha
|
2020-01-10 19:50:06 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/glorytun-tcp/tun' + str(userid), 'rb'))).hexdigest()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/glorytun-tcp/tun' + str(userid) + '.key', 'w') as outfile:
|
2018-12-06 09:48:23 +00:00
|
|
|
outfile.write(key)
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/glorytun-udp/tun' + str(userid) + '.key', 'w') as outfile:
|
2018-12-06 09:48:23 +00:00
|
|
|
outfile.write(key)
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/glorytun-tcp/tun' + str(userid), 'r') as f, open(tmpfile, 'a+') as n:
|
2018-12-06 09:48:23 +00:00
|
|
|
for line in f:
|
|
|
|
if 'PORT=' in line:
|
|
|
|
n.write('PORT=' + str(port) + '\n')
|
2019-05-23 19:55:49 +00:00
|
|
|
elif 'OPTIONS=' in line:
|
|
|
|
if chacha:
|
|
|
|
n.write('OPTIONS="chacha20 retry count -1 const 5000000 timeout 90000 keepalive count 5 idle 10 interval 2 buffer-size 65536 multiqueue"\n')
|
|
|
|
else:
|
|
|
|
n.write('OPTIONS="retry count -1 const 5000000 timeout 90000 keepalive count 5 idle 10 interval 2 buffer-size 65536 multiqueue"\n')
|
2018-12-06 09:48:23 +00:00
|
|
|
else:
|
|
|
|
n.write(line)
|
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/glorytun-tcp/tun' + str(userid))
|
2020-01-10 19:50:06 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/glorytun-tcp/tun' + str(userid), 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-10 19:50:06 +00:00
|
|
|
os.system("systemctl -q restart glorytun-tcp@tun" + str(userid))
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/glorytun-udp/tun' + str(userid), 'rb'))).hexdigest()
|
2018-12-06 09:48:23 +00:00
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/glorytun-udp/tun' + str(userid), 'r') as f, open(tmpfile, 'a+') as n:
|
2018-12-06 09:48:23 +00:00
|
|
|
for line in f:
|
|
|
|
if 'BIND_PORT=' in line:
|
|
|
|
n.write('BIND_PORT=' + str(port) + '\n')
|
2019-05-23 19:55:49 +00:00
|
|
|
elif 'OPTIONS=' in line:
|
|
|
|
if chacha:
|
|
|
|
n.write('OPTIONS="chacha persist"\n')
|
|
|
|
else:
|
|
|
|
n.write('OPTIONS="persist"\n')
|
2018-12-06 09:48:23 +00:00
|
|
|
else:
|
|
|
|
n.write(line)
|
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/glorytun-udp/tun' + str(userid))
|
2020-01-10 19:50:06 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/glorytun-udp/tun' + str(userid), 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-10 19:50:06 +00:00
|
|
|
os.system("systemctl -q restart glorytun-udp@tun" + str(userid))
|
2020-03-03 12:49:23 +00:00
|
|
|
shorewall_add_port(current_user, str(port), 'tcp', 'glorytun')
|
2020-03-24 20:07:41 +00:00
|
|
|
shorewall_add_port(current_user, str(port), 'udp', 'glorytun')
|
2019-08-12 14:43:05 +00:00
|
|
|
set_lastchange()
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'result': 'done'}
|
2018-12-06 09:48:23 +00:00
|
|
|
|
2019-08-02 15:22:43 +00:00
|
|
|
# Set A Dead Simple VPN config
|
2019-11-02 17:32:35 +00:00
|
|
|
class DSVPN(BaseModel):
|
|
|
|
key: str
|
2020-07-03 14:27:09 +00:00
|
|
|
port: int = Query(..., gt=0, lt=65535)
|
2019-11-02 17:32:35 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/dsvpn', summary="Modify DSVPN configuration")
|
2020-03-03 12:49:23 +00:00
|
|
|
def dsvpn(*, params: DSVPN, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2019-12-26 19:25:11 +00:00
|
|
|
set_lastchange(10)
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'dsvpn'}
|
2020-01-12 17:41:34 +00:00
|
|
|
userid = current_user.userid
|
2020-04-21 12:55:35 +00:00
|
|
|
if userid is None:
|
2020-01-12 17:41:34 +00:00
|
|
|
userid = 0
|
2019-11-02 17:32:35 +00:00
|
|
|
key = params.key
|
|
|
|
port = params.port
|
2019-08-02 15:22:43 +00:00
|
|
|
if not key or port is None:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'dsvpn'}
|
2020-01-12 17:41:34 +00:00
|
|
|
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/dsvpn/dsvpn' + str(userid), 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-12 17:41:34 +00:00
|
|
|
for line in f:
|
|
|
|
if 'PORT=' in line:
|
|
|
|
n.write('PORT=' + str(port) + '\n')
|
|
|
|
else:
|
|
|
|
n.write(line)
|
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/dsvpn/dsvpn' + str(userid))
|
2020-01-12 17:41:34 +00:00
|
|
|
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/dsvpn/dsvpn' + str(userid) + '.key', 'rb'))).hexdigest()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/dsvpn/dsvpn.key', 'w') as outfile:
|
2019-08-02 15:22:43 +00:00
|
|
|
outfile.write(key)
|
2020-01-12 17:41:34 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/dsvpn/dsvpn' + str(userid) + '.key', 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-12 17:41:34 +00:00
|
|
|
os.system("systemctl -q restart dsvpn-server@dsvpn" + str(userid))
|
2020-03-03 12:49:23 +00:00
|
|
|
shorewall_add_port(current_user, str(port), 'tcp', 'dsvpn')
|
2019-08-12 14:43:05 +00:00
|
|
|
set_lastchange()
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'result': 'done'}
|
2019-08-02 15:22:43 +00:00
|
|
|
|
2021-03-15 14:07:25 +00:00
|
|
|
# Set MLVPN config
|
|
|
|
class MLVPN(BaseModel):
|
|
|
|
timeout: int
|
|
|
|
reorder_buffer_size: int
|
|
|
|
loss_tolerence: int
|
|
|
|
cleartext_data: int
|
|
|
|
password: str
|
|
|
|
|
|
|
|
@app.post('/mlvpn', summary="Modify MLVPN configuration")
|
|
|
|
def mlvpn(*, params: MLVPN, current_user: User = Depends(get_current_user)):
|
|
|
|
if current_user.permissions == "ro":
|
|
|
|
set_lastchange(10)
|
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'mlvpn'}
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/mlvpn/mlvpn0.conf', 'rb'))).hexdigest()
|
|
|
|
mlvpn_config = configparser.ConfigParser()
|
|
|
|
mlvpn_config.read_file(open(r'/etc/mlvpn/mlvpn0.conf'))
|
|
|
|
mlvpn_config.set('general', 'password', '"' + params.password + '"')
|
|
|
|
mlvpn_config.set('general', 'timeout',str(params.timeout))
|
|
|
|
mlvpn_config.set('general', 'reorder_buffer_size',str(params.reorder_buffer_size))
|
|
|
|
mlvpn_config.set('general', 'loss_tolerence',str(params.loss_tolerence))
|
|
|
|
mlvpn_config.set('general', 'cleartext_data',str(params.cleartext_data))
|
|
|
|
with open('/etc/mlvpn/mlvpn0.conf','w') as mlvpn_file:
|
|
|
|
mlvpn_config.write(mlvpn_file)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/mlvpn/mlvpn0.conf', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5:
|
|
|
|
os.system("systemctl -q restart mlvpn@mlvpn0")
|
|
|
|
set_lastchange()
|
|
|
|
return {'result': 'done', 'reason': 'changes applied', 'route': 'mlvpn'}
|
|
|
|
|
|
|
|
|
2018-12-06 09:48:23 +00:00
|
|
|
# Set OpenVPN config
|
2019-11-02 17:32:35 +00:00
|
|
|
class OpenVPN(BaseModel):
|
2020-07-03 14:27:09 +00:00
|
|
|
port: int = Query(..., gt=0, lt=65535)
|
2020-07-02 16:12:31 +00:00
|
|
|
cipher: str = "AES-256-CBC"
|
2019-11-02 17:32:35 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/openvpn', summary="Modify OpenVPN TCP configuration")
|
2020-07-02 16:12:31 +00:00
|
|
|
def openvpn(*, params: OpenVPN, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2019-12-26 19:25:11 +00:00
|
|
|
set_lastchange(10)
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'openvpn'}
|
2020-07-02 16:12:31 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/openvpn/tun0', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
|
|
|
with open('/etc/openvpn/tun0', 'r') as f, open(tmpfile, 'a+') as n:
|
|
|
|
for line in f:
|
|
|
|
if 'cipher ' in line:
|
|
|
|
n.write('cipher ' + params.cipher + '\n')
|
|
|
|
elif 'port ' in line:
|
|
|
|
n.write('port ' + str(params.port) + '\n')
|
|
|
|
else:
|
|
|
|
n.write(line)
|
|
|
|
os.close(fd)
|
|
|
|
move(tmpfile, '/etc/openvpn/tun0')
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/openvpn/tun0', 'rb'))).hexdigest()
|
|
|
|
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2019-06-02 21:11:58 +00:00
|
|
|
os.system("systemctl -q restart openvpn@tun0")
|
2020-07-02 16:12:31 +00:00
|
|
|
shorewall_add_port(current_user, str(port), 'tcp', 'openvpn')
|
|
|
|
set_lastchange()
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'result': 'done'}
|
|
|
|
|
2021-03-02 13:28:35 +00:00
|
|
|
# Set WireGuard config
|
|
|
|
class WireGuardPeer(BaseModel):
|
|
|
|
ip: str
|
|
|
|
key: str
|
|
|
|
|
|
|
|
class WireGuard(BaseModel):
|
|
|
|
peers: List[WireGuardPeer] = []
|
|
|
|
|
|
|
|
@app.post('/wireguard', summary="Modify Wireguard configuration")
|
|
|
|
def wireguard(*, params: WireGuard, current_user: User = Depends(get_current_user)):
|
2021-03-05 18:56:56 +00:00
|
|
|
if not os.path.isfile('/etc/wireguard/wg0.conf'):
|
|
|
|
return {'result': 'error', 'reason': 'Wireguard config not found', 'route': 'wireguard'}
|
2021-03-02 17:24:22 +00:00
|
|
|
wg_config = configparser.ConfigParser(strict=False)
|
2021-03-02 13:28:35 +00:00
|
|
|
wg_config.read_file(open(r'/etc/wireguard/wg0.conf'))
|
|
|
|
wg_port = wg_config.get('Interface', 'ListenPort')
|
|
|
|
wg_key = wg_config.get('Interface', 'PrivateKey')
|
|
|
|
|
2021-03-02 17:24:22 +00:00
|
|
|
fd, tmpfile = mkstemp()
|
2021-03-02 13:28:35 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/wireguard/wg0.conf', 'rb'))).hexdigest()
|
|
|
|
with open(tmpfile, 'a+') as n:
|
|
|
|
n.write('[Interface]\n')
|
|
|
|
n.write('ListenPort = ' + wg_port + '\n')
|
|
|
|
n.write('PrivateKey = ' + wg_key + '\n')
|
|
|
|
for peer in params.peers:
|
|
|
|
n.write('\n')
|
2021-03-05 18:56:56 +00:00
|
|
|
n.write('[Peer]\n')
|
2021-03-02 13:28:35 +00:00
|
|
|
n.write('PublicKey = ' + peer.key + '\n')
|
2021-03-02 17:24:22 +00:00
|
|
|
n.write('AllowedIPs = ' + peer.ip + '\n')
|
2021-03-02 13:28:35 +00:00
|
|
|
move(tmpfile, '/etc/wireguard/wg0.conf')
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/wireguard/wg0.conf', 'rb'))).hexdigest()
|
|
|
|
if initial_md5 != final_md5:
|
|
|
|
os.system("wg setconf wg0 /etc/wireguard/wg0.conf")
|
|
|
|
shorewall_add_port(current_user, str(wg_port), 'udp', 'wireguard')
|
|
|
|
set_lastchange()
|
2021-03-04 13:52:04 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied', 'route': 'wireguard'}
|
2021-03-02 13:28:35 +00:00
|
|
|
|
|
|
|
|
2019-11-02 17:10:10 +00:00
|
|
|
class Wanips(BaseModel):
|
|
|
|
ips: str
|
2018-11-14 14:10:42 +00:00
|
|
|
|
2019-08-29 20:39:22 +00:00
|
|
|
# Set WANIP
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/wan', summary="Set WAN IPs")
|
2020-03-03 12:49:23 +00:00
|
|
|
def wan(*, wanips: Wanips, current_user: User = Depends(get_current_user)):
|
2019-11-02 17:10:10 +00:00
|
|
|
ips = wanips.ips
|
2019-08-29 20:39:22 +00:00
|
|
|
if not ips:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'wan'}
|
2019-08-29 20:39:22 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shadowsocks-libev/local.acl', 'rb'))).hexdigest()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shadowsocks-libev/local.acl', 'w') as outfile:
|
2019-08-29 20:39:22 +00:00
|
|
|
outfile.write('[white_list]\n')
|
|
|
|
outfile.write(ips)
|
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shadowsocks-libev/local.acl', 'rb'))).hexdigest()
|
2020-06-20 07:08:51 +00:00
|
|
|
#modif_config_user(current_user.username,{'wanips': wanip})
|
2021-03-04 13:52:04 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied', 'route': 'wan'}
|
2019-08-29 20:39:22 +00:00
|
|
|
|
2020-01-09 21:20:05 +00:00
|
|
|
class Lanips(BaseModel):
|
|
|
|
lanips: List[str] = []
|
|
|
|
|
|
|
|
# Set user lan config
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/lan', summary="Set current user LAN IPs")
|
2020-03-03 12:49:23 +00:00
|
|
|
def lan(*, lanconfig: Lanips, current_user: User = Depends(get_current_user)):
|
2020-01-09 21:20:05 +00:00
|
|
|
lanips = lanconfig.lanips
|
|
|
|
if not lanips:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'lan'}
|
2020-06-20 07:08:51 +00:00
|
|
|
modif_config_user(current_user.username, {'lanips': lanips})
|
2020-01-12 17:41:34 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
omr_config_data = json.load(f)
|
2020-01-13 20:47:29 +00:00
|
|
|
client2client = False
|
2020-01-12 17:41:34 +00:00
|
|
|
if 'client2client' in omr_config_data:
|
|
|
|
client2client = omr_config_data["client2client"]
|
2020-01-17 20:32:48 +00:00
|
|
|
if client2client == True:
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/openvpn/ccd/' + current_user.username, 'w') as outfile:
|
2020-01-13 20:47:29 +00:00
|
|
|
for lan in lanips:
|
|
|
|
ip = IPNetwork(lan)
|
|
|
|
outfile.write('iroute ' + str(ip.network) + ' ' + str(ip.netmask) + "\n")
|
|
|
|
#outfile.write('route ' + str(ip.network) + ' ' + str(ip.netmask) + "\n")
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/openvpn/tun0.conf', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/openvpn/tun0.conf', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-13 20:47:29 +00:00
|
|
|
for line in f:
|
|
|
|
if not 'push "route ' + str(ip.network) + ' ' + str(ip.netmask) + '"' in line:
|
|
|
|
n.write(line)
|
|
|
|
n.write('push "route ' + str(ip.network) + ' ' + str(ip.netmask) + '"' + "\n")
|
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/openvpn/tun0.conf')
|
2020-01-13 20:47:29 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/openvpn/tun0.conf', 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-13 20:47:29 +00:00
|
|
|
os.system("systemctl -q restart openvpn@tun0")
|
|
|
|
set_lastchange()
|
2021-03-04 13:52:04 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied', 'route': 'lan'}
|
2020-01-09 21:20:05 +00:00
|
|
|
|
2020-01-17 07:10:44 +00:00
|
|
|
class VPNips(BaseModel):
|
2020-07-03 14:27:09 +00:00
|
|
|
remoteip: str = Query(..., regex='^(10(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){3}|((172\.(1[6-9]|2[0-9]|3[01]))|192\.168)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){2})$')
|
|
|
|
localip: str = Query(..., regex='^(10(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){3}|((172\.(1[6-9]|2[0-9]|3[01]))|192\.168)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{1,2}|[0-9]{1,2})){2})$')
|
|
|
|
remoteip6: Optional[str] = Query(None, regex='(?:^|(?<=\s))(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?=\s|$)')
|
|
|
|
localip6: Optional[str] = Query(None, regex='(?:^|(?<=\s))(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?=\s|$)')
|
|
|
|
ula: Optional[str] = None
|
2020-01-17 07:10:44 +00:00
|
|
|
|
|
|
|
# Set user vpn IPs
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/vpnips', summary="Set current user VPN IPs")
|
2020-03-03 12:49:23 +00:00
|
|
|
def vpnips(*, vpnconfig: VPNips, current_user: User = Depends(get_current_user)):
|
2020-05-14 08:44:16 +00:00
|
|
|
if current_user.permissions == "ro":
|
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'vpnips'}
|
2020-01-17 07:10:44 +00:00
|
|
|
remoteip = vpnconfig.remoteip
|
|
|
|
localip = vpnconfig.localip
|
2020-05-20 16:23:24 +00:00
|
|
|
remoteip6 = vpnconfig.remoteip6
|
|
|
|
localip6 = vpnconfig.localip6
|
2020-04-15 11:33:20 +00:00
|
|
|
ula = vpnconfig.ula
|
2020-05-14 08:44:16 +00:00
|
|
|
if not remoteip or not localip:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'vpnips'}
|
2020-06-20 07:08:51 +00:00
|
|
|
modif_config_user(current_user.username, {'vpnremoteip': remoteip})
|
|
|
|
modif_config_user(current_user.username, {'vpnlocalip': localip})
|
2020-05-14 08:44:16 +00:00
|
|
|
if ula:
|
2020-06-20 07:08:51 +00:00
|
|
|
modif_config_user(current_user.username, {'ula': ula})
|
2020-01-17 07:10:44 +00:00
|
|
|
userid = current_user.userid
|
2020-04-21 12:55:35 +00:00
|
|
|
if userid is None:
|
2020-01-17 07:10:44 +00:00
|
|
|
userid = 0
|
2020-01-21 18:30:29 +00:00
|
|
|
if os.path.isfile('/etc/openmptcprouter-vps-admin/omr-6in4/user' + str(userid)):
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/openmptcprouter-vps-admin/omr-6in4/user' + str(userid), 'rb'))).hexdigest()
|
|
|
|
else:
|
|
|
|
initial_md5 = ''
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-6in4/user' + str(userid), 'w+') as n:
|
2020-01-17 07:10:44 +00:00
|
|
|
n.write('LOCALIP=' + localip + "\n")
|
|
|
|
n.write('REMOTEIP=' + remoteip + "\n")
|
2020-05-14 08:44:16 +00:00
|
|
|
if localip6:
|
|
|
|
n.write('LOCALIP6=' + localip6 + "\n")
|
|
|
|
else:
|
2020-05-22 09:09:04 +00:00
|
|
|
n.write('LOCALIP6=fe80::a0' + hex(userid)[2:] + ':1/126' + "\n")
|
2020-05-14 08:44:16 +00:00
|
|
|
if remoteip6:
|
|
|
|
n.write('REMOTEIP6=' + remoteip6 + "\n")
|
|
|
|
else:
|
2020-05-22 09:09:04 +00:00
|
|
|
n.write('REMOTEIP6=fe80::a0' + hex(userid)[2:] + ':2/126' + "\n")
|
2020-05-14 08:44:16 +00:00
|
|
|
if ula:
|
|
|
|
n.write('ULA=' + ula + "\n")
|
2020-01-21 18:30:29 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/openmptcprouter-vps-admin/omr-6in4/user' + str(userid), 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-17 07:10:44 +00:00
|
|
|
os.system("systemctl -q restart omr6in4@user" + str(userid))
|
|
|
|
set_lastchange()
|
2020-01-20 20:05:40 +00:00
|
|
|
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/params.vpn', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall/params.vpn', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-20 20:05:40 +00:00
|
|
|
for line in f:
|
2020-01-21 18:30:29 +00:00
|
|
|
if not ('OMR_ADDR_USER' + str(userid) +'=' in line and not userid == 0) and not ('OMR_ADDR=' in line and userid == 0):
|
2020-01-20 20:05:40 +00:00
|
|
|
n.write(line)
|
2020-01-21 18:30:29 +00:00
|
|
|
if not userid == 0:
|
|
|
|
n.write('OMR_ADDR_USER' + str(userid) + '=' + remoteip + '\n')
|
|
|
|
elif userid == 0:
|
|
|
|
n.write('OMR_ADDR=' + remoteip + '\n')
|
2020-01-20 20:05:40 +00:00
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall/params.vpn')
|
2020-01-20 20:05:40 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/params.vpn', 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-03-03 12:49:23 +00:00
|
|
|
os.system("systemctl -q reload shorewall")
|
2020-01-20 20:05:40 +00:00
|
|
|
set_lastchange()
|
|
|
|
|
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall6/params.vpn', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall6/params.vpn', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-20 20:05:40 +00:00
|
|
|
for line in f:
|
2020-01-21 18:30:29 +00:00
|
|
|
if not ('OMR_ADDR_USER' + str(userid) +'=' in line and not userid == 0) and not ('OMR_ADDR=' in line and userid == 0):
|
2020-01-20 20:05:40 +00:00
|
|
|
n.write(line)
|
2020-01-21 18:30:29 +00:00
|
|
|
if not userid == 0:
|
2020-05-22 09:09:04 +00:00
|
|
|
n.write('OMR_ADDR_USER' + str(userid) + '=fe80::a0' + hex(userid)[2:] + ':2/126' + '\n')
|
2020-01-21 18:30:29 +00:00
|
|
|
elif userid == 0:
|
2020-05-22 09:09:04 +00:00
|
|
|
n.write('OMR_ADDR=fe80::a0' + hex(userid)[2:] + ':2/126' + '\n')
|
2020-01-21 18:30:29 +00:00
|
|
|
|
2020-01-20 20:05:40 +00:00
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall6/params.vpn')
|
2020-01-20 20:05:40 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall6/params.vpn', 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-03-03 12:49:23 +00:00
|
|
|
os.system("systemctl -q reload shorewall6")
|
2020-01-20 20:05:40 +00:00
|
|
|
set_lastchange()
|
|
|
|
|
2021-03-04 13:52:04 +00:00
|
|
|
return {'result': 'done', 'reason': 'changes applied', 'route': 'vpnips'}
|
2020-01-17 07:10:44 +00:00
|
|
|
|
2018-12-06 09:48:23 +00:00
|
|
|
# Update VPS
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.get('/update', summary="Update VPS script")
|
2019-11-02 17:10:10 +00:00
|
|
|
def update(current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'update'}
|
2021-01-06 08:27:40 +00:00
|
|
|
LOG.debug("Update VPS...")
|
|
|
|
os.system("systemctl stop omr")
|
|
|
|
os.system("wget -O - http://www.openmptcprouter.com/server/debian10-x86_64.sh | sh &")
|
|
|
|
LOG.debug("Update VPS... done")
|
2021-02-01 14:44:26 +00:00
|
|
|
os.system("/sbin/reboot")
|
2021-03-04 13:52:04 +00:00
|
|
|
return {'result': 'done', 'route': 'update'}
|
2018-11-08 17:05:34 +00:00
|
|
|
|
2019-09-29 18:54:54 +00:00
|
|
|
# Backup
|
2019-11-02 17:32:35 +00:00
|
|
|
class Backupfile(BaseModel):
|
2020-07-03 14:27:09 +00:00
|
|
|
data: str = Query(..., title="OpenMPTCProuter backup file in tar.gz encoded in base64")
|
2019-11-02 17:32:35 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/backuppost', summary="Send current user router backup file")
|
2020-03-03 12:49:23 +00:00
|
|
|
def backuppost(*, backupfile: Backupfile, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'backuppost'}
|
2019-11-02 17:32:35 +00:00
|
|
|
backup_file = backupfile.data
|
2019-09-29 18:54:54 +00:00
|
|
|
if not backup_file:
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'error', 'reason': 'Invalid parameters', 'route': 'backuppost'}
|
|
|
|
with open('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz', 'wb') as f:
|
2019-09-29 18:54:54 +00:00
|
|
|
f.write(base64.b64decode(backup_file))
|
2021-03-04 13:52:04 +00:00
|
|
|
return {'result': 'done', 'route': 'backuppost'}
|
2019-09-29 18:54:54 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.get('/backupget', summary="Get current user router backup file")
|
2019-11-02 17:10:10 +00:00
|
|
|
def send_backup(current_user: User = Depends(get_current_user)):
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz', "rb") as backup_file:
|
2019-09-29 18:54:54 +00:00
|
|
|
file_base64 = base64.b64encode(backup_file.read())
|
|
|
|
file_base64utf = file_base64.decode('utf-8')
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'data': file_base64utf}
|
2019-09-29 18:54:54 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.get('/backuplist', summary="List available current user backup")
|
2019-11-02 17:10:10 +00:00
|
|
|
def list_backup(current_user: User = Depends(get_current_user)):
|
2019-12-26 19:25:11 +00:00
|
|
|
if os.path.isfile('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz'):
|
|
|
|
modiftime = os.path.getmtime('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz')
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'backup': True, 'modif': modiftime}
|
2019-10-10 19:13:14 +00:00
|
|
|
else:
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'backup': False}
|
2019-10-10 19:13:14 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.get('/backupshow', summary="Show current user backup")
|
2019-11-02 17:10:10 +00:00
|
|
|
def show_backup(current_user: User = Depends(get_current_user)):
|
2019-12-26 19:25:11 +00:00
|
|
|
if os.path.isfile('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz'):
|
|
|
|
router = OpenWrt(native=open('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz'))
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'backup': True, 'data': router}
|
2019-10-10 19:13:14 +00:00
|
|
|
else:
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'backup': False}
|
2019-10-10 19:13:14 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/backupedit', summary="Modify current user backup")
|
2020-03-03 12:49:23 +00:00
|
|
|
def edit_backup(params, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if current_user.permissions == "ro":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Read only user', 'route': 'backupedit'}
|
2019-10-10 19:13:14 +00:00
|
|
|
o = OpenWrt(params)
|
2020-03-03 12:49:23 +00:00
|
|
|
o.write(current_user.username + '-backup', path='/var/opt/openmptcprouter/')
|
2019-11-02 17:10:10 +00:00
|
|
|
return {'result': 'done'}
|
2019-10-10 19:13:14 +00:00
|
|
|
|
2020-07-03 14:27:09 +00:00
|
|
|
#class VPN(str, Enum):
|
|
|
|
# openvpn = "openvpn"
|
|
|
|
# glorytuntcp = "glorytun_tcp"
|
|
|
|
# glorytunudp = "glorytun_udp"
|
|
|
|
# dsvpn = "dsvpn"
|
2019-12-30 19:49:39 +00:00
|
|
|
|
2020-01-09 08:48:02 +00:00
|
|
|
class permissions(str, Enum):
|
2019-12-30 19:49:39 +00:00
|
|
|
ro = "ro"
|
|
|
|
rw = "rw"
|
|
|
|
admin = "admin"
|
2019-09-29 18:54:54 +00:00
|
|
|
|
2019-12-26 19:25:11 +00:00
|
|
|
class NewUser(BaseModel):
|
2020-07-03 14:27:09 +00:00
|
|
|
username: str = Query(..., title="Username")
|
2020-01-09 08:48:02 +00:00
|
|
|
permission: permissions = Query("ro", title="permission of the user")
|
|
|
|
vpn: VPN = Query("openvpn", title="default VPN for the user")
|
2020-07-03 14:27:09 +00:00
|
|
|
shadowsocks_port: Optional[int] = Query(None, gt=0, lt=65535, title="Shadowsocks port")
|
|
|
|
userid: Optional[int] = Query(None, title="User ID")
|
|
|
|
ips: Optional[List[str]] = Query(None, title="Public exit IP")
|
2020-01-09 08:48:02 +00:00
|
|
|
# userid: int = Query(0, title="User ID",description="User ID is used to create port of each VPN and shadowsocks",gt=0,le=99)
|
2019-12-26 19:25:11 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/add_user', summary="Add a new user")
|
2020-03-03 12:49:23 +00:00
|
|
|
def add_user(*, params: NewUser, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if not current_user.permissions == "admin":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'add_user'}
|
2020-01-09 08:48:02 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = json.load(f)
|
2020-06-20 07:08:51 +00:00
|
|
|
userid = params.userid
|
2020-08-21 16:50:34 +00:00
|
|
|
if userid is None or userid == 0:
|
2020-06-20 07:08:51 +00:00
|
|
|
userid = 2
|
|
|
|
for users in content['users'][0]:
|
|
|
|
if 'userid' in content['users'][0][users]:
|
|
|
|
if int(content['users'][0][users]['userid']) > userid:
|
|
|
|
userid = int(content['users'][0][users]['userid'])
|
|
|
|
userid = userid + 1
|
2020-07-03 14:27:09 +00:00
|
|
|
if params.ips is None:
|
|
|
|
publicips = []
|
|
|
|
else:
|
|
|
|
publicips = params.ips
|
2019-12-27 20:42:47 +00:00
|
|
|
user_key = secrets.token_hex(32)
|
2020-08-21 17:50:34 +00:00
|
|
|
user_json = json.loads('{"'+ params.username + '": {"username":"'+ params.username +'","permissions":"'+params.permission+'","user_password": "'+user_key.upper()+'","disabled":"false","userid":"' + str(userid) + '","public_ips":'+ json.dumps(publicips) +'}}')
|
2020-01-09 08:48:02 +00:00
|
|
|
# shadowsocks_port = params.shadowsocks_port
|
|
|
|
# if params.shadowsocks_port is None:
|
2020-06-20 07:08:51 +00:00
|
|
|
# shadowsocks_port = '651{:02d}'.format(userid)
|
2020-08-21 17:50:34 +00:00
|
|
|
shadowsocks_port = params.shadowsocks_port
|
2020-01-09 08:48:02 +00:00
|
|
|
shadowsocks_key = base64.urlsafe_b64encode(secrets.token_hex(16).encode())
|
2020-07-03 14:27:09 +00:00
|
|
|
if not publicips:
|
|
|
|
shadowsocks_port = add_ss_user(str(shadowsocks_port), shadowsocks_key.decode('utf-8'), userid)
|
|
|
|
else:
|
|
|
|
for publicip in publicips:
|
|
|
|
shadowsocks_port = add_ss_user(str(shadowsocks_port), shadowsocks_key.decode('utf-8'), userid, publicip)
|
|
|
|
shadowsocks_port = shadowsocks_port + 1
|
2020-01-09 08:48:02 +00:00
|
|
|
user_json[params.username].update({"shadowsocks_port": shadowsocks_port})
|
2019-12-27 20:42:47 +00:00
|
|
|
if params.vpn is not None:
|
|
|
|
user_json[params.username].update({"vpn": params.vpn})
|
|
|
|
content['users'][0].update(user_json)
|
2021-02-05 13:33:43 +00:00
|
|
|
if content:
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as f:
|
|
|
|
json.dump(content, f, indent=4)
|
2021-02-05 14:28:56 +00:00
|
|
|
else:
|
|
|
|
LOG.debug("Empty data for add_user")
|
2020-01-09 08:48:02 +00:00
|
|
|
# Create VPNs configuration
|
2020-01-06 20:18:29 +00:00
|
|
|
os.system('cd /etc/openvpn/ca && EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "' + params.username + '" nopass')
|
2020-01-09 08:48:02 +00:00
|
|
|
add_glorytun_tcp(userid)
|
|
|
|
add_glorytun_udp(userid)
|
2020-02-14 20:46:05 +00:00
|
|
|
add_dsvpn(userid)
|
2020-01-09 08:48:02 +00:00
|
|
|
|
|
|
|
set_lastchange(30)
|
2020-01-06 20:18:29 +00:00
|
|
|
os.execv(__file__, sys.argv)
|
2019-12-27 20:42:47 +00:00
|
|
|
|
|
|
|
class RemoveUser(BaseModel):
|
|
|
|
username: str
|
2019-12-26 19:25:11 +00:00
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/remove_user', summary="Remove an user")
|
2020-03-03 12:49:23 +00:00
|
|
|
def remove_user(*, params: RemoveUser, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if not current_user.permissions == "admin":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'remove_user'}
|
2019-12-27 20:42:47 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = json.load(f)
|
|
|
|
shadowsocks_port = content['users'][0][params.username]['shadowsocks_port']
|
2020-03-03 13:06:18 +00:00
|
|
|
userid = int(content['users'][0][params.username]['userid'])
|
2019-12-27 20:42:47 +00:00
|
|
|
del content['users'][0][params.username]
|
|
|
|
remove_ss_user(str(shadowsocks_port))
|
2021-02-05 13:33:43 +00:00
|
|
|
if content:
|
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as f:
|
|
|
|
json.dump(content, f, indent=4)
|
2021-02-05 14:28:56 +00:00
|
|
|
else:
|
|
|
|
LOG.debug("Empty data for remover_user")
|
2020-01-14 18:23:14 +00:00
|
|
|
os.system('cd /etc/openvpn/ca && ./easyrsa --batch revoke ' + params.username)
|
|
|
|
os.system('cd /etc/openvpn/ca && ./easyrsa gen-crl')
|
|
|
|
os.system("systemctl -q restart openvpn@tun0")
|
2020-02-14 20:46:05 +00:00
|
|
|
remove_glorytun_tcp(userid)
|
|
|
|
remove_glorytun_udp(userid)
|
|
|
|
remove_dsvpn(userid)
|
|
|
|
|
2020-01-09 08:48:02 +00:00
|
|
|
set_lastchange(30)
|
2020-01-06 20:18:29 +00:00
|
|
|
os.execv(__file__, sys.argv)
|
2019-12-27 20:42:47 +00:00
|
|
|
|
2020-01-13 20:47:29 +00:00
|
|
|
class ClienttoClient(BaseModel):
|
|
|
|
enable: bool = False
|
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.post('/client2client', summary="Enable client 2 client communications")
|
2020-03-03 12:49:23 +00:00
|
|
|
def client2client(*, params: ClienttoClient, current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if not current_user.permissions == "admin":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'client2client'}
|
|
|
|
set_global_param('client2client', params.enable)
|
2020-01-13 20:47:29 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/openvpn/tun0.conf', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/openvpn/tun0.conf', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-13 20:47:29 +00:00
|
|
|
for line in f:
|
|
|
|
if not 'client-to-client' in line:
|
|
|
|
n.write(line)
|
2020-03-05 14:09:49 +00:00
|
|
|
if params.enable == True:
|
|
|
|
n.write('client-to-client' + "\n")
|
2020-01-13 20:47:29 +00:00
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/openvpn/tun0.conf')
|
2020-01-13 20:47:29 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/openvpn/tun0.conf', 'rb'))).hexdigest()
|
2020-07-03 14:27:09 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-13 20:47:29 +00:00
|
|
|
os.system("systemctl -q restart openvpn@tun0")
|
2020-01-29 20:20:43 +00:00
|
|
|
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/policy', 'rb'))).hexdigest()
|
|
|
|
fd, tmpfile = mkstemp()
|
2020-03-03 12:49:23 +00:00
|
|
|
with open('/etc/shorewall/policy', 'r') as f, open(tmpfile, 'a+') as n:
|
2020-01-29 20:20:43 +00:00
|
|
|
for line in f:
|
|
|
|
if not line == 'vpn vpn DROP\n' and not line == '# THE FOLLOWING POLICY MUST BE LAST\n' and not line == 'all all REJECT info\n':
|
|
|
|
n.write(line)
|
2020-03-06 18:49:33 +00:00
|
|
|
if params.enable == False:
|
2020-01-29 20:20:43 +00:00
|
|
|
n.write('vpn vpn DROP\n')
|
|
|
|
n.write('# THE FOLLOWING POLICY MUST BE LAST\n')
|
|
|
|
n.write('all all REJECT info\n')
|
|
|
|
os.close(fd)
|
2020-03-03 12:49:23 +00:00
|
|
|
move(tmpfile, '/etc/shorewall/policy')
|
2020-01-29 20:20:43 +00:00
|
|
|
final_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/policy', 'rb'))).hexdigest()
|
2020-03-05 14:02:20 +00:00
|
|
|
if initial_md5 != final_md5:
|
2020-01-29 20:20:43 +00:00
|
|
|
os.system("systemctl -q reload shorewall")
|
2020-01-13 20:47:29 +00:00
|
|
|
return {'result': 'done'}
|
|
|
|
|
2020-11-23 15:54:46 +00:00
|
|
|
class SerialEnforce(BaseModel):
|
|
|
|
enable: bool = False
|
|
|
|
|
|
|
|
@app.post('/serialenforce', summary="Enable client serial number control")
|
|
|
|
def serialenforce(*, params: SerialEnforce, current_user: User = Depends(get_current_user)):
|
|
|
|
if not current_user.permissions == "admin":
|
|
|
|
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'serialenforce'}
|
|
|
|
set_global_param('serial_enforce', params.enable)
|
|
|
|
return {'result': 'done'}
|
|
|
|
|
2020-06-23 18:26:08 +00:00
|
|
|
@app.get('/list_users', summary="List all users")
|
2020-02-15 12:44:35 +00:00
|
|
|
async def list_users(current_user: User = Depends(get_current_user)):
|
2020-01-13 20:47:29 +00:00
|
|
|
if not current_user.permissions == "admin":
|
2020-03-03 12:49:23 +00:00
|
|
|
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'list_users'}
|
2019-12-27 20:42:47 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
content = json.load(f)
|
2020-01-09 08:48:02 +00:00
|
|
|
return content['users'][0]
|
2019-12-26 19:25:11 +00:00
|
|
|
|
2020-07-16 07:55:19 +00:00
|
|
|
@app.get('/speedtest', summary="Test speed from the server")
|
|
|
|
async def list_users(current_user: User = Depends(get_current_user)):
|
2020-08-10 18:49:47 +00:00
|
|
|
return FileResponse('/usr/share/omr-server/speedtest/test.img')
|
2020-07-16 07:55:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2021-02-10 13:48:43 +00:00
|
|
|
def main(omrport: int, omrhost: str):
|
2020-06-19 13:49:07 +00:00
|
|
|
LOG.debug("Main OMR-Admin launch")
|
2021-02-25 09:44:34 +00:00
|
|
|
uvicorn.run(app, host=omrhost, port=omrport, log_level='error', ssl_certfile='/etc/openmptcprouter-vps-admin/cert.pem', ssl_keyfile='/etc/openmptcprouter-vps-admin/key.pem', ssl_version=5)
|
2021-02-10 13:48:43 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2018-12-13 14:14:45 +00:00
|
|
|
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json') as f:
|
|
|
|
omr_config_data = json.load(f)
|
2020-03-03 12:49:23 +00:00
|
|
|
omrport = 65500
|
2018-12-13 14:14:45 +00:00
|
|
|
if 'port' in omr_config_data:
|
|
|
|
omrport = omr_config_data["port"]
|
2020-03-03 12:49:23 +00:00
|
|
|
omrhost = '0.0.0.0'
|
2019-12-27 20:42:47 +00:00
|
|
|
if 'host' in omr_config_data:
|
|
|
|
omrhost = omr_config_data["host"]
|
2021-02-25 09:44:34 +00:00
|
|
|
parser = argparse.ArgumentParser(description="OpenMPTCProuter Server API")
|
2021-02-10 13:48:43 +00:00
|
|
|
parser.add_argument("--port", type=int, help="Listening port", default=omrport)
|
|
|
|
parser.add_argument("--host", type=str, help="Listening host", default=omrhost)
|
|
|
|
args = parser.parse_args()
|
|
|
|
main(args.port, args.host)
|