mirror of
https://github.com/opensim/opensim.git
synced 2026-08-05 00:46:02 +08:00
Basic implementation of SSL selfsigned certificates creation and renewal
Allows selfsigned certificates creation and renewal for local and external use. When enabled, will create a folder SSL\ and 2 sub folders SSL\ssl\ and SSL\src\. Next creates and store an RSA private key in SSL\src\ and the derived selfsigned certificates in SSL\ssl\ folder. Is also possible to renew the certificate on every server restart if CertRenewOnStartup is set to true. Note: The SSL related params in the network section was adapted to be user friendly and allow the usage just by uncommenting the SSL params in both sections and a password change.
This commit is contained in:
committed by
UbitUmarov
parent
e2b655a939
commit
c2c3ca418a
@@ -308,7 +308,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
if(htype == UriHostNameType.Unknown || htype == UriHostNameType.Basic)
|
||||
return false;
|
||||
if(htype == UriHostNameType.Dns)
|
||||
if(htype == UriHostNameType.Dns || htype == UriHostNameType.IPv4)
|
||||
{
|
||||
foreach(string name in m_certNames)
|
||||
{
|
||||
|
||||
@@ -56,6 +56,7 @@ using OpenMetaverse.StructuredData;
|
||||
using Amib.Threading;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
@@ -1480,6 +1481,71 @@ namespace OpenSim.Framework
|
||||
return streamReader.ReadToEnd();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void CreateOrUpdateSelfsignedCert(string certFileName, string certHostName, string certHostIp, string certPassword)
|
||||
{
|
||||
CreateOrUpdateSelfsignedCertificate(certFileName, certHostName, certHostIp, certPassword);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create or renew an SSL selfsigned certificate using the parameters set in the startup section of OpenSim.ini
|
||||
/// </summary>
|
||||
/// <param name="certFileName">The certificate file name.</param>
|
||||
/// <param name="certHostName">The certificate host DNS name (CN).</param>
|
||||
/// <param name="certHostIp">The certificate host IP address.</param>
|
||||
/// <param name="certPassword">The certificate password.</param>
|
||||
private static void CreateOrUpdateSelfsignedCertificate(string certFileName, string certHostName, string certHostIp, string certPassword)
|
||||
{
|
||||
SubjectAlternativeNameBuilder san = new();
|
||||
san.AddDnsName(certHostName);
|
||||
san.AddIpAddress(IPAddress.Parse(certHostIp));
|
||||
|
||||
// What OpenSim check (CN).
|
||||
X500DistinguishedName dn = new($"CN={certHostName}");
|
||||
|
||||
using (RSA rsa = RSA.Create(2048))
|
||||
{
|
||||
CertificateRequest request = new(dn, rsa, HashAlgorithmName.SHA256,RSASignaturePadding.Pkcs1);
|
||||
|
||||
// (Optional)...
|
||||
request.CertificateExtensions.Add(
|
||||
new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature , false));
|
||||
|
||||
// (Optional) SSL Server Authentication...
|
||||
request.CertificateExtensions.Add(
|
||||
new X509EnhancedKeyUsageExtension(
|
||||
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
|
||||
|
||||
request.CertificateExtensions.Add(san.Build());
|
||||
|
||||
X509Certificate2 certificate = request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow), new DateTimeOffset(DateTime.UtcNow.AddDays(3650)));
|
||||
|
||||
string privateKey = Convert.ToBase64String(rsa.ExportRSAPrivateKey(), Base64FormattingOptions.InsertLineBreaks);
|
||||
|
||||
// Create the SSL folder and sub folders if not exists.
|
||||
if (!Directory.Exists("SSL\\src\\"))
|
||||
Directory.CreateDirectory("SSL\\src\\");
|
||||
|
||||
if (!Directory.Exists("SSL\\ssl\\"))
|
||||
Directory.CreateDirectory("SSL\\ssl\\");
|
||||
|
||||
// Store the RSA key in SSL\src\
|
||||
File.WriteAllText($"SSL\\src\\{certFileName}.txt", privateKey);
|
||||
|
||||
// Export and store the .pfx and .p12 certificates in SSL\ssl\.
|
||||
// Note: Pfx is a Pkcs12 certificate and both files work for OpenSim.
|
||||
byte[] pfxCertBytes = string.IsNullOrEmpty(certPassword)
|
||||
? certificate.Export(X509ContentType.Pfx)
|
||||
: certificate.Export(X509ContentType.Pfx, certPassword);
|
||||
File.WriteAllBytes($"SSL\\ssl\\{certFileName}.pfx", pfxCertBytes);
|
||||
|
||||
byte[] p12CertBytes = string.IsNullOrEmpty(certPassword)
|
||||
? certificate.Export(X509ContentType.Pkcs12)
|
||||
: certificate.Export(X509ContentType.Pkcs12, certPassword);
|
||||
File.WriteAllBytes($"SSL\\ssl\\{certFileName}.p12", p12CertBytes);
|
||||
}
|
||||
}
|
||||
|
||||
public static int fast_distance2d(int x, int y)
|
||||
{
|
||||
x = Math.Abs(x);
|
||||
|
||||
@@ -352,7 +352,22 @@ namespace OpenSim
|
||||
IConfig startupConfig = Config.Configs["Startup"];
|
||||
if (startupConfig == null || startupConfig.GetBoolean("JobEngineEnabled", true))
|
||||
WorkManager.JobEngine.Start();
|
||||
|
||||
|
||||
// Sure is not the right place for this but do the job...
|
||||
// Must always be called before (all) / the HTTP servers starting for the Certs creation or renewals.
|
||||
if(startupConfig.GetBoolean("EnbleSelfsignedCertSupport"))
|
||||
{
|
||||
if(!File.Exists("SSL\\ssl\\"+ startupConfig.GetString("CertFileName") +".p12") || startupConfig.GetBoolean("CertRenewOnStartup"))
|
||||
{
|
||||
Util.CreateOrUpdateSelfsignedCert(
|
||||
string.IsNullOrEmpty(startupConfig.GetString("CertFileName")) ? "OpenSim" : startupConfig.GetString("CertFileName"),
|
||||
string.IsNullOrEmpty(startupConfig.GetString("CertHostName")) ? "localhost" : startupConfig.GetString("CertHostName"),
|
||||
string.IsNullOrEmpty(startupConfig.GetString("CertHostIp")) ? "127.0.0.1" : startupConfig.GetString("CertHostIp"),
|
||||
string.IsNullOrEmpty(startupConfig.GetString("CertPassword")) ? string.Empty : startupConfig.GetString("CertPassword")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_networkServersInfo.HttpUsesSSL)
|
||||
{
|
||||
m_httpServerSSL = true;
|
||||
|
||||
@@ -310,6 +310,33 @@
|
||||
; TelehubAllowLandmark = false
|
||||
|
||||
|
||||
;; SSL selfsigned certificate settings.
|
||||
;; Enable selfsigned certificate creation for local and external use. When set to true, will create a folder SSL\ and 2 sub folders SSL\ssl\ and SSL\src\. Next creates and store an RSA private key in SSL\src\ and the derived selfsigned certificate in SSL\ssl\ folder. Is also possible to renew the certificate on every server restart if CertRenewOnStartup is set to true.
|
||||
;# {EnbleSelfsignedCertSupport} {} {Enable selfsigned certificate creation and renew} {true false} false
|
||||
;EnbleSelfsignedCertSupport = true
|
||||
|
||||
;; Is free... so why not :). Renew the selfsigned certificate on every server startup ?
|
||||
;# {CertRenewOnStartup} {} {renew the selfsigned certificate on the server startup} {true false} true
|
||||
;CertRenewOnStartup = true
|
||||
|
||||
;; Certificate options:
|
||||
;; Set the certificate file name. the output files extensions are CertFileName.p12 and CertFileName.pfx.
|
||||
;# {CertFileName} {} {set the certificate file name} {} "OpenSim"
|
||||
;CertFileName = "OpenSim"
|
||||
|
||||
;; Set the certificate password.
|
||||
;# {CertPassword} {} {set the certificate password} {} ""
|
||||
;CertPassword = "mycertpass"
|
||||
|
||||
;; The certificate host name (domain or IP of this machine CN).
|
||||
;# {CertHostName} {} {set the certificate host name} {} ${Const|BaseHostname}
|
||||
;CertHostName = ${Const|BaseHostname}
|
||||
|
||||
;; The certificate host IP (IP of this machine).
|
||||
;# {CertHostIp} {} {set the certificate host IP} {}
|
||||
;CertHostIp = "127.0.0.1"
|
||||
|
||||
|
||||
;; SSL certificate validation options
|
||||
;; you can allow selfsigned certificates or no official CA with next option set to true
|
||||
;# {NoVerifyCertChain} {} {do not verify SSL Cert Chain} {true false} true
|
||||
@@ -317,7 +344,7 @@
|
||||
|
||||
;; you can also bypass the hostname or domain verification
|
||||
;# {NoVerifyCertHostname} {} {do not verify SSL Cert name versus peer name} {true false} true
|
||||
; NoVerifyCertHostname = true
|
||||
; NoVerifyCertHostname = false
|
||||
;; having both options true does provide encryption but with low security
|
||||
;; set both true if you don't care to use SSL, they are needed to contact regions or grids that do use it.
|
||||
|
||||
@@ -581,24 +608,24 @@
|
||||
; the main unsecure port will still open for some services. this may change in future.
|
||||
|
||||
; set http_listener_ssl to enable main server ssl. it will replace unsecure port on most functions
|
||||
;# {http_listener_ssl}{} {enable main server ssl port)} {} false
|
||||
;# {http_listener_ssl}{} {enable main server ssl port} {} false
|
||||
;http_listener_ssl = false
|
||||
|
||||
; Set port for main SSL connections
|
||||
;# {http_listener_sslport}{} {main server ssl port)} {} 9001
|
||||
;# {http_listener_sslport}{} {main server ssl port} {} 9001
|
||||
;http_listener_sslport = 9001 ;
|
||||
|
||||
; currently if using ssl, regions ExternalHostName must the the same and equal to http_listener_cn
|
||||
; this may be removed in future
|
||||
;# {http_listener_cn}{} {main server ssl externalHostName)} {} ""
|
||||
;http_listener_cn = "myRegionsExternalHostName"
|
||||
;# {http_listener_cn}{} {main server ssl externalHostName} {} ""
|
||||
;http_listener_cn = ${Const|BaseHostname}
|
||||
|
||||
; the path for the certificate path
|
||||
;# {http_listener_cert_path}{} {main server ssl certificate file path)} {} ""
|
||||
;http_listener_cert_path = "mycert.p12"
|
||||
;# {http_listener_cert_path}{} {main server ssl certificate file path} {} ""
|
||||
;http_listener_cert_path = "SSL\ssl\OpenSim.p12"
|
||||
|
||||
;# {http_listener_cert_pass}{} {main server ssl certificate password)} {} ""
|
||||
;http_listener_cert_pass = "mycertpass" ; the cert passwork
|
||||
;# {http_listener_cert_pass}{} {main server ssl certificate password} {} ""
|
||||
;http_listener_cert_pass = "mycertpass"
|
||||
|
||||
; By default, OpenSimulator does not allow scripts to make HTTP calls to addresses on the simulator's LAN.
|
||||
; See the OutboundDisallowForUserScripts parameter in OpenSimDefaults.ini for more information on this filter.
|
||||
|
||||
@@ -399,6 +399,29 @@
|
||||
; routing and land at the landmark coordinates when set to true
|
||||
; default is false
|
||||
; TelehubAllowLandmark = false
|
||||
|
||||
; #
|
||||
; # SSL selfsigned certificate settings.
|
||||
; #
|
||||
|
||||
; Enable selfsigned certificate creation for local and external use. When set to true, will create a folder SSL\ and 2 sub folders SSL\ssl\ and SSL\src\. Next creates and store an RSA private key in SSL\src\ and the derived selfsigned certificate in SSL\ssl\ folder. Is also possible to renew the certificate on every server restart if CertRenewOnStartup is set to true.
|
||||
EnbleSelfsignedCertSupport = false
|
||||
|
||||
; Is free... so why not :). Renew the selfsigned certificate on every server startup ?
|
||||
;CertRenewOnStartup = true
|
||||
|
||||
; # Certificate options:
|
||||
; Set the certificate file name. the output files extensions are CertFileName.p12 and CertFileName.pfx.
|
||||
;CertFileName = "OpenSim"
|
||||
|
||||
; Set the certificate password.
|
||||
;CertPassword = "mycertpass"
|
||||
|
||||
; The certificate host name (domain or IP of this machine CN).
|
||||
;CertHostName = ${Const|BaseHostname}
|
||||
|
||||
; The certificate host IP (IP of this machine).
|
||||
;CertHostIp = "127.0.0.1"
|
||||
|
||||
; #
|
||||
; # SSL certificates validation options
|
||||
|
||||
Reference in New Issue
Block a user