1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-vps-admin.git synced 2025-03-09 15:40:05 +00:00

Fix for gre tunnel, userid in shadowsocks and better generated doc

This commit is contained in:
Ycarus 2020-06-23 20:26:08 +02:00
parent ff3abb92a6
commit 19d95df70b

View file

@ -123,7 +123,7 @@ def modif_config_user(user, changes):
with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as f: with open('/etc/openmptcprouter-vps-admin/omr-admin-config.json', 'w') as f:
json.dump(content, f, indent=4) json.dump(content, f, indent=4)
def add_ss_user(port, key, ip=''): def add_ss_user(port, key, userid=0, ip=''):
with open('/etc/shadowsocks-libev/manager.json') as f: with open('/etc/shadowsocks-libev/manager.json') as f:
content = f.read() content = f.read()
content = re.sub(",\s*}", "}", content) # pylint: disable=W1401 content = re.sub(",\s*}", "}", content) # pylint: disable=W1401
@ -148,7 +148,7 @@ def add_ss_user(port, key, ip=''):
try: try:
ss_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ss_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
if ip != '': if ip != '':
data = 'add: {"server_port": ' + port + ', "key": "' + key + '", "local_addr": "' + ip + '"}' data = 'add: {"server_port": ' + port + ', "key": "' + key + '", "local_addr": "' + ip + '", "userid": ' + userid + '}'
else: else:
data = 'add: {"server_port": ' + port + ', "key": "' + key + '"}' data = 'add: {"server_port": ' + port + ', "key": "' + key + '"}'
ss_socket.settimeout(3) ss_socket.settimeout(3)
@ -234,7 +234,6 @@ def add_gre_tunnels():
n.write('BROADCASTIP=' + str(network.broadcast) + "\n") n.write('BROADCASTIP=' + str(network.broadcast) + "\n")
n.write('USERNAME=' + str(username) + "\n") n.write('USERNAME=' + str(username) + "\n")
n.write('USERID=' + str(userid) + "\n") n.write('USERID=' + str(userid) + "\n")
initial_md5 = hashlib.md5(file_as_bytes(open('/etc/shorewall/snat', 'rb'))).hexdigest()
fd, tmpfile = mkstemp() fd, tmpfile = mkstemp()
with open('/etc/shorewall/snat', 'r') as h, open(tmpfile, 'a+') as n: with open('/etc/shorewall/snat', 'r') as h, open(tmpfile, 'a+') as n:
for line in h: for line in h:
@ -243,9 +242,9 @@ def add_gre_tunnels():
n.write('SNAT(' + str(addr) + ') ' + str(network) + ' ' + str(intf) + ' # OMR GRE for public IP ' + str(addr) + ' for user ' + str(user) + "\n") n.write('SNAT(' + str(addr) + ') ' + str(network) + ' ' + str(intf) + ' # OMR GRE for public IP ' + str(addr) + ' for user ' + str(user) + "\n")
os.close(fd) os.close(fd)
move(tmpfile, '/etc/shorewall/snat') move(tmpfile, '/etc/shorewall/snat')
user_gre_tunnels = [] user_gre_tunnels = { }
if 'gre_tunnels' in content['users'][0]: if 'gre_tunnels' in content['users'][0][user]:
user_gre_tunnels = content['users'][0]['gre_tunnels'] user_gre_tunnels = content['users'][0][user]['gre_tunnels']
if not gre_intf in user_gre_tunnels or user_gre_tunnels[gre_intf]['public_ip'] != str(addr): if not gre_intf in user_gre_tunnels or user_gre_tunnels[gre_intf]['public_ip'] != str(addr):
with open('/etc/shadowsocks-libev/manager.json') as g: with open('/etc/shadowsocks-libev/manager.json') as g:
contentss = g.read() contentss = g.read()
@ -256,7 +255,10 @@ def add_gre_tunnels():
ss_key = datass['port_key'][str(ss_port)] ss_key = datass['port_key'][str(ss_port)]
if 'port_conf' in datass: if 'port_conf' in datass:
ss_key = datass['port_conf'][str(ss_port)]['key'] ss_key = datass['port_conf'][str(ss_port)]['key']
user_gre_tunnels.append({gre_intf: {'shadowsocks_port': str(add_ss_user('',ss_key,str(addr))), 'local_ip': str(list(network)[1]), 'remote_ip': str(list(network)[2]), 'public_ip': str(addr)}}) if gre_intf not in user_gre_tunnels:
user_gre_tunnels[gre_intf] = {}
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)}
#user_gre_tunnels[gre_intf] = {'local_ip': str(list(network)[1]), 'remote_ip': str(list(network)[2]), 'public_ip': str(addr)}
modif_config_user(user,{'gre_tunnels': user_gre_tunnels}) modif_config_user(user,{'gre_tunnels': user_gre_tunnels})
nbip = nbip + 1 nbip = nbip + 1
except Exception as exception: except Exception as exception:
@ -652,7 +654,7 @@ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearerCookie(tokenUrl="/token") oauth2_scheme = OAuth2PasswordBearerCookie(tokenUrl="/token")
app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None) app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None, title="OpenMPTCProuter Server API")
def create_access_token(*, data: dict, expires_delta: timedelta = None): def create_access_token(*, data: dict, expires_delta: timedelta = None):
@ -770,7 +772,7 @@ async def status(request: Request):
return {"client_host": client_host} return {"client_host": client_host}
# Get VPS status # Get VPS status
@app.get('/status') @app.get('/status', summary="Get current server load average, uptime and release")
async def status(current_user: User = Depends(get_current_user)): async def status(current_user: User = Depends(get_current_user)):
LOG.debug('Get status...') LOG.debug('Get status...')
vps_loadavg = os.popen("cat /proc/loadavg | awk '{print $1\" \"$2\" \"$3}'").read().rstrip() vps_loadavg = os.popen("cat /proc/loadavg | awk '{print $1\" \"$2\" \"$3}'").read().rstrip()
@ -793,7 +795,7 @@ async def status(current_user: User = Depends(get_current_user)):
return {'error': 'No iface defined', 'route': 'status'} return {'error': 'No iface defined', 'route': 'status'}
# Get VPS config # Get VPS config
@app.get('/config') @app.get('/config', summary="Get full server configuration for current user")
async def config(current_user: User = Depends(get_current_user)): async def config(current_user: User = Depends(get_current_user)):
LOG.debug('Get config...') LOG.debug('Get config...')
userid = current_user.userid userid = current_user.userid
@ -1157,7 +1159,7 @@ class ShadowsocksConfigparams(BaseModel):
obfs_type: str obfs_type: str
key: str key: str
@app.post('/shadowsocks') @app.post('/shadowsocks', summary="Modify Shadowsocks-libev configuration")
def shadowsocks(*, params: ShadowsocksConfigparams, current_user: User = Depends(get_current_user)): def shadowsocks(*, params: ShadowsocksConfigparams, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
set_lastchange(10) set_lastchange(10)
@ -1316,7 +1318,7 @@ class ShorewallAllparams(BaseModel):
redirect_ports: str redirect_ports: str
ipproto: str = "ipv4" ipproto: str = "ipv4"
@app.post('/shorewall') @app.post('/shorewall', summary="Redirect all ports from Server to router")
def shorewall(*, params: ShorewallAllparams, current_user: User = Depends(get_current_user)): def shorewall(*, params: ShorewallAllparams, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewall'} return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewall'}
@ -1370,7 +1372,7 @@ class ShorewallListparams(BaseModel):
name: str name: str
ipproto: str = "ipv4" ipproto: str = "ipv4"
@app.post('/shorewalllist') @app.post('/shorewalllist', summary="Display all OpenMPTCProuter rules in Shorewall config")
def shorewall_list(*, params: ShorewallListparams, current_user: User = Depends(get_current_user)): def shorewall_list(*, params: ShorewallListparams, current_user: User = Depends(get_current_user)):
name = params.name name = params.name
if name is None: if name is None:
@ -1396,7 +1398,7 @@ class Shorewallparams(BaseModel):
ipproto: str = "ipv4" ipproto: str = "ipv4"
source_dip: str = "" source_dip: str = ""
@app.post('/shorewallopen') @app.post('/shorewallopen', summary="Redirect a port from Server to Router")
def shorewall_open(*, params: Shorewallparams, current_user: User = Depends(get_current_user)): def shorewall_open(*, params: Shorewallparams, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewallopen'} return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewallopen'}
@ -1413,7 +1415,7 @@ def shorewall_open(*, params: Shorewallparams, current_user: User = Depends(get_
shorewall6_add_port(current_user, str(port), proto, name, fwtype, source_dip) shorewall6_add_port(current_user, str(port), proto, name, fwtype, source_dip)
return {'result': 'done', 'reason': 'changes applied'} return {'result': 'done', 'reason': 'changes applied'}
@app.post('/shorewallclose') @app.post('/shorewallclose', summary="Remove a redirected port")
def shorewall_close(*, params: Shorewallparams, current_user: User = Depends(get_current_user)): def shorewall_close(*, params: Shorewallparams, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewallclose'} return {'result': 'permission', 'reason': 'Read only user', 'route': 'shorewallclose'}
@ -1438,7 +1440,7 @@ class MPTCPparams(BaseModel):
syn_retries: int syn_retries: int
congestion_control: str congestion_control: str
@app.post('/mptcp') @app.post('/mptcp', summary="Modify MPTCP configuration of the server")
def mptcp(*, params: MPTCPparams, current_user: User = Depends(get_current_user)): def mptcp(*, params: MPTCPparams, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
set_lastchange(10) set_lastchange(10)
@ -1462,7 +1464,7 @@ class Vpn(BaseModel):
vpn: str vpn: str
# Set global VPN config # Set global VPN config
@app.post('/vpn') @app.post('/vpn', summary="Set VPN used by the current user")
def vpn(*, vpnconfig: Vpn, current_user: User = Depends(get_current_user)): def vpn(*, vpnconfig: Vpn, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
set_lastchange(10) set_lastchange(10)
@ -1483,7 +1485,7 @@ class GlorytunConfig(BaseModel):
chacha: bool chacha: bool
# Set Glorytun config # Set Glorytun config
@app.post('/glorytun') @app.post('/glorytun', summary="Modify Glorytun configuration")
def glorytun(*, glorytunconfig: GlorytunConfig, current_user: User = Depends(get_current_user)): def glorytun(*, glorytunconfig: GlorytunConfig, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
set_lastchange(10) set_lastchange(10)
@ -1544,7 +1546,7 @@ class DSVPN(BaseModel):
key: str key: str
port: int port: int
@app.post('/dsvpn') @app.post('/dsvpn', summary="Modify DSVPN configuration")
def dsvpn(*, params: DSVPN, current_user: User = Depends(get_current_user)): def dsvpn(*, params: DSVPN, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
set_lastchange(10) set_lastchange(10)
@ -1581,7 +1583,7 @@ def dsvpn(*, params: DSVPN, current_user: User = Depends(get_current_user)):
class OpenVPN(BaseModel): class OpenVPN(BaseModel):
key: str key: str
@app.post('/openvpn') @app.post('/openvpn', summary="Modify OpenVPN TCP configuration")
def openvpn(*, ovpn: OpenVPN, current_user: User = Depends(get_current_user)): def openvpn(*, ovpn: OpenVPN, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
set_lastchange(10) set_lastchange(10)
@ -1602,7 +1604,7 @@ class Wanips(BaseModel):
ips: str ips: str
# Set WANIP # Set WANIP
@app.post('/wan') @app.post('/wan', summary="Set WAN IPs")
def wan(*, wanips: Wanips, current_user: User = Depends(get_current_user)): def wan(*, wanips: Wanips, current_user: User = Depends(get_current_user)):
ips = wanips.ips ips = wanips.ips
if not ips: if not ips:
@ -1619,7 +1621,7 @@ class Lanips(BaseModel):
lanips: List[str] = [] lanips: List[str] = []
# Set user lan config # Set user lan config
@app.post('/lan') @app.post('/lan', summary="Set current user LAN IPs")
def lan(*, lanconfig: Lanips, current_user: User = Depends(get_current_user)): def lan(*, lanconfig: Lanips, current_user: User = Depends(get_current_user)):
lanips = lanconfig.lanips lanips = lanconfig.lanips
if not lanips: if not lanips:
@ -1659,7 +1661,7 @@ class VPNips(BaseModel):
ula: str = "" ula: str = ""
# Set user vpn IPs # Set user vpn IPs
@app.post('/vpnips') @app.post('/vpnips', summary="Set current user VPN IPs")
def vpnips(*, vpnconfig: VPNips, current_user: User = Depends(get_current_user)): def vpnips(*, vpnconfig: VPNips, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
return {'result': 'permission', 'reason': 'Read only user', 'route': 'vpnips'} return {'result': 'permission', 'reason': 'Read only user', 'route': 'vpnips'}
@ -1737,7 +1739,7 @@ def vpnips(*, vpnconfig: VPNips, current_user: User = Depends(get_current_user))
return {'result': 'done', 'reason': 'changes applied'} return {'result': 'done', 'reason': 'changes applied'}
# Update VPS # Update VPS
@app.get('/update') @app.get('/update', summary="Update VPS script")
def update(current_user: User = Depends(get_current_user)): def update(current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
return {'result': 'permission', 'reason': 'Read only user', 'route': 'update'} return {'result': 'permission', 'reason': 'Read only user', 'route': 'update'}
@ -1749,7 +1751,7 @@ def update(current_user: User = Depends(get_current_user)):
class Backupfile(BaseModel): class Backupfile(BaseModel):
data: str data: str
@app.post('/backuppost') @app.post('/backuppost', summary="Send current user router backup file")
def backuppost(*, backupfile: Backupfile, current_user: User = Depends(get_current_user)): def backuppost(*, backupfile: Backupfile, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
return {'result': 'permission', 'reason': 'Read only user', 'route': 'backuppost'} return {'result': 'permission', 'reason': 'Read only user', 'route': 'backuppost'}
@ -1760,14 +1762,14 @@ def backuppost(*, backupfile: Backupfile, current_user: User = Depends(get_curre
f.write(base64.b64decode(backup_file)) f.write(base64.b64decode(backup_file))
return {'result': 'done'} return {'result': 'done'}
@app.get('/backupget') @app.get('/backupget', summary="Get current user router backup file")
def send_backup(current_user: User = Depends(get_current_user)): def send_backup(current_user: User = Depends(get_current_user)):
with open('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz', "rb") as backup_file: with open('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz', "rb") as backup_file:
file_base64 = base64.b64encode(backup_file.read()) file_base64 = base64.b64encode(backup_file.read())
file_base64utf = file_base64.decode('utf-8') file_base64utf = file_base64.decode('utf-8')
return {'data': file_base64utf} return {'data': file_base64utf}
@app.get('/backuplist') @app.get('/backuplist', summary="List available current user backup")
def list_backup(current_user: User = Depends(get_current_user)): def list_backup(current_user: User = Depends(get_current_user)):
if os.path.isfile('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz'): 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') modiftime = os.path.getmtime('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz')
@ -1775,7 +1777,7 @@ def list_backup(current_user: User = Depends(get_current_user)):
else: else:
return {'backup': False} return {'backup': False}
@app.get('/backupshow') @app.get('/backupshow', summary="Show current user backup")
def show_backup(current_user: User = Depends(get_current_user)): def show_backup(current_user: User = Depends(get_current_user)):
if os.path.isfile('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz'): 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')) router = OpenWrt(native=open('/var/opt/openmptcprouter/' + current_user.username + '-backup.tar.gz'))
@ -1783,7 +1785,7 @@ def show_backup(current_user: User = Depends(get_current_user)):
else: else:
return {'backup': False} return {'backup': False}
@app.post('/backupedit') @app.post('/backupedit', summary="Modify current user backup")
def edit_backup(params, current_user: User = Depends(get_current_user)): def edit_backup(params, current_user: User = Depends(get_current_user)):
if current_user.permissions == "ro": if current_user.permissions == "ro":
return {'result': 'permission', 'reason': 'Read only user', 'route': 'backupedit'} return {'result': 'permission', 'reason': 'Read only user', 'route': 'backupedit'}
@ -1811,7 +1813,7 @@ class NewUser(BaseModel):
ips: List[str] = Query([], title="Public exit IP") ips: List[str] = Query([], title="Public exit IP")
# userid: int = Query(0, title="User ID",description="User ID is used to create port of each VPN and shadowsocks",gt=0,le=99) # userid: int = Query(0, title="User ID",description="User ID is used to create port of each VPN and shadowsocks",gt=0,le=99)
@app.post('/add_user') @app.post('/add_user', summary="Add a new user")
def add_user(*, params: NewUser, current_user: User = Depends(get_current_user)): def add_user(*, params: NewUser, current_user: User = Depends(get_current_user)):
if not current_user.permissions == "admin": if not current_user.permissions == "admin":
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'add_user'} return {'result': 'permission', 'reason': 'Need admin user', 'route': 'add_user'}
@ -1833,7 +1835,7 @@ def add_user(*, params: NewUser, current_user: User = Depends(get_current_user))
shadowsocks_port = '' shadowsocks_port = ''
shadowsocks_key = base64.urlsafe_b64encode(secrets.token_hex(16).encode()) shadowsocks_key = base64.urlsafe_b64encode(secrets.token_hex(16).encode())
shadowsocks_port = add_ss_user(str(shadowsocks_port), shadowsocks_key.decode('utf-8'), params.ips[0]) shadowsocks_port = add_ss_user(str(shadowsocks_port), shadowsocks_key.decode('utf-8'), userid, params.ips[0])
user_json[params.username].update({"shadowsocks_port": shadowsocks_port}) user_json[params.username].update({"shadowsocks_port": shadowsocks_port})
if params.vpn is not None: if params.vpn is not None:
user_json[params.username].update({"vpn": params.vpn}) user_json[params.username].update({"vpn": params.vpn})
@ -1852,7 +1854,7 @@ def add_user(*, params: NewUser, current_user: User = Depends(get_current_user))
class RemoveUser(BaseModel): class RemoveUser(BaseModel):
username: str username: str
@app.post('/remove_user') @app.post('/remove_user', summary="Remove an user")
def remove_user(*, params: RemoveUser, current_user: User = Depends(get_current_user)): def remove_user(*, params: RemoveUser, current_user: User = Depends(get_current_user)):
if not current_user.permissions == "admin": if not current_user.permissions == "admin":
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'remove_user'} return {'result': 'permission', 'reason': 'Need admin user', 'route': 'remove_user'}
@ -1877,7 +1879,7 @@ def remove_user(*, params: RemoveUser, current_user: User = Depends(get_current_
class ClienttoClient(BaseModel): class ClienttoClient(BaseModel):
enable: bool = False enable: bool = False
@app.post('/client2client') @app.post('/client2client', summary="Enable client 2 client communications")
def client2client(*, params: ClienttoClient, current_user: User = Depends(get_current_user)): def client2client(*, params: ClienttoClient, current_user: User = Depends(get_current_user)):
if not current_user.permissions == "admin": if not current_user.permissions == "admin":
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'client2client'} return {'result': 'permission', 'reason': 'Need admin user', 'route': 'client2client'}
@ -1912,7 +1914,7 @@ def client2client(*, params: ClienttoClient, current_user: User = Depends(get_cu
os.system("systemctl -q reload shorewall") os.system("systemctl -q reload shorewall")
return {'result': 'done'} return {'result': 'done'}
@app.get('/list_users') @app.get('/list_users', summary="List all users")
async def list_users(current_user: User = Depends(get_current_user)): async def list_users(current_user: User = Depends(get_current_user)):
if not current_user.permissions == "admin": if not current_user.permissions == "admin":
return {'result': 'permission', 'reason': 'Need admin user', 'route': 'list_users'} return {'result': 'permission', 'reason': 'Need admin user', 'route': 'list_users'}