Skip to content

Commit

Permalink
lg: get rid of DOMAIN and improve configuration of proxied hosts
Browse files Browse the repository at this point in the history
This simplifies and clarify the configuration, while making it more generic

Proxied hosts can now be reached over HTTP or HTTPS, through any DNS name,
and even through IP literals to avoid dependency on DNS.  With the
previous code, proxied hosts needed to be reachable with the fixed scheme
`http://<host>.<DOMAIN>:<port>`, and this was a big limitation for some
deployments.

This is not backwards compatible, users will have to adapt their
configuration.  We rename the `PROXY` variable to `HOSTS` to make that
extra-clear.
  • Loading branch information
Baptiste Jonglez committed Jun 16, 2020
1 parent 967c721 commit 74935d3
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 43 deletions.
40 changes: 24 additions & 16 deletions lg.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,36 @@ DEBUG = False
LOG_FILE="/var/log/lg.log"
LOG_LEVEL="WARNING"

DOMAIN = "tetaneutral.net"

# Used to optionally restrict access to lgproxy based on a shared secret.
SHARED_SECRET="ThisTokenIsNotSecret"

BIND_IP = "0.0.0.0"
BIND_PORT = 5000

PROXY = {
"gw": 5000,
"h3": 5000,
}

# Used for bgpmap
ROUTER_IP = {
"gw" : [ "91.224.148.2", "2a01:6600:8000::175" ],
"h3" : [ "91.224.148.3", "2a01:6600:8000::131" ]
}

AS_NUMBER = {
"gw" : "197422",
"h3" : "197422"
# List of hosts to query (each one is a lgproxy instances)
HOSTS = {
"r1": {
# Endpoint at which lgproxy can be queried
"endpoint": "http://r1.example.com:5000",
# ASN and Router IP are used to make the bgpmap more pretty
"asn": "65551",
"routerip": ["198.51.100.99", "192.0.2.12", "2001:db8:42:cafe::175"],
},
"r2": {
# Using a plain IP address as endpoint is possible
"endpoint": "http://203.0.113.42:5000",
# It is fine to provide no "routerip" or "asn" field
},
"r3": {
# IPv6 litterals are supported too
"endpoint": "http://[2001:db8:ffff::42]:5000",
"asn": "65551",
},
"r4": {
# Example with HTTPS
"endpoint": "https://r5.example.com",
"asn": "64498",
},
}

#WHOIS_SERVER = "whois.foo.bar"
Expand Down
47 changes: 21 additions & 26 deletions lg.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,17 +142,14 @@ def bird_proxy(host, proto, service, query):
elif proto == "ipv4":
path = service

port = app.config["PROXY"].get(host, "")
if not path:
return False, 'Proto "%s" invalid' % proto

if not port:
if host not in app.config["HOSTS"]:
return False, 'Host "%s" invalid' % host
elif not path:
return False, 'Proto "%s" invalid' % proto

url = "http://%s" % (host)
if "DOMAIN" in app.config:
url = "%s.%s" % (url, app.config["DOMAIN"])
url = "%s:%d/%s?" % (url, port, path)
endpoint = app.config["HOSTS"][host]["endpoint"]
url = "%s/%s?" % (endpoint, path)
if "SHARED_SECRET" in app.config:
url = "%ssecret=%s&" % (url, app.config["SHARED_SECRET"])
url = "%sq=%s" % (url, quote(query))
Expand All @@ -162,7 +159,7 @@ def bird_proxy(host, proto, service, query):
resultat = f.read()
status = True # retreive remote status
except IOError:
resultat = "Failed to retrieve URL for host %s" % host
resultat = "Failed to retrieve data from host %s" % host
app.logger.warning("Failed to retrieve URL for host %s: %s", host, url)
status = False

Expand Down Expand Up @@ -192,12 +189,12 @@ def inject_commands():

@app.context_processor
def inject_all_host():
return dict(all_hosts="+".join(app.config["PROXY"].keys()))
return dict(all_hosts="+".join(app.config["HOSTS"].keys()))


@app.route("/")
def hello():
return redirect("/summary/%s/ipv4" % "+".join(app.config["PROXY"].keys()))
return redirect("/summary/%s/ipv4" % "+".join(app.config["HOSTS"].keys()))


def error_page(text):
Expand Down Expand Up @@ -467,17 +464,16 @@ def add_edge(_previous_as, _as, **kwargs):
return edges[edge_tuple]

for host, asmaps in data.iteritems():
if "DOMAIN" in app.config:
add_node(host, label= "%s\r%s" % (host.upper(), app.config["DOMAIN"].upper()), shape="box", fillcolor="#F5A9A9")
else:
add_node(host, label= "%s" % (host.upper()), shape="box", fillcolor="#F5A9A9")
add_node(host, label= "%s" % (host.upper()), shape="box", fillcolor="#F5A9A9")

as_number = app.config["AS_NUMBER"].get(host, None)
if as_number:
node = add_node(as_number, fillcolor="#F5A9A9")
edge = add_edge(as_number, nodes[host])
edge.set_color("red")
edge.set_style("bold")
host_config = app.config["HOSTS"].get(host)
if host_config:
as_number = host_config.get("asn")
if as_number:
node = add_node(as_number, fillcolor="#F5A9A9")
edge = add_edge(as_number, nodes[host])
edge.set_color("red")
edge.set_style("bold")

#colors = [ "#009e23", "#1a6ec1" , "#d05701", "#6f879f", "#939a0e", "#0e9a93", "#9a0e85", "#56d8e1" ]
previous_as = None
Expand Down Expand Up @@ -581,11 +577,10 @@ def build_as_tree_from_raw_bird_ouput(host, proto, text):
peer_ip = expr2.group(2).strip()
if expr2.group(4):
peer_protocol_name = expr2.group(4).strip()
# Check if via line is a internal route
for rt_host, rt_ips in app.config["ROUTER_IP"].iteritems():
# Special case for internal routing
if peer_ip in rt_ips:
path = [rt_host]
# Check if via line is an internal route (special case for internal routing)
for other_host in app.config["HOSTS"].keys():
if peer_ip in app.config["HOSTS"][other_host].get("routerip", []):
path = [other_host]
break
else:
# ugly hack for good printing
Expand Down
2 changes: 1 addition & 1 deletion templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<li class="navbar-text">Nodes:&nbsp;&nbsp;</li>
<li class="hosts"><a id="{{all_hosts}}" href="#">all</a></li>

{% for host in config.PROXY %}
{% for host in config.HOSTS %}
<li class="hosts"><a id="{{host}}" href="#">{{host}}</a></li>
{% endfor %}

Expand Down

0 comments on commit 74935d3

Please sign in to comment.