private void Init()
        {
            var dbPassword         = _context.Stub ? "RANDOM_DATABASE_PASSWORD" : Helpers.SecureRandomString(32);
            var dbConnectionString = new SqlConnectionStringBuilder
            {
                DataSource               = "tcp:mssql,1433",
                InitialCatalog           = "vault",
                UserID                   = "sa",
                Password                 = dbPassword,
                MultipleActiveResultSets = false,
                Encrypt                  = true,
                ConnectTimeout           = 30,
                TrustServerCertificate   = true,
                PersistSecurityInfo      = false
            }.ConnectionString;

            _globalOverrideValues = new Dictionary <string, string>
            {
                ["globalSettings__baseServiceUri__vault"]               = _context.Config.Url,
                ["globalSettings__baseServiceUri__api"]                 = $"{_context.Config.Url}/api",
                ["globalSettings__baseServiceUri__identity"]            = $"{_context.Config.Url}/identity",
                ["globalSettings__baseServiceUri__admin"]               = $"{_context.Config.Url}/admin",
                ["globalSettings__baseServiceUri__notifications"]       = $"{_context.Config.Url}/notifications",
                ["globalSettings__sqlServer__connectionString"]         = $"\"{dbConnectionString}\"",
                ["globalSettings__identityServer__certificatePassword"] = _context.Install?.IdentityCertPassword,
                ["globalSettings__attachment__baseDirectory"]           = $"{_context.OutputDir}/core/attachments",
                ["globalSettings__attachment__baseUrl"]                 = $"{_context.Config.Url}/attachments",
                ["globalSettings__dataProtection__directory"]           = $"{_context.OutputDir}/core/aspnet-dataprotection",
                ["globalSettings__logDirectory"]        = $"{_context.OutputDir}/logs",
                ["globalSettings__licenseDirectory"]    = $"{_context.OutputDir}/core/licenses",
                ["globalSettings__internalIdentityKey"] = _context.Stub ? "RANDOM_IDENTITY_KEY" :
                                                          Helpers.SecureRandomString(64, alpha: true, numeric: true),
                ["globalSettings__duo__aKey"] = _context.Stub ? "RANDOM_DUO_AKEY" :
                                                Helpers.SecureRandomString(64, alpha: true, numeric: true),
                ["globalSettings__installation__id"]        = _context.Install?.InstallationId.ToString(),
                ["globalSettings__installation__key"]       = _context.Install?.InstallationKey,
                ["globalSettings__yubico__clientId"]        = "REPLACE",
                ["globalSettings__yubico__key"]             = "REPLACE",
                ["globalSettings__mail__replyToEmail"]      = $"no-reply@{_context.Config.Domain}",
                ["globalSettings__mail__smtp__host"]        = "REPLACE",
                ["globalSettings__mail__smtp__port"]        = "587",
                ["globalSettings__mail__smtp__ssl"]         = "false",
                ["globalSettings__mail__smtp__username"]    = "******",
                ["globalSettings__mail__smtp__password"]    = "******",
                ["globalSettings__disableUserRegistration"] = "false",
                ["adminSettings__admins"] = string.Empty,
            };

            if (!_context.Config.PushNotifications)
            {
                _globalOverrideValues.Add("globalSettings__pushRelayBaseUri", "REPLACE");
            }

            _mssqlOverrideValues = new Dictionary <string, string>
            {
                ["ACCEPT_EULA"] = "Y",
                ["MSSQL_PID"]   = "Express",
                ["SA_PASSWORD"] = dbPassword,
            };
        }
예제 #2
0
        private void Init()
        {
            var dbPassword         = _context.Stub ? "RANDOM_DATABASE_PASSWORD" : Helpers.SecureRandomString(32);
            var dbConnectionString = new SqlConnectionStringBuilder
            {
                DataSource               = "tcp:mssql,1433",
                InitialCatalog           = _context.Install?.Database ?? "vault",
                UserID                   = "sa",
                Password                 = dbPassword,
                MultipleActiveResultSets = false,
                Encrypt                  = true,
                ConnectTimeout           = 30,
                TrustServerCertificate   = true,
                PersistSecurityInfo      = false
            }.ConnectionString;

            _globalOverrideValues = new Dictionary <string, string>
            {
                ["globalSettings__baseServiceUri__vault"]               = _context.Config.Url,
                ["globalSettings__sqlServer__connectionString"]         = $"\"{dbConnectionString.Replace("\"", "\\\"")}\"",
                ["globalSettings__identityServer__certificatePassword"] = _context.Install?.IdentityCertPassword,
                ["globalSettings__internalIdentityKey"] = _context.Stub ? "RANDOM_IDENTITY_KEY" :
                                                          Helpers.SecureRandomString(64, alpha: true, numeric: true),
                ["globalSettings__oidcIdentityClientKey"] = _context.Stub ? "RANDOM_IDENTITY_KEY" :
                                                            Helpers.SecureRandomString(64, alpha: true, numeric: true),
                ["globalSettings__duo__aKey"] = _context.Stub ? "RANDOM_DUO_AKEY" :
                                                Helpers.SecureRandomString(64, alpha: true, numeric: true),
                ["globalSettings__installation__id"]        = _context.Install?.InstallationId.ToString(),
                ["globalSettings__installation__key"]       = _context.Install?.InstallationKey,
                ["globalSettings__yubico__clientId"]        = "REPLACE",
                ["globalSettings__yubico__key"]             = "REPLACE",
                ["globalSettings__mail__replyToEmail"]      = $"no-reply@{_context.Config.Domain}",
                ["globalSettings__mail__smtp__host"]        = "REPLACE",
                ["globalSettings__mail__smtp__port"]        = "587",
                ["globalSettings__mail__smtp__ssl"]         = "false",
                ["globalSettings__mail__smtp__username"]    = "******",
                ["globalSettings__mail__smtp__password"]    = "******",
                ["globalSettings__disableUserRegistration"] = "false",
                ["globalSettings__hibpApiKey"] = "REPLACE",
                ["adminSettings__admins"]      = string.Empty,
            };

            if (!_context.Config.PushNotifications)
            {
                _globalOverrideValues.Add("globalSettings__pushRelayBaseUri", "REPLACE");
            }

            _mssqlOverrideValues = new Dictionary <string, string>
            {
                ["SA_PASSWORD"] = dbPassword,
            };
        }
예제 #3
0
        private void Init()
        {
            var dbPassword         = Helpers.SecureRandomString(32);
            var dbConnectionString = Helpers.MakeSqlConnectionString("mssql", "vault", "sa", dbPassword);

            _globalOverrideValues = new Dictionary <string, string>
            {
                ["globalSettings__baseServiceUri__vault"]               = _context.Config.Url,
                ["globalSettings__baseServiceUri__api"]                 = $"{_context.Config.Url}/api",
                ["globalSettings__baseServiceUri__identity"]            = $"{_context.Config.Url}/identity",
                ["globalSettings__baseServiceUri__admin"]               = $"{_context.Config.Url}/admin",
                ["globalSettings__baseServiceUri__notifications"]       = $"{_context.Config.Url}/notifications",
                ["globalSettings__sqlServer__connectionString"]         = $"\"{dbConnectionString}\"",
                ["globalSettings__identityServer__certificatePassword"] = _context.Install?.IdentityCertPassword,
                ["globalSettings__attachment__baseDirectory"]           = $"{_context.OutputDir}/core/attachments",
                ["globalSettings__attachment__baseUrl"]                 = $"{_context.Config.Url}/attachments",
                ["globalSettings__dataProtection__directory"]           = $"{_context.OutputDir}/core/aspnet-dataprotection",
                ["globalSettings__logDirectory"]         = $"{_context.OutputDir}/logs",
                ["globalSettings__licenseDirectory"]     = $"{_context.OutputDir}/core/licenses",
                ["globalSettings__internalIdentityKey"]  = Helpers.SecureRandomString(64, alpha: true, numeric: true),
                ["globalSettings__duo__aKey"]            = Helpers.SecureRandomString(64, alpha: true, numeric: true),
                ["globalSettings__installation__id"]     = _context.Install?.InstallationId.ToString(),
                ["globalSettings__installation__key"]    = _context.Install?.InstallationKey,
                ["globalSettings__yubico__clientId"]     = "REPLACE",
                ["globalSettings__yubico__key"]          = "REPLACE",
                ["globalSettings__mail__replyToEmail"]   = $"no-reply@{_context.Config.Domain}",
                ["globalSettings__mail__smtp__host"]     = "REPLACE",
                ["globalSettings__mail__smtp__username"] = "******",
                ["globalSettings__mail__smtp__password"] = "******",
                ["globalSettings__mail__smtp__ssl"]      = "true",
                ["globalSettings__mail__smtp__port"]     = "587",
                ["globalSettings__mail__smtp__useDefaultCredentials"] = "false",
                ["globalSettings__disableUserRegistration"]           = "false",
                ["adminSettings__admins"] = string.Empty,
            };

            if (!_context.Config.PushNotifications)
            {
                _globalOverrideValues.Add("globalSettings__pushRelayBaseUri", "REPLACE");
            }

            _mssqlOverrideValues = new Dictionary <string, string>
            {
                ["ACCEPT_EULA"] = "Y",
                ["MSSQL_PID"]   = "Express",
                ["SA_PASSWORD"] = dbPassword,
            };
        }
예제 #4
0
파일: Program.cs 프로젝트: AlecJY/core
        private static void BuildEnvironmentFiles()
        {
            Console.WriteLine("Building docker environment override files.");
            Directory.CreateDirectory("/bitwarden/env/");
            var dbPass             = Helpers.SecureRandomString(32);
            var dbConnectionString = Helpers.MakeSqlConnectionString("mssql", "vault", "sa", dbPass);

            using (var sw = File.CreateText("/bitwarden/env/global.override.env"))
            {
                sw.Write($@"globalSettings__baseServiceUri__vault={_url}
globalSettings__baseServiceUri__api={_url}/api
globalSettings__baseServiceUri__identity={_url}/identity
globalSettings__sqlServer__connectionString=""{dbConnectionString}""
globalSettings__identityServer__certificatePassword={_identityCertPassword}
globalSettings__attachment__baseDirectory={_outputDir}/core/attachments
globalSettings__attachment__baseUrl={_url}/attachments
globalSettings__dataProtection__directory={_outputDir}/core/aspnet-dataprotection
globalSettings__logDirectory={_outputDir}/core/logs
globalSettings__licenseDirectory={_outputDir}/core/licenses
globalSettings__duo__aKey={Helpers.SecureRandomString(64, alpha: true, numeric: true)}
globalSettings__installation__id={_installationId}
globalSettings__installation__key={_installationKey}
globalSettings__yubico__clientId=REPLACE
globalSettings__yubico__key=REPLACE
globalSettings__mail__replyToEmail=no-reply@{_domain}
globalSettings__mail__smtp__host=REPLACE
globalSettings__mail__smtp__username=REPLACE
globalSettings__mail__smtp__password=REPLACE
globalSettings__mail__smtp__ssl=true
globalSettings__mail__smtp__port=587
globalSettings__mail__smtp__useDefaultCredentials=false
globalSettings__disableUserRegistration=false");

                if (!_push)
                {
                    sw.Write(@"
globalSettings__pushRelayBaseUri=REPLACE");
                }
            }

            using (var sw = File.CreateText("/bitwarden/env/mssql.override.env"))
            {
                sw.Write($@"ACCEPT_EULA=Y
MSSQL_PID=Express
SA_PASSWORD={dbPass}");
            }
        }
예제 #5
0
        private void Init(bool forInstall)
        {
            var dbConnectionString = Helpers.MakeSqlConnectionString("mssql", "vault", "sa", DatabasePassword);

            _globalValues = new Dictionary <string, string>
            {
                ["globalSettings__baseServiceUri__vault"]               = Url,
                ["globalSettings__baseServiceUri__api"]                 = $"{Url}/api",
                ["globalSettings__baseServiceUri__identity"]            = $"{Url}/identity",
                ["globalSettings__sqlServer__connectionString"]         = $"\"{ dbConnectionString }\"",
                ["globalSettings__identityServer__certificatePassword"] = IdentityCertPassword,
                ["globalSettings__attachment__baseDirectory"]           = $"{OutputDirectory}/core/attachments",
                ["globalSettings__attachment__baseUrl"]                 = $"{Url}/attachments",
                ["globalSettings__dataProtection__directory"]           = $"{OutputDirectory}/core/aspnet-dataprotection",
                ["globalSettings__logDirectory"]         = $"{OutputDirectory}/core/logs",
                ["globalSettings__licenseDirectory"]     = $"{OutputDirectory}/core/licenses",
                ["globalSettings__duo__aKey"]            = $"{Helpers.SecureRandomString(64, alpha: true, numeric: true)}",
                ["globalSettings__installation__id"]     = InstallationId?.ToString(),
                ["globalSettings__installation__key"]    = InstallationKey,
                ["globalSettings__yubico__clientId"]     = "REPLACE",
                ["globalSettings__yubico__key"]          = "REPLACE",
                ["globalSettings__mail__replyToEmail"]   = $"no-reply@{Domain}",
                ["globalSettings__mail__smtp__host"]     = "REPLACE",
                ["globalSettings__mail__smtp__username"] = "******",
                ["globalSettings__mail__smtp__password"] = "******",
                ["globalSettings__mail__smtp__ssl"]      = "true",
                ["globalSettings__mail__smtp__port"]     = "587",
                ["globalSettings__mail__smtp__useDefaultCredentials"] = "false",
                ["globalSettings__disableUserRegistration"]           = "false",
            };

            if (forInstall && !Push)
            {
                _globalValues.Add("globalSettings__pushRelayBaseUri", "REPLACE");
            }

            _mssqlValues = new Dictionary <string, string>
            {
                ["ACCEPT_EULA"] = "Y",
                ["MSSQL_PID"]   = "Express",
                ["SA_PASSWORD"] = DatabasePassword,
            };
        }
예제 #6
0
        private static void Install()
        {
            _outputDir = _parameters.ContainsKey("out") ?
                         _parameters["out"].ToLowerInvariant() : _outputDir;
            _domain = _parameters.ContainsKey("domain") ?
                      _parameters["domain"].ToLowerInvariant() : "localhost";
            _letsEncrypt = _parameters.ContainsKey("letsencrypt") ?
                           _parameters["letsencrypt"].ToLowerInvariant() == "y" : false;

            if (!ValidateInstallation())
            {
                return;
            }

            _ssl = _letsEncrypt;
            if (!_letsEncrypt)
            {
                Console.Write("(!) Do you have a SSL certificate to use? (y/n): ");
                _ssl = Console.ReadLine().ToLowerInvariant() == "y";

                if (_ssl)
                {
                    Console.WriteLine("Make sure 'certificate.crt' and 'private.key' are provided in the " +
                                      "appropriate directory (see setup instructions).");
                }
            }

            _identityCertPassword = Helpers.SecureRandomString(32, alpha: true, numeric: true);
            MakeCerts();

            _url = _ssl ? $"https://{_domain}" : $"http://{_domain}";
            BuildNginxConfig();

            Console.Write("(!) Do you want to use push notifications? (y/n): ");
            _push = Console.ReadLine().ToLowerInvariant() == "y";

            BuildEnvironmentFiles();
            BuildAppSettingsFiles();
            BuildAppId();
        }
예제 #7
0
        public void BuildForInstall()
        {
            if (_context.Stub)
            {
                _context.Config.Ssl                   = true;
                _context.Install.Trusted              = true;
                _context.Install.SelfSignedCert       = false;
                _context.Install.DiffieHellman        = false;
                _context.Install.IdentityCertPassword = "******";
                return;
            }

            _context.Config.Ssl = _context.Config.SslManagedLetsEncrypt;

            if (!_context.Config.Ssl)
            {
                var skipSSL = _context.Parameters.ContainsKey("skip-ssl") && (_context.Parameters["skip-ssl"] == "true" || _context.Parameters["skip-ssl"] == "1");

                if (!skipSSL)
                {
                    _context.Config.Ssl = Helpers.ReadQuestion("Do you have a SSL certificate to use?");
                    if (_context.Config.Ssl)
                    {
                        Directory.CreateDirectory($"/bitwarden/ssl/{_context.Install.Domain}/");
                        var message = "Make sure 'certificate.crt' and 'private.key' are provided in the \n" +
                                      "appropriate directory before running 'start' (see docs for info).";
                        Helpers.ShowBanner(_context, "NOTE", message);
                    }
                    else if (Helpers.ReadQuestion("Do you want to generate a self-signed SSL certificate?"))
                    {
                        Directory.CreateDirectory($"/bitwarden/ssl/self/{_context.Install.Domain}/");
                        Helpers.WriteLine(_context, "Generating self signed SSL certificate.");
                        _context.Config.Ssl             = true;
                        _context.Install.Trusted        = false;
                        _context.Install.SelfSignedCert = true;
                        Helpers.Exec("openssl req -x509 -newkey rsa:4096 -sha256 -nodes -days 36500 " +
                                     $"-keyout /bitwarden/ssl/self/{_context.Install.Domain}/private.key " +
                                     $"-out /bitwarden/ssl/self/{_context.Install.Domain}/certificate.crt " +
                                     $"-reqexts SAN -extensions SAN " +
                                     $"-config <(cat /usr/lib/ssl/openssl.cnf <(printf '[SAN]\nsubjectAltName=DNS:{_context.Install.Domain}\nbasicConstraints=CA:true')) " +
                                     $"-subj \"/C=US/ST=California/L=Santa Barbara/O=Bitwarden Inc./OU=Bitwarden/CN={_context.Install.Domain}\"");
                    }
                }
            }

            if (_context.Config.SslManagedLetsEncrypt)
            {
                _context.Install.Trusted       = true;
                _context.Install.DiffieHellman = true;
                Directory.CreateDirectory($"/bitwarden/letsencrypt/live/{_context.Install.Domain}/");
                Helpers.Exec($"openssl dhparam -out " +
                             $"/bitwarden/letsencrypt/live/{_context.Install.Domain}/dhparam.pem 2048");
            }
            else if (_context.Config.Ssl && !_context.Install.SelfSignedCert)
            {
                _context.Install.Trusted = Helpers.ReadQuestion("Is this a trusted SSL certificate " +
                                                                "(requires ca.crt, see docs)?");
            }

            Helpers.WriteLine(_context, "Generating key for IdentityServer.");
            _context.Install.IdentityCertPassword = Helpers.SecureRandomString(32, alpha: true, numeric: true);
            Directory.CreateDirectory("/bitwarden/identity/");
            Helpers.Exec("openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout identity.key " +
                         "-out identity.crt -subj \"/CN=Bitwarden IdentityServer\" -days 36500");
            Helpers.Exec("openssl pkcs12 -export -out /bitwarden/identity/identity.pfx -inkey identity.key " +
                         $"-in identity.crt -passout pass:{_context.Install.IdentityCertPassword}");

            Helpers.WriteLine(_context);

            if (!_context.Config.Ssl)
            {
                var message = "You are not using a SSL certificate. Bitwarden requires HTTPS to operate. \n" +
                              "You must front your installation with a HTTPS proxy or the web vault (and \n" +
                              "other Bitwarden apps) will not work properly.";
                Helpers.ShowBanner(_context, "WARNING", message, ConsoleColor.Yellow);
            }
            else if (_context.Config.Ssl && !_context.Install.Trusted)
            {
                var message = "You are using an untrusted SSL certificate. This certificate will not be \n" +
                              "trusted by Bitwarden client applications. You must add this certificate to \n" +
                              "the trusted store on each device or else you will receive errors when trying \n" +
                              "to connect to your installation.";
                Helpers.ShowBanner(_context, "WARNING", message, ConsoleColor.Yellow);
            }
        }
예제 #8
0
        private static void Install()
        {
            var outputDir = _parameters.ContainsKey("out") ?
                            _parameters["out"].ToLowerInvariant() : "/etc/bitwarden";
            var domain = _parameters.ContainsKey("domain") ?
                         _parameters["domain"].ToLowerInvariant() : "localhost";
            var letsEncrypt = _parameters.ContainsKey("letsencrypt") ?
                              _parameters["letsencrypt"].ToLowerInvariant() == "y" : false;

            if (!ValidateInstallation())
            {
                return;
            }

            var ssl = letsEncrypt;

            if (!letsEncrypt)
            {
                Console.Write("(!) Do you have a SSL certificate to use? (y/n): ");
                ssl = Console.ReadLine().ToLowerInvariant() == "y";

                if (ssl)
                {
                    Console.WriteLine("Make sure 'certificate.crt' and 'private.key' are provided in the " +
                                      "appropriate directory (see setup instructions).");
                }
            }

            var identityCertPassword = Helpers.SecureRandomString(32, alpha: true, numeric: true);
            var certBuilder          = new CertBuilder(domain, identityCertPassword, letsEncrypt, ssl);
            var selfSignedSsl        = certBuilder.BuildForInstall();

            ssl = certBuilder.Ssl; // Ssl prop can get flipped during the build

            var url          = ssl ? $"https://{domain}" : $"http://{domain}";
            var nginxBuilder = new NginxConfigBuilder(domain, ssl, selfSignedSsl, letsEncrypt);

            nginxBuilder.BuildForInstaller();

            Console.Write("(!) Do you want to use push notifications? (y/n): ");
            var push = Console.ReadLine().ToLowerInvariant() == "y";

            var environmentFileBuilder = new EnvironmentFileBuilder
            {
                DatabasePassword     = Helpers.SecureRandomString(32),
                Domain               = domain,
                IdentityCertPassword = identityCertPassword,
                InstallationId       = _installationId,
                InstallationKey      = _installationKey,
                OutputDirectory      = outputDir,
                Push = push,
                Url  = url
            };

            environmentFileBuilder.Build();

            var appSettingsBuilder = new AppSettingsBuilder(url, domain);

            appSettingsBuilder.Build();

            var appIdBuilder = new AppIdBuilder(url);

            appIdBuilder.Build();
        }
예제 #9
0
        private static void Install()
        {
            var outputDir = _parameters.ContainsKey("out") ?
                            _parameters["out"].ToLowerInvariant() : "/etc/bitwarden";
            var domain = _parameters.ContainsKey("domain") ?
                         _parameters["domain"].ToLowerInvariant() : "localhost";
            var letsEncrypt = _parameters.ContainsKey("letsencrypt") ?
                              _parameters["letsencrypt"].ToLowerInvariant() == "y" : false;

            if (!ValidateInstallation())
            {
                return;
            }

            var ssl = letsEncrypt;

            if (!letsEncrypt)
            {
                Console.Write("(!) Do you have a SSL certificate to use? (y/n): ");
                ssl = Console.ReadLine().ToLowerInvariant() == "y";

                if (ssl)
                {
                    Directory.CreateDirectory($"/bitwarden/ssl/{domain}/");
                    Console.WriteLine("Make sure 'certificate.crt' and 'private.key' are provided in the " +
                                      "appropriate directory (see setup instructions).");
                }
            }

            var identityCertPassword = Helpers.SecureRandomString(32, alpha: true, numeric: true);
            var certBuilder          = new CertBuilder(domain, identityCertPassword, letsEncrypt, ssl);
            var selfSignedSsl        = certBuilder.BuildForInstall();

            ssl = certBuilder.Ssl; // Ssl prop can get flipped during the build

            var url = ssl ? $"https://{domain}" : $"http://{domain}";

            Console.Write("(!) Do you want to use the default ports for HTTP (80) and HTTPS (443)? (y/n): ");
            var defaultPorts = Console.ReadLine().ToLowerInvariant() == "y";
            int httpPort = default(int), httpsPort = default(int);

            if (!defaultPorts)
            {
                Console.Write("(!) HTTP port: ");
                if (int.TryParse(Console.ReadLine().ToLowerInvariant().Trim(), out httpPort))
                {
                    if (ssl)
                    {
                        Console.Write("(!) HTTPS port: ");
                        if (int.TryParse(Console.ReadLine().ToLowerInvariant().Trim(), out httpsPort))
                        {
                            if (httpsPort != 443)
                            {
                                url += (":" + httpsPort);
                            }
                        }
                        else
                        {
                            Console.WriteLine("Invalid HTTPS port.");
                            httpPort = httpsPort = default(int);
                        }
                    }
                    else if (httpPort != 80)
                    {
                        url += (":" + httpPort);
                    }
                }
                else
                {
                    Console.WriteLine("Invalid HTTP port.");
                }
            }

            Console.Write("(!) Is your installation behind a reverse proxy? (y/n): ");
            var reverseProxy = Console.ReadLine().ToLowerInvariant() == "y";

            if (reverseProxy)
            {
                Console.Write("(!) Do you use the default ports on your reverse proxy (80/443)? (y/n): ");
                var proxyDefaultPorts = Console.ReadLine().ToLowerInvariant() == "y";

                if (proxyDefaultPorts)
                {
                    url = ssl ? $"https://{domain}" : $"http://{domain}";
                }
                else
                {
                    int httpReversePort = default(int), httpsReversePort = default(int);
                    Console.Write("(!) Proxy HTTP port: ");
                    if (int.TryParse(Console.ReadLine().ToLowerInvariant().Trim(), out httpReversePort))
                    {
                        if (ssl)
                        {
                            Console.Write("(!) Proxy HTTPS port: ");
                            if (int.TryParse(Console.ReadLine().ToLowerInvariant().Trim(), out httpsReversePort))
                            {
                                if (httpsReversePort != 443)
                                {
                                    url += (":" + httpsReversePort);
                                }
                            }
                            else
                            {
                                Console.WriteLine("Invalid proxy HTTPS port.");
                                httpReversePort = httpsReversePort = default(int);
                            }
                        }
                        else if (httpReversePort != 80)
                        {
                            url += (":" + httpReversePort);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Invalid proxy HTTP port.");
                    }
                }
            }

            Console.Write("(!) Do you want to use push notifications? (y/n): ");
            var push = Console.ReadLine().ToLowerInvariant() == "y";

            var nginxBuilder = new NginxConfigBuilder(domain, url, ssl, selfSignedSsl, letsEncrypt);

            nginxBuilder.BuildForInstaller();

            var environmentFileBuilder = new EnvironmentFileBuilder
            {
                DatabasePassword     = Helpers.SecureRandomString(32),
                Domain               = domain,
                IdentityCertPassword = identityCertPassword,
                InstallationId       = _installationId,
                InstallationKey      = _installationKey,
                OutputDirectory      = outputDir,
                Push = push,
                Url  = url
            };

            environmentFileBuilder.BuildForInstaller();

            var appSettingsBuilder = new AppSettingsBuilder();

            appSettingsBuilder.Build();

            var appIdBuilder = new AppIdBuilder(url);

            appIdBuilder.Build();

            var dockerComposeBuilder = new DockerComposeBuilder(_hostOs, _webVersion, _coreVersion);

            dockerComposeBuilder.BuildForInstaller(httpPort, httpsPort);
        }
예제 #10
0
        private static void Install()
        {
            var outputDir = _parameters.ContainsKey("out") ?
                            _parameters["out"].ToLowerInvariant() : "/etc/bitwarden";
            var domain = _parameters.ContainsKey("domain") ?
                         _parameters["domain"].ToLowerInvariant() : "localhost";
            var letsEncrypt = _parameters.ContainsKey("letsencrypt") ?
                              _parameters["letsencrypt"].ToLowerInvariant() == "y" : false;

            if (!ValidateInstallation())
            {
                return;
            }

            var ssl = letsEncrypt;

            if (!letsEncrypt)
            {
                ssl = Helpers.ReadQuestion("Do you have a SSL certificate to use?");
                if (ssl)
                {
                    Directory.CreateDirectory($"/bitwarden/ssl/{domain}/");
                    var message = "Make sure 'certificate.crt' and 'private.key' are provided in the \n" +
                                  "appropriate directory before running 'start' (see docs for info).";
                    Helpers.ShowBanner("NOTE", message);
                }
            }

            var identityCertPassword = Helpers.SecureRandomString(32, alpha: true, numeric: true);
            var certBuilder          = new CertBuilder(domain, identityCertPassword, letsEncrypt, ssl);
            var selfSignedSsl        = certBuilder.BuildForInstall();

            ssl = certBuilder.Ssl; // Ssl prop can get flipped during the build

            var sslTrusted       = letsEncrypt;
            var sslDiffieHellman = letsEncrypt;

            if (ssl && !selfSignedSsl && !letsEncrypt)
            {
                sslDiffieHellman = Helpers.ReadQuestion("Use Diffie Hellman ephemeral parameters for SSL " +
                                                        "(requires dhparam.pem, see docs)?");
                sslTrusted = Helpers.ReadQuestion("Is this a trusted SSL certificate (requires ca.crt, see docs)?");
            }

            if (!ssl)
            {
                var message = "You are not using a SSL certificate. Bitwarden requires HTTPS to operate. \n" +
                              "You must front your installation with a HTTPS proxy. The web vault (and \n" +
                              "other Bitwarden apps) will not work properly without HTTPS.";
                Helpers.ShowBanner("WARNING", message, ConsoleColor.Yellow);
            }
            else if (ssl && !sslTrusted)
            {
                var message = "You are using an untrusted SSL certificate. This certificate will not be \n" +
                              "trusted by Bitwarden client applications. You must add this certificate to \n" +
                              "the trusted store on each device or else you will receive errors when trying \n" +
                              "to connect to your installation.";
                Helpers.ShowBanner("WARNING", message, ConsoleColor.Yellow);
            }

            var url = $"https://{domain}";
            int httpPort = default(int), httpsPort = default(int);

            if (Helpers.ReadQuestion("Do you want to use the default ports for HTTP (80) and HTTPS (443)?"))
            {
                httpPort = 80;
                if (ssl)
                {
                    httpsPort = 443;
                }
            }
            else if (ssl)
            {
                httpsPort = 443;
                if (int.TryParse(Helpers.ReadInput("HTTPS port").Trim(), out httpsPort) && httpsPort != 443)
                {
                    url += (":" + httpsPort);
                }
                else
                {
                    Console.WriteLine("Using default port.");
                }
            }
            else
            {
                httpPort = 80;
                if (!int.TryParse(Helpers.ReadInput("HTTP port").Trim(), out httpPort) && httpPort != 80)
                {
                    Console.WriteLine("Using default port.");
                }
            }

            if (Helpers.ReadQuestion("Is your installation behind a reverse proxy?"))
            {
                if (Helpers.ReadQuestion("Do you use the default HTTPS port (443) on your reverse proxy?"))
                {
                    url = $"https://{domain}";
                }
                else
                {
                    if (int.TryParse(Helpers.ReadInput("Proxy HTTPS port").Trim(), out var httpsReversePort) &&
                        httpsReversePort != 443)
                    {
                        url += (":" + httpsReversePort);
                    }
                    else
                    {
                        Console.WriteLine("Using default port.");
                        url = $"https://{domain}";
                    }
                }
            }
            else if (!ssl)
            {
                Console.WriteLine("ERROR: You must use a reverse proxy if not using SSL.");
                return;
            }

            var push = Helpers.ReadQuestion("Do you want to use push notifications?");

            var nginxBuilder = new NginxConfigBuilder(domain, url, ssl, selfSignedSsl, letsEncrypt,
                                                      sslTrusted, sslDiffieHellman);

            nginxBuilder.BuildForInstaller();

            var environmentFileBuilder = new EnvironmentFileBuilder
            {
                DatabasePassword     = Helpers.SecureRandomString(32),
                Domain               = domain,
                IdentityCertPassword = identityCertPassword,
                InstallationId       = _installationId,
                InstallationKey      = _installationKey,
                OutputDirectory      = outputDir,
                Push = push,
                Url  = url
            };

            environmentFileBuilder.BuildForInstaller();

            var appIdBuilder = new AppIdBuilder(url);

            appIdBuilder.Build();

            var dockerComposeBuilder = new DockerComposeBuilder(_hostOs, _webVersion, _coreVersion);

            dockerComposeBuilder.BuildForInstaller(httpPort, httpsPort);
        }