diff --git a/src/Jackett.Common/Content/custom.js b/src/Jackett.Common/Content/custom.js index f0bda8d69..7f0e106f6 100644 --- a/src/Jackett.Common/Content/custom.js +++ b/src/Jackett.Common/Content/custom.js @@ -120,6 +120,7 @@ function loadJackettSettings() { $("#jackett-savedir").val(data.blackholedir); $("#jackett-allowext").attr('checked', data.external); + $("#jackett-local-bind-address").val(data.local_bind_address); $("#jackett-allowcors").attr('checked', data.cors); $("#jackett-allowupdate").attr('checked', data.updatedisabled); $("#jackett-prerelease").attr('checked', data.prerelease); @@ -1611,6 +1612,7 @@ function bindUIButtons() { var jackett_basepathoverride = $("#jackett-basepathoverride").val(); var jackett_baseurloverride = $("#jackett-baseurloverride").val(); var jackett_external = $("#jackett-allowext").is(':checked'); + var jackett_local_bind_address = $("#jackett-local-bind-address").val(); var jackett_cors = $("#jackett-allowcors").is(':checked'); var jackett_update = $("#jackett-allowupdate").is(':checked'); var jackett_prerelease = $("#jackett-prerelease").is(':checked'); @@ -1632,6 +1634,7 @@ function bindUIButtons() { var jsonObject = { port: jackett_port, external: jackett_external, + local_bind_address: jackett_local_bind_address, cors: jackett_cors, updatedisabled: jackett_update, prerelease: jackett_prerelease, diff --git a/src/Jackett.Common/Content/index.html b/src/Jackett.Common/Content/index.html index 608b085da..27c28cd3b 100644 --- a/src/Jackett.Common/Content/index.html +++ b/src/Jackett.Common/Content/index.html @@ -179,6 +179,10 @@ External access: +
+ Local bind address: + +
Allow CORS: @@ -756,6 +760,6 @@ - + diff --git a/src/Jackett.Common/Models/Config/ServerConfig.cs b/src/Jackett.Common/Models/Config/ServerConfig.cs index f2e6f9e9e..0be424301 100644 --- a/src/Jackett.Common/Models/Config/ServerConfig.cs +++ b/src/Jackett.Common/Models/Config/ServerConfig.cs @@ -15,6 +15,7 @@ namespace Jackett.Common.Models.Config observers = new List>(); // Default values Port = 9117; + LocalBindAddress = "127.0.0.1"; AllowExternal = Environment.OSVersion.Platform == PlatformID.Unix; CacheEnabled = true; // Sonarr 15min, Radarr 60min, LazyLibrarian 20min, Readarr 15min, Lidarr = 15min @@ -32,6 +33,7 @@ namespace Jackett.Common.Models.Config } public int Port { get; set; } + public string LocalBindAddress { get; set; } public bool AllowExternal { get; set; } public bool AllowCORS { get; set; } public string APIKey { get; set; } @@ -114,7 +116,7 @@ namespace Jackett.Common.Models.Config else { return new string[] { - "http://127.0.0.1:" + Port + "/" + $"http://{LocalBindAddress}:{Port}/" }; } } diff --git a/src/Jackett.Common/Models/DTO/ServerConfig.cs b/src/Jackett.Common/Models/DTO/ServerConfig.cs index d957b634a..5c19d405a 100644 --- a/src/Jackett.Common/Models/DTO/ServerConfig.cs +++ b/src/Jackett.Common/Models/DTO/ServerConfig.cs @@ -15,6 +15,8 @@ namespace Jackett.Common.Models.DTO [DataMember] public bool external { get; set; } [DataMember] + public string local_bind_address { get; set; } + [DataMember] public bool cors { get; set; } [DataMember] public string api_key { get; set; } @@ -72,6 +74,7 @@ namespace Jackett.Common.Models.DTO this.notices = notices; port = config.Port; external = config.AllowExternal; + local_bind_address = config.LocalBindAddress; cors = config.AllowCORS; api_key = config.APIKey; blackholedir = config.BlackholeDir; diff --git a/src/Jackett.Common/Utils/Clients/WebClient.cs b/src/Jackett.Common/Utils/Clients/WebClient.cs index eb5c17ef5..9af7e4089 100644 --- a/src/Jackett.Common/Utils/Clients/WebClient.cs +++ b/src/Jackett.Common/Utils/Clients/WebClient.cs @@ -61,7 +61,7 @@ namespace Jackett.Common.Utils.Clients { // in case of error in DNS resolution, we use a fake proxy to avoid leaking the user IP (disabling proxy) // https://github.com/Jackett/Jackett/issues/8826 - var addresses = new[] { new IPAddress(2130706433) }; // 127.0.0.1 + var addresses = new[] { IPAddress.Parse(serverConfig.LocalBindAddress) }; try { addresses = Dns.GetHostAddressesAsync(serverConfig.ProxyUrl).Result; diff --git a/src/Jackett.Server/Controllers/ServerConfigurationController.cs b/src/Jackett.Server/Controllers/ServerConfigurationController.cs index bac4834a0..0a44f595b 100644 --- a/src/Jackett.Server/Controllers/ServerConfigurationController.cs +++ b/src/Jackett.Server/Controllers/ServerConfigurationController.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Threading; using Jackett.Common.Models; using Jackett.Common.Models.Config; @@ -76,8 +77,10 @@ namespace Jackett.Server.Controllers var webHostRestartNeeded = false; var originalPort = serverConfig.Port; + var originalLocalBindAddress = serverConfig.LocalBindAddress; var originalAllowExternal = serverConfig.AllowExternal; var port = config.port; + var local_bind_address = config.local_bind_address; var external = config.external; var cors = config.cors; var saveDir = config.blackholedir; @@ -181,7 +184,7 @@ namespace Jackett.Server.Controllers cacheService.CleanCache(); } - if (port != serverConfig.Port || external != serverConfig.AllowExternal) + if (port != serverConfig.Port || external != serverConfig.AllowExternal || local_bind_address != serverConfig.LocalBindAddress) { if (ServerUtil.RestrictedPorts.Contains(port)) throw new Exception("The port you have selected is restricted, try a different one."); @@ -189,9 +192,20 @@ namespace Jackett.Server.Controllers if (port < 1 || port > 65535) throw new Exception("The port you have selected is invalid, it must be below 65535."); - // Save port to the config so it can be picked up by the if needed when running as admin below. + if (string.IsNullOrWhiteSpace(local_bind_address)) + { + throw new Exception("You need to provide a local bind address."); + } + + if (!IPAddress.IsLoopback(IPAddress.Parse(local_bind_address))) + { + throw new Exception("The local address you selected is not a loopback one."); + } + + // Save port and LocalAddr to the config so they can be picked up by the if needed when running as admin below. serverConfig.AllowExternal = external; serverConfig.Port = port; + serverConfig.LocalBindAddress = local_bind_address; configService.SaveConfig(serverConfig); // On Windows change the url reservations @@ -206,11 +220,12 @@ namespace Jackett.Server.Controllers } catch { + serverConfig.LocalBindAddress = originalLocalBindAddress; serverConfig.Port = originalPort; serverConfig.AllowExternal = originalAllowExternal; configService.SaveConfig(serverConfig); - throw new Exception("Failed to acquire admin permissions to reserve the new port."); + throw new Exception("Failed to acquire admin permissions to reserve the new local_bind_address/port."); } } else diff --git a/src/Jackett.Tray/Main.cs b/src/Jackett.Tray/Main.cs index 0c275831c..847ca601a 100644 --- a/src/Jackett.Tray/Main.cs +++ b/src/Jackett.Tray/Main.cs @@ -119,7 +119,7 @@ namespace Jackett.Tray { var psi = new ProcessStartInfo { - FileName = "http://127.0.0.1:" + serverConfig.Port, + FileName = "http://" + serverConfig.LocalBindAddress + ":" + serverConfig.Port, UseShellExecute = true };