For the last couple years, my schtick has been that I don’t care about your scripts, just your infrastructure. I’m pretty sure in my talk at SeConf London I mused that it was bonkers that we had got away communicating to the Se Server via HTTP. (I have to deal with vendor audits at work and they get really antsy at any mention of HTTP.) At SeConf Chicago I crashed the Se Grid workshop and asked (knowingly) if I was correct that communication was only via HTTP hoping someone would fix it for me. Alas, no one took the bait so at SeConf in London, I was describing the problem to Simon who happened to be creating a ticket (actually, a couple) as I talked, and then I got an alert saying it was assigned to me. The squeaky wheel applies its own grease it seems.
There are a couple catch-22’s in place before I can update the official Selenium Documentation (have you seen the new doc site? It’s great!), so in lieu of that, here is a quick how-to on something that will be in Selenium 4 Alpha 2 (or now if you build it yourself).
What is below is the output of ‘info security’ on the new server. (The ‘info’ command is also new and as of yet undocumented.)
Selenium Grid by default communicates over HTTP. This is fine for a lot of use cases, especially if everything is contained within the firewall and against test sites with testing data. However, if your server is exposed to the Internet or is being used in environments with production data (or that which has PII) then you should secure it.
Standalone
In order to run the server using HTTPS instead of HTTP you need to start it with the --https-private-key
and --https-certificate
flags to provide it the certificate and private key (as a PKCS8 file).
java -jar selenium.jar \ hub \ --https-private-key /path/to/key.pkcs8 \ --https-certificate /path/to/cert.pem
Distributed
Alternatively, if you are starting things individually you would also specify HTTPS when telling where to find things.
java -jar selenium.jar \ sessions \ --https-private-key /path/to/key.pkcs8 \ --https-certificate /path/to/cert.pem
java -jar selenium.jar \ distributor \ --https-private-key /path/to/key.pkcs8 \ --https-certificate /path/to/cert.pem \ -s https://sessions.grid.com:5556
java -jar selenium.jar \ router \ --https-private-key /path/to/key.pkcs8 \ --https-certificate /path/to/cert.pem \ -s https://sessions.grid.com:5556 \ -d https://distributor.grid.com:5553 \
Certificates
The Selenium Grid will not operate with self-signed certificates, as a result you will need to have some provisioned to you from a Certificate Authority of some sort. For experimentation purposes you can use MiniCA to create and sign your certificates.
minica --domains sessions.grid.com,distributor.grid.com,router.grid.com
This will create minica.pem and minica.key in the current directory as well as cert.pem and key.pem in a directory sessions.grid.com
which will have both distributor.grid.com and router.grid.com as alternative names. Because Selenium Grid requires the key to be in PKCS8, you have to convert it.
openssl pkcs8 \ -in sessions.grid.com/key.pem \ -topk8 \ -out sessions.grid.com/key.pkcs8 \ -nocrypt
And since we are using a non-standard CA, we have to teach Java about it. To do that you add it to the cacert truststore which is by default, $JAVA_HOME/jre/lib/security/cacerts
sudo keytool \ -import \ -file /path/to/minica.pem \ -alias minica \ -keystore $JAVA_HOME/jre/lib/security/cacerts \ -storepass changeit \ -cacerts
Clients
None of the official clients have been updated yet to support this, but if you are using a CA that the system knows about you can just use an HTTPS Command Executor and everything will work. If you are using a non-standard one (like MiniCA) you probably will have to just through a hoop or two similar to here in Python which basically says “Yes, yes, I know you don’t know about the CA but I do so just continue along anyways.”
from selenium import webdriver import urllib3 urllib3.disable_warnings() options = webdriver.FirefoxOptions() driver = webdriver.Remote( command_executor='https://router.grid.com:4444', options = options ) driver.close()
Post a Comment