TLS (“SSL”) Quirks in OpenSim

This is not a post about my ongoing struggles to make OpenSim work with TLS and communicate properly with other grids, using a transparent Nginx reverse proxy. I suspect there may be one or two bugs to report but I am still investigating numerous issues, particularly around why the XMLRPC method verify_agent seems to fail to reach the target grid consistently – is it my proxy settings or is it something in OpenSim?

I am going to write about the alleged “out of band” TLS settings, a topic which confused me for some time. You will find these in Robust[.HG].ini (for my earlier work on TLS for the simulator, please see my earlier post, which makes edits to OpenSim.ini). In fact, despite my earlier credence in this statement, it is potentially misleading. It is in fact possible to add a native HTTPS port to the simulator, to set it as the main listener port rather than as the additional port, and to set it up with TLS provided externally. There are some considerable quirks in this system – and one major drawback that means that you will continue to need to use an external reverse proxy like Nginx to operate a grid using TLS.

I will be studiously avoiding the common and erroneous use of the term SSL for TLS, since the use of SSL instead of its successor TLS for HTTPS and similar protocols has long been compromised and is both insecure and deprecated. In fact it is wisest only to use TLS versions 1.2 and 1.3 if at all possible, never version 1.0. It may still be necessary to use version 1.1 for some limited purposes but I shall not address that further here. Both 1.0 and 1.1 have been deprecated by major browsers since March 2020.

The settings in question under [Network] are https_listener, https_main and https_external (of which the latter remains undocumented, even in OpenSimDefaults.ini).

The first of these, https_listener = True, adds an additional secure HTTPS (TLS) port as documented. You will also need to set https_port = 9002 (or whatever suits your setup, but I am popularising 9002 and 9003 for the defaults for TLS), cert_path = “path/to/cert.p12” (location of the X509 certificate) and cert_pass = “yourpassword”, as well as possibly needing to look again under [Startup] at NoVerifyCertChain = true and NoVerifyCertHostname = true (set to false if you are using a certificate authority to validate your certificates via LetsEncrypt or some other authority).

The next setting https_main = True sets the main listener as the HTTPS port. However, whether by design or by oversight, it does not transfer any of the HTTP handlers (use show http-handlers on the Robust console to show these) to the HTTPS listener port. This is a problem for Hypergrid (and presumably for the purposes of all the other handlers too!) since you will be unable to verify the identity of the agent and the client without the relevant XMLRPC methods. For this reason, setting up a grid to use TLS still requires the use of Nginx as a reverse proxy. (I am still having problems getting this to work despite successful manual XMLRPC calls to the ports with cURL to check that the correct results are in fact returned from the server.) This quirk is really quite annoying but I do not know if there is some reason for it. Since this is the main public port, I can see no reason not to switch it over or duplicate these endpoints. Another less important quirk is that port is not replaced, irrespective of how you set https_main, and that https_port is additional, similar to the situation on the simulator that I documented in my earlier post. This is no problem: you don’t have to let it through your firewall.

Ed. [2022-02-18 10:58]: Are the missing HTTP handlers related to this commit?

The third quirk relates to the entirely undocumented https_external setting. I discovered this by looking at the code in Framework/NetworkServersInfo.cs (and, for example, in the OpenSim Mantis such as in this feature request). This is a very peculiar setting indeed because, if https_external = True and https_listener = True together, the https_port port will be added without TLS i.e. it will be reachable only by the protocol http:// and not by https:// on the server. It will then require an external proxy like Nginx to provide the latter (for which see my comments above on the ongoing issues that I am testing). In essence, despite the name https_port, it is then an additional HTTP port without any of the HTTP handlers that are provided on port. You then have two plain HTTP ports. That seems rather eccentric, but it works and is logical, though it is counter-intuitive. You wouldn’t guess this without some help, especially as it isn’t documented.

To summarise, the description of these settings as only being useful for “out of band” purposes like the remote console is still accurate because the HTTP handlers are not available, whether it is the secondary or the main public port on the Robust server. If these were transferred and/or duplicated then it follows that it would also be of primary use in setting up TLS on Robust without the need for a reverse proxy. I would like to see this happen: it might help with my struggles with the Hypergrid with TLS.

I hope this post is of use to OpenSim developers, testers and grid admins alike. I will document what I suspect may be problems/bugs in using TLS with reverse proxies in another post when I can (still testing).

Lastly, I repeat my assertion that this is a priority matter and that all grids should at least use TLS for the login server so that passwords are not broadcast in the clear – Ed. note that the SceneGate viewer actually warns you about this by default unless you tell it not to after the first time. That is the industry standard for a reason. I accept the arguments about the excessive overheads of encryption for other purposes, although I am reminded of SL being hacked by giant penises back in the day and thus suggest that it might be an idea to secure some other public data transmissions too. The overheads are not that much in practice on modern hardware and with modern compression standards, and you don’t need to use TLS on the internal port (usually 8003) unless you really need to open that up to the Internet i.e. simulators on remote machines will need to connect to your Robust services or you split services over multiple remote machines. Most of the rest of the Internet now uses HTTPS for almost everything, certainly for the Web, FTP, SSH, e-mail and so on. That bring me to a final observation: there are no TLS settings for the internal port in this situation, so you would still need to use Nginx as a reverse proxy for this. Correction: there is no separate setting but, when https_main = True and https_listener = True, both the private port and the https_port are served over HTTPS unless http_external is also set. Should this be documented more precisely? There is a use case for these settings existing in such a situation, although most people probably wouldn’t need to use them unless they anticipate running a public grid to which others can connect regions. It’s a bit problematic too if you want no HTTPS on the firewalled internal port (where there is no need for the encryption overhead) but you do want it on the public-facing port.

MySQL 8.0 TLS connection issue

MySQL 8.0 TLS connection issue

This arose with an upgrade to MySQL 8.0.4 on my server, which caused OpenSim (0.9.2.0 in this case) to be unable to connect via TLS (“SSL”) to Robust.

Here follows the text from https://oceangrid.net/news/107-mysql-8-0-tls-connection-issue.html

——

An upgrade to MySQL caused the grid to fail to connect to the database, since OpenSim 0.9.2.0 was not properly configured to connect to MySQL 8.0 by TLS, which is what MySQL 8.0 now assumes by default unless instructed otherwise, unlike in earlier versions.

There is a Mantis report that outlines the issue. However, default-authentication-plugin=mysql_native_password was already set in /etc/mysql/mysql.conf.d/mysqld.cnf and no change was required (Ubuntu 21.04.3 LTS).

There is no need for the overhead of TLS since the connection is being made on localhost, so the solution was to connect without TLS and thus without needing to configure the certificates by changing a line in Robust[.HG].ini as follows (with the parts in bold added):

[DatabaseService]
; MySQL
; Uncomment these lines if you want to use MySQL storage
    ; Change the connection string to your db details
    ; Remove SslMode=None if you need secure connection to the local MySQL
; If using MySQL 8.0.4 or later, check that default-authentication-plugin=mysql_native_password rather than caching_sha2_password is set in /etc/mysql/mysql.conf.d/mysqld.cnf (not applicable to MariaDB).
; In most cases ssl is just a pure waste of resources, specially when MySQL is on same machine, and closed to outside
StorageProvider = “OpenSim.Data.MySQL.dll”
ConnectionString = “Data Source=localhost;Database=opensim;User ID=opensim;Password=*****;Old Guids=true;SslMode=None;

You will notice that this hasn’t been documented, whereas it has been documented in GridCommon.ini and StandaloneCommon.ini as follows (with the suggested extra documentation added):

And also there needs to be a change to GridCommon.ini

[DatabaseService]
; MySQL
; Uncomment these lines if you want to use MySQL storage
; Change the connection string to your db details
; Remove SslMode=None if you need secure connection to the local MySQL
; If using MySQL 8.0.4 or later, check that default-authentication-plugin=mysql_native_password rather than caching_sha2_password is set in /etc/mysql/mysql.conf.d/mysqld.cnf (not applicable to MariaDB).
; In most cases ssl is just a pure waste of resources, specially when MySQL is on same machine, and closed to outside
StorageProvider = “OpenSim.Data.MySQL.dll”
ConnectionString = “Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;SslMode=None;”

; Uncomment this line if you are using MySQL and want to use a different database for estates
; The usual application for this is to allow estates to be spread out across multiple simulators by share the same database.
; Most people won’t need to do this so only uncomment if you know what you’re doing.
;EstateConnectionString = “Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;SslMode=None;”

This requires a patch to the documentation so that the same problem won’t affect others.

Patch suggested: http://opensimulator.org/mantis/view.php?id=8966