일단은 개념정리를 먼저 하자면 CA(Certificate Authority)라는 곳에서 클라이언트와 서버 사이에서 인증서를 가지고 맞는 클라이언트인지 검증을 해주는데 평소의 인터넷에서 사용시에는 공신력이 있는 민간 기업이 CA를 맡고 있다. CSR(Certificate Signing Request)란 CA에게 인증서 발급을 해달라고 요청하는 파일 포맷을 말한다. CSR에는 인증서 발급을 해달라고 요청하는 곳의 기관이름이나 국가 등의 정보가 포함되어 있다.
SSC(Self Signed Certificate)란 민간 기업(CA)를 사용하지 않고 스스로 root ca라는 내가 사용할 가상의 CA를 만든후, 내가 만든 키로 서명해서 최상위 인증기관의 인증서를 만들어서 사용하는걸 self signed certificate라고 한다. 즉
유저가 CSR을 사용해서 CA에게 인증서 요청을 보내면 CA에서 인증서를 발급해준다는 얘기이다.
self signed certificate를 만들고 사용해보자. 첫번째로 ROOT CA(최상위 인증기관)와 관련된것들을 만들어보자. 1. root ca가 사용할 key 생성.
openssl genrsa -aes256 -out rootca.key 2048
2. 위에서 만든 키로 CSR을 만들건데 CSR을 만들때는 config가 필요하다. config에는 위에서 언급했듯이 CSR을 할 때 필요한 기관이름이나 국가 등등의 정보가 포함되어 있다.
rootca.conf
[req]
default_bits = 2048
default_md = sha1
default_keyfile = rootca.key
distinguished_name = req_distinguished_name
extensions = v3_ca
req_extensions = v3_ca
[v3_ca]
basicConstraints = critical, CA:TRUE, pathlen:0
subjectKeyIdentifier = hash
##authorityKeyIdentifier = keyid:always, issuer:always
keyUsage = keyCertSign, cRLSign
nsCertType = sslCA, emailCA, objCA
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = KR
countryName_min = 2
countryName_max = 2
organizationName = Organization Name (eg, company)
organizationName_default = test_company Inc.
organizationalUnitName = test_name (eg, section)
organizationalUnitName_default = test_team
commonName = Common Name (eg, your name or your server's hostname)
commonName_default = test_self_signed_ca
commonName_max = 64
이제 위와 같은 과정들을 거치면서 다음과 같은 파일이 만들어졌다. rootca.key -> rootca용 내가 만든 키 rootca.conf -> csr과 rootca 인증서를 만들기 위한 설정 파일. rootca.csf -> rootca 인증서 요청을 하기 위한 csr파일. rootca.crt -> rootca 인증서. (openssl x509 -text -in ./rootca.crt 로 잘 만들었는지 확인이 가능하다.)
그리고 이제는 rootca와 관련된 것들이 만들어졌으니 내가 사용할 인증서를 만들어보자. 위에서 적었듯이 원래는 사설 ca에서 인증을 받아야 하지만 self signed certificate은 내가 스스로 싸인해서 만든 root ca를 사용한다. 위에서 rootca를 만들때와 절차가 비슷하다.
1. 내가사용할 key 생성.
openssl genrsa -aes256 -out test.key 2048
2. Passphrase를 키에서 제거. 위의 링크에 따르면 아래처럼 작업을 해서 비밀번호를 입력하지 않아도 되도록 만들수 있다고 한다. 제거하지 않으면 httpd구동때마다 항상 입력해야 하므로 귀찮지 않게 이걸 제거해주는 과정이라고 한다.
3. 내가 사용할 CSR생성. 이번에도 conf가 필요한데 myhost.conf라고 이름짓고 만들어본다. 내부 내용은 위의 링크에 나온것에서 이름만 몇개 바꿨다.
myhost.conf
[req]
default_bits = 2048
default_md = sha1
default_keyfile = rootca.key
distinguished_name = req_distinguished_name
extensions = v3_user
## 인증서 요청시에도 extension 이 들어가면 authorityKeyIdentifier 를 찾지 못해 에러가 나므로 막아둔다.
## req_extensions = v3_user
[v3_user]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
authorityKeyIdentifier = keyid,issuer
subjectKeyIdentifier = hash
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
## SSL 용 확장키 필드
extendedKeyUsage = serverAuth,clientAuth
subjectAltName = @alt_names
[alt_names]
## Subject AltName의 DNSName field에 SSL Host 의 도메인 이름을 적어준다.
## 멀티 도메인일 경우 *.lesstif.com 처럼 쓸 수 있다.
DNS.1 = mytest.net
[req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = KR
countryName_min = 2
countryName_max = 2
# 회사명 입력
organizationName = Organization Name (eg, company)
organizationName_default = mycompany Inc.
# 부서 입력
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = myorganization
# SSL 서비스할 domain 명 입력
commonName = Common Name (eg, your name or your server's hostname)
commonName_default = mytest.net
commonName_max = 64
2. 그리고 위 링크에 나온것처럼 nginx.conf를 설정해주고 리로드해준다. 아래 설정파일에서 주의해야할건 ssl_certificate와 ssl_certificate_key는 내가 만든 rootca가 아닌, 위에서 만든 test.crt와 test.key를 넣는다는거다. 꼭 아래처럼 확장자가 .pem으로 끝나지 않아도 된다.
worker_processes 4;
worker_rlimit_nofile 40000;
events {
worker_connections 8192;
}
http {
upstream rancher {
server IP_NODE_1:80;
server IP_NODE_2:80;
server IP_NODE_3:80;
}
map $http_upgrade $connection_upgrade {
default Upgrade;
'' close;
}
server {
listen 443 ssl http2;
server_name FQDN;
ssl_certificate /certs/fullchain.pem;
ssl_certificate_key /certs/privkey.pem;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://rancher;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# This allows the ability for the execute shell window to remain open for up to 15 minutes. Without this parameter, the default is 1 minute and will automatically close.
proxy_read_timeout 900s;
proxy_buffering off;
}
}
server {
listen 80;
server_name FQDN;
return 301 https://$server_name$request_uri;
}
}
4. 위처럼 ingress.tls.source를 통해 파일에서 가져온다고 했다. 위처럼 랜쳐는 설치되었지만 certificate를 넣어줘야 한다. 위의 링크에도 나와있지만 요 링크에서 certificate를 추가하는 방법이 나와있다. 1) 사용자 인증서 추가. 아래의 tls.crt, tls.key는 rootca의 것이 아닌 위에서 만든 test.crt, test.key이다.