테스트용 인증서 발급
ca 인증서 발급
1
2
3
4
5
6
7
8
| openssl req \
-newkey rsa:4096 \
-x509 \
-keyout ca.key \
-out ca.crt \
-days 30 \
-nodes \
-subj "/CN=my_ca"
|
서버 인증서 발급
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| openssl req \
-newkey rsa:4096 \
-keyout server.key \
-out server.csr \
-nodes \
-days 30 \
-subj "/CN=localhost"
openssl x509 \
-req \
-in server.csr \
-out server.crt \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-days 30
|
클라이언트 인증서 발급
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| openssl req \
-newkey rsa:4096 \
-keyout client.key \
-out client.csr \
-nodes \
-days 30 \
-subj "/CN=client/serialNumber=110111-7107728"
openssl x509 \
-req \
-in client.csr \
-out client.crt \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-days 30
|
nginx 세팅
nginx install (docker)
1
2
3
4
5
6
7
8
9
10
11
12
13
| # docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:1.16.1
ports:
- "8443:443"
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf # nginx 설정 파일 경로
- ./server/:/etc/ssl/ # 서버 인증서 폴더 경로
- ./ca/ca.crt:/etc/nginx/client_certs/ca.crt # ca 인증서 경로
|
1
| $ docker-compose up --build
|
nginx 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| # default.conf
server {
listen 443 ssl;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
ssl_certificate /etc/ssl/server.crt;
ssl_certificate_key /etc/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_client_certificate /etc/nginx/client_certs/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
location / {
if ($ssl_client_verify != SUCCESS) { return 403; }
proxy_set_header SSL_Client_Issuer $ssl_client_i_dn;
proxy_set_header SSL_Client $ssl_client_s_dn;
proxy_set_header SSL_Client_Verify $ssl_client_verify;
proxy_set_header SSL_CLIENT_ESCAPED_CERT $ssl_client_escaped_cert; # urlencoded된 client 인증서를 헤더에 삽입
proxy_pass http://host.docker.internal:9090;
}
}
|
host.docker.internal
: docker 내부에서 로컬을 바라볼 때 사용하는 주소
client에서 nginx로 요청 보내기
postman 사용
SETTINGS에서 ca, client 인증서 등록 (아래 사진 참조)

요청 보내기
포스트맨에서 알아서 헤더에 인증서 삽입해주므로 헤더 세팅 필요 없음

요청 세부

curl 이용
1
2
3
4
| curl https://localhost:8443/test \
--cacert ca.crt \
--key client.key \
--cert client.crt
|
WAS에서 헤더에 삽입된 인증서 뽑아내기
1
2
3
4
5
| @GetMapping("/test")
fun test(req: HttpServletRequest): String {
val rawClientCert = req.getHeader("ssl_client_escaped_cert")
return rawClientCert
}
|
What to do next
rawClientCert를 X509Certificate
타입으로 변환시킨 다음, 인증서 안에 있는 항목을 뽑아낼 수 있다.