add display of existing peerings+check if supplied ips are in allowed ip ranges
This commit is contained in:
parent
d48b754da6
commit
14bb23690e
5 changed files with 138 additions and 20 deletions
2
web/.gitignore
vendored
2
web/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
||||||
venv
|
venv
|
||||||
backend/peerings/
|
backend/peerings.json
|
|
@ -52,24 +52,22 @@ class Config (dict):
|
||||||
|
|
||||||
class PeeringManager:
|
class PeeringManager:
|
||||||
|
|
||||||
def __init__(self, peering_dir):
|
def __init__(self, peerings_file):
|
||||||
self._peering_dir = peering_dir
|
self._peering_file = peerings_file
|
||||||
|
|
||||||
self._load_peerings()
|
self._load_peerings()
|
||||||
|
|
||||||
def _load_peerings(self):
|
def _load_peerings(self):
|
||||||
if not os.path.exists(self._peering_dir):
|
if not os.path.exists(self._peering_file):
|
||||||
os.mkdir(self._peering_dir)
|
with open(self._peering_file, "x") as p:
|
||||||
if not os.path.exists(f"{self._peering_dir}/peerings.json"):
|
|
||||||
with open(f"{self._peering_dir}/peerings.json", "x") as p:
|
|
||||||
json.dump({"mnter":{},"asn":{}}, p)
|
json.dump({"mnter":{},"asn":{}}, p)
|
||||||
try:
|
try:
|
||||||
with open(f"{self._peering_dir}/peerings.json","r") as p:
|
with open(self._peering_file,"r") as p:
|
||||||
self.peerings = json.load(p)
|
self.peerings = json.load(p)
|
||||||
except json.decoder.JSONDecodeError:
|
except json.decoder.JSONDecodeError:
|
||||||
with open(f"{self._peering_dir}/peerings.json", "w") as p:
|
with open(self._peering_file, "w") as p:
|
||||||
json.dump({"mnter":{},"asn":{}}, p)
|
json.dump({"mnter":{},"asn":{}}, p)
|
||||||
with open(f"{self._peering_dir}/peerings.json","r") as p:
|
with open(self._peering_file,"r") as p:
|
||||||
self.peerings = json.load(p)
|
self.peerings = json.load(p)
|
||||||
|
|
||||||
# self.peerings = {}
|
# self.peerings = {}
|
||||||
|
@ -86,7 +84,7 @@ class PeeringManager:
|
||||||
# with open(f"{self._peering_dir}/peerings.json","w") as p:
|
# with open(f"{self._peering_dir}/peerings.json","w") as p:
|
||||||
# json.dump(self._peerings, p, indent=4)
|
# json.dump(self._peerings, p, indent=4)
|
||||||
def _save_peerings(self):
|
def _save_peerings(self):
|
||||||
with open(f"{self._peering_dir}/peerings.json", "w") as p:
|
with open(self._peering_file, "w") as p:
|
||||||
json.dump(self.peerings, p, indent=4)
|
json.dump(self.peerings, p, indent=4)
|
||||||
|
|
||||||
def get_peerings_by_mnt(self, mnt):
|
def get_peerings_by_mnt(self, mnt):
|
||||||
|
@ -125,7 +123,7 @@ class PeeringManager:
|
||||||
|
|
||||||
|
|
||||||
config = Config()
|
config = Config()
|
||||||
peerings = PeeringManager(config["peering-dir"])
|
peerings = PeeringManager(config["peerings"])
|
||||||
def auth_required():
|
def auth_required():
|
||||||
def wrapper(f):
|
def wrapper(f):
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
|
@ -186,15 +184,15 @@ def login():
|
||||||
return render_template("login.html", session=session,config=config,return_addr=session["return_url"], msg=msg)
|
return render_template("login.html", session=session,config=config,return_addr=session["return_url"], msg=msg)
|
||||||
mnt = request.form["mnt"]
|
mnt = request.form["mnt"]
|
||||||
asn = request.form["asn"]
|
asn = request.form["asn"]
|
||||||
asn = asn[2:] if asn[:1].lower() == "as" else asn
|
asn = asn[2:] if asn[:2].lower() == "as" else asn
|
||||||
if "allowed4" in request.form:
|
if "allowed4" in request.form:
|
||||||
allowed4 = request.form["allowed4"]
|
allowed4 = request.form["allowed4"]
|
||||||
allowed4 = allowed4.split(",") if "," in allowed4 else allowed4
|
# allowed4 = allowed4.split(",") if "," in allowed4 else allowed4
|
||||||
else:
|
else:
|
||||||
allowed4 = None
|
allowed4 = None
|
||||||
if "allowed6" in request.form:
|
if "allowed6" in request.form:
|
||||||
allowed6 = request.form["allowed6"]
|
allowed6 = request.form["allowed6"]
|
||||||
allowed6 = allowed6.split(",") if "," in allowed6 else allowed6
|
# allowed6 = allowed6.split(",") if "," in allowed6 else allowed6
|
||||||
else:
|
else:
|
||||||
allowed6 = None
|
allowed6 = None
|
||||||
session["user-data"] = {'asn':asn,'allowed4': allowed4, 'allowed6': allowed6,'mnt':mnt, 'authtype': "debug"}
|
session["user-data"] = {'asn':asn,'allowed4': allowed4, 'allowed6': allowed6,'mnt':mnt, 'authtype': "debug"}
|
||||||
|
@ -213,6 +211,19 @@ def login():
|
||||||
def peerings_delete():
|
def peerings_delete():
|
||||||
|
|
||||||
return f"{request.method} /peerings/delete?{str(request.args)}{str(request.form)}"
|
return f"{request.method} /peerings/delete?{str(request.args)}{str(request.form)}"
|
||||||
|
|
||||||
|
@app.route("/peerings/edit", methods=["GET","POST"])
|
||||||
|
@auth_required()
|
||||||
|
def peerings_edit():
|
||||||
|
print(session)
|
||||||
|
if request.method == "GET":
|
||||||
|
if "node" in request.args and request.args["node"] in config["nodes"]:
|
||||||
|
return render_template("peerings-new.html", config=config, selected_node=request.args["node"], peerings=peerings)
|
||||||
|
else:
|
||||||
|
return render_template("peerings-new.html", session=session,config=config, peerings=peerings)
|
||||||
|
elif request.method == "POST":
|
||||||
|
|
||||||
|
return f"{request.method} /peerings/edit?{str(request.args)}{str(request.form)}"
|
||||||
@app.route("/peerings/new", methods=["GET","POST"])
|
@app.route("/peerings/new", methods=["GET","POST"])
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def peerings_new():
|
def peerings_new():
|
||||||
|
@ -301,16 +312,31 @@ def peerings_new():
|
||||||
if new_peering["peer-v4"]:
|
if new_peering["peer-v4"]:
|
||||||
ipv4 = ip_address(new_peering["peer-v4"])
|
ipv4 = ip_address(new_peering["peer-v4"])
|
||||||
if not ipv4.version == 4: raise ValueError()
|
if not ipv4.version == 4: raise ValueError()
|
||||||
if ipv4.is_private:
|
if ipv4.is_link_local:
|
||||||
|
pass
|
||||||
|
elif ipv4.is_private:
|
||||||
if not (ipv4.compressed.startswith("172.2") or ipv4.compressed.startswith("10.")):
|
if not (ipv4.compressed.startswith("172.2") or ipv4.compressed.startswith("10.")):
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
elif ipv4.is_link_local:
|
is_in_allowed = False
|
||||||
pass
|
if session["user-data"]["allowed4"]:
|
||||||
|
for allowed4 in session["user-data"]["allowed4"].split(","):
|
||||||
|
if ipv4 in ip_network(allowed4):
|
||||||
|
is_in_allowed = True
|
||||||
|
if not is_in_allowed:
|
||||||
|
return render_template("peerings-new.html", session=session,config=config, peerings=peerings, msg="supplied ipv4 addr not in allowed ip range"), 400
|
||||||
else: raise ValueError()
|
else: raise ValueError()
|
||||||
if new_peering["peer-v6"]:
|
if new_peering["peer-v6"]:
|
||||||
ipv6 = ip_address(new_peering["peer-v6"])
|
ipv6 = ip_address(new_peering["peer-v6"])
|
||||||
if not ipv6.version == 6: raise ValueError()
|
if not ipv6.version == 6: raise ValueError()
|
||||||
if not ipv6.is_private: raise ValueError()
|
if not ipv6.is_private: raise ValueError()
|
||||||
|
if ipv6.is_link_local: raise ValueError()
|
||||||
|
is_in_allowed = False
|
||||||
|
if session["user-data"]["allowed6"]:
|
||||||
|
for allowed6 in session["user-data"]["allowed6"].split(","):
|
||||||
|
if ipv6 in ip_network(allowed6):
|
||||||
|
is_in_allowed = True
|
||||||
|
if not is_in_allowed:
|
||||||
|
return render_template("peerings-new.html", session=session,config=config, peerings=peerings, msg="supplied ipv6 addr not in allowed ip range"), 400
|
||||||
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return render_template("peerings-new.html", session=session,config=config, peerings=peerings, msg="invalid ip address(es) supplied"), 400
|
return render_template("peerings-new.html", session=session,config=config, peerings=peerings, msg="invalid ip address(es) supplied"), 400
|
||||||
|
|
|
@ -146,6 +146,11 @@
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><input type="text" name="peer-asn" id="peer-asn" disabled="disabled" value="{{session['user-data']['asn']}}"></td>
|
<td><input type="text" name="peer-asn" id="peer-asn" disabled="disabled" value="{{session['user-data']['asn']}}"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><h4>Wireguard</h4></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for="peer-wgkey">your Wireguard Publickey</label></td>
|
<td><label for="peer-wgkey">your Wireguard Publickey</label></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
|
@ -171,7 +176,23 @@
|
||||||
<td><input type="checkbox" name="peer-v6-enabled" id="peer-v6-enabled"onchange="return update_from_v6()"></td>
|
<td><input type="checkbox" name="peer-v6-enabled" id="peer-v6-enabled"onchange="return update_from_v6()"></td>
|
||||||
<td><input type="text" name="peer-v6" id="peer-v6"onchange="return update_from_v6()"></td>
|
<td><input type="text" name="peer-v6" id="peer-v6"onchange="return update_from_v6()"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><h4>BGP</h4></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>MultiProtocol</td>
|
||||||
|
<td><input type="checkbox" name="bgp-multi-protocol" id="bgp-multi-protocol" onchange="return update_from_mpbgp()" checked></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>extended next hop</td>
|
||||||
|
<td><input type="checkbox" name="bgp-extended-next-hop" id="bgp-extended-next-hop" onchange="return update_from_enh()" checked></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<input type="submit" value="submit">
|
<input type="submit" value="submit">
|
||||||
</form>
|
</form>
|
||||||
<div class="example-config">
|
<div class="example-config">
|
||||||
|
|
|
@ -4,9 +4,35 @@
|
||||||
<div>
|
<div>
|
||||||
<a href="peerings/new"><button>add new</button></a>
|
<a href="peerings/new"><button>add new</button></a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="flex flex-row">
|
||||||
{% for peering in peerings.get_peerings_by_mnt(session["login"]) %}
|
{% for peering in peerings.get_peerings_by_mnt(session["login"]) %}
|
||||||
{{peering}} <br>
|
<div class="peering">
|
||||||
|
<div>
|
||||||
|
<div>Node: {{peering["node"]}}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr><td>ASN:</td><td>{{peering["ASN"]}}</td></tr>
|
||||||
|
<tr><td>WG-PublicKey:</td><td>{{peering["wg_key"][:8]}}...</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
{% if peering["ipv6ll"] %}<tr><td>ipv6 linklocal:</td><td>{{peering["ipv6ll"]}}</td></tr>{% endif %}
|
||||||
|
{% if peering["ipv4"] %}<tr><td>ipv4:</td><td>{{peering["ipv4"]}}</td></tr>{% endif %}
|
||||||
|
{% if peering["ipv6"] %}<tr><td>ipv6:</td><td>{{peering["ipv6"]}}</td></tr>{% endif %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- <div>{{peering}}</div> -->
|
||||||
|
<div>
|
||||||
|
<a href="peerings/edit?node={{peering['node']}}&asn={{peering['ASN']}}">
|
||||||
|
<button class="peering-edit">edit</button>
|
||||||
|
</a>
|
||||||
|
<a href="peerings/delete?node={{peering['node']}}&asn={{peering['ASN']}}">
|
||||||
|
<button class="peering-delete">delete</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -71,4 +71,49 @@ footer.flex {
|
||||||
|
|
||||||
form > div > * {
|
form > div > * {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peering {
|
||||||
|
border-color: var(--other-background);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border-style: inset;
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.peering > div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.peering > div > * {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: #00000020;
|
||||||
|
border-color: var(--text-color);
|
||||||
|
border-width: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peering>* {
|
||||||
|
width:auto;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peering-edit {
|
||||||
|
border-color: lightblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peering-edit:hover {
|
||||||
|
background-color: #87cefaaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.peering-delete {
|
||||||
|
border-color: darkred;
|
||||||
|
}
|
||||||
|
.peering-delete:hover {
|
||||||
|
background-color: #ff0000aa;
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue