Skip to content

Commit

Permalink
Merge pull request #694 from NethServer/bug-6976
Browse files Browse the repository at this point in the history
Fix VPN routing error

Refs NethServer/dev#6976
  • Loading branch information
DavidePrincipi authored Aug 7, 2024
2 parents 798686b + a5b582f commit a20f286
Showing 1 changed file with 18 additions and 19 deletions.
37 changes: 18 additions & 19 deletions core/imageroot/usr/local/sbin/apply-vpn-routes
Original file line number Diff line number Diff line change
Expand Up @@ -35,40 +35,37 @@ agent.assert_exp(cluster_network)
# Convert Redis VPN records to our VPN data model
destmap = {}
for node_id in peers:
if self_id == leader_id:
if self_id == node_id:
# Skip the destinations for the local node: they use default
# kernel routing rules.
pass
elif self_id == leader_id:
# The local node is the Leader and the VPN hub. One node
# corresponds to a VPN peer, and its destinations are the node
# destinations with its IP address
destmap.setdefault(node_id, set())
destmap[node_id].update(peers[node_id]['destinations'].split())
destmap[node_id].add(peers[node_id]['ip_address'])

elif self_id == node_id:
# Skip the destinations for the local node: they use default
# kernel routing rules.
pass

else:
# Default VPN routing rule: send all traffic to the Leader
destmap.setdefault(leader_id, set())
destmap[leader_id].update(peers[node_id]['destinations'].split())
destmap[leader_id].add(peers[node_id]['ip_address'])

def get_wgset_endpoint_clause(endpoint):
def resolve_endpoint(endpoint):
"""Resolve the endpoint IP address and return the endpoint arguments
for the `wg set` subcommand"""
if not endpoint:
return []

return (None, None)
address, port = endpoint.rsplit(':')

try:
addrinfo = socket.getaddrinfo(address, port)
# Get the IP address (the last 0) of the first entry (first 0) from
# sockaddr item (index 4)
return ['endpoint', ':'.join([addrinfo[0][4][0], port])]
except:
return []
except Exception as ex:
print(agent.SD_ERR+f"Endpoint {address} resolution failed", ex, file=sys.stderr)
return (None, port)
# Get the IP address (the last 0) of the first entry (first 0) from
# sockaddr item (index 4)
return (addrinfo[0][4][0] , str(port))

# Find the networks of the local interfaces. Addresses of these networks
# are not routed through the VPN.
Expand All @@ -85,19 +82,21 @@ for iface in ipaddr_reply:
errors = 0
valid_destinations = []
for node_id in destmap:
peer_host, peer_port = resolve_endpoint(peers[node_id].get('endpoint', ''))
allowed_ips = destmap[node_id] - {peer_host}
# Apply immediately the new configuration to the WireGuard wg0 interface...
wset_proc = agent.run_helper('wg', 'set', 'wg0', 'peer', peers[node_id]["public_key"],
'persistent-keepalive', '25',
'allowed-ips', ','.join(destmap[node_id]),
*get_wgset_endpoint_clause(peers[node_id].get('endpoint', '')),
'allowed-ips', ','.join(allowed_ips),
*(['endpoint', f"{peer_host}:{peer_port}"] if peer_host else []), # optional arguments
log_command=True,
)
if wset_proc.returncode != 0:
errors +=1
print(agent.SD_ERR + f'Runtime change of allowed-ips has failed for peer node/{node_id}', file=sys.stderr)

# ...and to the system routing table:
for xdest in destmap[node_id]:
for xdest in allowed_ips:
push_route = False

odest = ipm.ip_address(xdest) # object form of xdest for network calculations
Expand Down

0 comments on commit a20f286

Please sign in to comment.