一、只需要配置jexus,将现有的http网站改成https
1.首先查看“/lib”或“/usr/lib”等系统库文件夹中是否有SSL库文件的名字,该文件名应该是“libssl.so.版本号”(find / -name libssl.so.*),如果没有列出文件名,就证明你的系统还没有安装OpenSSL,请安装后再操作。
find / -name libssl.so.*
2.查找到结果的话,如图
3.进入jexus解压目录
cd /usr/jexus
ls
4.进入mono lib目录
cd runtime/lib
ls
5.将找到的SSL库创建软链到mono lib目录下( 在新的jexus版本中也可能libssl.so已经存在了,就不需要再链接)
ln -s /usr/lib64/libssl.so.10 libssl.so
备注:/usr/lib64/libssl.so.10 是本机搜索出来的绝对路径,并非写死的路径
6.启网站的HTTPS功能
打开站点配置(siteconf)下的配置项,启用https(其实解开注释项即可),注意:端口修改为443
port=443
hosts=xxx.com
UseHttps=true
ssl.certificate=/x/xxx.pem
ssl.certificatekey=/x/xxx.key
ssl.protocol=TLSv1.2
我这里 xxx.pem xxx.key 是在阿里云申请的免费的证书。这里下载的证书是nignx版本。
(如果不用jexus,单独运行dontnet程序,程序内有一行代码:
var certificate = new X509Certificate2("/var/www/19liangpin/ssl/pfx/xxxx.pfx", "password");
这里的 pfx文件和密码是下载的iis版本的证书.
)
注意: 阿里云ECS服务器安全一定要放开443端口,否则无论如何都打不开。我就因为这个原因折腾了一下午。最后花了84元请了个阿里云专家,一下自己就找到这个原因了:)
7.重启jexus
./jws restart
8.输入https://xxx.com 测试
二、为了更好的使用https,需要修改你的.net core 代码
之前看到一篇博客 https://www.cnblogs.com/jjg0519/p/8572202.html
作者提到还需要在.net core程序中添加代码启用https,否则微信支付,微软OAuth等需要回调的功能就没法使用。
就这个问题和宇内讨论后,他的建议是.net core内部不要再启用https,做两次https性能会下降。
为了更好的使用https功能(获取客户端真实的IP地址、端口,以及是http还是https)需要修改一下代码,
jexus作者宇内流云写了一个中间件JwsIntegration.cs(IIS也有类似的中间件),加到项目里,然后在program.cs里代码如下,
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseJexusIntegration() //加这一句即可
.UseStartup<Startup>()
.Build();
JwsIntegration.cs代码如下:
/*******JwsIntegration.cs代码开始*******************/
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore
{
/// <summary>
/// 用于处理客户IP地址、端口、协议的HostBuilder中间件
/// </summary>
public static class JwsWebHostBuilderExtensions
{
/// <summary>
/// 启用JexusIntegration中间件
/// </summary>
/// <param name="hostBuilder"></param>
/// <returns></returns>
public static IWebHostBuilder UseJexusIntegration(this IWebHostBuilder hostBuilder)
{
if (hostBuilder == null)
{
throw new ArgumentNullException(nameof(hostBuilder));
}
// 检查是否已经加载过了
if (hostBuilder.GetSetting(nameof(UseJexusIntegration)) != null)
{
return hostBuilder;
}
// 设置已加载标记,防止重复加载
hostBuilder.UseSetting(nameof(UseJexusIntegration), true.ToString());
// 添加configure处理
hostBuilder.ConfigureServices(services =>
{
services.AddSingleton<IStartupFilter>(new JwsSetupFilter());
}); return hostBuilder;
}
}
class JwsSetupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
app.UseMiddleware<JwsMiddleware>();
next(app);
};
}
}
class JwsMiddleware
{
RequestDelegate _next;
public JwsMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IOptions<IISOptions> options)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var headers = httpContext.Request.Headers;
try
{
//解析访问者IP地址和端口号
if (headers != null && headers.ContainsKey("X-Original-For"))
{
var ipaddAdndPort = headers["X-Original-For"].ToArray()[0];
var dot = ipaddAdndPort.IndexOf(":");
var ip = ipaddAdndPort;
var port = 0;
if (dot > 0)
{
ip = ipaddAdndPort.Substring(0, dot);
port = int.Parse(ipaddAdndPort.Substring(dot + 1));
}
httpContext.Connection.RemoteIpAddress = System.Net.IPAddress.Parse(ip);
if (port != 0) httpContext.Connection.RemotePort = port;
}
//处理HTTP/HTTPS协议标记
if (headers != null && headers.ContainsKey("X-Original-Proto"))
{
httpContext.Request.Scheme = headers["X-Original-Proto"].ToArray()[0];
}
}
finally
{
await _next(httpContext);
}
}
}
}
/*******JwsIntegration.cs代码j结束*******************/
三、用户输入Http地址自动跳转到https
实现这个功能很简单,只要增加一个80地址,host指向一个不存在的地址(这里一定要指向一个不存在的地址,任意输入字符也行,但不能是*,如果为*,用户输入http也能打开页面,地址栏不会显示https,展示的内容可能不完整),root也指向不存在的即可。这样的做法好像有点像偏方,但是和宇内沟通后,的确是这样做的。这样做的目的只有一个,就是打开服务器的80端口。如果服务器上有一个80端口的网站,你什么也不用做就可以实现跳转。至于跳转到哪个网站,你输入的url里已经包含了地址信息,jexus会根据配置文件中的host字段(一般可配置成网址或*) 设置自动匹配对应的网站。
四.开启gzip压缩
jexus本身就带了gzip功能,但是那是针对,net core之前的版本的,对于.net core由于jexus只是端口转发,所以不会启用gzip,需要在.net core程序中自行开启。
1. 通过nuget安装微软的 ResponseCompress中间件
2. 在startup.cs中的configureServices方法中添加如下代码
services.Configure<GzipCompressionProviderOptions>(options =>
options.Level = System.IO.Compression.CompressionLevel.Optimal);//压缩比
services.AddResponseCompression(options =>
{
options.EnableForHttps = true; //注意,如果在jexus中开启了https,这里一定要设置成true,否则不会压缩
options.MimeTypes =new[] //压缩的文件类型
{
// General
"text/plain",
// Static files
"text/css",
"application/javascript",
// MVC
"text/html",
"application/xml",
"text/xml",
"application/json",
"text/json",
};
options.Providers.Add<GzipCompressionProvider>();
});
3.在 Configure方法中添加如下代码
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCompression();//放在usemvc前面
至此gzip已经开启了
4.检查gzip效果
用chrome打开网页,按F12进入调试界面,点network标签,Content-Encoding列默认无,可以在列头中把它勾选出来。Size列展示的就是压缩过的大小,可以和原文件进行一下对比,可见压缩率是非常可观的,相当于winrar的压缩比