I have a local proxy server running on 127.0.0.1:5001
which is forwarded to a remote server using SSH. It should be used by my Selenium Firefox instance. This method is deprecated, Selenium recomments to use the FirefoxOptions
instead. So I tried the following simple POC and modified it to use a socks instead of http proxy:
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System;
namespace SeleniumProxyTest {
class Program {
static void Main(string[] args) {
var opts = new FirefoxOptions();
var proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.SocksProxy = "127.0.0.1:5002";
opts.Proxy = proxy;
var driver = new FirefoxDriver(opts);
driver.Navigate().GoToUrl("https://www.perfect-privacy.com/de/tests/check-ip");
Console.WriteLine("Finished");
Console.ReadLine();
}
}
}
But after some time, an exception occurs during creation of the FirefoxDriver
:
InvalidArgumentError: Expected "socksVersion" to be a positive integer, got [object Undefined] undefined (SessionNotCreated)
But the OpenQA.Selenium.Proxy
class doesn't contain any attribute related to the socks version.
What I have tried
Setting the protocol in the proxy url
proxy.SocksProxy = "socks5://127.0.0.1:5002";
Resulting in an error that no procotol should be specified:
OpenQA.Selenium.WebDriverException: "socksProxy must not contain a scheme: socks5://127.0.0.1:5002"
Setting socksVersion
as settings in the constructor
I found that the constructor of the Proxy
class accepts a dictionary of settings. Since the exception expects a specific property, I tried to set the version there:
var proxySettings = new Dictionary<string, object>() { { "socksVersion", 5 } };
var proxy = new Proxy(proxySettings);
Since Selenium is open source, I could confirm this assumption by taking a look in the Proxy.cs
class where the version is fetched from the provided settings dictionary. So my code should work.
Now I got rid of the socketVersion
error. However, it still doesn't work, now it throws a time ouf in the new FirefoxDriver
line:
OpenQA.Selenium.WebDriverException: "The HTTP request to the remote WebDriver server for URL http://localhost:32904/session timed out after 60 seconds."
The Firefox window of Selenium is opened far before that exception, but no navigation is done and the proxy settings are set to the default use the proxy settings of the system.
Since the Firefox window was opened and it says Listening on 127.0.0.1:45089
in the console, I thought that the local communication between my .NET Core application and the geckodriver doesn't work because of the proxy. So I added exceptions:
proxy.AddBypassAddresses(new string[] { "localhost", "127.0.0.1" });
Those doesn't seem to help. Also still no proxy entry in the network config as shown on the screenshot above.
Using HTTP proxy works
Strangely it works when I setup a HTTP instead of Socks5 proxy on 127.0.0.1 without any exception rules for local addresses.
Edit: Preferences also doesn't work
I translated this example to C#, which sets the proxy directly as prefernece in the profile:
var profile = new FirefoxProfile();
profile.SetPreference("network.proxy.type", 1);
profile.SetPreference("network.proxy.socks", "127.0.0.1");
profile.SetPreference("network.proxy.socks_port", 5002);
profile.SetPreference("network.proxy.socks_remote_dns", true);
var opts = new FirefoxOptions();
opts.Profile = profile;
var driver = new FirefoxDriver(opts);
Now Firefox navigates to the URL without timeout, but no proxy is set or used.
So I'm wondering why it doesn't work on Socks5 proxies and what I need to change to make it work?
Used package versions:
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver.GeckoDriver" Version="0.29.1" />