From 38cb818469438afb8b1586c8c3139f00e2e30b80 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 12 Jan 2020 10:52:34 +0000 Subject: [PATCH] Anonymise client IPs and allow server operators to disable sharing. --- OpenRA.Game/Network/Session.cs | 20 +++++++++++++++++++ OpenRA.Game/Server/Server.cs | 1 + OpenRA.Game/Settings.cs | 3 +++ .../Widgets/Logic/PlayerProfileLogic.cs | 4 ++-- launch-dedicated.cmd | 3 ++- launch-dedicated.sh | 4 +++- 6 files changed, 31 insertions(+), 4 deletions(-) diff --git a/OpenRA.Game/Network/Session.cs b/OpenRA.Game/Network/Session.cs index 51e34e2b16..f8d2eb70ae 100644 --- a/OpenRA.Game/Network/Session.cs +++ b/OpenRA.Game/Network/Session.cs @@ -12,6 +12,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; +using System.Net.Sockets; using OpenRA.Primitives; namespace OpenRA.Network @@ -26,6 +28,18 @@ namespace OpenRA.Network public Global GlobalSettings = new Global(); + public static string AnonymizeIP(IPAddress ip) + { + if (ip.AddressFamily == AddressFamily.InterNetwork) + { + // Follow convention used by Google Analytics: remove last octet + var b = ip.GetAddressBytes(); + return "{0}.{1}.{2}.*".F(b[0], b[1], b[2]); + } + + return null; + } + public static Session Deserialize(string data) { try @@ -115,8 +129,14 @@ namespace OpenRA.Network public string Faction; public int SpawnPoint; public string Name; + + // The full IP address is required for the IP banning moderation feature + // but we must not share the un-anonymized address with other players. + [FieldLoader.Ignore] public string IpAddress; + public string AnonymizedIPAddress; public string Location; + public ClientState State = ClientState.Invalid; public int Team; public string Slot; // Slot ID, or null for observer diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index 9ad42ed72e..a8d4dc97c7 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -348,6 +348,7 @@ namespace OpenRA.Server { Name = OpenRA.Settings.SanitizedPlayerName(handshake.Client.Name), IpAddress = ipAddress.ToString(), + AnonymizedIPAddress = Settings.ShareAnonymizedIPs ? Session.AnonymizeIP(ipAddress) : null, Location = GeoIP.LookupCountry(ipAddress), Index = newConn.PlayerIndex, PreferredColor = handshake.Client.PreferredColor, diff --git a/OpenRA.Game/Settings.cs b/OpenRA.Game/Settings.cs index 3610e22827..6e62f649a9 100644 --- a/OpenRA.Game/Settings.cs +++ b/OpenRA.Game/Settings.cs @@ -86,6 +86,9 @@ namespace OpenRA "Database files can be downloaded from https://dev.maxmind.com/geoip/geoip2/geolite2/")] public string GeoIPDatabase = null; + [Desc("Allow clients to see anonymised IPs for other clients.")] + public bool ShareAnonymizedIPs = true; + public ServerSettings Clone() { return (ServerSettings)MemberwiseClone(); diff --git a/OpenRA.Mods.Common/Widgets/Logic/PlayerProfileLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/PlayerProfileLogic.cs index f08a5a6a2e..69e090afa2 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/PlayerProfileLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/PlayerProfileLogic.cs @@ -329,10 +329,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic adminLabel.Bounds.Y += locationLabel.Bounds.Height; } - if (client.IpAddress != null) + if (client.AnonymizedIPAddress != null) { ipLabel.IsVisible = () => true; - ipLabel.GetText = () => client.IpAddress; + ipLabel.GetText = () => client.AnonymizedIPAddress; widget.Bounds.Height += ipLabel.Bounds.Height; adminLabel.Bounds.Y += locationLabel.Bounds.Height; } diff --git a/launch-dedicated.cmd b/launch-dedicated.cmd index ca140e909a..c2c8efe9c4 100644 --- a/launch-dedicated.cmd +++ b/launch-dedicated.cmd @@ -16,9 +16,10 @@ set ProfileIDWhitelist="" set EnableSingleplayer=False set EnableSyncReports=False +set ShareAnonymizedIPs=True :loop -OpenRA.Server.exe Game.Mod=%Mod% Server.Name=%Name% Server.ListenPort=%ListenPort% Server.AdvertiseOnline=%AdvertiseOnline% Server.EnableSingleplayer=%EnableSingleplayer% Server.Password=%Password% Server.GeoIPDatabase=%GeoIPDatabase% Server.RequireAuthentication=%RequireAuthentication% Server.ProfileIDBlacklist=%ProfileIDBlacklist% Server.ProfileIDWhitelist=%ProfileIDWhitelist% Server.EnableSyncReports=%EnableSyncReports% +OpenRA.Server.exe Game.Mod=%Mod% Server.Name=%Name% Server.ListenPort=%ListenPort% Server.AdvertiseOnline=%AdvertiseOnline% Server.EnableSingleplayer=%EnableSingleplayer% Server.Password=%Password% Server.GeoIPDatabase=%GeoIPDatabase% Server.RequireAuthentication=%RequireAuthentication% Server.ProfileIDBlacklist=%ProfileIDBlacklist% Server.ProfileIDWhitelist=%ProfileIDWhitelist% Server.EnableSyncReports=%EnableSyncReports% Server.ShareAnonymizedIPs=%ShareAnonymizedIPs% goto loop diff --git a/launch-dedicated.sh b/launch-dedicated.sh index 604a1c31f6..77b2ddffa5 100755 --- a/launch-dedicated.sh +++ b/launch-dedicated.sh @@ -20,6 +20,7 @@ ProfileIDWhitelist="${ProfileIDWhitelist:-""}" EnableSingleplayer="${EnableSingleplayer:-"False"}" EnableSyncReports="${EnableSyncReports:-"False"}" +ShareAnonymizedIPs="${ShareAnonymizedIPs:-"True"}" while true; do mono --debug OpenRA.Server.exe Game.Mod="$Mod" \ @@ -32,5 +33,6 @@ while true; do Server.RequireAuthentication="$RequireAuthentication" \ Server.ProfileIDBlacklist="$ProfileIDBlacklist" \ Server.ProfileIDWhitelist="$ProfileIDWhitelist" \ - Server.EnableSyncReports="$EnableSyncReports" + Server.EnableSyncReports="$EnableSyncReports" \ + Server.ShareAnonymizedIPs="$ShareAnonymizedIPs" done