private async Task <bool> SetupSsl(StringBuilder sb, GatewayServiceRegistrationData gatewayServiceRegistrationData, string serverName, CancellationToken token) { var certCN = gatewayServiceRegistrationData.Ssl.UseHttp01Challenge ? serverName : string.Join(".", serverName.Split('.').TakeLast(2)); var certs = storageAccount.CreateCloudBlobClient().GetContainerReference("certs"); var keyBlob = certs.GetBlockBlobReference($"{certCN}.key"); var chainBlob = certs.GetBlockBlobReference($"{certCN}.fullchain.pem"); Directory.CreateDirectory(Path.Combine(Context.CodePackageActivationContext.WorkDirectory, "letsencrypt")); if (await chainBlob.ExistsAsync() && await keyBlob.ExistsAsync()) { await keyBlob.DownloadToFileAsync($"{Context.CodePackageActivationContext.WorkDirectory}/letsencrypt/{certCN}.key", FileMode.Create); await chainBlob.DownloadToFileAsync($"{Context.CodePackageActivationContext.WorkDirectory}/letsencrypt/{certCN}.fullchain.pem", FileMode.Create); sb.AppendLine($"\t\tssl_certificate {Context.CodePackageActivationContext.WorkDirectory}/letsencrypt/{certCN}.fullchain.pem;"); sb.AppendLine($"\t\tssl_certificate_key {Context.CodePackageActivationContext.WorkDirectory}/letsencrypt/{certCN}.key;"); sb.AppendLine($"\t\tssl_session_timeout 5m;"); sb.AppendLine($"\t\tssl_prefer_server_ciphers on;"); sb.AppendLine($"\t\tssl_protocols TLSv1 TLSv1.1 TLSv1.2;"); sb.AppendLine($"\t\tssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';"); sb.AppendLine($"\t\tadd_header Strict-Transport-Security max-age=15768000;"); return(true); } await GetCertGenerationStateAsync(serverName, gatewayServiceRegistrationData.Ssl, true, token); return(false); }
private static async Task WriteProxyPassLocation(int level, string location, string url, StringBuilder sb_outer, string uniquekey, string upstreamName, GatewayServiceRegistrationData gatewayServiceRegistrationData) { var tabs = string.Join("", Enumerable.Range(0, level + 1).Select(r => "\t")); sb_outer.AppendLine($"{string.Join("", Enumerable.Range(0, level).Select(r => "\t"))}location {location} {{"); { var sb = new StringBuilder(); // rewrite ^ /268be5f6-90b1-4aa1-9eac-2225d8f7ab29/131356467681395031/$1 break; var uri = new Uri(url); if (location.StartsWith("~") || location.Trim().StartsWith("/.well-known/")) { if (!string.IsNullOrEmpty(uri.AbsolutePath?.TrimEnd('/'))) { sb.AppendLine($"{tabs}rewrite ^ {uri.AbsolutePath}$uri break;"); } sb.AppendLine($"{tabs}proxy_pass {uri.GetLeftPart(UriPartial.Authority)};"); } else { if (gatewayServiceRegistrationData?.Properties.ContainsKey("nginx-rewrite") ?? false) { sb.AppendLine($"{tabs}rewrite {gatewayServiceRegistrationData?.Properties["nginx-rewrite"]}"); } sb.AppendLine($"{tabs}proxy_pass {url.TrimEnd('/')}/;"); } if (gatewayServiceRegistrationData?.Properties.ContainsKey("cf-real-ip") ?? false) { var realIpPath = "conf/realip.conf"; Directory.CreateDirectory(Path.GetFullPath("conf")); var realIp = new StringBuilder(); var http = new HttpClient(); var ipsv4 = await http.GetStringAsync("https://www.cloudflare.com/ips-v4"); var ipsv6 = await http.GetStringAsync("https://www.cloudflare.com/ips-v6"); var breaks = new[] { "\r\n", "\r", "\n" }; foreach (var line in ipsv4 .Split(breaks, StringSplitOptions.None) .Concat(ipsv6.Split(breaks, StringSplitOptions.None)) .Where(s => !string.IsNullOrWhiteSpace(s))) { realIp.AppendLine($"set_real_ip_from {line};"); } realIp.AppendLine($"real_ip_header CF-Connecting-IP;"); File.WriteAllText(realIpPath, realIp.ToString()); sb.AppendLine($"{tabs}include {Path.GetFullPath(realIpPath).Replace("\\","/")};"); } if (gatewayServiceRegistrationData?.CacheOptions?.Enabled ?? false) { sb.AppendLine($"{tabs}proxy_cache {upstreamName};"); sb.AppendLine($"{tabs}proxy_cache_revalidate on;"); sb.AppendLine($"{tabs}proxy_cache_min_uses 3;"); sb.AppendLine($"{tabs}add_header X-Cache-Status $upstream_cache_status;"); sb.AppendLine($"{tabs}proxy_cache_valid 200 1d;"); sb.AppendLine($"{tabs}proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;"); } // sb.AppendLine($"{tabs}proxy_redirect off;"); sb.AppendLine($"{tabs}server_name_in_redirect on;"); sb.AppendLine($"{tabs}port_in_redirect off;"); sb.AppendLine($"{tabs}proxy_set_header Upgrade $http_upgrade;"); sb.AppendLine($"{tabs}proxy_set_header Connection $connection_upgrade;"); // sb.AppendLine($"{tabs}proxy_set_header Host $host;"); sb.AppendLine($"{tabs}proxy_set_header X-Real-IP $remote_addr;"); sb.AppendLine($"{tabs}proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;"); sb.AppendLine($"{tabs}proxy_set_header X-Forwarded-Host $host;"); sb.AppendLine($"{tabs}proxy_set_header X-Forwarded-Server $host;"); sb.AppendLine($"{tabs}proxy_set_header X-Forwarded-Proto $scheme;"); sb.AppendLine($"{tabs}proxy_set_header X-Forwarded-Path $request_uri;"); sb.AppendLine($"{tabs}proxy_set_header X-ServiceFabric-Key {uniquekey};"); sb.AppendLine($"{tabs}proxy_connect_timeout 3s;"); sb.AppendLine($"{tabs}proxy_http_version 1.1;"); if (location.Trim().StartsWith("~") || location.Trim().StartsWith("/.well-known/")) { sb.AppendLine($"{tabs}proxy_set_header X-Forwarded-PathBase /;"); } else if (location.Trim().StartsWith("=")) { sb.AppendLine($"{tabs}proxy_set_header X-Forwarded-PathBase {location.Substring(1).Trim()};"); } else { var pathbase = location.TrimEnd('/'); sb.AppendLine($"{tabs}proxy_set_header X-Forwarded-PathBase {(string.IsNullOrEmpty(pathbase) ? "/" : pathbase)};"); } sb.AppendLine($"{tabs}proxy_cache_bypass $http_upgrade;"); sb.AppendLine($"{tabs}proxy_cache_bypass $http_pragma;"); var path = $"conf/{ToGuid(location + gatewayServiceRegistrationData?.Key)}.conf"; Directory.CreateDirectory(Path.GetFullPath("conf")); File.WriteAllText(path, sb.ToString()); sb_outer.AppendLine($"{tabs}include {Path.GetFullPath(path).Replace("\\", "/")};"); // sb_outer.Append(sb.ToString()); } sb_outer.AppendLine($"{string.Join("", Enumerable.Range(0, level).Select(r => "\t"))}}}"); if (gatewayServiceRegistrationData?.Properties?.ContainsKey("nginx-locations") ?? false) { var additionals = (string[])gatewayServiceRegistrationData.Properties["nginx-locations"]; foreach (var extra in additionals) { sb_outer.AppendLine($"{string.Join("", Enumerable.Range(0, level).Select(r => "\t"))}location {extra} {{"); { var path = $"conf/{ToGuid(location + gatewayServiceRegistrationData?.Key)}.conf"; sb_outer.AppendLine($"{tabs}include {Path.GetFullPath(path)};"); } sb_outer.AppendLine($"{string.Join("", Enumerable.Range(0, level).Select(r => "\t"))}}}"); } } }