Loading...

文章背景图

[学习,记录,整理] halo在不使用nginx进行反代的情况下开启ssl

2021-01-31
1245
-
- 分钟

起因

事情起因是我所购买的建站机,不允许用于代理和使用反代,这样我就没有了使用nginx进行反代的机会。
想在不使用反代的情况下开启ssl,需要自行拉取halo源码并进行一些修改。修改方式有两种。

  • 对自带的jetty进行配置
  • 使用tomcat替换自带的jetty,对tomcat进行配置

Tomcat

使用tomcat需要在build.gradle的dependencies中添加以下依赖

compile group: "org.apache.tomcat.embed", name: "tomcat-embed-core", version: "9.0.39"

再添加一个文件,文件名随意,这里我起的名是TomcatSslConfiguration.java

package run.halo.app.config;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties
public class TomcatSslConfiguration {

    @Value("${server.port}")
    private int https;
    @Value("${server.ssl.port}")
    private int http;

    @Bean
    public TomcatServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint constraint = new SecurityConstraint();
                constraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                // 全路径重定向到https
                collection.addPattern("/*");
                constraint.addCollection(collection);
                context.addConstraint(constraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(httpConnector());
        return tomcat;
    }

    @Bean
    public Connector httpConnector() {
        if (http == 0) {
            http = 8090;
        }
        if (https == 0) {
            https = 8443;
        }
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        // 设置用什么方案接收请求
        connector.setScheme("http");
        // 设置要监听的端口号
        connector.setPort(http);
        // 开启http重定向到https
        connector.setSecure(false);
        // 重定向到哪个端口
        connector.setRedirectPort(https);
        return connector;
    }

}

然后使用Tasks > build > build进行编译,虽然会有过时待删除的警告,但在build > lib文件夹中能看到编译出的jar包。
然后去下载适用于tomcat的证书文件,推荐将证书文件放在.halo文件夹下,部署的时候在.halo/application.yaml中添加以下配置。

server:
  # https端口
  port: 443
  ssl:
    # http端口
    port: 80
    key-store: .halo/证书文件
    key-store-password: 证书密码
    keyStoreType: PKCS12

配置完即可启动自己编译出的halo检验成果。以上操作相当于直接往SpringBoot中塞了一个tomcat,用来替换原来的web服务器,并在tomcat中进行ssl相关的配置。

文章引用

Spring Boot配置ssl证书启用HTTPS协议
springboot配置ssl证书
Https系列之三:让服务器同时支持http、https,基于spring boot


Jetty

halo使用的SpringBoot,默认的容器是Jetty,不需要额外导入依赖,仅需添加一个配置类。
文件名随意,这里我起名为JettySslConfiguration.java

package run.halo.app.config;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
import java.util.Collections;

@Slf4j
@Configuration
@EnableConfigurationProperties
public class JettySslConfiguration extends AbstractConfiguration implements
    WebServerFactoryCustomizer<JettyServletWebServerFactory> {

    @Value("${server.port}")
    private int https;
    @Value("${server.ssl.port}")
    private int http;
    @Value("${jetty.connect.maxThreads}")
    private int maxThread;
    @Value("${jetty.connect.minThreads}")
    private int minThread;
    @Value("${jetty.connect.idleTimeout}")
    private int idleTimeout;

    @Override
    public void configure(WebAppContext context) throws Exception {
        Constraint constraint = new Constraint();
        constraint.setDataConstraint(Constraint.DC_CONFIDENTIAL);

        ConstraintMapping mapping = new ConstraintMapping();
        mapping.setPathSpec("/*");
        mapping.setConstraint(constraint);

        ConstraintSecurityHandler handler = new ConstraintSecurityHandler();
        handler.addConstraintMapping(mapping);

        context.setSecurityHandler(handler);
    }

    @Override
    public void customize(JettyServletWebServerFactory factory) {
        factory.setConfigurations(Collections.singleton(this));

        factory.addServerCustomizers(
            server -> {
                // 配置线程池
                threadPool(server);

                HttpConfiguration httpsConfiguration = new HttpConfiguration();
                httpsConfiguration.setSecurePort(https);
                httpsConfiguration.setSecureScheme("https");

                ServerConnector connector = new ServerConnector(server);
                connector.addConnectionFactory(new HttpConnectionFactory(httpsConfiguration));
                connector.setPort(http);

                server.addConnector(connector);
            }
        );
    }

    private void threadPool(Server server) {
        // 线程池
        final QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class);
        //默认最大线程连接数200
        threadPool.setMaxThreads(maxThread);
        //默认最小线程连接数8
        threadPool.setMinThreads(minThread);
        //默认线程最大空闲时间60000ms
        threadPool.setIdleTimeout(idleTimeout);
    }

}

在不配置threadPool的情况下,部署配置与tomcat的相同,如果配置了threadPool,则还需要修改application.yaml,在编译前/运行前添加以下配置。

jetty:
  connect:
    # 最大线程数
    maxThreads: 150
    # 最小线程数
    minThreads: 10
    # 线程最大空闲时间
    idleTimeout: 30000

文章引用

Springboot以Jetty为容器实现http重定向到https
springboot使用tomcat或jetty开通http,https端口

评论交流

文章目录