This week, after the announcement of Ignition Maker Edition, I downloaded the Windows ZIP installer, and unzipped it into two locations, each with a different purpose; one would be full-fleged Ignition, and the other Maker Edition.
Since in my company we are still supporting 7.9, I’ve been doing this ZIP installs for quite some time; having each Gateway registered with its own service name, and configuring all in different ports (HTTP, HTTPS, Metro SSL).
Before this week I was only running 7.9.14, and 8.0.13 on my own PC, but now that I’m running Ignition-8.0.14 and Maker-8.0.14 I am noticing a very odd behavior.
When I log into the Config on Maker-8.0.14 I am logged off from Ignition-8.0.14, and viceversa, but the 7.9.14 remains unaffected. I extended my test and ZIP-installed 8.0.13, and all 8.0.X version appear to be affected when all of them are running on the same PC.
It seems as if sessions were being shared across all 8.0.X Gateways.
I believe this is a bug, because I would not expect this to be intended behavior.
Posting my gateway.xml file settings in case I am inadvertently doing something I’m not supposed to.
7.9.14
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Context Settings</comment>
<entry key="catapult.maxThreads">300</entry>
<entry key="catapult.metroSSLPort">8068</entry>
<entry key="catapult.sslport">8043</entry>
<entry key="catapult.keepAliveTimeout">60000</entry>
<entry key="localdb.autobackup.delay">2</entry>
<entry key="context.startup.useautobackups">true</entry>
<entry key="context.props.version">3</entry>
<entry key="catapult.acceptCount">100</entry>
<entry key="catapult.port">8088</entry>
<entry key="catapult.maxKeepAliveRequests">200</entry>
<entry key="localdb.autobackup.count">5</entry>
<entry key="localdb.faultbackup.count">3</entry>
<entry key="catapult.connectionTimeout">60000</entry>
</properties>
8.0.13
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Context Settings</comment>
<entry key="gateway.publicAddress.httpPort"></entry>
<entry key="gateway.publicAddress.autoDetect">true</entry>
<entry key="gateway.publicAddress.httpsPort"></entry>
<entry key="gateway.forceSecureRedirect">false</entry>
<entry key="gateway.metroSSLPort">8460</entry>
<entry key="gateway.includedCipherSuites">[]</entry>
<entry key="localdb.autobackup.delay">2</entry>
<entry key="context.startup.useautobackups">true</entry>
<entry key="gateway.sslport">8443</entry>
<entry key="gateway.maxKeepAliveRequests">200</entry>
<entry key="context.props.version">3</entry>
<entry key="gateway.port">8480</entry>
<entry key="localdb.autobackup.count">5</entry>
<entry key="gateway.maxThreads">300</entry>
<entry key="gateway.connectionTimeout">60000</entry>
<entry key="localdb.faultbackup.count">3</entry>
<entry key="data.dir">data\</entry>
<entry key="gateway.acceptCount">100</entry>
<entry key="gateway.keepAliveTimeout">60000</entry>
<entry key="gateway.excludedCipherSuites">[]</entry>
<entry key="gateway.publicAddress.address"></entry>
</properties>
8.0.14
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Context Settings</comment>
<entry key="gateway.publicAddress.httpPort"></entry>
<entry key="gateway.publicAddress.autoDetect">true</entry>
<entry key="gateway.publicAddress.httpsPort"></entry>
<entry key="gateway.forceSecureRedirect">false</entry>
<entry key="gateway.metroSSLPort">8060</entry>
<entry key="gateway.includedCipherSuites">[]</entry>
<entry key="localdb.autobackup.delay">2</entry>
<entry key="context.startup.useautobackups">true</entry>
<entry key="gateway.sslport">43</entry>
<entry key="gateway.maxKeepAliveRequests">200</entry>
<entry key="context.props.version">3</entry>
<entry key="gateway.port">80</entry>
<entry key="localdb.autobackup.count">5</entry>
<entry key="gateway.maxThreads">300</entry>
<entry key="gateway.connectionTimeout">60000</entry>
<entry key="localdb.faultbackup.count">3</entry>
<entry key="data.dir">data\</entry>
<entry key="gateway.acceptCount">100</entry>
<entry key="gateway.keepAliveTimeout">60000</entry>
<entry key="gateway.excludedCipherSuites">[]</entry>
<entry key="gateway.publicAddress.address"></entry>
</properties>
8.0.14-Maker
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Context Settings</comment>
<entry key="gateway.publicAddress.httpPort"></entry>
<entry key="gateway.publicAddress.autoDetect">true</entry>
<entry key="gateway.publicAddress.httpsPort"></entry>
<entry key="gateway.forceSecureRedirect">false</entry>
<entry key="gateway.metroSSLPort">8860</entry>
<entry key="gateway.includedCipherSuites">[]</entry>
<entry key="localdb.autobackup.delay">2</entry>
<entry key="context.startup.useautobackups">true</entry>
<entry key="gateway.sslport">8843</entry>
<entry key="gateway.maxKeepAliveRequests">200</entry>
<entry key="context.props.version">3</entry>
<entry key="gateway.port">8888</entry>
<entry key="localdb.autobackup.count">5</entry>
<entry key="gateway.maxThreads">300</entry>
<entry key="gateway.connectionTimeout">60000</entry>
<entry key="localdb.faultbackup.count">3</entry>
<entry key="data.dir">data\</entry>
<entry key="gateway.acceptCount">100</entry>
<entry key="gateway.keepAliveTimeout">60000</entry>
<entry key="gateway.excludedCipherSuites">[]</entry>
<entry key="gateway.publicAddress.address"></entry>
</properties>
Furthermore, this is happening on Google Chrome, Microsoft Edge “Chromium”, and Safari.
As I suspected, if I access Ignition-8.0.14 from the regular browser, and Maker-8.0.14 from an Incognito window, both sessions remain active.
Finally, I just installed two 7.9.14 Gateways, and the same behavior is occurring on both.
One logged-in session is killed as soon as I even dare to click Status or Config on the other Gateway; there is no need to start a session. This is experienced on both versions, 7.9.14 and 8.0.14.
We have also seen this issue with being logged in to the gateway.
We use docker for development, so when I want to compare two gateway settings, I had them both open. But every time I logged in to one, the other was logged out.
These gateways were completely isolated, but shared the same ip address. So it’s not related to the gateway, but to how the browser and the session cookies interact. A cookie works per ip address, and is shared over all ports of that ip address.
Our solution was to use private mode (since that stops sharing the cookies over multiple tabs). Or in Firefox you also have the feature “Multi account containers”, which will limit the cookies to a certain number of tabs.
2 Likes
Sure, it makes sense. But still something feels kind of “wrong” about this.
If both are completely isolated, they should be completely isolated. Specially Docker containers.
Just as I was able to run 7.9.14 and 8.0.13 side by side, there must be a way I could run two Gateways from the same version at the same time. As if I were testing redundancy; 8.0.14-Master and 8.0.14-Backup.
I am aware that this is not intended, and possibly not even something that Inductive Automation might consider, but it would be a nice-to-have.
The gateways are completely isolated. And that’s exactly the issue.
It’s the browser that just uses the same cookie for both (which is according to spec, but the specs were made before the rise of containers).
So if you log in to one gateway, it sets the session cookie. And the next time you go to the other gateway, it finds a session cookie with a secret it doesn’t know about. So it logs you out.
Even if you would do tricks, like keep a secret per port on your session cookie, it wouldn’t work. As the session cookie is downloaded on page load, and send again on a new request. But doesn’t get updated in the meantime. So another gateway would still just override the session cookie and you’d be logged out on one or the other.
The only possibility would be for the gateways to communicate the given secret to each other. But this has a potential for big security holes, would be hard to maintain across versions, and wouldn’t even work in our case with containers.
2 Likes
Thanks for taking the time. I had a suspicion, and it has been confirmed.
1 Like
For those still trying to wrap their minds around this phenomenon, you should note that they aren't completely isolated. They share an IP address. You can mitigate the problem by giving them all their own hostname in /etc/hosts and only accessing via name. Then the cookie would be associated with the name instead of the common IP address.
The other point to note is that your browser is a non-isolated common point. Which is why your browser is showing the problem.
3 Likes
While that is true, that would require this to be changed on all clients, which is cumbersome.
But fortunately after doing a quick search, I found a very promising solution; and that is tinkering with the web.xml
file for Ignition's webserver found at [Install.dir]\webserver\webapps\main\WEB-INF
.
Disclaimer: Do the following at your own risk.
I left the full-fledged Ignition settings untouched, but I did modify the Maker web settings, like this:
Original settings
<context-param>
<param-name>org.eclipse.jetty.servlet.SessionIdPathParameterName</param-name>
<param-value>none</param-value>
</context-param>
<context-param>
<param-name>org.eclipse.jetty.servlet.Default.dirAllowed</param-name>
<param-value>false</param-value>
</context-param>
Modified settings
<!-- Start of added section -->
<context-param>
<param-name>org.eclipse.jetty.servlet.SessionCookie</param-name>
<param-value>XSESSIONID</param-value>
</context-param>
<!-- End of added section -->
<context-param>
<param-name>org.eclipse.jetty.servlet.SessionIdPathParameterName</param-name>
<param-value>xsessionid</param-value> <!-- Modified this value from none to xsessionid. -->
</context-param>
<context-param>
<param-name>org.eclipse.jetty.servlet.Default.dirAllowed</param-name>
<param-value>false</param-value>
</context-param>
After saving my settings I just restarted the Maker Gateway, and everything was running as expected.
There wasn't a problem when I was running 7.9 and 8 at the same time, because for 7.9 the JSESSIONID Path points not to the root, but /main
. That's why I never noticed this before.
In this picture JSESSIONID localhost/
identifies the 8.0.14 Gateway, XSESSIONID localhost/
the Maker 8.0.14 Gateway, and JSESSIONID localhost/main
the 7.9.14 Gateway.
And now I can access Config and Status on any browser, and PC, and everything is working fine.
2 Likes