본문 바로가기
Java

[JAVA] Netty에 SSL 적용하기

by teamnova 2023. 10. 13.
728x90

안녕하세요

이번 시간에는 Netty WebSocket 서버에 SSL 을 적용해보겠습니다.

 

Netty로 WebSocket 서버를 만드는 방법은 다음 글을 참고해주세요.

 

1. SSL 인증서 가져오기

 

2. /etc/ssl 디렉토리에 넣기

예제에서는 다음과 같이 넣었습니다.

/etc/ssl/ca_bundle.crt

/etc/ssl/certificate.crt

/etc/ssl/private/private.key

 

3. 다음 명령어로 private.key 의 PKCS8 형식 파일을 만들어줍니다.

예제에서는 private_netty.key 파일을 따로 만들었습니다.

openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private.key -out private_netty.key

 

4. Main.java 에 코드 삽입

Main.java 코드에 다음 코드를 삽입해줍니다.

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;
SslContext sslCtx = SslContextBuilder.forServer(new File("/etc/ssl/certificate.crt"), new File("/etc/ssl/private/private_netty.key"), null).build();
sslCtx.newHandler(ch.alloc())

 

전체 Main.java 코드는 다음과 같습니다.

package com.bardlind.ws;

import com.bardlind.ws.playerinfo.Player;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketFrameAggregator;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;

import java.io.File;
import java.util.ArrayList;

public class Main {

    private static int PORT = 4000;

    public static ArrayList<Player> playerArrayList = new ArrayList<>();
    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        SslContext sslCtx = SslContextBuilder.forServer(new File("/etc/ssl/certificate.crt"), new File("/etc/ssl/private/private_netty.key"), null).build();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<Channel>() {
                        @Override
                        protected void initChannel(Channel ch) {
                            ch.pipeline().addLast(
                                    sslCtx.newHandler(ch.alloc()),
                                    new HttpServerCodec(),
                                    new HttpObjectAggregator(65536),
                                    new WebSocketFrameAggregator(65536),
                                    new WebSocketServerProtocolHandler("/websocket"),
                                    new WebSocketEchoServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture future = b.bind(PORT).sync();
            future.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

 

5. 빌드 및 실행

다음 명령어로 빌드 후 실행.

mvn clean install
mvn exec:java

 

 

6. 참고자료

https://stackoverflow.com/questions/8290435/convert-pem-traditional-private-key-to-pkcs8-private-key