From 9466813ba172282e0ca3baa1fac861483b350288 Mon Sep 17 00:00:00 2001 From: James Lu Date: Mon, 11 Jun 2018 17:26:36 -0700 Subject: [PATCH] relay: switch to a flexible, pool-based configuration scheme for IP sharing This deprecates the "relay::show_ips" and network-specific "relay_no_ips" options, replacing it with the "relay::ip_share_pools" list. --- example-conf.yml | 23 ++++++++++++----------- plugins/relay.py | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/example-conf.yml b/example-conf.yml index cb2db5e..4f8048d 100644 --- a/example-conf.yml +++ b/example-conf.yml @@ -211,11 +211,6 @@ servers: # This setting is EXPERIMENTAL as of PyLink 1.2.x. #encoding: utf-8 - # If enabled, this opts this network out of relay IP sharing: this network - # will not have its users' IPs sent across the relay, and it will not see any - # IPs of other networks' users. - #relay_no_ips: true - # If relay nick tagging is disabled, this option specifies a list of nick globs to always # tag when introducing remote users *onto* this network. #relay_forcetag_nicks: ["someuser", "Guest*"] @@ -651,12 +646,18 @@ relay: # if not set. hideoper: true - # Determines whether real IPs should be sent across the relay. You should - # generally have a consensus with your linked networks on whether this should - # be turned on. You will see other networks' user IP addresses, and they - # will see yours. Individual networks can also opt out of IP sharing - # both ways by defining "relay_no_ips: true" in their server block. - show_ips: false + # This option defines lists of networks to relay user IPs between (instead of + # masking them as 0.0.0.0). If a network is in a pool (case-SENSITIVE), their + # opers will see the IPs from users in the rest of the pool, and the rest of + # the pool will receive IPs from that network too. + # You should generally have a consensus among your linked networks as to which + # network should be in which pool. A network can be part of one pool, multiple + # pools, or none at all. + # This option replaces the "relay::show_ips" and network-specific "relay_no_ips" + # options, which are DEPRECATED as of 2.0-alpha4. + #ip_share_pools: + # - ["net1", "net2", "net3"] + # - ["net1", "meganet"] # Determines whether NickServ login info should be shown in the /whois output for # relay users. diff --git a/plugins/relay.py b/plugins/relay.py index 55a75a7..c4ded73 100644 --- a/plugins/relay.py +++ b/plugins/relay.py @@ -66,10 +66,20 @@ def main(irc=None): if irc is not None: # irc is defined when the plugin is reloaded. Otherwise, it means that we've just started the # server. Iterate over all connected networks and initialize their relay users. - for ircobj in world.networkobjects.values(): + for netname, ircobj in world.networkobjects.items(): if ircobj.connected.is_set(): initialize_all(ircobj) + if 'relay_no_ips' in ircobj.serverdata: + log.warning('(%s) The "relay_no_ips" option is deprecated as of 2.0-alpha4. Consider migrating ' + 'to "ip_share_pools", which provides more fine-grained control over which networks ' + 'see which networks\' IPs.', netname) + + if 'relay' in conf.conf and 'show_ips' in conf.conf['relay']: + log.warning('The "relay::show_ips" option is deprecated as of 2.0-alpha4. Consider migrating ' + 'to "ip_share_pools", which provides more fine-grained control over which networks ' + 'see which networks\' IPs.') + log.debug('relay.main: finished initialization sequence') def die(irc=None): @@ -308,6 +318,21 @@ def get_relay_server_sid(irc, remoteirc, spawn_if_missing=True): spawnlocks_servers[irc.name].release() return sid +def _has_common_pool(sourcenet, targetnet, namespace): + """ + Returns the source network and target networks are in a pool under the given namespace + (e.g. "ip_share_pools"). + """ + if 'relay' not in conf.conf: + return False + + for pool in conf.conf['relay'].get(namespace, []): + if sourcenet in pool and targetnet in pool: + log.debug('relay._has_common_pool: found networks %r and %r in %s pool %r', sourcenet, targetnet, + namespace, pool) + return True + return False + def spawn_relay_user(irc, remoteirc, user, times_tagged=0, reuse_sid=None): """ Spawns a relay user representing "user" from "irc" (the local network) on remoteirc (the target network). @@ -358,12 +383,17 @@ def spawn_relay_user(irc, remoteirc, user, times_tagged=0, reuse_sid=None): 'working SID).', irc.name, user, nick, remoteirc.name) return + # This is the legacy (< 2.0-alpha4) control for relay IP sharing try: showRealIP = conf.conf['relay']['show_ips'] and not \ irc.serverdata.get('relay_no_ips') and not \ remoteirc.serverdata.get('relay_no_ips') + except KeyError: showRealIP = False + + # New (>= 2.0-alpha4) IP sharing is configured via pools of networks + showRealIP = showRealIP or _has_common_pool(irc.name, remoteirc.name, "ip_share_pools") if showRealIP: ip = userobj.ip realhost = userobj.realhost @@ -372,7 +402,7 @@ def spawn_relay_user(irc, remoteirc, user, times_tagged=0, reuse_sid=None): ip = '0.0.0.0' u = remoteirc.spawn_client(nick, ident=ident, host=host, realname=realname, modes=modes, - opertype=opertype, server=rsid, ip=ip, realhost=realhost).uid + opertype=opertype, server=rsid, ip=ip, realhost=realhost).uid try: remoteirc.users[u].remote = (irc.name, user) remoteirc.users[u].opertype = opertype